diff --git a/ansible/playbooks/dataverse.yaml b/ansible/playbooks/dataverse.yaml new file mode 100644 index 000000000..eb94937d9 --- /dev/null +++ b/ansible/playbooks/dataverse.yaml @@ -0,0 +1,5 @@ +- hosts: dataverse + sudo: yes + sudo_user: root + roles: + - role: dataverse diff --git a/ansible/playbooks/rserve.yaml b/ansible/playbooks/rserve.yaml new file mode 100644 index 000000000..a2ed1a0cd --- /dev/null +++ b/ansible/playbooks/rserve.yaml @@ -0,0 +1,5 @@ +- hosts: rserve + sudo: yes + sudo_user: root + roles: + - role: rserve diff --git a/ansible/roles/dataverse/README.md b/ansible/roles/dataverse/README.md new file mode 100644 index 000000000..22fbdf30e --- /dev/null +++ b/ansible/roles/dataverse/README.md @@ -0,0 +1,16 @@ +# Dataverse Ansible role + +This [Ansible][ansible] role aims to install [Dataverse][dataverse] and its prerequisites. +The role installs PostgreSQL 9.3, GlassFish 4.1 and other prerequisites, then deploys Dataverse 4.2.1 +into GlassFish. + +## Usage: + ansible-playbook -i [-u ] [-s] [-K] -e @ [-v] dataverse.yaml + +The role currently supports CentOS 7 with all services running on the same machine, but hopes to become OS-agnostic and support multiple nodes for scalability. + +This is a community effort, only distantly supported by [IQSS][iqss]. The role is under active development - pull requests, suggestions and other contributions are welcome! + +[ansible]: http://ansible.com +[dataverse]: https://dataverse.org +[iqss]: http://www.iq.harvard.edu diff --git a/ansible/roles/dataverse/dataverse.yaml b/ansible/roles/dataverse/dataverse.yaml new file mode 100644 index 000000000..eb94937d9 --- /dev/null +++ b/ansible/roles/dataverse/dataverse.yaml @@ -0,0 +1,5 @@ +- hosts: dataverse + sudo: yes + sudo_user: root + roles: + - role: dataverse diff --git a/ansible/roles/dataverse/files/attribute-map.xml b/ansible/roles/dataverse/files/attribute-map.xml new file mode 100644 index 000000000..f6386b620 --- /dev/null +++ b/ansible/roles/dataverse/files/attribute-map.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ansible/roles/dataverse/files/dataverse-idp-metadata.xml b/ansible/roles/dataverse/files/dataverse-idp-metadata.xml new file mode 100644 index 000000000..07970b26c --- /dev/null +++ b/ansible/roles/dataverse/files/dataverse-idp-metadata.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + testshib.org + + TestShib Test IdP + TestShib IdP. Use this as a source of attributes for your test SP. + https://idp.testshib.org/idp/images/logo.jpg + + + + + + + MIIEDjCCAvagAwIBAgIBADANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzEV + MBMGA1UECBMMUGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1cmdoMREwDwYD + VQQKEwhUZXN0U2hpYjEZMBcGA1UEAxMQaWRwLnRlc3RzaGliLm9yZzAeFw0wNjA4 + MzAyMTEyMjVaFw0xNjA4MjcyMTEyMjVaMGcxCzAJBgNVBAYTAlVTMRUwEwYDVQQI + EwxQZW5uc3lsdmFuaWExEzARBgNVBAcTClBpdHRzYnVyZ2gxETAPBgNVBAoTCFRl + c3RTaGliMRkwFwYDVQQDExBpZHAudGVzdHNoaWIub3JnMIIBIjANBgkqhkiG9w0B + AQEFAAOCAQ8AMIIBCgKCAQEArYkCGuTmJp9eAOSGHwRJo1SNatB5ZOKqDM9ysg7C + yVTDClcpu93gSP10nH4gkCZOlnESNgttg0r+MqL8tfJC6ybddEFB3YBo8PZajKSe + 3OQ01Ow3yT4I+Wdg1tsTpSge9gEz7SrC07EkYmHuPtd71CHiUaCWDv+xVfUQX0aT + NPFmDixzUjoYzbGDrtAyCqA8f9CN2txIfJnpHE6q6CmKcoLADS4UrNPlhHSzd614 + kR/JYiks0K4kbRqCQF0Dv0P5Di+rEfefC6glV8ysC8dB5/9nb0yh/ojRuJGmgMWH + gWk6h0ihjihqiu4jACovUZ7vVOCgSE5Ipn7OIwqd93zp2wIDAQABo4HEMIHBMB0G + A1UdDgQWBBSsBQ869nh83KqZr5jArr4/7b+QazCBkQYDVR0jBIGJMIGGgBSsBQ86 + 9nh83KqZr5jArr4/7b+Qa6FrpGkwZzELMAkGA1UEBhMCVVMxFTATBgNVBAgTDFBl + bm5zeWx2YW5pYTETMBEGA1UEBxMKUGl0dHNidXJnaDERMA8GA1UEChMIVGVzdFNo + aWIxGTAXBgNVBAMTEGlkcC50ZXN0c2hpYi5vcmeCAQAwDAYDVR0TBAUwAwEB/zAN + BgkqhkiG9w0BAQUFAAOCAQEAjR29PhrCbk8qLN5MFfSVk98t3CT9jHZoYxd8QMRL + I4j7iYQxXiGJTT1FXs1nd4Rha9un+LqTfeMMYqISdDDI6tv8iNpkOAvZZUosVkUo + 93pv1T0RPz35hcHHYq2yee59HJOco2bFlcsH8JBXRSRrJ3Q7Eut+z9uo80JdGNJ4 + /SJy5UorZ8KazGj16lfJhOBXldgrhppQBb0Nq6HKHguqmwRfJ+WkxemZXzhediAj + Geka8nz8JjwxpUjAiSWYKLtJhGEaTqCYxCCX2Dw+dOTqUzHOZ7WKv4JXPK5G/Uhr + 8K/qhmFT2nIQi538n6rVYLeWj8Bbnl+ev0peYzxFyF5sQA== + + + + + + + + + + + + + urn:mace:shibboleth:1.0:nameIdentifier + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + + + + + + + + MIIEDjCCAvagAwIBAgIBADANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzEV + MBMGA1UECBMMUGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1cmdoMREwDwYD + VQQKEwhUZXN0U2hpYjEZMBcGA1UEAxMQaWRwLnRlc3RzaGliLm9yZzAeFw0wNjA4 + MzAyMTEyMjVaFw0xNjA4MjcyMTEyMjVaMGcxCzAJBgNVBAYTAlVTMRUwEwYDVQQI + EwxQZW5uc3lsdmFuaWExEzARBgNVBAcTClBpdHRzYnVyZ2gxETAPBgNVBAoTCFRl + c3RTaGliMRkwFwYDVQQDExBpZHAudGVzdHNoaWIub3JnMIIBIjANBgkqhkiG9w0B + AQEFAAOCAQ8AMIIBCgKCAQEArYkCGuTmJp9eAOSGHwRJo1SNatB5ZOKqDM9ysg7C + yVTDClcpu93gSP10nH4gkCZOlnESNgttg0r+MqL8tfJC6ybddEFB3YBo8PZajKSe + 3OQ01Ow3yT4I+Wdg1tsTpSge9gEz7SrC07EkYmHuPtd71CHiUaCWDv+xVfUQX0aT + NPFmDixzUjoYzbGDrtAyCqA8f9CN2txIfJnpHE6q6CmKcoLADS4UrNPlhHSzd614 + kR/JYiks0K4kbRqCQF0Dv0P5Di+rEfefC6glV8ysC8dB5/9nb0yh/ojRuJGmgMWH + gWk6h0ihjihqiu4jACovUZ7vVOCgSE5Ipn7OIwqd93zp2wIDAQABo4HEMIHBMB0G + A1UdDgQWBBSsBQ869nh83KqZr5jArr4/7b+QazCBkQYDVR0jBIGJMIGGgBSsBQ86 + 9nh83KqZr5jArr4/7b+Qa6FrpGkwZzELMAkGA1UEBhMCVVMxFTATBgNVBAgTDFBl + bm5zeWx2YW5pYTETMBEGA1UEBxMKUGl0dHNidXJnaDERMA8GA1UEChMIVGVzdFNo + aWIxGTAXBgNVBAMTEGlkcC50ZXN0c2hpYi5vcmeCAQAwDAYDVR0TBAUwAwEB/zAN + BgkqhkiG9w0BAQUFAAOCAQEAjR29PhrCbk8qLN5MFfSVk98t3CT9jHZoYxd8QMRL + I4j7iYQxXiGJTT1FXs1nd4Rha9un+LqTfeMMYqISdDDI6tv8iNpkOAvZZUosVkUo + 93pv1T0RPz35hcHHYq2yee59HJOco2bFlcsH8JBXRSRrJ3Q7Eut+z9uo80JdGNJ4 + /SJy5UorZ8KazGj16lfJhOBXldgrhppQBb0Nq6HKHguqmwRfJ+WkxemZXzhediAj + Geka8nz8JjwxpUjAiSWYKLtJhGEaTqCYxCCX2Dw+dOTqUzHOZ7WKv4JXPK5G/Uhr + 8K/qhmFT2nIQi538n6rVYLeWj8Bbnl+ev0peYzxFyF5sQA== + + + + + + + + + + + + + urn:mace:shibboleth:1.0:nameIdentifier + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + TestShib Two Identity Provider + TestShib Two + http://www.testshib.org/testshib-two/ + + + Nate + Klingenstein + ndk@internet2.edu + + + diff --git a/ansible/roles/dataverse/files/jhove.conf b/ansible/roles/dataverse/files/jhove.conf new file mode 100644 index 000000000..dbe5162bb --- /dev/null +++ b/ansible/roles/dataverse/files/jhove.conf @@ -0,0 +1,39 @@ + + + /usr/local/src/jhove + utf-8 + /tmp + 131072 + 1.0 + 1024 + + edu.harvard.hul.ois.jhove.module.AiffModule + + + edu.harvard.hul.ois.jhove.module.WaveModule + + + edu.harvard.hul.ois.jhove.module.PdfModule + + + edu.harvard.hul.ois.jhove.module.Jpeg2000Module + + + edu.harvard.hul.ois.jhove.module.JpegModule + + + edu.harvard.hul.ois.jhove.module.GifModule + + + edu.harvard.hul.ois.jhove.module.TiffModule + + + edu.harvard.hul.ois.jhove.module.HtmlModule + + + edu.harvard.hul.ois.jhove.module.AsciiModule + + + edu.harvard.hul.ois.jhove.module.Utf8Module + + diff --git a/ansible/roles/dataverse/files/pg_hba.conf b/ansible/roles/dataverse/files/pg_hba.conf new file mode 100644 index 000000000..56dce9069 --- /dev/null +++ b/ansible/roles/dataverse/files/pg_hba.conf @@ -0,0 +1,6 @@ +# "local" is for Unix domain socket connections only +local all all trust +# IPv4 local connections: +host all all 127.0.0.1/32 password +# IPv6 local connections: +host all all ::1/128 password diff --git a/ansible/roles/dataverse/files/solr.conf b/ansible/roles/dataverse/files/solr.conf new file mode 100644 index 000000000..d8552d29b --- /dev/null +++ b/ansible/roles/dataverse/files/solr.conf @@ -0,0 +1,13 @@ +start on runlevel [2345] +stop on runlevel [!2345] + +kill timeout 30 +respawn + +#setuid solr +#setgid solr + +script + chdir /usr/local/solr + exec /usr/bin/java -jar start.jar +end script diff --git a/ansible/roles/dataverse/files/solr.service b/ansible/roles/dataverse/files/solr.service new file mode 100644 index 000000000..a4eabd087 --- /dev/null +++ b/ansible/roles/dataverse/files/solr.service @@ -0,0 +1,12 @@ +[Unit] +Description = Apache Solr +After = syslog.target network.target remote-fs.target nss-lookup.target + +[Service] +Type = simple +WorkingDirectory = /usr/local/solr/example +ExecStart = /usr/bin/java -jar -server /usr/local/solr/example/start.jar +Restart=on-failure + +[Install] +WantedBy = multi-user.target diff --git a/ansible/roles/dataverse/group_vars/example.vars b/ansible/roles/dataverse/group_vars/example.vars new file mode 100644 index 000000000..1ddce51d9 --- /dev/null +++ b/ansible/roles/dataverse/group_vars/example.vars @@ -0,0 +1,21 @@ +dataverse_adminpass: notPr0d +dataverse_db: dvndb +dataverse_dbhost: localhost +dataverse_dbuser: dvnuser +dataverse_dbpass: dvnsecret +dataverse_dbport: 5432 +dataverse_filesdir: /usr/local/dvn/data +dataverse_gf_user: glassfish +dataverse_gf_group: glassfish +dataverse_gf_root: /usr/local/glassfish4 +dataverse_gf_domain: domain1 +dataverse_gf_adminuser: admin +dataverse_gf_adminpass: notPr0d +dataverse_host_address: dataverse.yourinstitution.edu +dataverse_memheap: 2048 +dataverse_smtp: smtp.yourinstitution.edu +dataverse_version: 4.2.1 +rserve_host: rserve.yourinstitution.edu +rserve_user: rserve +rserve_pass: rserve +rserve_port: 6311 diff --git a/ansible/roles/dataverse/inventories/example.yaml b/ansible/roles/dataverse/inventories/example.yaml new file mode 100644 index 000000000..04532332d --- /dev/null +++ b/ansible/roles/dataverse/inventories/example.yaml @@ -0,0 +1,12 @@ +[systems] +dataverse.yourinstitution.edu + +[web-nodes] +webnode1.yourinstitution.edu +webnode2.yourinstitution.edu + +[db] +db.yourinstitution.edu + +[rserve] +rserve.yourinstitution.edu diff --git a/ansible/roles/dataverse/tasks/dataverse-install.yaml b/ansible/roles/dataverse/tasks/dataverse-install.yaml new file mode 100644 index 000000000..b27c472ee --- /dev/null +++ b/ansible/roles/dataverse/tasks/dataverse-install.yaml @@ -0,0 +1,127 @@ +--- + +# version numbers changed on github. only used this because files were missing from install.zip +#- name: clone {{ dataverse_version }} from git. optimally replace install.zip with this. +# git: repo=git://github.com/IQSS/dataverse.git dest=/tmp/dataverse_{{ dataverse_version }} version={{ dataverse_version }} +# clone=yes depth=1 accept_hostkey=true +# tags: dataverse + +- name: download dataverse installer. unarchive urls supported in ansible 2.0 + get_url: url=https://github.com/IQSS/dataverse/releases/download/v{{ dataverse_version }}/dvinstall.zip dest=/tmp mode=0644 + tags: dataverse + +- name: unzip dataverse installer + shell: unzip /tmp/dvinstall.zip -d /tmp + tags: dataverse + +- name: install jdbc driver + shell: "/bin/cp /tmp/dvinstall/pgdriver/postgresql-9.1-902.jdbc4.jar {{ dataverse_gf_root }}/glassfish/lib/" + tags: dataverse + +- name: copy jhove config + copy: src=jhove.conf dest={{ dataverse_gf_root }}/domains/glassfish/{{ dataverse_gf_domain }}/config/ owner=root group=root mode=0644 + tags: dataverse + +- name: run glassfish-setup.sh + shell: "cd /tmp/dvinstall && nohup ./glassfish-setup.sh > /tmp/glassfish-setup.out 2>&1" + become: yes + become_user: "{{ dataverse_gf_user }}" + environment: + HOST_ADDRESS: "{{ dataverse_host_address }}" + GLASSFISH_ROOT: "{{ dataverse_gf_root }}" + GLASSFISH_DOMAIN: "{{ dataverse_gf_domain }}" + FILES_DIR: "{{ dataverse_filesdir }}" + DB_NAME: "{{ dataverse_db }}" + DB_PORT: "{{ dataverse_dbport }}" + DB_HOST: "{{ dataverse_dbhost }}" + DB_USER: "{{ dataverse_dbuser }}" + DB_PASS: "{{ dataverse_dbpass }}" + RSERVE_HOST: "{{ rserve_host }}" + RSERVE_PORT: "{{ rserve_port }}" + RSERVE_USER: "{{ rserve_user }}" + RSERVE_PASS: "{{ rserve_pass }}" + SMTP_SERVER: "{{ dataserve_smtp }}" + MEM_HEAP_SIZE: "{{ dataverse_memheap }}" + tags: dataverse + +- name: deploy dataverse.war + become: yes + become_user: "{{ dataverse_gf_user }}" + shell: "nohup {{ dataverse_gf_root }}/bin/asadmin deploy /tmp/dvinstall/dataverse.war" + tags: dataverse + +- name: restart glassfish post-deployment + shell: "nohup {{ dataverse_gf_root }}/bin/asadmin restart-domain {{ dataverse_gf_domain }}" + tags: dataverse + +# my 2-core VM completes in ~30 seconds, allowing 60 +- name: give glassfish 60 seconds to wake up + pause: seconds=60 + tags: dataverse + +- name: setup-all.sh kitchen sink configuration. + shell: "cd /tmp/dvinstall && ./setup-all.sh > /tmp/setup-all.out 2>&1" + tags: dataverse + +- name: populate reference data + shell: "psql -U {{ dataverse_dbuser }} -h {{ dataverse_dbhost }} -d {{ dataverse_db }} -f /tmp/dvinstall/reference_data.sql" + environment: + PGPASSWORD: "{{ dataverse_dbpass }}" + tags: dataverse + +- name: suppress grizzly ajp warnings + become: yes + become_user: "{{ dataverse_gf_user }}" + shell: "{{ dataverse_gf_root }}/bin/asadmin set-log-levels org.glassfish.grizzly.http.server.util.RequestUtils=SEVERE" + tags: dataverse + +- name: enable Shibboleth in Glassfish + become: yes + become_user: "{{ dataverse_gf_user }}" + shell: "curl -X PUT -d true http://localhost:8080/api/admin/settings/:ShibEnabled" + tags: dataverse + +- name: Fin + debug: msg="Dataverse installation complete! Please check output logs in /tmp for further review." + tags: dataverse + +########### don't think we want the below for a production installation ########### +#- name: publish root dataverse +# shell: "cd /tmp/dataverse_{{ dataverse_version }} && ./scripts/search/tests/publish-dataverse-root" +# tags: dataverse +# +#- name: grant authusers add on root +# shell: "cd /tmp/dataverse_{{ dataverse_version }} && ./scripts/search/tests/grant-authusers-add-on-root" +# tags: dataverse +# +#- name: populate users +# shell: "cd /tmp/dataverse_{{ dataverse_version }} && ./scripts/search/populate-users" +# tags: dataverse +# +#- name: create-users +# shell: "cd /tmp/dataverse_{{ dataverse_version }} && ./scripts/search/create-users" +# tags: dataverse +# +#- name: create all and test +# shell: "cd /tmp/dataverse_{{ dataverse_version }} && ./scripts/search/tests/create-all-and-test" +# tags: dataverse +# +#- name: public spruce1 and test (do we want this?) +# shell: "cd /tmp/dataverse_{{ dataverse_version }} && ./scripts/search/tests/public-spruce1-and-test" +# tags: dataverse +# +#- name: copy admin password file +# template: src=adminpass.txt.j2 dest=/tmp/dvinstall/adminpass.txt owner={{ dataverse_gf_user }} group={{ dataverse_gf_group }} mode=0600 +# tags: dataverse +# +#- name: set admin password +# shell: "{{ dataverse_gf_root }}/bin/asadmin --user {{ dataverse_gf_adminuser }} --passwordfile /tmp/dvinstall/adminpass.txt change-admin-password" +# tags: dataverse +# +#- name: enable secure admin +# shell: "{{ dataverse_gf_root }}/bin/asadmin --user {{ dataverse_gf_adminuser }} --passwordfile /tmp/dvinstall/adminpass.txt enable-secure-admin" +# tags: dataverse +# +#- name: remove admin password hash tmp file +# file: path=/tmp/dvinstall/adminpass.txt state=absent +# tags: dataverse diff --git a/ansible/roles/dataverse/tasks/dataverse-prereqs.yaml b/ansible/roles/dataverse/tasks/dataverse-prereqs.yaml new file mode 100644 index 000000000..6c511e03f --- /dev/null +++ b/ansible/roles/dataverse/tasks/dataverse-prereqs.yaml @@ -0,0 +1,316 @@ +--- + +- name: ensure EPEL repository for RedHat7/CentOS7 + yum: name=epel-release state=latest + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: install java-1.8.0-openjdk-devel for RedHat/CentOS. Dataverse requires this version. + yum: name="{{item}}" state=latest + with_items: + - git + - httpd + - java-1.7.0-openjdk-devel + - jq + - mod_ssl + - perl + - python-psycopg2 + - unzip + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: install openjdk-8-jdk, apache, etc. for Ubuntu/Debian. + apt: name="{{item}}" state=latest update_cache=true + with_items: + - apache2 + - git + - jq + - libapache2-mod-shib2 + - openjdk-8-jdk + - perl5 + - python-psycopg2 + - unzip + when: ansible_os_family == "Debian" + tags: dataverse + +- name: install shibboleth repo for RedHat/CentOS7 + get_url: url=http://download.opensuse.org/repositories/security:/shibboleth/CentOS_7/security:shibboleth.repo + dest=/etc/yum.repos.d owner=root group=root mode=0644 + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" and + dataverse_shib == "true" + tags: dataverse + +- name: install Shibboleth RPMs for RedHat/CentOS7 + yum: name="{{item}}" state=latest + with_items: + - shibboleth + - shibboleth-embedded-ds + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" and + dataverse_shib == "true" + tags: dataverse + +# TODO: install shib on Debian/Ubuntu + +- name: install http redirect template + template: src=http.redirect.conf.j2 dest=/etc/httpd/conf.d/http.redirect.conf + owner=root group=root mode=0644 + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" and + dataverse_shib == "true" + tags: dataverse + +- name: install mod_ssl template + template: src=ssl.conf.j2 dest=/etc/httpd/conf.d/ssl.conf + owner=root group=root mode=0644 + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" and + dataverse_shib == "true" + tags: dataverse + +- name: install shibboleth2.xml template + template: src=shibboleth2.xml.j2 dest=/etc/shibboleth/shibboleth2.xml + owner=root group=root mode=0644 + when: dataverse_shib == "true" + tags: dataverse + +- name: copy attribute-map.xml file + copy: src=attribute-map.xml dest=/etc/shibboleth/attribute-map.xml + owner=root group=root mode=0644 + when: dataverse_shib == "true" + tags: dataverse + +- name: copy TestShib IdP metadata XML file + copy: src=dataverse-idp-metadata.xml dest=/etc/shibboleth/dataverse-idp-metadata.xml + owner=root group=root mode=0644 + when: dataverse_shib == "true" + tags: dataverse + +- name: enable and start shibd on RedHat / CentOS 7. + service: name=shibd enabled=yes state=started + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" and + dataverse_shib == "true" + tags: dataverse + +- name: enable and start httpd on RedHat / CentOS 7. + service: name=httpd enabled=yes state=started + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" and + dataverse_shib == "true" + tags: dataverse + +# TODO: restart shib on Debian/Ubuntu + +- name: restart apache2 on Debian/Ubuntu + service: name=apache2 state=restarted + when: ansible_os_family == "Debian" and + dataverse_shib == "true" + tags: dataverse + +- name: install postgres-9.3 repo on Redhat / CentOS 7. + yum: name=http://yum.postgresql.org/9.3/redhat/rhel-7-x86_64/pgdg-centos93-9.3-2.noarch.rpm state=present + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: install postgres-9.3 on RedHat / CentOS 7. + yum: name=postgresql93-server state=latest + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: init postgres-9.3 on RedHat / CentOS 7. + shell: /usr/pgsql-9.3/bin/postgresql93-setup initdb + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: install and init postgres-9.3 for Debian/Ubuntu + apt: pkg=postgresql-9.3 state=latest update_cache=true + when: ansible_os_family == "Debian" + tags: dataverse + +- name: install pg_hba.conf on RedHat / CentOS 7. + copy: src=pg_hba.conf dest=/var/lib/pgsql/9.3/data + owner=postgres group=postgres mode=0644 + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: enable postgres-9.3 on RedHat / CentOS 7. + service: name=postgresql-9.3 enabled=yes + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: start postgres-9.3 on RedHat / CentOS 7. + service: name=postgresql-9.3 state=started + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: install pg_hba.conf on Debian/Ubuntu + copy: src=pg_hba.conf dest=/etc/postgresql/9.3/main + owner=postgres group=postgres mode=0644 + when: ansible_os_family == "Debian" + tags: dataverse + +- name: restart postgres on Debian/Ubuntu + service: postgresql state=restarted + when: ansible_os_family == "Debian" + tags: dataverse + +- name: create glassfish postgres database + postgresql_db: name={{ dataverse_db }} + tags: dataverse + +- name: create glassfish postgres user, set permissions + postgresql_user: db={{ dataverse_db }} name={{ dataverse_dbuser }} + password={{ dataverse_dbpass }} + role_attr_flags=NOSUPERUSER,CREATEDB,CREATEROLE,INHERIT,LOGIN + tags: dataverse + +- name: download glassfish4. unarchive urls supported in ansible 2.0 + get_url: url=http://dlc-cdn.sun.com/glassfish/4.1/release/glassfish-4.1.zip + dest=/tmp mode=0644 + tags: dataverse + +- name: unzip glassfish. unarchive urls supported in ansible 2.0 + shell: unzip /tmp/glassfish-4.1.zip -d /tmp + tags: dataverse + +- name: ensure dataverse_gf_root exists + file: path={{ dataverse_gf_root }} state=directory + owner=root group=root mode=0755 + tags: dataverse + +- name: copy glassfish into desired glassfish root. (synchronize module barfs even with pty, file wants to copy local/remote. shell it is.) + shell: "/bin/cp -r /tmp/glassfish4/* {{ dataverse_gf_root }}" + tags: dataverse + +- name: create glassfish service group + group: name={{ dataverse_gf_group }} state=present + tags: dataverse + +- name: create glassfish service account + user: name={{ dataverse_gf_user }} group={{ dataverse_gf_group }} + tags: dataverse + +- name: glassfish service account should own {{ dataverse_gf_domain }} + file: path={{ dataverse_gf_root }}/glassfish/domains/{{ dataverse_gf_domain }} owner={{ dataverse_gf_user }} + group={{ dataverse_gf_group }} state=directory recurse=yes + tags: dataverse + +- name: glassfish should own dataverse_filesdir + file: path={{ dataverse_filesdir }} state=directory + owner={{ dataverse_gf_user }} group={{ dataverse_gf_group }} + tags: dataverse + +- name: remove old weld jar + shell: /bin/rm {{ dataverse_gf_root }}/glassfish/modules/weld-osgi-bundle.jar + tags: dataverse + +- name: get patched weld jar + get_url: url=http://central.maven.org/maven2/org/jboss/weld/weld-osgi-bundle/2.2.10.SP1/weld-osgi-bundle-2.2.10.SP1-glassfish4.jar + dest={{ dataverse_gf_root }}/glassfish/modules owner=root group=root mode=0644 + tags: dataverse + +- name: remove old grizzly jar + file: name={{ dataverse_gf_root }}/glassfish/modules/glassfish-grizzly-extra-all.jar state=absent + tags: dataverse + +- name: get patched grizzly jar + get_url: url=http://guides.dataverse.org/en/latest/_static/installation/files/issues/2180/grizzly-patch/glassfish-grizzly-extra-all.jar + dest={{ dataverse_gf_root }}/glassfish/modules owner=root group=root mode=0644 + tags: dataverse + +- name: install glassfish systemd conf file for RedHat / CentOS7 + template: src=glassfish.service.j2 dest=/usr/lib/systemd/system/glassfish.service + owner=root group=root mode=0644 + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: reload systemd on RedHat/CentOS7 + shell: systemctl daemon-reload + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: enable glassfish on RedHat/CentOS7 - but don't start it with systemd during Ansible installation + service: name=glassfish enabled=yes + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: install glassfish upstart script for Debian/Ubuntu + template: src=glassfish.conf.j2 dest=/etc/init + owner=root group=root mode=0644 + when: ansible_os_family == "Debian" + tags: dataverse + +- name: start glassfish with asadmin so subsequent Ansible-initiated restarts succeed on RedHat/CentOS + become: yes + become_user: "{{ dataverse_gf_user }}" + shell: "nohup {{ dataverse_gf_root }}/bin/asadmin start-domain" + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: start glassfish on Debian/Ubuntu + service: glassfish state=started + when: ansible_os_family == "Debian" + tags: dataverse + +- name: download solr. unarchive urls supported in 2.0. + get_url: url=https://archive.apache.org/dist/lucene/solr/4.6.0/solr-4.6.0.tgz + dest=/tmp mode=0644 + tags: dataverse + +- name: unpack solr + shell: tar xvfz /tmp/solr-4.6.0.tgz -C /usr/local + tags: dataverse + +- name: move solr + command: mv /usr/local/solr-4.6.0 /usr/local/solr + tags: dataverse + +#- name: get updated solr schema +# get_url: url="https://github.com/IQSS/dataverse/releases/download/v{{ dataverse_version }}/schema.xml" +# dest=/usr/local/solr/example/solr/collection1/conf/ +# owner={{ dataverse_gf_user }} group={{ dataverse_gf_group }} mode=0644 +# tags: dataverse + +- name: get most recent solr schema + get_url: url="https://github.com/IQSS/dataverse/releases/download/v4.2.2/schema.xml" + dest=/usr/local/solr/example/solr/collection1/conf/ + owner={{ dataverse_gf_user }} group={{ dataverse_gf_group }} mode=0644 + tags: dataverse + +- name: install solr upstart script for Debian/Ubuntu + copy: src=solr.conf dest=/etc/init owner=root group=root mode=0644 + when: ansible_os_family == "Debian" + tags: dataverse + +- name: install solr systemd conf file for RedHat/CentOS + copy: src=solr.service dest=/usr/lib/systemd/system + owner=root group=root mode=0644 + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: reload systemd + shell: systemctl daemon-reload + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse + +- name: enable solr on boot, start solr + service: name=solr enabled=yes state=started + when: ansible_os_family == "RedHat" and + ansible_distribution_major_version == "7" + tags: dataverse diff --git a/ansible/roles/dataverse/tasks/main.yaml b/ansible/roles/dataverse/tasks/main.yaml new file mode 100644 index 000000000..868e96823 --- /dev/null +++ b/ansible/roles/dataverse/tasks/main.yaml @@ -0,0 +1,4 @@ +--- + +- include: dataverse-prereqs.yaml +- include: dataverse-install.yaml diff --git a/ansible/roles/dataverse/templates/adminpass.txt.j2 b/ansible/roles/dataverse/templates/adminpass.txt.j2 new file mode 100644 index 000000000..17eddb67e --- /dev/null +++ b/ansible/roles/dataverse/templates/adminpass.txt.j2 @@ -0,0 +1 @@ +AS_ADMIN_PASSWORD={{ dataverse_gf_adminpass }} diff --git a/ansible/roles/dataverse/templates/gfclient.j2 b/ansible/roles/dataverse/templates/gfclient.j2 new file mode 100644 index 000000000..061bf200e --- /dev/null +++ b/ansible/roles/dataverse/templates/gfclient.j2 @@ -0,0 +1,2 @@ +# Do not edit this file by hand. Use login interface instead. +asadmin://{{ dataverse_gf_adminuser }}@localhost:4848 diff --git a/ansible/roles/dataverse/templates/glassfish.conf.j2 b/ansible/roles/dataverse/templates/glassfish.conf.j2 new file mode 100644 index 000000000..3c85f9609 --- /dev/null +++ b/ansible/roles/dataverse/templates/glassfish.conf.j2 @@ -0,0 +1,20 @@ +# Job configuration info +description "GlassFish4" + +# Instance per domain +instance {{ dataverse_gf_domain }} + +# log to server.log +console none + +# Run as glassfish service account +setuid {{ dataverse_gf_user }} +setgid {{ dataverse_gf_group }} +umask 0022 +chdir {{ dataverse_gf_root }} + +# start +exec {{ dataverse_gf_root }}/bin/asadmin start-domain {{ dataverse_gf_domain }} + +# stop +pre-stop exec {{ dataverse_gf_root }}/bin/asadmin stop-domain {{ dataverse_gf_domain }} diff --git a/ansible/roles/dataverse/templates/glassfish.service.j2 b/ansible/roles/dataverse/templates/glassfish.service.j2 new file mode 100644 index 000000000..028470bd7 --- /dev/null +++ b/ansible/roles/dataverse/templates/glassfish.service.j2 @@ -0,0 +1,13 @@ +[Unit] +Description = GlassFish Server v4.1 +After = syslog.target network.target + +[Service] +User={{ dataverse_gf_user }} +ExecStart = /usr/bin/java -jar {{ dataverse_gf_root }}/glassfish/lib/client/appserver-cli.jar start-domain +ExecStop = /usr/bin/java -jar {{ dataverse_gf_root }}/glassfish/lib/client/appserver-cli.jar stop-domain +ExecReload = /usr/bin/java -jar {{ dataverse_gf_root }}/glassfish/lib/client/appserver-cli.jar restart-domain +Type = forking + +[Install] +WantedBy = multi-user.target diff --git a/ansible/roles/dataverse/templates/http.redirect.conf.j2 b/ansible/roles/dataverse/templates/http.redirect.conf.j2 new file mode 100644 index 000000000..b18cc292f --- /dev/null +++ b/ansible/roles/dataverse/templates/http.redirect.conf.j2 @@ -0,0 +1,19 @@ + + +ServerName {{ dataverse_host_address }} + +# From https://wiki.apache.org/httpd/RewriteHTTPToHTTPS + +RewriteEngine On +# This will enable the Rewrite capabilities + +RewriteCond %{HTTPS} !=on +# This checks to make sure the connection is not already HTTPS + +RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L] +# This rule will redirect users from their original location, to the same location but using HTTPS. +# i.e. http://www.example.com/foo/ to https://www.example.com/foo/ +# The leading slash is made optional so that this will work either in httpd.conf +# or .htaccess context + + diff --git a/ansible/roles/dataverse/templates/install.de.j2 b/ansible/roles/dataverse/templates/install.de.j2 new file mode 100755 index 000000000..eb773ee51 --- /dev/null +++ b/ansible/roles/dataverse/templates/install.de.j2 @@ -0,0 +1,1195 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use Getopt::Long; +use Socket; +use File::Copy; + +my $verbose; +my $pg_only; +my $hostname; +my $gfdir; +my $mailserver; +my $yes; +my $force; +my $nogfpasswd; +my ($rez) = GetOptions( + #"length=i" => \$length, # numeric + #"file=s" => \$data, # string + "verbose" => \$verbose, + "pg_only" => \$pg_only, + "hostname=s" => \$hostname, + "gfdir=s" => \$gfdir, + "mailserver=s" => \$mailserver, + "y|yes" => \$yes, + "f|force" => \$force, + "nogfpasswd" => \$nogfpasswd, +); + +my $postgresonly = 0; + +my @CONFIG_VARIABLES = ( + 'HOST_DNS_ADDRESS', + 'GLASSFISH_DIRECTORY', + 'MAIL_SERVER', + + 'POSTGRES_SERVER', + 'POSTGRES_PORT', + 'POSTGRES_DATABASE', + 'POSTGRES_USER', + 'POSTGRES_PASSWORD', + + 'RSERVE_HOST', + 'RSERVE_PORT', + 'RSERVE_USER', + 'RSERVE_PASSWORD' + +); + +if ($pg_only) { +# exit; + @CONFIG_VARIABLES = + ( 'POSTGRES_SERVER', 'POSTGRES_PORT', 'POSTGRES_DATABASE', 'POSTGRES_USER', 'POSTGRES_PASSWORD' ); + + $postgresonly = 1; +} + +# TODO: +# supply pre-set, default values in a text file; +# this way we can provide different sets of default +# values, for the installers intended for different +# groups of users - local developers vs. "real" +# dataverse users. + +my %CONFIG_DEFAULTS = ( + 'HOST_DNS_ADDRESS', '{{ inventory_hostname }}', + 'GLASSFISH_DIRECTORY', '/usr/local/glassfish4', + 'MAIL_SERVER', '{{ dataverse_relay }}', + + 'POSTGRES_SERVER', 'localhost', + 'POSTGRES_PORT', 5432, + 'POSTGRES_DATABASE', '{{ dataverse_db }}', + 'POSTGRES_USER', '{{ dataverse_dbuser }}', + 'POSTGRES_PASSWORD', '{{ dataverse_dbpass }}', + + 'RSERVE_HOST', '{{ rserve_host }}', + 'RSERVE_PORT', {{ rserve_port }}, + 'RSERVE_USER', '{{ rserve_user }}', + 'RSERVE_PASSWORD', '{{ rserve_pass }}' + +); + +my %CONFIG_PROMPTS = ( + 'HOST_DNS_ADDRESS', 'Internet Address of your host', + 'GLASSFISH_DIRECTORY', 'Glassfish Directory', + 'MAIL_SERVER', 'SMTP (mail) server to relay notification messages', + + 'POSTGRES_SERVER', 'Postgres Server', + 'POSTGRES_PORT', 'Postgres Server Port', + 'POSTGRES_DATABASE', 'Name of the Postgres Database', + 'POSTGRES_USER', 'Name of the Postgres User', + 'POSTGRES_PASSWORD', 'Postgres user password', + + 'RSERVE_HOST', 'Rserve Server', + 'RSERVE_PORT', 'Rserve Server Port', + 'RSERVE_USER', 'Rserve User Name', + 'RSERVE_PASSWORD', 'Rserve User Password' + +); + +# Supported Posstgres JDBC drivers: +# (have to be configured explicitely, so that Perl "taint" (security) mode +# doesn't get paranoid) + +my %POSTGRES_DRIVERS = ( + # "8_4", "postgresql-8.3-603.jdbc4.jar", + "8_4", "postgresql-8.4-703.jdbc4.jar", + "9_0", "postgresql-9.0-802.jdbc4.jar", + "9_1", "postgresql-9.1-902.jdbc4.jar", + "9_2", "postgresql-9.1-902.jdbc4.jar", + "9_3", "postgresql-9.1-902.jdbc4.jar" +); + +# A few preliminary checks: + +# user -- must be root: + +my $user_real = `who am i`; +chop $user_real; +$user_real =~ s/ .*$//; + +if ( $< != 0 ) { + print STDERR "\nERROR: You must be logged in as root to run the installer.\n\n"; + exit 1; +} + +# OS: + +my $uname_out = `uname -a`; + +# hostname: + +my $hostname_from_cmdline = `hostname`; +chop $hostname_from_cmdline; + +if ($hostname) { + $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'} = $hostname; +} +else { + $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'} = $hostname_from_cmdline; +} + +if ($mailserver) { + $CONFIG_DEFAULTS{'MAIL_SERVER'} = $mailserver; +} + +if ($gfdir) { + $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'} = $gfdir; +} + +print "\nWelcome to the Dataverse installer.\n"; +unless ($postgresonly) { + print "You will be guided through the process of setting up a NEW\n"; + print "instance of the dataverse application\n"; +} +else { + print "You will be guided through the process of configuring the\n"; + print "LOCAL instance of PostgreSQL database for use by the DVN\n"; + print "application.\n"; +} + +my @uname_tokens = split( " ", $uname_out ); + +my $WORKING_OS; +if ( $uname_tokens[0] eq "Darwin" ) { + print "\nThis appears to be a MacOS X system; good.\n"; + # TODO: check the OS version + + $WORKING_OS = "MacOSX"; +} +elsif ( $uname_tokens[0] eq "Linux" ) { + if ( -f "/etc/redhat-release" ) { + print "\nThis appears to be a RedHat system; good.\n"; + $WORKING_OS = "RedHat"; + # TODO: check the distro version + } + else { + print "\nThis appears to be a non-RedHat Linux system;\n"; + print "this installation *may* succeed; but we're not making any promises!\n"; + $WORKING_OS = "Linux"; + } +} +else { + print "\nWARNING: This appears to be neither a Linux or MacOS X system!\n"; + print "This installer script will most likely fail. Please refer to the\n"; + print "DVN Installers Guide for more information.\n\n"; + + $WORKING_OS = "Unknown"; + + print "Do you wish to continue?\n [y/n] "; + + my $yesnocont; + + if ($yes) { + $yesnocont = "y"; + } + else { + print "here"; + exit; + $yesnocont = <>; + chop $yesnocont; + } + + while ( $yesnocont ne "y" && $yesnocont ne "n" ) { + print "Please enter 'y' or 'n'!\n"; + print "(or ctrl-C to exit the installer)\n"; + $yesnocont = <>; + chop $yesnocont; + } + + if ( $yesnocont eq "n" ) { + exit 0; + } + +} + +ENTERCONFIG: +# +#print "\n"; +#print "Please enter the following configuration values:\n"; +#print "(hit [RETURN] to accept the default value)\n"; +#print "\n"; +# +#for my $ENTRY (@CONFIG_VARIABLES) { +# print $CONFIG_PROMPTS{$ENTRY} . ": "; +# print "[" . $CONFIG_DEFAULTS{$ENTRY} . "] "; +# +# my $user_entry; +# unless ($yes) { +# $user_entry = <>; +# chop $user_entry; +# } +# +# if ( $user_entry ne "" ) { +# $CONFIG_DEFAULTS{$ENTRY} = $user_entry; +# } +# +# print "\n"; +#} +# +# CONFIRM VALUES ENTERED: +# +#print "\nOK, please confirm what you've entered:\n\n"; +# +#for my $ENTRY (@CONFIG_VARIABLES) { +# print $CONFIG_PROMPTS{$ENTRY} . ": " . $CONFIG_DEFAULTS{$ENTRY} . "\n"; +#} +# +#my $yesno; +#if ($yes) { +# $yesno = "y"; +#} +#else { +# print "\nIs this correct? [y/n] "; +# $yesno = <>; +# chop $yesno; +#} +# +#while ( $yesno ne "y" && $yesno ne "n" ) { +# print "Please enter 'y' or 'n'!\n"; +# print "(or ctrl-C to exit the installer)\n"; +# $yesno = <>; +# chop $yesno; +#} +# +#if ( $yesno eq "n" ) { +# goto ENTERCONFIG; +#} +# +# VALIDATION/VERIFICATION OF THE CONFIGURATION VALUES: +# 1. VERIFY MAIL SERVER THEY CONFIGURED: + +unless ($postgresonly) { + + my ( $mail_server_iaddr, $mail_server__paddr, $mail_server_proto, $mail_server_status ); + + $mail_server_status = 1; + + unless ( $mail_server_iaddr = inet_aton( $CONFIG_DEFAULTS{'MAIL_SERVER'} ) ) { + print STDERR "Could not look up $CONFIG_DEFAULTS{'MAIL_SERVER'},\n"; + print STDERR "the host you specified as your mail server\n"; + $mail_server_status = 0; + } + + if ($mail_server_status) { + my $mail_server_paddr = sockaddr_in( 25, $mail_server_iaddr ); + $mail_server_proto = getprotobyname('tcp'); + + unless ( socket( SOCK, PF_INET, SOCK_STREAM, $mail_server_proto ) + && connect( SOCK, $mail_server_paddr ) ) + { + print STDERR "Could not establish connection to $CONFIG_DEFAULTS{'MAIL_SERVER'},\n"; + print STDERR "the address you provided for your Mail server.\n"; + print STDERR "Please select a valid mail server, and try again.\n\n"; + + $mail_server_status = 0; + } + + } + + close(SOCK); + + unless ($mail_server_status) { + goto ENTERCONFIG; + } +} + +# 2. CHECK IF THE WAR FILE IS AVAILABLE: + +print "\nChecking if the application .war file is available... "; + +# if this installation is running out of the installer zib bundle directory, +# the war file will be sitting right here, named "dataverse.war": + +my $WARFILE_LOCATION = "dataverse.war"; + +# but if it's not here, this is probably a personal development +# setup, so their build should be up in their source tree: + +unless ( -f $WARFILE_LOCATION ) { + my $DATAVERSE_VERSION = ""; + my $DATAVERSE_POM_FILE = "../../pom.xml"; + if ( -f $DATAVERSE_POM_FILE ) + { + open DPF, $DATAVERSE_POM_FILE; + my $pom_line; + while ($pom_line=) + { + chop $pom_line; + if ($pom_line =~/^[ \t]*([0-9\.]+)<\/version>/) + { + $DATAVERSE_VERSION=$1; + last; + } + } + close DPF; + + if ($DATAVERSE_VERSION ne "") { + $WARFILE_LOCATION = "../../target/dataverse-" . $DATAVERSE_VERSION . ".war"; + } + } +} + +# But, if the war file cannot be found in either of the 2 +# places - we'll just have to give up: + +unless ( -f $WARFILE_LOCATION ) { + print "\nWARNING: Can't find the project .war file!\n"; + print "\tAre you running the installer in the right directory?\n"; + print "\tHave you built the war file?\n"; + print "\t(if not, build the project and run the installer again)\n"; + + exit 0; +} + +print " Yes, it is!\n"; + + +# check the working (installer) dir: +my $cwd; +chomp( $cwd = `pwd` ); + +# 2b. CHECK IF THE SQL TEMPLATE IS IN PLACE AND CREATE THE SQL FILE + +my $SQL_REFERENCE_DATA = "reference_data_filtered.sql"; +my $SQL_REFERENCE_TEMPLATE = "../database/reference_data.sql"; + +unless ( -f $SQL_REFERENCE_TEMPLATE ) { + $SQL_REFERENCE_TEMPLATE = "reference_data.sql"; +} + +unless ( -f $SQL_REFERENCE_TEMPLATE ) { + print "\nWARNING: Can't find .sql data template!\n"; + print "(are you running the installer in the right directory?)\n"; + + exit 0; +} + +open DATATEMPLATEIN, $SQL_REFERENCE_TEMPLATE || die $@; +open SQLDATAOUT, '>' . $SQL_REFERENCE_DATA || die $@; + +while () { + s/dvnapp/$CONFIG_DEFAULTS{'POSTGRES_USER'}/g; + print SQLDATAOUT $_; +} + +close DATATEMPLATEIN; +close SQLDATAOUT; + +# 3. CHECK POSTGRES AND JQ AVAILABILITY: + +my $pg_local_connection = 0; +my $psql_exec; +my $jq_exec = ""; +my $pg_major_version = 0; +my $pg_minor_version = 0; + +my $POSTGRES_SYS_UID; +if ( $CONFIG_DEFAULTS{'POSTGRES_SERVER'} eq 'localhost' ) { + $pg_local_connection = 1; + + # 3a. CHECK FOR USER postgres: + + print "\nChecking system user \"postgres\"... "; + + my $POSTGRES_SYS_NAME = "postgres"; + $POSTGRES_SYS_UID = ( getpwnam("postgres") )[2]; + + unless ($POSTGRES_SYS_UID) { + print STDERR "\nERROR: I haven't been able to find user \"postgres\" on the system! Is PostgreSQL installed?\n"; + print STDERR "(TODO: prompt the user instead to supply an alternative username, if\n"; + print STDERR "available)\n"; + + exit 1; + } + + print "OK.\n"; + + # 3b. LOCATE THE EXECUTABLE: + + my $sys_path = $ENV{'PATH'}; + my @sys_path_dirs = split( ":", $sys_path ); + + $psql_exec = ""; + + for my $sys_path_dir (@sys_path_dirs) { + if ( -x $sys_path_dir . "/psql" ) { + $psql_exec = $sys_path_dir; + last; + } + } + + for my $sys_path_dir (@sys_path_dirs) { + if ( -x $sys_path_dir . "/jq" ) { + $jq_exec = $sys_path_dir; + last; + } + } + if ( $jq_exec eq "" ) { + print STDERR "\nERROR: I haven't been able to find the jq command in your PATH! Please install it from http://stedolan.github.io/jq/\n"; + exit 1; + + } + + my $psql_major_version = 0; + my $psql_minor_version = 0; + + # 3c. IF PSQL WAS FOUND IN THE PATH, CHECK ITS VERSION: + + unless ( $psql_exec eq "" ) { + open( PSQLOUT, $psql_exec . "/psql --version|" ); + + my $psql_version_line = ; + chop $psql_version_line; + close PSQLOUT; + + my ( $postgresName, $postgresNameLong, $postgresVersion ) = split( " ", $psql_version_line ); + + unless ( $postgresName eq "psql" && $postgresVersion =~ /^[0-9][0-9\.]*$/ ) { + print STDERR "\nWARNING: Unexpected output from psql command!\n"; + } + else { + my (@psql_version_tokens) = split( '\.', $postgresVersion ); + + print "\n\nFound Postgres psql command, version $postgresVersion.\n\n"; + + $psql_major_version = $psql_version_tokens[0]; + $psql_minor_version = $psql_version_tokens[1]; + + $pg_major_version = $psql_major_version; + $pg_minor_version = $psql_minor_version; + + } + } + + # a frequent problem with MacOSX is that the copy of psql found in the PATH + # belongs to the older version of PostgresQL supplied with the OS, which happens + # to be incompatible with the newer builds from the Postgres project; which are + # recommended to be used with dataverse. So if this is a MacOSX box, we'll + # check what other versions of PG are available, and select the highest version + # we can find: + + if ( $WORKING_OS eq "MacOSX" ) { + my $macos_pg_major_version = 0; + my $macos_pg_minor_version = 0; + + for $macos_pg_minor_version ( "3", "2", "1", "0" ) { + if ( -x "/Library/PostgreSQL/9." . $macos_pg_minor_version . "/bin/psql" ) { + $macos_pg_major_version = 9; + if ( ( $macos_pg_major_version > $psql_major_version ) + || ( $macos_pg_minor_version >= $psql_minor_version ) ) + { + $psql_exec = "/Library/PostgreSQL/9." . $macos_pg_minor_version . "/bin"; + $pg_major_version = $macos_pg_major_version; + $pg_minor_version = $macos_pg_minor_version; + } + last; + } + } + + # And if we haven't found an 9.* version of postgresql installed, we'll also check + # for version 8.* available: + + if ( $macos_pg_major_version < 9 ) { + for $macos_pg_minor_version ( "4", "3" ) + # TODO: + # Do we even want to support postgres 8.3? + { + if ( -x "/Library/PostgreSQL/8." . $macos_pg_minor_version . "/bin/psql" ) { + $macos_pg_major_version = 8; + if ( $macos_pg_major_version > $psql_major_version + || $macos_pg_minor_version > $psql_minor_version ) + { + $psql_exec = "/Library/PostgreSQL/8." . $macos_pg_minor_version . "/bin"; + $pg_major_version = $macos_pg_major_version; + $pg_minor_version = $macos_pg_minor_version; + } + last; + } + } + } + } + + if ( $psql_exec eq "" ) { + print STDERR "\nERROR: I haven't been able to find the psql command in your PATH!\n"; + print STDERR "Please make sure PostgresQL is properly installed; if necessary, add\n"; + print STDERR "the location of psql to the PATH, then try again.\n\n"; + + exit 1; + } + + if ( $pg_major_version == 0 ) { + } + + # 4. CONFIGURE POSTGRES: + + print "\nConfiguring Postgres Database:\n"; + print "(Using psql version " . $pg_major_version . "." . $pg_minor_version . ")\n"; + + $< = $POSTGRES_SYS_UID; + $> = $POSTGRES_SYS_UID; + + # 4a. CHECK IF POSTGRES IS RUNNING: + print "Checking if a local instance of Postgres is running and accessible...\n"; + + # (change to /tmp before executing the command below - + # we are trying to do it as user postgres, and it may not have + # access to the current, installer directory; the command would still + # work, but there would be an error message from the shell init on screen + # - potentially confusing) + + chdir("/tmp"); + + if ( !system( $psql_exec . "/psql -c 'SELECT * FROM pg_roles' > /dev/null 2>&1" ) ) { + print "Yes, it is.\n"; + } + else { + print "Nope, I haven't been able to connect to the local instance of PostgresQL.\n"; + print "daemon. Is postgresql running? \n"; + print "On a RedHat-like system, you can check the status of the daemon with\n\n"; + print " service postgresql status\n\n"; + print "and, if it's not running, start the daemon with\n\n"; + print " service postgresql start\n\n"; + print "On MacOSX, use Applications -> PostgresQL -> Start Server.\n"; + print "(or, if there's no \"Start Server\" item in your PostgresQL folder, \n"; + print "simply restart your MacOSX system!)\n"; + print "Also, please make sure that the daemon is listening to network connections,\n"; + print "at least on the localhost interface. (See \"Installing Postgres\" section\n"; + print "of the installation manual).\n"; + print "Finally, please make sure that the postgres user can make localhost \n"; + print "connections without supplying a password. (That's controlled by the \n"; + print "\"localhost ... ident\" line in pg_hba.conf; again, please consult the \n"; + print "installation manual).\n"; + + exit 1; + } + + # 4c. CHECK IF THIS DB ALREADY EXISTS: + + my $psql_command_dbcheck = + $psql_exec . "/psql -c \"\" -d " . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} . ">/dev/null 2>&1"; + if ($force) { + print "WARNING! Database " + . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} + . " already exists but --force given... continuing.\n"; + } + elsif ( ( my $exitcode = system($psql_command_dbcheck) ) == 0 ) { + $> = 0; + $< = 0; + + chdir($cwd); + + print "WARNING! Database " . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} . " already exists!\n"; + print "\nPlease note that you can only use this installer to create a blank, \n"; + print "new and shiny DVN database. I.e., you cannot install on top of an \n"; + print "existing database. Please enter a different name for the DVN database.\n"; + print "\nPress any key to continue, or ctrl-C to exit the installer...\n\n"; + + system "stty cbreak /dev/tty 2>&1"; + my $key = getc(STDIN); + system "stty -cbreak /dev/tty 2>&1"; + print "\n"; + + goto ENTERCONFIG; + + } + + # 4d. CHECK IF THIS USER ALREADY EXISTS: + + my $psql_command_rolecheck = + $psql_exec . "/psql -c \"\" -d postgres " . $CONFIG_DEFAULTS{'POSTGRES_USER'} . " >/dev/null 2>&1"; + if ( ( my $exitcode = system($psql_command_rolecheck) ) == 0 ) { + print "User (role) " . $CONFIG_DEFAULTS{'POSTGRES_USER'} . " already exists;\n"; + print "Proceeding."; + } + else { + # 4e. CREATE DVN DB USER: + + print "\nCreating Postgres user (role) for the DVN:\n"; + + open TMPCMD, ">/tmp/pgcmd.$$.tmp"; + + # with md5-encrypted password: + my $pg_password_md5 = + &create_pg_hash( $CONFIG_DEFAULTS{'POSTGRES_USER'}, $CONFIG_DEFAULTS{'POSTGRES_PASSWORD'} ); + my $sql_command = + "CREATE ROLE \"" + . $CONFIG_DEFAULTS{'POSTGRES_USER'} + . "\" PASSWORD 'md5" + . $pg_password_md5 + . "' NOSUPERUSER CREATEDB CREATEROLE INHERIT LOGIN"; + + print TMPCMD $sql_command; + close TMPCMD; + + my $psql_commandline = $psql_exec . "/psql -f /tmp/pgcmd.$$.tmp >/dev/null 2>&1"; + + my $out = qx($psql_commandline 2>&1); + my $exitcode = $?; + unless ( $exitcode == 0 ) { + print STDERR "Could not create the DVN Postgres user role!\n"; + print STDERR "(SQL: " . $sql_command . ")\n"; + print STDERR "(psql exit code: " . $exitcode . ")\n"; + print STDERR "(STDERR and STDOUT was: " . $out . ")\n"; + exit 1; + } + + unlink "/tmp/pgcmd.$$.tmp"; + print "done.\n"; + } + + # 4f. CREATE DVN DB: + + print "\nCreating Postgres database:\n"; + + my $psql_command = + $psql_exec + . "/createdb " + . $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} + . " --owner=" + . $CONFIG_DEFAULTS{'POSTGRES_USER'}; + + my $out = qx($psql_command 2>&1); + my $exitcode = $?; + unless ( $exitcode == 0 ) { + print STDERR "Could not create Postgres database for the DVN app!\n"; + print STDERR "(command: " . $psql_command . ")\n"; + print STDERR "(psql exit code: " . $exitcode . ")\n"; + print STDERR "(STDOUT and STDERR: " . $out . ")\n"; + if ($force) { + print STDERR "\n--force called, continuing\n"; + } + else { + print STDERR "\naborting the installation (sorry!)\n\n"; + exit 1; + } + } + + # Changing back to root UID: + + $> = 0; + $< = 0; + + chdir($cwd); + +} +else { + if (0) { # THE LINES BELOW WERE PART OF THE 3.* "DEV." INSTALLER: + # DO WE STILL WANT TO MAINTAIN THIS FUNCTIONALITY IN DATAVERSE 4.*? + + print "\nIt is strongly recommended that you use a local PostgresQL server,\n"; + print "running on localhost, in your development environment!\n\n"; + + print "Do you wish to continue?\n [y/n] "; + + my $yesnocont = <>; + chop $yesnocont; + + while ( $yesnocont ne "y" && $yesnocont ne "n" ) { + print "Please enter 'y' or 'n'!\n"; + print "(or ctrl-C to exit the installer)\n"; + $yesnocont = <>; + chop $yesnocont; + } + + if ( $yesnocont eq "n" ) { + print "(aborting the installation)\n" . exit 0; + } + } + + if ($pg_only) { + print "The script must be run in the --pg_only mode ONLY locally,\n"; + print "i.e., on the server where PostgresQL is running.\n"; + + exit 1; + } + + print "In order to use a PostgresQL database running on a remote server,\n"; + print "Please run this installer on that host with the \"--pg_only\" option:\n\n"; + print "./install --pg_only\n\n"; + + print "Press any key to continue the installation process once that has been\n"; + print "done. Or press ctrl-C to exit the installer.\n\n"; + + chdir("/tmp"); + system "stty cbreak /dev/tty 2>&1"; + my $key = getc(STDIN); + system "stty -cbreak /dev/tty 2>&1"; + print "\n"; + chdir($cwd); + + # Check if the role and database have been created on the remote server: + # -- TODO; + + # Find out what Postgres version is running remotely: + + $pg_major_version = 9; + $pg_minor_version = 1; + + print "What version of PostgresQL is installed on the remote server?\n [" + . $pg_major_version . "." + . $pg_minor_version . "] "; + + my $postgresVersion = <>; + chop $postgresVersion; + + while ( $postgresVersion ne "" && !( $postgresVersion =~ /^[0-9]+\.[0-9]+$/ ) ) { + print "Please enter valid Postgres version!\n"; + print "(or ctrl-C to exit the installer)\n"; + $postgresVersion = <>; + chop $postgresVersion; + } + + unless ( $postgresVersion eq "" ) { + my (@postgres_version_tokens) = split( '\.', $postgresVersion ); + + unless ( ( $postgres_version_tokens[0] == 8 && $postgres_version_tokens[1] >= 4 ) + || ( $postgres_version_tokens[0] >= 9 ) ) + { + print STDERR "\nERROR: PostgresQL version 8.4, or newer, is required!\n"; + print STDERR "Please make sure the right version of PostgresQL is properly installed\n"; + print STDERR "on the remote server, then try again.\n"; + + exit 1; + } + + $pg_major_version = $postgres_version_tokens[0]; + $pg_minor_version = $postgres_version_tokens[1]; + } + +} + +if ($postgresonly) { + print "\nOK, done.\n"; + print "You can now resume the installation on the main DVN host.\n\n"; + + exit 0; +} + +# 5. CONFIGURE GLASSFISH + +print "\nProceeding with the Glassfish setup.\n"; +print "\nChecking your Glassfish installation..."; + +my $glassfish_dir = $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'}; + +# 5a. CHECK IF GLASSFISH DIR LOOKS OK: + +unless ( -d $glassfish_dir . "/glassfish/domains/domain1" ) { + # TODO: need better check than this + + while ( !( -d $glassfish_dir . "/glassfish/domains/domain1" ) ) { + print "\nInvalid Glassfish directory " . $glassfish_dir . "!\n"; + print "Enter the root directory of your Glassfish installation:\n"; + print "(Or ctrl-C to exit the installer): "; + + $glassfish_dir = <>; + chop $glassfish_dir; + } +} + +print "OK!\n"; + +# 5b. DETERMINE HOW MUCH MEMORY TO GIVE TO GLASSFISH AS HEAP: + +my $gf_heap_default = "2048m"; +my $sys_mem_total = 0; + +if ( -e "/proc/meminfo" && open MEMINFO, "/proc/meminfo" ) { + # Linux + + while ( my $mline = ) { + if ( $mline =~ /MemTotal:[ \t]*([0-9]*) kB/ ) { + $sys_mem_total = $1; + } + } + + close MEMINFO; + +} +elsif ( -x "/usr/sbin/sysctl" ) { + # MacOS X, probably... + + $sys_mem_total = `/usr/sbin/sysctl -n hw.memsize`; + chop $sys_mem_total; + if ( $sys_mem_total > 0 ) { + $sys_mem_total = int( $sys_mem_total / 1024 ); + # size in kb + } +} + +if ( $sys_mem_total > 0 ) { + # setting the default heap size limit to 3/8 of the available + # amount of memory: + $gf_heap_default = ( int( $sys_mem_total / ( 8 / 3 * 1024 ) ) ); + + print "\nSetting the heap limit for Glassfish to " . $gf_heap_default . "MB. \n"; + print "You may need to adjust this setting to better suit \n"; + print "your system.\n\n"; + + #$gf_heap_default .= "m"; + +} +else { + print "\nCould not determine the amount of memory on your system.\n"; + print "Setting the heap limit for Glassfish to 2GB. You may need \n"; + print "to adjust the value to better suit your system.\n\n"; +} + +push @CONFIG_VARIABLES, "DEF_MEM_SIZE"; +$CONFIG_DEFAULTS{"DEF_MEM_SIZE"} = $gf_heap_default; + +# TODO: +# if the system has more than 4GB of memory (I believe), glassfish must +# be run with the 64 bit flag set explicitly (at least that was the case +# with the MacOS glassfish build...). Verify, and if still the case, +# add a check. + +print "\nInstalling the Glassfish PostgresQL driver... "; + +my $install_driver_jar = ""; + +$install_driver_jar = $POSTGRES_DRIVERS{ $pg_major_version . "_" . $pg_minor_version }; + +unless ( $install_driver_jar && -e "pgdriver/" . $install_driver_jar ) { + die "Installer could not find POSTGRES JDBC driver for your version of PostgresQL!\n(" + . $pg_major_version . "." + . $pg_minor_version . ")"; + +} + +system( "/bin/cp", "pgdriver/" . $install_driver_jar, $glassfish_dir . "/glassfish/lib" ); +# more diagnostics needed? + +print "done!\n"; + +print "\n*********************\n"; +print "PLEASE NOTE, SOME OF THE ASADMIN COMMANDS ARE GOING TO FAIL,\n"; +print "FOR EXAMPLE, IF A CONFIGURATION SETTING THAT WE ARE TRYING\n"; +print "TO CREATE ALREADY EXISTS; OR IF A JVM OPTION THAT WE ARE\n"; +print "DELETING DOESN'T. THESE \"FAILURES\" ARE NORMAL!\n"; +print "*********************\n\n"; +print "When/if asadmin asks you to \"Enter admin user name\",\n"; +print "it should be safe to hit return and accept the default\n"; +print "(which is \"admin\").\n"; + +# odum: skipping the Press of the Return Key +#print "\nPress any key to continue...\n\n"; +# +#system "stty cbreak /dev/tty 2>&1"; +#unless ($yes) { + #my $key = getc(STDIN); +#} +#system "stty -cbreak /dev/tty 2>&1"; +#print "\n"; + +# start domain, if not running: + +my $javacheck = `java -version`; +my $exitcode = $?; +unless ( $exitcode == 0 ) { + print STDERR "$javacheck\n" if $javacheck; + print STDERR "Do you have java installed?\n"; + exit 1; +} +my $DOMAIN = "domain1"; +my $DOMAIN_DOWN = + `$CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'}/bin/asadmin list-domains | grep "$DOMAIN " | grep "not running"`; +print STDERR $DOMAIN_DOWN . "\n"; +if ($DOMAIN_DOWN) { + print "Trying to start domain up...\n"; + system( $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'} . "/bin/asadmin start-domain domain1" ); +} +else { + print "domain appears to be up...\n"; +} + +# create asadmin login, so that the user doesn't have to enter +# the username and password for every asadmin command, if +# access to :4848 is password-protected: + +system( $glassfish_dir. "/bin/asadmin login -u {{ dataverse_gf_adminuser }}" ); + +# NEW: configure glassfish using ASADMIN commands: + +my $success = &setup_glassfish(); + +# CHECK EXIT STATUS, BARF IF SETUP SCRIPT FAILED: + +unless ($success) { + print "\nERROR! Failed to configure Glassfish domain!\n"; + print "(see the error messages above - if any)\n"; + print "Aborting...\n"; + + exit 1; +} + +# Additional config files: + +my $JHOVE_CONFIG = "../../conf/jhove/jhove.conf"; + +unless ( -f $JHOVE_CONFIG ) { + $JHOVE_CONFIG = "jhove.conf"; +} + +unless ( -f $JHOVE_CONFIG ) { + print "\nERROR! Configuration files not found in config dir!\n"; + print "(are you running the installer in the right directory?\n"; + print "Aborting...\n"; + exit 1; +} + +print "\nCopying additional configuration files... "; + +system( "/bin/cp -Rf " . $JHOVE_CONFIG . " " . $glassfish_dir . "/glassfish/domains/domain1/config" ); +#diagnostics needed! + +# install the DVN guides (HTML) into the application docroot: +# (if the built docs exist?) +# TODO: add documentation build/installation to the installer. +#system ( "/bin/cp -Rf doc/guides/* ".$glassfish_dir."/glassfish/domains/domain1/docroot/guides"); + +print "done!\n"; + +# check if glassfish is running: +# TODO. + +# 6. DEPLOY APPLICATION: + +# 6b. TRY TO (AUTO-)DEPLOY: + +unless ( + ( + my $exit_code = + system( "cp -f " . $WARFILE_LOCATION . " " . $glassfish_dir . "/glassfish/domains/domain1/autodeploy" ) + ) == 0 + ) +{ + print STDERR "Could copy the application into the auto-deploy directory!\n"; + print STDERR "(exit code: " . $exit_code . ")\n"; + exit 1; +} + +print "Waiting for the dataverse application to start...\n"; +sleep 60; + +# 7. POPULATE DATABASE: + +if ($pg_local_connection) { + # 7a. POPULATE LOCALLY: + print "\nPopulating the database (local PostgresQL instance):\n\n"; + + # Copy the SQL file to /tmp, where user postgres will definitely + # have read access to it: + + copy( $SQL_REFERENCE_DATA, "/tmp" ) or die "Could not copy $SQL_REFERENCE_DATA to /tmp: $!"; + unlink( $SQL_REFERENCE_DATA ); + + chdir("/tmp"); + $< = $POSTGRES_SYS_UID; + $> = $POSTGRES_SYS_UID; + my $psql_command = $psql_exec . "/psql -d $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} -f $SQL_REFERENCE_DATA"; + + unless ( ( my $exitcode = system("$psql_command") ) == 0 ) { + print STDERR "Could not populate Postgres database for the DVN app!\n"; + print STDERR "(command: " . $psql_command . ")\n"; + print STDERR "(psql exit code: " . $exitcode . ")\n"; + print STDERR "\nYou must populate the database before you can use your new\n"; + print STDERR "DVN instance. Please consult the installation manual and/or\n"; + print STDERR "seek support from the DVN team.\n\n"; + exit 1; + + } + +} +else { + # 7b. INSTRUCT THE USER TO POPULATE THE DB ON THE REMOTE SERVER: + # NOT SUPPORTED YET -- TODO + print "Please copy the file $SQL_REFERENCE_DATA (found in this directory)\n"; + print "onto the remote server and populate the database manually,\n"; + print "as user postgres, with the following command:\n\n"; + print " psql -d $CONFIG_DEFAULTS{'POSTGRES_DATABASE'} -f $SQL_REFERENCE_DATA\n"; + print "then start glassfish again on this server with \n\n"; + print " " . $glassfish_dir . "/bin/asadmin start-domain domain1\n\n"; + +# exit 0; + +} + +# back to root: + +$> = 0; +$< = 0; +chdir($cwd); +print "\nOK, done!\n"; + +# FIXME: don't just sleep... figure out if the app is up yet. +print "\n--Sleeping for 3 minutes--\n"; +sleep 180; + +# Populate the metadata block field values, create users +# and dataverses: + +unless ( -d "data" && -f "setup-datasetfields.sh" && -f "setup-users.sh" && -f "setup-dvs.sh" && -f "setup-all.sh" ) { + chdir("../api"); +} + +unless ( -d "data" && -f "setup-datasetfields.sh" && -f "setup-users.sh" && -f "setup-dvs.sh" && -f "setup-builtin-roles.sh" && -f "setup-all.sh" ) { + print "\nERROR: Can't find the metadata and user/dataverse setup scripts!\n"; + print "\tAre you running the installer in the right directory?\n"; + exit 1; +} + +for my $script ( "setup-all.sh" ) { + print "Executing script " . $script . "...\n"; + + my $my_hostname = $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'}; + + my $run_script; + #if ( $my_hostname ne "localhost" ) { + # system( "sed 's/localhost:8080/$my_hostname/g' < " . $script . " > tmpscript.sh; chmod +x tmpscript.sh" ); + # $run_script = "tmpscript.sh"; + #} + #else { + $run_script = $script; + #} + + unless ( my $exit_code = system( "./" . $run_script ) == 0 ) { + print "\nERROR executing script " . $script . "!\n"; + exit 1; + } + print "ok!\n"; +} + +chdir($cwd); + +print "\n\nYou should now have a running DVN instance at\n"; +print " http://" . $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'} . "[:8080]\n"; + +# (going to skip the Rserve check, for now) + +exit 0; + +# 9. FINALLY, CHECK IF RSERVE IS RUNNING: +print "\n\nFinally, checking if Rserve is running and accessible...\n"; + +unless ( $CONFIG_DEFAULTS{'RSERVE_PORT'} =~ /^[0-9][0-9]*$/ ) { + print $CONFIG_DEFAULTS{'RSERVE_HOST'} . " does not look like a valid port number,\n"; + print "defaulting to 6311.\n\n"; + + $CONFIG_DEFAULTS{'RSERVE_PORT'} = 6311; +} + +my ( $rserve_iaddr, $rserve_paddr, $rserve_proto ); + +unless ( $rserve_iaddr = inet_aton( $CONFIG_DEFAULTS{'RSERVE_HOST'} ) ) { + print STDERR "Could not look up $CONFIG_DEFAULTS{'RSERVE_HOST'},\n"; + print STDERR "the host you specified as your R server.\n"; + print STDERR "\nDVN can function without a working R server, but\n"; + print STDERR "much of the functionality concerning running statistics\n"; + print STDERR "and analysis on quantitative data will not be available.\n"; + print STDERR "Please consult the Installers guide for more info.\n"; + + exit 0; +} + +$rserve_paddr = sockaddr_in( $CONFIG_DEFAULTS{'RSERVE_PORT'}, $rserve_iaddr ); +$rserve_proto = getprotobyname('tcp'); + +unless ( socket( SOCK, PF_INET, SOCK_STREAM, $rserve_proto ) + && connect( SOCK, $rserve_paddr ) ) +{ + print STDERR "Could not establish connection to $CONFIG_DEFAULTS{'RSERVE_HOST'}\n"; + print STDERR "on port $CONFIG_DEFAULTS{'RSERVE_PORT'}, the address you provided\n"; + print STDERR "for your R server.\n"; + print STDERR "DVN can function without a working R server, but\n"; + print STDERR "much of the functionality concerning running statistics\n"; + print STDERR "and analysis on quantitative data will not be available.\n"; + print STDERR "Please consult the \"Installing R\" section in the Installers guide\n"; + print STDERR "for more info.\n"; + + exit 0; + +} + +close(SOCK); +print "\nOK!\n"; + +sub setup_glassfish { + my $success = 1; + my $failure = 0; + + # We are going to run a standalone shell script with a bunch of asadmin + # commands to set up all the glassfish components for the application. + # All the parameters must be passed to that script as environmental + # variables: + + $ENV{'GLASSFISH_ROOT'} = $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'}; + $ENV{'GLASSFISH_DOMAIN'} = "domain1"; + $ENV{'ASADMIN_OPTS'} = ""; + $ENV{'MEM_HEAP_SIZE'} = $CONFIG_DEFAULTS{'DEF_MEM_SIZE'}; + + $ENV{'DB_PORT'} = $CONFIG_DEFAULTS{'POSTGRES_PORT'}; + $ENV{'DB_HOST'} = $CONFIG_DEFAULTS{'POSTGRES_SERVER'}; + $ENV{'DB_NAME'} = $CONFIG_DEFAULTS{'POSTGRES_DATABASE'}; + $ENV{'DB_USER'} = $CONFIG_DEFAULTS{'POSTGRES_USER'}; + $ENV{'DB_PASS'} = $CONFIG_DEFAULTS{'POSTGRES_PASSWORD'}; + + $ENV{'RSERVE_HOST'} = $CONFIG_DEFAULTS{'RSERVE_HOST'}; + $ENV{'RSERVE_PORT'} = $CONFIG_DEFAULTS{'RSERVE_PORT'}; + $ENV{'RSERVE_USER'} = $CONFIG_DEFAULTS{'RSERVE_USER'}; + $ENV{'RSERVE_PASS'} = $CONFIG_DEFAULTS{'RSERVE_PASSWORD'}; + + $ENV{'HOST_ADDRESS'} = $CONFIG_DEFAULTS{'HOST_DNS_ADDRESS'}; + $ENV{'SMTP_SERVER'} = $CONFIG_DEFAULTS{'MAIL_SERVER'}; + $ENV{'FILES_DIR'} = + $CONFIG_DEFAULTS{'GLASSFISH_DIRECTORY'} . "/glassfish/domains/" . $ENV{'GLASSFISH_DOMAIN'} . "/files"; + + system("./glassfish-setup.sh"); + + if ($?) { + return $failure; + } + return $success; +} + +sub create_pg_hash { + my $pg_username = shift @_; + my $pg_password = shift @_; + + my $encode_line = $pg_password . $pg_username; + + # for Redhat: + + ##print STDERR "executing /bin/echo -n $encode_line | md5sum\n"; + + my $hash; + if ( $WORKING_OS eq "MacOSX" ) { + $hash = `/bin/echo -n $encode_line | md5`; + } + else { + $hash = `/bin/echo -n $encode_line | md5sum`; + } + + chop $hash; + + $hash =~ s/ \-$//; + + if ( ( length($hash) != 32 ) || ( $hash !~ /^[0-9a-f]*$/ ) ) { + print STDERR "Failed to generate a MD5-encrypted password hash for the Postgres database.\n"; + exit 1; + } + + return $hash; +} diff --git a/ansible/roles/dataverse/templates/shibboleth2.xml.j2 b/ansible/roles/dataverse/templates/shibboleth2.xml.j2 new file mode 100644 index 000000000..6a23a3baf --- /dev/null +++ b/ansible/roles/dataverse/templates/shibboleth2.xml.j2 @@ -0,0 +1,74 @@ + + + + + + + + + + + + + SAML2 SAML1 + + + + + SAML2 Local + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ansible/roles/dataverse/templates/ssl.conf.j2 b/ansible/roles/dataverse/templates/ssl.conf.j2 new file mode 100644 index 000000000..c5fd51b18 --- /dev/null +++ b/ansible/roles/dataverse/templates/ssl.conf.j2 @@ -0,0 +1,50 @@ +Listen 443 https + +SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog +SSLSessionCache shmcb:/run/httpd/sslcache(512000) +SSLSessionCacheTimeout 300 +SSLRandomSeed startup file:/dev/urandom 256 +SSLRandomSeed connect builtin +SSLCryptoDevice builtin + + + + ServerName {{ dataverse_host_address }}:443 + ErrorLog logs/ssl_error_log + TransferLog logs/ssl_access_log + LogLevel warn + + SSLEngine on + SSLProtocol all -SSLv2 + SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5 + SSLCertificateFile /etc/pki/tls/certs/localhost.crt + SSLCertificateKeyFile /etc/pki/tls/private/localhost.key + + + SSLOptions +StdEnvVars + + + SSLOptions +StdEnvVars + + + CustomLog logs/ssl_request_log \ + "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + + # don't pass paths used by rApache and TwoRavens to Glassfish + ProxyPassMatch ^/RApacheInfo$ ! + ProxyPassMatch ^/custom ! + ProxyPassMatch ^/dataexplore ! + # don't pass paths used by Shibboleth to Glassfish + ProxyPassMatch ^/Shibboleth.sso ! + ProxyPassMatch ^/shibboleth-ds ! + # pass everything else to Glassfish + ProxyPass / ajp://localhost:8009/ + + + AuthType shibboleth + ShibRequestSetting requireSession 1 + require valid-user + + + + diff --git a/ansible/roles/rserve/defaults/main.yaml b/ansible/roles/rserve/defaults/main.yaml new file mode 100644 index 000000000..09e4cc97f --- /dev/null +++ b/ansible/roles/rserve/defaults/main.yaml @@ -0,0 +1,6 @@ +rserve_user: rserve +rserve_group: rserve +rserve_source: http://mirrors.ibiblio.org/CRAN/src/contrib/Rserve_1.7-3.tar.gz +rserve_targz: Rserve_1.7-3.tar.gz +rserve_conf: Rserv.conf +rserve_systemd: r.service diff --git a/ansible/roles/rserve/files/Rserv.conf b/ansible/roles/rserve/files/Rserv.conf new file mode 100644 index 000000000..003fc1d63 --- /dev/null +++ b/ansible/roles/rserve/files/Rserv.conf @@ -0,0 +1 @@ +remote enable diff --git a/ansible/roles/rserve/files/r.service b/ansible/roles/rserve/files/r.service new file mode 100644 index 000000000..f8bad61ef --- /dev/null +++ b/ansible/roles/rserve/files/r.service @@ -0,0 +1,16 @@ +[Unit] +Description=R server +After=syslog.target +After=network.target + +[Service] +User={{ rserve_user }} +Group={{ rserve_group }} +ExecStart=/usr/bin/R CMD Rserve --no-gui --no-save +Type=forking + +# Give a reasonable amount of time for the server to start up/shut down +TimeoutSec=10 + +[Install] +WantedBy=multi-user.target diff --git a/ansible/roles/rserve/tasks/main.yaml b/ansible/roles/rserve/tasks/main.yaml new file mode 100644 index 000000000..0869945ac --- /dev/null +++ b/ansible/roles/rserve/tasks/main.yaml @@ -0,0 +1,43 @@ +--- + +- name: create rserve user/group + user: name={{ rserve_user }} + +- name: install epel-release for R + yum: name=epel-release state=present + when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7' + +- name: install R for CentOS 7 + yum: + name=R state=present + when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7' + +- name: download Rserve package + get_url: url={{ rserve_source }} dest=/home/{{ ansible_ssh_user }}/ + when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7' + +- name: install Rserve package + sudo: yes + sudo_user: root + shell: + R CMD INSTALL {{ rserve_targz }} + +- name: copy Rserve.conf file + sudo: yes + sudo_user: root + copy: src={{ rserve_conf }} dest=/etc/ owner=root group=root mode=0644 + +- name: copy Rserve systemd file + sudo: yes + sudo_user: root + copy: src={{ rserve_systemd }} dest=/usr/lib/systemd/system/ owner=root group=root mode=0644 + +- name: enable Rserve + sudo: yes + sudo_user: root + service: name=r.service enabled=yes + +- name: start Rserve + sudo: yes + sudo_user: root + service: name=r.service state=started