Merge remote-tracking branch 'origin/master' into DCD-798-fix-for-pg_dump-cusstom-format

This commit is contained in:
Varun Arbatti
2019-11-22 15:58:34 +11:00
32 changed files with 647 additions and 130 deletions

View File

@@ -1,15 +1,16 @@
# Atlassian Data Center Installation Automation
# Atlassian Data-Center Installation Automation
## Introduction
This repository is a suite of Ansible roles, playbooks and support scripts to This repository is a suite of Ansible roles, playbooks and support scripts to
automate the installation and maintenance of Atlassian Data Center products in automate the installation and maintenance of Atlassian Data Center products in
cloud environments. cloud environments.
## Usage On this page:
### Cloud DC-node deployment playbooks [TOC]
# Usage
## Configuring Data Center nodes on cloud deployments
The usual scenario for usage as part of a cloud deployment is to invoke the The usual scenario for usage as part of a cloud deployment is to invoke the
script as part of post-creation actions invoked while a new product node is script as part of post-creation actions invoked while a new product node is
@@ -27,12 +28,11 @@ sourced as environment variables to be retrieved at runtime . See the
helper-script `bin/ansible-with-atl-env` and the corresponding helper-script `bin/ansible-with-atl-env` and the corresponding
`groups_vars/aws_node_local.yml` var-file. `groups_vars/aws_node_local.yml` var-file.
#### Overriding parameters ## Customizing your deployment
If you want to customise the playbook behaviour the simplest method is to fork To customise playbook behaviour, you can fork this repository and edit it as
this repository and add your own. However, for some one-off tasks you can also needed. However, for one-off tasks you can also override the default and
override the default and calculated settings with special values. To do this, provide calculated settings with special values. To do this, provide command-line overrides to
command-line overrides to
[ansible-playbook](https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html). [ansible-playbook](https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html).
The most likely use-case for this is to download a custom product distribution The most likely use-case for this is to download a custom product distribution
@@ -61,49 +61,65 @@ them in the `Custom command-line parameters for Ansible` field:
-e atl_product_download_url=http://s3.amazon.com/atlassian/jira-9.0.0-PRE-TEST.tar.gz -e atl_use_system_jdk=true -e atl_download_format=tarball -e atl_product_download_url=http://s3.amazon.com/atlassian/jira-9.0.0-PRE-TEST.tar.gz -e atl_use_system_jdk=true -e atl_download_format=tarball
### Other customizable parameters
## Development For more deployment customization options, consult the following files for parameters you can
override:
### Development philosophy - [`/roles/product_install/defaults/main.yml`](roles/product_install/defaults/main.yml)
- [`/group_vars/aws_node_local.yml`](group_vars/aws_node_local.yml)
The suite is intended to consist of a number of small, composable roles that can More customizable parameters are defined in specific roles -- specifically, in the
be combined together into playbooks. Wherever possible the roles should be role's `defaults/main.yml` file. Most of these parameters use the `atl_` prefix. You can
platform-agnostic as possible, with platform-specific functionality broken out use the following [Bitbucket code search query](https://confluence.atlassian.com/bitbucket/search-873876782.html)
into more specific roles. to find them:
Where possible the roles are also product-agnostic (e.g. downloads), with more repo:dc-deployments-automation repo:dc-deployments-automation path:*/defaults/main.yml atl
specific functionality added in later product-specific roles.
Roles should be reasonably self-contained, with sensible defaults configured in # Development and testing
`<role>/defaults/main.yml` and overridden by the playbook at runtime. Roles may
implicitly depend on variables being defined elsewhere where they cannot define
them natively (e.g. the `jira_config` role depends on the `atl_cluster_node_id`
var being defined; on AWS this is provided by the `aws_common` role, which
should be run first).
### Development and testing
See [Development](DEVELOPMENT.md) for details on setting up a development See [Development](DEVELOPMENT.md) for details on setting up a development
environment and running tests. environment and running tests.
## Ansible layout # Roles philosophy
This suite is intended to consist of many small, composable roles that can
be combined together into playbooks. Wherever possible, roles should be product-agnostic
(e.g. downloads) and platform-agnostic. Functions that are product-specific or
platform-specific are split off into separate roles.
Roles should be reasonably self-contained, with sensible defaults configured in
`/roles/<role>/defaults/main.yml`. Like all playbook parameters, you can override
them at runtime.
Some roles implicitly depend on other variables beind defined elsewhere.
For example, the `jira_config` role depends on the `atl_cluster_node_id`
var being defined; on AWS this is provided by the `aws_common` role, which
should be run first.
# Ansible layout
* Helper scripts are in `bin/`. In particular the `bin/ansible-with-atl-env` * Helper scripts are in `bin/`. In particular the `bin/ansible-with-atl-env`
wrapper is of use during AWS node initialisation. See _Usage_ above for more wrapper is of use during AWS node initialisation. Refer to the [Usage](#markdown-header-usage) section for
information. more information.
* Inventory files are under `inv/`. For AWS `cfn-init` the inventory * Inventory files are under `inv/`. For AWS `cfn-init` the inventory
`inv/aws_node_local` inventory is probably what you want. `inv/aws_node_local` inventory is probably what you want.
* Note that this expects the environment to be setup with infrastructure * Note that this expects the environment to be setup with infrastructure information.
information; see _Usage_ above. Refer to the [Usage](#markdown-header-usage) section for more information.
* Global group vars loaded automatically from `group_vars/<group>.yml`. In * Global group vars loaded automatically from `group_vars/<group>.yml`. In
particular note `group_vars/aws_node_local.yml` which loads infrastructure particular note `group_vars/aws_node_local.yml` which loads infrastructure
information from the environment. information from the environment.
* Roles are under `roles/` * Roles are defined in `roles/`
* Platform specific roles start with `<platform-shortname>_...`, * Platform specific roles start with `<platform-shortname>_...`, e.g. `roles/aws_common/`.
e.g. `roles/aws_common/`.
* Similarly, product-specific roles should start with `<product>_...`. * Similarly, product-specific roles should start with `<product>_...`.
## License # Reporting issues
If you find any bugs in this repository, or have feature requests or use cases
for us, please raise them in our [public Jira project](https://jira.atlassian.com/projects/SCALE/summary).
# License
Copyright © 2019 Atlassian Corporation Pty Ltd. Copyright © 2019 Atlassian Corporation Pty Ltd.
Licensed under the Apache License, Version 2.0. Licensed under the Apache License, Version 2.0.

View File

@@ -7,6 +7,7 @@
atl_product_family: "jira" atl_product_family: "jira"
atl_product_user: "jira" atl_product_user: "jira"
atl_product_edition: "jira-{{ lookup('env', 'ATL_PRODUCT_EDITION') | lower }}" atl_product_edition: "jira-{{ lookup('env', 'ATL_PRODUCT_EDITION') | lower }}"
atl_install_jsd_as_obr: "{{ lookup('env', 'ATL_JSD_ASOBR') }}"
atl_systemd_service_name: "jira.service" atl_systemd_service_name: "jira.service"
atl_startup_systemd_params: atl_startup_systemd_params:

View File

@@ -14,7 +14,7 @@ pipelines:
- step: - step:
name: Pre Parallelization stage name: Pre Parallelization stage
script: script:
- echo "Running tests in 30 batches" - echo "Running tests in 32 batches"
- step: - step:
name: Check if number of batches match actual number of scenarios name: Check if number of batches match actual number of scenarios
script: script:
@@ -267,4 +267,20 @@ pipelines:
- apt-get update && ./bin/install-ansible --dev - apt-get update && ./bin/install-ansible --dev
- ./bin/run-tests-in-batches --batch 30 - ./bin/run-tests-in-batches --batch 30
- step:
name: Molecule Test Batch - 31
services:
- docker
script:
- apt-get update && ./bin/install-ansible --dev
- ./bin/run-tests-in-batches --batch 31
- step:
name: Molecule Test Batch - 32
services:
- docker
script:
- apt-get update && ./bin/install-ansible --dev
- ./bin/run-tests-in-batches --batch 32

View File

@@ -22,12 +22,13 @@ atl_product_download_filename: "{{ atl_download_edition | default(atl_product_ed
atl_product_temp_download: "{{ atl_installer_temp }}/{{ atl_product_download_filename }}" atl_product_temp_download: "{{ atl_installer_temp }}/{{ atl_product_download_filename }}"
atl_product_varfile: "{{ atl_installer_temp }}/{{ atl_product_family }}.varfile" atl_product_varfile: "{{ atl_installer_temp }}/{{ atl_product_family }}.varfile"
atl_product_home_shared_download_dir: "{{ atl_product_home_shared }}/downloads" atl_product_home_shared_download_dir: "{{ atl_shared_mountpoint }}/downloads"
atl_product_home_shared_download: "{{ atl_product_home_shared_download_dir }}/{{ atl_product_download_filename }}" atl_product_home_shared_download: "{{ atl_product_home_shared_download_dir }}/{{ atl_product_download_filename }}"
atl_product_home_shared_moving_lock: "{{ atl_product_home_shared_download }}_moving" atl_product_home_shared_moving_lock: "{{ atl_product_home_shared_download }}_moving"
atl_product_home_shared_completed_lock: "{{ atl_product_home_shared_download }}_completed" atl_product_home_shared_completed_lock: "{{ atl_product_home_shared_download }}_completed"
atl_marketplace_base: "https://marketplace.atlassian.com" atl_marketplace_base: "https://marketplace.atlassian.com"
atl_mpac_products: "https://marketplace.atlassian.com/rest/2/products"
atl_servicedesk_latest_url: "https://marketplace.atlassian.com/rest/2/products/key/jira-servicedesk/versions/latest" atl_servicedesk_latest_url: "https://marketplace.atlassian.com/rest/2/products/key/jira-servicedesk/versions/latest"
atl_servicedesk_versioned_url: "https://marketplace.atlassian.com/rest/2/products/key/jira-servicedesk/versions/name/{{ atl_product_version }}" atl_servicedesk_versioned_url: "https://marketplace.atlassian.com/rest/2/products/key/jira-servicedesk/versions/name/{{ atl_product_version }}"
atl_servicedesk_url_map: atl_servicedesk_url_map:

View File

@@ -37,7 +37,7 @@ def test_latest_is_downloaded(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
installer = host.file('/media/atl/bitbucket/shared/downloads/bitbucket.' + upstream + '-x64.bin') installer = host.file('/media/atl/downloads/bitbucket.' + upstream + '-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
@@ -47,6 +47,6 @@ def test_completed_lockfile(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
lockfile = host.file('/media/atl/bitbucket/shared/downloads/bitbucket.' + upstream + '-x64.bin_completed') lockfile = host.file('/media/atl/downloads/bitbucket.' + upstream + '-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -35,7 +35,7 @@ def test_latest_is_downloaded(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
installer = host.file('/media/atl/confluence/shared-home/downloads/confluence.'+upstream+'-x64.bin') installer = host.file('/media/atl/downloads/confluence.'+upstream+'-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
@@ -44,6 +44,6 @@ def test_completed_lockfile(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
lockfile = host.file('/media/atl/confluence/shared-home/downloads/confluence.'+upstream+'-x64.bin_completed') lockfile = host.file('/media/atl/downloads/confluence.'+upstream+'-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -37,7 +37,7 @@ def test_latest_is_downloaded(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
installer = host.file('/media/atl/crowd/shared/downloads/crowd.' + upstream + '.tar.gz') installer = host.file('/media/atl/downloads/crowd.' + upstream + '.tar.gz')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
@@ -47,6 +47,6 @@ def test_completed_lockfile(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
lockfile = host.file('/media/atl/crowd/shared/downloads/crowd.' + upstream + '.tar.gz_completed') lockfile = host.file('/media/atl/downloads/crowd.' + upstream + '.tar.gz_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -23,7 +23,7 @@ def test_latest_is_downloaded(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
installer = host.file('/media/atl/jira/shared/downloads/jira-core.'+upstream+'-x64.bin') installer = host.file('/media/atl/downloads/jira-core.'+upstream+'-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
@@ -32,6 +32,6 @@ def test_completed_lockfile(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
lockfile = host.file('/media/atl/jira/shared/downloads/jira-core.'+upstream+'-x64.bin_completed') lockfile = host.file('/media/atl/downloads/jira-core.'+upstream+'-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -0,0 +1,14 @@
# Molecule managed
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi

View File

@@ -0,0 +1,30 @@
---
dependency:
name: galaxy
driver:
name: docker
lint:
name: yamllint
platforms:
- name: amazon_linux2
image: amazonlinux:2
groups:
- aws_node_local
- name: ubuntu_lts
image: ubuntu:bionic
groups:
- aws_node_local
provisioner:
name: ansible
options:
skip-tags: runtime_pkg
lint:
name: ansible-lint
inventory:
links:
group_vars: ../../../../group_vars/
verifier:
name: testinfra
lint:
name: flake8
enabled: false

View File

@@ -0,0 +1,28 @@
---
- name: Converge
hosts: all
vars:
atl_product_family: "jira"
atl_product_edition: "jira-software"
atl_product_user: "jira"
atl_product_version: "7.13.1"
atl_install_jsd_as_obr: true
atl_systemd_service_name: "jira.service"
atl_jdbc_encoding: 'UNICODE'
atl_jdbc_collation: 'C'
atl_jdbc_ctype: 'C'
atl_jdbc_template: 'template0'
pre_tasks:
- name: Create cache dir
file:
path: '/media/atl/jira/shared/'
state: directory
- name: Seed version
copy:
dest: '/media/atl/jira/shared/jira-core.version'
content: "7.13.1"
force: false # For idempotency check
roles:
- role: linux_common
- role: product_common
- role: product_install

View File

@@ -0,0 +1,48 @@
import os
from six.moves import urllib
import testinfra.utils.ansible_runner
import json
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
def test_version_is_correct(host):
verfile = host.file('/media/atl/jira/shared/jira-software.version')
assert verfile.exists
assert verfile.content.decode("UTF-8").strip() == "7.13.1"
def test_is_downloaded(host):
installer = host.file('/media/atl/downloads/jira-software.7.13.1-x64.bin')
assert installer.exists
assert installer.user == 'root'
def test_completed_lockfile(host):
lockfile = host.file('/media/atl/downloads/jira-software.7.13.1-x64.bin_completed')
assert lockfile.exists
assert lockfile.user == 'root'
def test_is_unpacked(host):
installer = host.file('/opt/atlassian/jira-software/7.13.1/atlassian-jira/')
assert installer.exists
assert installer.is_directory
assert installer.user == 'jira'
assert installer.mode == 0o0755
def test_obr_is_downloaded(host):
installer = host.file('/media/atl/downloads/jira-servicedesk-application-3.16.1.obr')
assert installer.exists
assert installer.user == 'root'
def test_obr_completed_lockfile(host):
lockfile = host.file('/media/atl/downloads/jira-servicedesk-application-3.16.1.obr_completed')
assert lockfile.exists
assert lockfile.user == 'root'
def test_obr_is_unpacked(host):
jsdjar = host.file('/media/atl/jira/shared/plugins/installed-plugins/jira-servicedesk-application-3.16.1.jar')
assert jsdjar.exists
assert jsdjar.user == 'jira'
assert jsdjar.mode == 0o0750

View File

@@ -14,12 +14,12 @@ def test_version_is_correct(host):
assert verfile.content.decode("UTF-8").strip() == "7.10.2" assert verfile.content.decode("UTF-8").strip() == "7.10.2"
def test_is_downloaded(host): def test_is_downloaded(host):
installer = host.file('/media/atl/jira/shared/downloads/jira-core.7.10.2-x64.bin') installer = host.file('/media/atl/downloads/jira-core.7.10.2-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
def test_completed_lockfile(host): def test_completed_lockfile(host):
lockfile = host.file('/media/atl/jira/shared/downloads/jira-core.7.10.2-x64.bin_completed') lockfile = host.file('/media/atl/downloads/jira-core.7.10.2-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -14,12 +14,12 @@ def test_version_is_correct(host):
assert verfile.content.decode("UTF-8").strip() == "7.10.1" assert verfile.content.decode("UTF-8").strip() == "7.10.1"
def test_is_downloaded(host): def test_is_downloaded(host):
installer = host.file('/media/atl/jira/shared/downloads/jira-core.7.10.1-x64.bin') installer = host.file('/media/atl/downloads/jira-core.7.10.1-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
def test_completed_lockfile(host): def test_completed_lockfile(host):
lockfile = host.file('/media/atl/jira/shared/downloads/jira-core.7.10.1-x64.bin_completed') lockfile = host.file('/media/atl/downloads/jira-core.7.10.1-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -35,7 +35,7 @@ def test_latest_is_downloaded(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
installer = host.file('/media/atl/jira/shared/downloads/jira-software.'+upstream+'-x64.bin') installer = host.file('/media/atl/downloads/jira-software.'+upstream+'-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
@@ -44,6 +44,6 @@ def test_completed_lockfile(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
lockfile = host.file('/media/atl/jira/shared/downloads/jira-software.'+upstream+'-x64.bin_completed') lockfile = host.file('/media/atl/downloads/jira-software.'+upstream+'-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -23,7 +23,7 @@ def test_latest_is_downloaded(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
installer = host.file('/media/atl/jira/shared/downloads/jira-core.'+upstream+'.tar.gz') installer = host.file('/media/atl/downloads/jira-core.'+upstream+'.tar.gz')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
@@ -32,6 +32,6 @@ def test_completed_lockfile(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
lockfile = host.file('/media/atl/jira/shared/downloads/jira-core.'+upstream+'.tar.gz_completed') lockfile = host.file('/media/atl/downloads/jira-core.'+upstream+'.tar.gz_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -14,12 +14,12 @@ def test_version_is_correct(host):
assert verfile.content.decode("UTF-8").strip() == "7.9.0" assert verfile.content.decode("UTF-8").strip() == "7.9.0"
def test_is_downloaded(host): def test_is_downloaded(host):
installer = host.file('/media/atl/jira/shared/downloads/jira-core.7.9.0-x64.bin') installer = host.file('/media/atl/downloads/jira-core.7.9.0-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
def test_completed_lockfile(host): def test_completed_lockfile(host):
lockfile = host.file('/media/atl/jira/shared/downloads/jira-core.7.9.0-x64.bin_completed') lockfile = host.file('/media/atl/downloads/jira-core.7.9.0-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -23,7 +23,7 @@ def test_latest_is_downloaded(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
installer = host.file('/media/atl/jira/shared/downloads/jira-core.'+upstream+'-x64.bin') installer = host.file('/media/atl/downloads/jira-core.'+upstream+'-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
@@ -32,6 +32,6 @@ def test_completed_lockfile(host):
upstream_json = json.load(upstream_fd) upstream_json = json.load(upstream_fd)
upstream = upstream_json['version'] upstream = upstream_json['version']
lockfile = host.file('/media/atl/jira/shared/downloads/jira-core.'+upstream+'-x64.bin_completed') lockfile = host.file('/media/atl/downloads/jira-core.'+upstream+'-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -14,12 +14,12 @@ def test_version_is_correct(host):
assert verfile.content.decode("UTF-8").strip() == "7.13.2" assert verfile.content.decode("UTF-8").strip() == "7.13.2"
def test_is_downloaded(host): def test_is_downloaded(host):
installer = host.file('/media/atl/jira/shared/downloads/jira-core.7.13.2-x64.bin') installer = host.file('/media/atl/downloads/jira-core.7.13.2-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
def test_completed_lockfile(host): def test_completed_lockfile(host):
lockfile = host.file('/media/atl/jira/shared/downloads/jira-core.7.13.2-x64.bin_completed') lockfile = host.file('/media/atl/downloads/jira-core.7.13.2-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -14,12 +14,12 @@ def test_version_is_correct(host):
assert verfile.content.decode("UTF-8").strip() == "3.9.0" assert verfile.content.decode("UTF-8").strip() == "3.9.0"
def test_is_downloaded(host): def test_is_downloaded(host):
installer = host.file('/media/atl/jira/shared/downloads/servicedesk.3.9.0-x64.bin') installer = host.file('/media/atl/downloads/servicedesk.3.9.0-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
def test_completed_lockfile(host): def test_completed_lockfile(host):
lockfile = host.file('/media/atl/jira/shared/downloads/servicedesk.3.9.0-x64.bin_completed') lockfile = host.file('/media/atl/downloads/servicedesk.3.9.0-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -14,12 +14,12 @@ def test_version_is_correct(host):
assert verfile.content.decode("UTF-8").strip() == "4.1.0" assert verfile.content.decode("UTF-8").strip() == "4.1.0"
def test_is_downloaded(host): def test_is_downloaded(host):
installer = host.file('/media/atl/jira/shared/downloads/servicedesk.4.1.0-x64.bin') installer = host.file('/media/atl/downloads/servicedesk.4.1.0-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
def test_completed_lockfile(host): def test_completed_lockfile(host):
lockfile = host.file('/media/atl/jira/shared/downloads/servicedesk.4.1.0-x64.bin_completed') lockfile = host.file('/media/atl/downloads/servicedesk.4.1.0-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -23,12 +23,12 @@ def test_version_is_correct(host):
assert verfile.content.decode("UTF-8").strip() == sd assert verfile.content.decode("UTF-8").strip() == sd
def test_is_downloaded(host): def test_is_downloaded(host):
installer = host.file('/media/atl/jira/shared/downloads/servicedesk.'+sd+'-x64.bin') installer = host.file('/media/atl/downloads/servicedesk.'+sd+'-x64.bin')
assert installer.exists assert installer.exists
assert installer.user == 'root' assert installer.user == 'root'
def test_completed_lockfile(host): def test_completed_lockfile(host):
lockfile = host.file('/media/atl/jira/shared/downloads/servicedesk.'+sd+'-x64.bin_completed') lockfile = host.file('/media/atl/downloads/servicedesk.'+sd+'-x64.bin_completed')
assert lockfile.exists assert lockfile.exists
assert lockfile.user == 'root' assert lockfile.user == 'root'

View File

@@ -0,0 +1 @@
no_op.yml

View File

@@ -0,0 +1,174 @@
---
- name: Get the installer product version info
uri:
url: "{{ atl_mpac_products }}/key/jira-software/versions/name/{{ atl_product_version }}"
return_content: yes
register: atl_product_version_info
- name: Show the returned build number
debug:
msg="buildNumber={{ atl_product_version_info.json.buildNumber }}"
- name: Get the JSD build version info
uri:
url: "{{ atl_mpac_products }}/key/jira-servicedesk/versions/latest?application=\
jira&applicationBuild={{ atl_product_version_info.json.buildNumber }}"
return_content: yes
register: atl_jsd_build_info
- name: Show the returned obr binary href
debug:
msg="obr_ref={{ atl_jsd_build_info.json._embedded.artifact._links.binary.href }}"
- name: how about getting the obr filename
debug:
msg="obr_name=jira-servicedesk-application-{{ atl_jsd_build_info.json.name }}.obr"
- name: is shared_home set ?
debug:
msg="atl_product_home_shared_download_dir={{ atl_product_home_shared_download_dir }}"
# For the first run a temp obr should be downloaded but moved to
# shared home to ensure all subsequent nodes have access
# to the same specific version binary.
# To prevent a race condition with multiple downloads at the same time
# a directory is used as a lockfile (atomic operation) when moving obr.
- name: Set assumptions to avoid race condition
set_fact:
download_obr: true
move_obr: false
atl_obr_download_href: "{{ atl_jsd_build_info.json._embedded.artifact._links.binary.href }}"
atl_obr_filename: "jira-servicedesk-application-{{ atl_jsd_build_info.json.name }}.obr"
atl_obr_download: "{{ atl_installer_temp }}/jira-servicedesk-application-{{ atl_jsd_build_info.json.name }}.obr"
atl_obr_shared_download: "{{ atl_product_home_shared_download_dir }}/jira-servicedesk-application-{{ atl_jsd_build_info.json.name }}.obr"
atl_obr_moving_lock: "{{ atl_product_home_shared_download_dir }}/jira-servicedesk-application-{{ atl_jsd_build_info.json.name }}.obr_moving"
atl_obr_completed_lock: "{{ atl_product_home_shared_download_dir }}/jira-servicedesk-application-{{ atl_jsd_build_info.json.name }}.obr_completed"
# Check for pre-downloaded obr on shared_home and completed lock dir.
- name: Check for completed lock directory
stat:
path: "{{ atl_obr_completed_lock }}"
register: completed_lock
- name: Check for obr in home_shared
stat:
path: "{{ atl_obr_shared_download }}"
register: home_shared_download
# If obr exists and lockdir exists use this obr instead
- name: Check lock directory and obr exists on shared_home
set_fact:
download_obr: false
atl_obr_download: "{{ atl_obr_shared_download }}"
when:
- home_shared_download.stat.exists
- completed_lock.stat.isdir is defined
- completed_lock.stat.isdir
# Fetch obr if required
- name: download_obr is true so fetch and do all the things
block:
# Fetch obr and copy to temp
- name: Fetch obr
get_url:
url: "{{ atl_obr_download_href }}"
dest: "{{ atl_obr_download }}"
mode: 0755
force: false
register: atl_obr_completed
# If obr was fetched make the lock directory
- name: Create moving_lock.
file:
path: "{{ atl_obr_moving_lock }}"
state: directory
when:
- atl_obr_completed is succeeded
register: moving_lock_created
# Directory lock was created by this run?
# If so, then set a fact intending to move obr
- name: Move obr Scenario - lock created by this run
set_fact:
move_obr: true
when:
- moving_lock_created is succeeded
- moving_lock_created.changed
# Otherwise directory lock was either already created or
# could not be created. Fall back is to continue and install from temp
when: download_obr
# If the intention is to move obr to home_shared
- name: Move obr to home_shared
block:
- name: Copy temp installer to home_shared
copy:
src: "{{ atl_obr_download }}"
dest: "{{ atl_obr_shared_download }}"
remote_src: true
register: copied
- name: Create completed_lock once obr downloaded and copied
file:
path: "{{ atl_obr_completed_lock }}"
state: directory
when: copied is succeeded
register: completed_lock_created
- name: Remove moving_lock to show that obr is completed
file:
path: "{{ atl_obr_moving_lock }}"
state: absent
when:
- completed_lock_created is succeeded
- copied is succeeded
register: moving_lock_removed
- name: Delete old temp installer
file:
path: "{{ atl_obr_download }}"
state: absent
when: moving_lock_removed is succeeded
register: temp_deleted
- name: Set install to home_shared location
set_fact:
atl_obr_download: "{{ atl_obr_shared_download }}"
when: temp_deleted is succeeded
when: move_obr
# At this point the binary is in {{ atl_obr_download }}
# (which is either on home_shared or temp)
- name: Ensure instaled-plugins dir exists
file:
path: "{{ atl_product_home_shared }}/plugins/installed-plugins"
state: directory
mode: 0750
owner: "{{ atl_product_user }}"
group: "{{ atl_product_user }}"
# Note as ansible unarchive cant handle "-j junk paths" we need to ignore errors to bypass the path verify
- name: Unpack the obr into the installed-plugins dir
unarchive:
remote_src: true
src: "{{ atl_obr_download }}"
dest: "{{ atl_product_home_shared }}/plugins/installed-plugins"
creates: "{{ atl_product_home_shared }}/plugins/installed-plugins/jira-servicedesk-application-{{ atl_jsd_build_info.json.name }}.jar"
list_files: no
exclude:
- M*
owner: "{{ atl_product_user }}"
group: "{{ atl_product_user }}"
mode: 0750
ignore_errors: yes
- name: Move JSD dependency jars into the installed-plugins dir
shell:
cmd: "mv {{ atl_product_home_shared }}/plugins/installed-plugins/dependencies/*.jar {{ atl_product_home_shared }}/plugins/installed-plugins"
creates: "{{ atl_product_home_shared }}/plugins/installed-plugins/servicedesk-core-ui-plugin-{{ atl_jsd_build_info.json.name }}-*.jar"

View File

@@ -249,3 +249,9 @@
dest: "{{ atl_product_installation_current }}" dest: "{{ atl_product_installation_current }}"
state: link state: link
force: true force: true
- name: Include if jsd is requested to be installed from OBR
include_tasks: "jira-servicedesk_as_obr.yml"
when:
- atl_install_jsd_as_obr is defined
- atl_install_jsd_as_obr

View File

@@ -0,0 +1,14 @@
# Molecule managed
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi

View File

@@ -0,0 +1,30 @@
---
dependency:
name: galaxy
driver:
name: docker
lint:
name: yamllint
platforms:
- name: amazon_linux2
image: amazonlinux:2
groups:
- aws_node_local
ulimits:
- nofile:262144:262144
provisioner:
name: ansible
options:
skip-tags: runtime_pkg
lint:
name: ansible-lint
options:
x: ["701"]
inventory:
links:
group_vars: ../../../../group_vars/
verifier:
name: testinfra
lint:
name: flake8
enabled: false

View File

@@ -0,0 +1,75 @@
---
- name: Converge
hosts: all
vars:
atl_backup_home_dest: "{{ test_archive }}"
atl_backup_home_restore_canary_path: '/tmp/canary.tmp'
atl_backup_id: 'test-backup'
atl_backup_manifest_url: 'fake_manifest'
atl_product_edition: 'jira-software'
atl_product_home_shared: '/media/atl/jira/shared'
atl_product_user: 'jira'
atl_product_user_uid: '2001'
atl_product_version_cache: "{{ atl_product_home_shared }}/{{ atl_product_edition }}.version"
test_archive: '/tmp/hello.tar.gz'
test_archive_file: 'hello.txt'
test_archive_source: '/tmp/hello'
test_pre_step_prefix: '[PRE-TEST]'
test_product_version_file: "/tmp/{{ atl_product_edition }}.version"
pre_tasks:
- name: "{{ test_pre_step_prefix }} Install tar"
package:
state: present
name: tar
- name: "{{ test_pre_step_prefix }} Install useradd and groupadd binaries"
package:
state: present
name: shadow-utils
- name: "{{ test_pre_step_prefix }} Create application group"
group:
name: "{{ atl_product_user }}"
gid: "{{ atl_product_user_uid }}"
- name: "{{ test_pre_step_prefix }} Create application user"
user:
name: "{{ atl_product_user }}"
uid: "{{ atl_product_user_uid }}"
group: "{{ atl_product_user }}"
- block:
- name: "{{ test_pre_step_prefix }} Create a directory for the shared home archive"
file:
path: "{{ test_archive_source }}"
state: directory
mode: 0755
- name: "{{ test_pre_step_prefix }} Create a file in the shared home"
lineinfile:
create: yes
line: 'Hello, world!'
path: "{{ test_archive_source }}/{{ test_archive_file }}"
mode: 0640
- name: "{{ test_pre_step_prefix }} Create the version file in the shared home"
lineinfile:
create: yes
line: '8.5'
path: "{{ test_product_version_file }}"
mode: 0640
- name: "{{ test_pre_step_prefix }} Archive the shared home"
archive:
path:
- "{{ test_archive_source }}"
- "{{ test_product_version_file }}"
dest: "{{ test_archive }}"
owner: "{{ atl_product_user }}"
tasks:
- name: Install distro-specific restore support packages
include_tasks: "../../tasks/{{ ansible_distribution|lower }}.yml"
- name: Restore shared home
include_tasks: "../../tasks/home_restore.yml"

View File

@@ -0,0 +1,39 @@
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
@pytest.mark.parametrize('exe', [
'/usr/bin/pg_dump',
'/usr/bin/pg_restore',
'/usr/bin/psql'
])
def test_postgresql_amazon_linux_extras_exes(host, exe):
assert host.file(exe).exists
def test_postgresql_version(host):
pg_dump_version_output = host.check_output('pg_dump --version')
assert '(PostgreSQL) 9.6' in pg_dump_version_output
@pytest.mark.parametrize('file', [
'/media/atl/jira/shared',
'/media/atl/jira/shared/hello',
'/media/atl/jira/shared/hello/hello.txt'
])
def test_shared_home_owner(host, file):
assert host.file(file).exists
assert host.file(file).user == 'jira'
assert host.file(file).group == 'jira'
def test_file_modes(host):
assert host.file('/media/atl/jira/shared/hello').mode == 0o755
assert host.file('/media/atl/jira/shared/hello/hello.txt').mode == 0o640
def test_version_file_owned_by_root(host):
assert host.file('/media/atl/jira/shared/jira-software.version').exists
assert host.file('/media/atl/jira/shared/jira-software.version').user == 'root'
assert host.file('/media/atl/jira/shared/jira-software.version').group == 'root'

View File

@@ -8,3 +8,5 @@
PYTHON: /bin/python PYTHON: /bin/python
args: args:
creates: /usr/bin/psql creates: /usr/bin/psql
environment:
PYTHON: /bin/python

View File

@@ -0,0 +1,44 @@
---
- name: Check for the restore canary file
stat:
path: "{{ atl_backup_home_restore_canary_path }}"
register: restore_canary
- block:
- name: Create shared home if necessary
file:
path: "{{ atl_product_home_shared }}"
state: directory
mode: 0750
owner: "{{ atl_product_user }}"
group: "{{ atl_product_user }}"
- name: Restore the shared-home backup
unarchive:
src: "{{ atl_backup_home_dest }}"
remote_src: yes
dest: "{{ atl_product_home_shared }}"
- name: Set shared home owner and group to application user
file:
path: "{{ atl_product_home_shared }}"
recurse: yes
group: "{{ atl_product_user }}"
owner: "{{ atl_product_user }}"
state: directory
- name: Set version file owner and group to root
file:
path: "{{ atl_product_version_cache }}"
group: root
owner: root
state: file
# Ignore the error in case there is no product version file in the backup
ignore_errors: yes
- name: Create restore-canary if necessary
copy:
dest: "{{ atl_backup_home_restore_canary_path }}"
content: "{{ atl_backup_id }}"
when: not restore_canary.stat.exists

View File

@@ -68,7 +68,9 @@
overwrite: different overwrite: different
bucket: "{{ atl_backup_manifest.artifacts.db.location.location | urlsplit('hostname') }}" bucket: "{{ atl_backup_manifest.artifacts.db.location.location | urlsplit('hostname') }}"
object: "{{ atl_backup_manifest.artifacts.db.location.location | urlsplit('path') }}" object: "{{ atl_backup_manifest.artifacts.db.location.location | urlsplit('path') }}"
dest: "{{ atl_backup_db_dest }}" # We save the backup as a .tar file so that the postgresql_db module uses pg_restore instead of psql to do restore
# This can be removed when ansible 2.10 is released
dest: "{{ atl_backup_db_dest }}.tar"
- name: Fetch Home backup from S3 - name: Fetch Home backup from S3
aws_s3: aws_s3:
@@ -96,42 +98,18 @@
template: "{{ atl_jdbc_template }}" template: "{{ atl_jdbc_template }}"
# Depends on fetch_backup roles # Depends on fetch_backup roles
state: restore state: restore
target: "{{ atl_backup_db_dest }}" target: "{{ atl_backup_db_dest }}.tar"
target_opts: "-Fc"
register: result register: result
# managed DBs in cloud providers are not allowing full root access to the DB engine, we can safely ignore the COMMENT ON EXTENSION error
failed_when: failed_when:
- result.rc != 0 - result.rc != 0
- "COMMENT ON EXTENSION" not in result.msg - '"COMMENT ON EXTENSION" not in result.msg'
when: db_created.changed and atl_backup_db_dest is defined when: db_created.changed and atl_backup_db_dest is defined
- name: Check for the restore canary file - name: Restore shared home
stat: include_tasks: "home_restore.yml"
path: "{{ atl_backup_home_restore_canary_path }}"
register: restore_canary
- block:
- name: Create shared home if necessary
file:
path: "{{ atl_product_home_shared }}"
state: directory
mode: 0750
owner: "{{ atl_product_user }}"
group: "{{ atl_product_user }}"
- name: Restore the shared-home backup
unarchive:
src: "{{ atl_backup_home_dest }}"
dest: "{{ atl_product_home_shared }}"
owner: "{{ atl_product_user }}"
group: "{{ atl_product_user }}"
- name: Create restore-canary if necessary
copy:
dest: "{{ atl_backup_home_restore_canary_path }}"
content: "{{ atl_backup_id }}"
when: not restore_canary.stat.exists
when: atl_restore_required when: atl_restore_required