| # |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| # |
| |
| --- |
| # Need database facts to populate db connection info in settings_local.py |
| - name: Gather facts about database servers |
| setup: |
| delegate_to: "{{item}}" |
| delegate_facts: True |
| with_items: |
| - "{{ groups['database'] }}" |
| |
| # - name: Hostvars |
| # debug: |
| # var: hostvars[item] |
| # with_items: |
| # - "{{ django_database_hosts }}" |
| |
| - name: Run tasks to setup Django database |
| include_tasks: database.yml |
| args: |
| apply: |
| delegate_to: "{{ item }}" |
| become: yes |
| become_user: "{{ hostvars[item]['user'] }}" |
| with_items: |
| - "{{ django_database_hosts }}" |
| |
| - name: Create root directory |
| file: path="{{ doc_root_dir }}" state=directory owner="{{user}}" group="{{group}}" |
| become: yes |
| |
| - name: Create local temp directory for django portal clone and build |
| local_action: |
| module: tempfile |
| # The temp directory must be in a location that allows it to be mounted |
| # into the Docker container. On macOS the default behavior creates temp |
| # directories in /var but /var isn't available to Docker containers. |
| path: /tmp |
| state: directory |
| register: airavata_django_portal_tempdir |
| run_once: true |
| |
| - name: Make local temp directory for django portal clone world readable |
| local_action: |
| module: file |
| # The Django portal clone directory needs to be world readable on the |
| # remote server and rsync preserves permissions, so make the local clone |
| # directory world readable |
| path: "{{ airavata_django_portal_tempdir.path }}" |
| mode: o+rx |
| run_once: true |
| |
| - name: git clone {{ airavata_django_git_branch }} branch of {{ airavata_django_repo }} |
| local_action: |
| module: git |
| repo: "{{ airavata_django_repo }}" |
| dest: "{{ airavata_django_portal_tempdir.path }}" |
| version: "{{ airavata_django_git_branch }}" |
| update: yes |
| force: yes |
| run_once: true |
| |
| # TODO: check if Docker is running (docker_host_info can_talk_to_docker https://docs.ansible.com/ansible/latest/modules/docker_host_info_module.html#return-values) |
| # NOTE: docker_host_info only available from Ansible 2.8 |
| # - name: check if Docker is running |
| # local_action: |
| # module: docker_host_info |
| # register: docker_result |
| # run_once: true |
| # |
| # - name: Fail if Docker isn't running |
| # local_action: |
| # module: fail |
| # msg: Docker daemon isn't running or isn't accessible. Start Docker daemon and then rerun this playbook. |
| # when: not docker_result.can_talk_to_docker |
| # run_once: true |
| |
| - name: build airavata-django-portal Docker image |
| local_action: |
| module: docker_image |
| build: |
| path: "{{ airavata_django_portal_tempdir.path }}/" |
| name: airavata-django-portal |
| force_source: true |
| force_tag: true |
| source: build |
| run_once: true |
| |
| - name: create Docker container so we can copy built files out of it |
| local_action: |
| module: docker_container |
| # Don't need to start the container, just create it |
| state: present |
| name: ansible-airavata-django-portal |
| image: airavata-django-portal |
| run_once: true |
| |
| - name: copy built JS files from Docker container |
| local_action: command docker cp ansible-airavata-django-portal:/code/{{ item }}/. {{ airavata_django_portal_tempdir.path }}/{{ item }} |
| run_once: true |
| with_items: "{{ django_portal_js_build_dirs }}" |
| |
| - name: remove Docker container |
| local_action: |
| module: docker_container |
| state: absent |
| name: ansible-airavata-django-portal |
| run_once: true |
| |
| - name: rsync built Django code to {{ airavata_django_checkout }} |
| synchronize: |
| src: "{{ airavata_django_portal_tempdir.path }}/" |
| dest: "{{ airavata_django_checkout }}" |
| rsync_opts: |
| - "--exclude=node_modules" |
| - "--exclude=.git" |
| # Don't copy over wsgi.py just yet since that triggers a restart of uwsgi |
| - "--exclude=wsgi.py" |
| # Bug: become_user doesn't work with synchronize: https://github.com/ansible/ansible/issues/29698 |
| rsync_path: "sudo -u {{ user }} rsync" |
| # become: yes |
| # become_user: "{{user}}" |
| notify: |
| - restart uwsgi |
| - delete older files |
| |
| - name: rsync built Django code to {{ airavata_django_checkout }}, deleting older built files |
| synchronize: |
| src: "{{ airavata_django_portal_tempdir.path }}/{{ item }}/" |
| dest: "{{ airavata_django_checkout }}/{{ item }}" |
| delete: yes |
| rsync_opts: |
| - "--exclude=node_modules" |
| # Bug: become_user doesn't work with synchronize: https://github.com/ansible/ansible/issues/29698 |
| rsync_path: "sudo -u {{ user }} rsync" |
| # become: yes |
| # become_user: "{{user}}" |
| notify: |
| - restart uwsgi |
| - delete older files |
| with_items: "{{ django_portal_js_build_dirs }}" |
| |
| - name: Create virtual environment for Django portal and update pip, setuptools and wheel |
| pip: |
| name: "{{ item }}" |
| virtualenv: "{{ django_venv_dir }}" |
| virtualenv_command: "{{ python_virtualenv_command }}" |
| chdir: "{{ airavata_django_checkout }}" |
| state: latest |
| become: yes |
| become_user: "{{user}}" |
| with_list: |
| - pip |
| - setuptools |
| - wheel |
| |
| - name: Install dependencies in virtual environment for Django portal |
| pip: |
| requirements: "{{ item }}" |
| virtualenv: "{{ django_venv_dir }}" |
| virtualenv_command: "{{ python_virtualenv_command }}" |
| chdir: "{{ airavata_django_checkout }}" |
| become: yes |
| become_user: "{{user}}" |
| with_list: |
| - "{{ airavata_django_checkout }}/requirements.txt" |
| - "{{ airavata_django_checkout }}/requirements-mysql.txt" |
| |
| - name: Install additional dependencies |
| pip: |
| name: "{{ item }}" |
| virtualenv: "{{ django_venv_dir }}" |
| # TODO: maybe set editable to true if a git url? |
| become: yes |
| become_user: "{{user}}" |
| with_list: "{{ airavata_django_extra_dependencies }}" |
| |
| - name: Copy the settings_local.py file |
| template: src={{ django_settings_local_template }} dest="{{ airavata_django_checkout }}/django_airavata/settings_local.py" owner="{{user}}" group="{{group}}" |
| become: yes |
| notify: |
| - restart uwsgi |
| |
| - name: Run Django's manage.py migrate |
| django_manage: |
| command: migrate |
| app_path: "{{ airavata_django_checkout }}" |
| virtualenv: "{{ django_venv_dir }}" |
| become: yes |
| become_user: "{{user}}" |
| |
| - name: Run Django's manage.py set_wagtail_site based on hostname |
| django_manage: |
| command: set_wagtail_site |
| app_path: "{{ airavata_django_checkout }}" |
| virtualenv: "{{ django_venv_dir }}" |
| become: yes |
| become_user: "{{user}}" |
| # if there are no Django Portal pages in Wagtail, then this command fails, |
| # but we can ignore it until Wagtail pages are created |
| ignore_errors: yes |
| |
| - name: Run Django's manage.py collectstatic |
| django_manage: |
| command: "collectstatic -i node_modules --noinput" |
| app_path: "{{ airavata_django_checkout }}" |
| virtualenv: "{{ django_venv_dir }}" |
| become: yes |
| become_user: "{{user}}" |
| notify: |
| - restart uwsgi |
| - delete older files |
| |
| # TODO: this is really slow with lots of files |
| - name: Create experiment data dir |
| file: path="{{ experiment_data_dir }}" state=directory owner="{{user}}" group="{{group}}" recurse=no follow=yes |
| become: yes |
| |
| - name: Create file upload tmp dir |
| file: path="{{ file_upload_tmp_dir }}" state=directory owner="{{user}}" group="{{group}}" recurse=yes |
| become: yes |
| |
| - name: set selinux context to allow read on static directory |
| sefcontext: |
| target: "{{ doc_root_dir }}/static(/.*)?" |
| setype: httpd_sys_content_t |
| state: present |
| become: yes |
| notify: |
| - restart httpd |
| when: ansible_os_family == "RedHat" |
| |
| - name: set selinux context to allow exec on virtual env directory |
| sefcontext: |
| target: "{{ django_venv_dir }}(/.*)?" |
| setype: httpd_sys_script_exec_t |
| state: present |
| become: yes |
| notify: |
| - restart httpd |
| when: ansible_os_family == "RedHat" |
| |
| - name: set selinux context to allow read/write on django directory |
| sefcontext: |
| target: "{{ airavata_django_checkout }}(/.*)?" |
| setype: httpd_sys_rw_content_t |
| state: present |
| become: yes |
| notify: |
| - restart httpd |
| when: ansible_os_family == "RedHat" |
| |
| - name: Allow Django code to execute Java code (Pyjnius, see https://github.com/SciGaP/simccs-maptool) |
| seboolean: |
| name: httpd_execmem |
| state: yes |
| persistent: yes |
| become: yes |
| when: ansible_os_family == "RedHat" |
| |
| # some Python libraries want to write files to /tmp and execute them, see |
| # https://bugzilla.redhat.com/show_bug.cgi?id=645193 for more details |
| - name: Allow Django code to exec in tmp directory |
| seboolean: |
| name: httpd_tmp_exec |
| state: yes |
| persistent: yes |
| become: yes |
| when: ansible_os_family == "RedHat" |
| |
| - name: run restorecon on those directories |
| command: restorecon -F -R {{ doc_root_dir }} |
| become: yes |
| when: ansible_os_family == "RedHat" |
| |
| - name: copy virtual host config file |
| template: src={{ django_vhost_template }} dest={{ httpd_confd_file_location[ansible_os_family] }} backup=yes |
| become: yes |
| notify: |
| - restart httpd |
| when: not vhost_ssl |
| |
| - name: copy SSL enabled virtual host config file |
| template: src={{ django_ssl_vhost_template }} dest={{ httpd_confd_file_location[ansible_os_family] }} backup=yes |
| become: yes |
| notify: |
| - restart httpd |
| when: vhost_ssl |
| |
| - name: Enable site in Apache (Debian) |
| command: a2ensite {{ django_vhost_conf_name }} |
| become: yes |
| notify: |
| - restart httpd |
| when: ansible_os_family == "Debian" |
| |
| - name: copy user's SSH key for the gateway data store |
| authorized_key: |
| user: "{{user}}" |
| key: "{{ gateway_data_store_ssh_public_key }}" |
| become: yes |
| when: gateway_data_store_ssh_public_key != "" |
| |
| - name: Copy the wsgi.py file |
| copy: |
| src: "{{ airavata_django_portal_tempdir.path }}/django_airavata/wsgi.py" |
| dest: "{{ airavata_django_checkout }}/django_airavata/wsgi.py" |
| owner: "{{ user }}" |
| group: "{{ group }}" |
| become: yes |
| notify: |
| - restart uwsgi |
| |
| - name: remove Django portal clone temp directory |
| local_action: |
| module: file |
| state: absent |
| path: "{{ airavata_django_portal_tempdir.path }}" |
| run_once: true |
| |
| - name: add domain to Zabbix monitoring checklist |
| lineinfile: |
| path: /etc/zabbix/domain_checklist |
| line: "{{ vhost_servername }}" |
| create: yes |
| become: yes |
| when: vhost_ssl |
| |
| - name: add redirect domain to Zabbix monitoring checklist |
| lineinfile: |
| path: /etc/zabbix/domain_checklist |
| line: "{{ vhost_server_redirect }}" |
| create: yes |
| become: yes |
| when: vhost_ssl and vhost_server_redirect_ssl_certificate_file is defined |