378 lines
13 KiB
YAML
378 lines
13 KiB
YAML
---
|
|
#
|
|
# Copyright (c) 2019 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# ROLE DESCRIPTION:
|
|
# This role is to backup StarlingX platform data and
|
|
# StarlingX OpenStack Application data if the app exists.
|
|
# The backup data are stored in two separate tar files.
|
|
#
|
|
- name: Do StarlingX backup
|
|
block:
|
|
- name: Generate backup_in_progress alarm
|
|
script: fm_alarm.py "--set" "--backup"
|
|
register: alarm_result
|
|
failed_when: false
|
|
|
|
- name: Fail if alarm script throws an exception
|
|
fail:
|
|
msg: "Failed to generate backup-in-progress alarm."
|
|
when: alarm_result.rc != 0
|
|
|
|
- name: Create temp dir
|
|
tempfile:
|
|
path: "{{ backup_dir }}"
|
|
state: directory
|
|
register: tempdir
|
|
|
|
- name: Create postgres temp dir
|
|
file:
|
|
path: "{{ tempdir.path }}/postgres"
|
|
state: directory
|
|
register: postgres_dir
|
|
|
|
- name: Backup roles, table spaces and schemas for databases.
|
|
shell: >-
|
|
sudo -u postgres pg_dumpall
|
|
--clean --schema-only > {{ postgres_dir.path }}/postgres.postgreSql.config
|
|
args:
|
|
warn: false
|
|
|
|
- name: Backup postgres, template1, sysinv, barbican db data
|
|
shell: >-
|
|
sudo -u postgres pg_dump --format=plain --inserts --disable-triggers --data-only
|
|
{{ item }} > {{ postgres_dir.path }}/{{ item }}.postgreSql.data
|
|
args:
|
|
warn: false
|
|
with_items:
|
|
- postgres
|
|
- template1
|
|
- sysinv
|
|
- barbican
|
|
|
|
- name: Backup fm db data
|
|
shell: >-
|
|
sudo -u postgres pg_dump --format=plain --inserts --disable-triggers
|
|
--data-only fm --exclude-table=alarm > {{ postgres_dir.path }}/fm.postgreSql.data
|
|
args:
|
|
warn: false
|
|
|
|
- name: Check if it is the primary region
|
|
command: grep -i "region_config\s*=\s*no" {{ platform_conf_path }}/platform.conf
|
|
register: check_region
|
|
failed_when: false
|
|
|
|
- name: Backup keystone db for primary region
|
|
shell: >-
|
|
sudo -u postgres pg_dump --format=plain --inserts --disable-triggers
|
|
--data-only keystone > {{ postgres_dir.path }}/keystone.postgreSql.data
|
|
args:
|
|
warn: false
|
|
when: check_region.rc == 0
|
|
|
|
- name: Check if it is dc controller
|
|
command: >-
|
|
grep -i "distributed_cloud_role\s*=\s*systemcontroller"
|
|
{{ platform_conf_path }}/platform.conf
|
|
register: check_dc_controller
|
|
failed_when: false
|
|
|
|
- block:
|
|
- name: Backup dcmanager db for dc controller
|
|
shell: >-
|
|
sudo -u postgres pg_dump --format=plain --inserts --disable-triggers
|
|
--data-only dcmanager > {{ postgres_dir.path }}/dcmanager.postgreSql.data
|
|
args:
|
|
warn: false
|
|
|
|
- name: Backup dcorch db for dc controller
|
|
set_fact:
|
|
dcorch_db: "sudo -u postgres pg_dump --format=plain --inserts --disable-triggers --data-only dcorch "
|
|
|
|
- name: Update dcorch tables that will be excluded from backup
|
|
set_fact:
|
|
dcorch_db: "{{ dcorch_db }} --exclude-table={{ item }}"
|
|
with_items:
|
|
- orch_job
|
|
- orch_request
|
|
- resource
|
|
- subcloud_resource
|
|
|
|
- name: Backup dcorch db
|
|
shell: "{{ dcorch_db }} > {{ postgres_dir.path }}/dcorch.postgreSql.data"
|
|
|
|
when: check_dc_controller.rc == 0
|
|
|
|
- name: Create mariadb temp dir
|
|
file:
|
|
path: "{{ tempdir.path }}/mariadb"
|
|
state: directory
|
|
register: mariadb_dir
|
|
|
|
- name: Check if mariadb pod is running
|
|
shell: >-
|
|
kubectl --kubeconfig={{ kube_config_dir }} get pods -n openstack | grep {{ mariadb_pod }} | grep -i 'running'
|
|
failed_when: false
|
|
register: check_mariadb_pod
|
|
|
|
- block:
|
|
- name: Set k8s cmd prefix
|
|
set_fact:
|
|
kube_cmd_prefix: "kubectl --kubeconfig={{ kube_config_dir }} exec -i {{ mariadb_pod }} -n openstack -- bash -c "
|
|
|
|
- name: Show databases
|
|
shell: "{{ kube_cmd_prefix }} 'exec mysql -uroot -p\"$MYSQL_DBADMIN_PASSWORD\" -e\"show databases\"'"
|
|
register: databases
|
|
|
|
- name: Backup mariadb
|
|
shell: >-
|
|
{{ kube_cmd_prefix }} 'exec mysqldump -uroot -p"$MYSQL_DBADMIN_PASSWORD" {{ item }}' >
|
|
{{ mariadb_dir.path }}/{{ item }}.mariadb.data
|
|
with_items: "{{ databases.stdout_lines | difference(skip_os_dbs) }}"
|
|
|
|
when: check_mariadb_pod.rc == 0
|
|
|
|
- block:
|
|
|
|
- name: Get stx-openstack status
|
|
shell: >-
|
|
source /etc/platform/openrc; system application-show stx-openstack --column status --format value
|
|
failed_when: false
|
|
register: openstack_status
|
|
|
|
- name: Fail the backup if MariaDB is not running
|
|
fail:
|
|
msg: "WARNING: {{ mariadb_pod }} is not running. Cannot backup mariadb data."
|
|
when: openstack_status.stdout == "applied"
|
|
when: check_mariadb_pod.rc != 0
|
|
|
|
# In order to restore only the stx-openstack, the user needs to manually
|
|
# remove, delete and upload the application.
|
|
# This procedure will make the helm overrides data that is
|
|
# present in the sysinv DB and the stx-openstack DB to be inconsistent.
|
|
# A dump file containing the overrides data is used here to solve this inconsistency issue.
|
|
# Note that this file will contain only 'update' sql commands because the
|
|
# overrides are already created when we uploaded the application.
|
|
- name: Create Helm overrides temp dir
|
|
file:
|
|
path: "{{ tempdir.path }}/helm_overrides_dir"
|
|
state: directory
|
|
register: helm_overrides_dir
|
|
|
|
- name: Get the openstack Helm overrides from the from the database
|
|
shell: >-
|
|
psql -c "copy(select row_to_json(t) from (select name, user_overrides, system_overrides
|
|
from helm_overrides where namespace='openstack') as t) to stdout" sysinv | sed -e 's/\\\\/\\/g'
|
|
become_user: postgres
|
|
register: helm_overrides_list
|
|
|
|
- name: Generate postgres update commands for Helm overrides
|
|
set_fact:
|
|
updates_list: >
|
|
{{ updates_list | default('') }}update helm_overrides set
|
|
system_overrides={% if item.system_overrides %}'{{ item.system_overrides }}'{% else %}NULL{% endif %},
|
|
user_overrides={% if item.user_overrides %}'{{ item.user_overrides }}'{% else %}NULL{% endif %}
|
|
where name='{{ item.name }}' and namespace='openstack';
|
|
with_items: "{{ helm_overrides_list.stdout_lines | map('from_json') | list }}"
|
|
|
|
- name: Backup Helm overrides
|
|
copy:
|
|
dest: "{{ helm_overrides_dir.path }}/helm_overrides_dump.sql"
|
|
mode: 0755
|
|
content: '{{ updates_list | default("") }}'
|
|
|
|
|
|
# Now Postgres data and MariaDB data are stored in staging dir, we can estimate
|
|
# the disk size requirement for the backup archive.
|
|
- name: Check the size (in kilobyte) of directories that will be backed up
|
|
shell: "du -sh -k {{ item }} | awk '{print $1}'"
|
|
with_items:
|
|
- /etc
|
|
- /home
|
|
- "{{ config_permdir }}"
|
|
- "{{ sysinv_permdir }}"
|
|
- "{{ puppet_permdir }}/hieradata"
|
|
- "{{ keyring_permdir }}"
|
|
- "{{ patching_permdir }}"
|
|
- "{{ patching_repo_permdir }}"
|
|
- "{{ extension_permdir }}"
|
|
- "{{ patch_vault_permdir }}"
|
|
- "{{ postgres_dir.path }}"
|
|
- "{{ armada_permdir }}"
|
|
- "{{ helm_charts_permdir }}"
|
|
- "{{ mariadb_dir.path }}"
|
|
- "{{ helm_overrides_dir.path }}"
|
|
register: size_output
|
|
|
|
# Estimate the backup size. We add 128M overhead for things like ceph crushmap,
|
|
# ldap data, etc. that will be generated and stored in the staging dir later on.
|
|
- name: Estimate the total required disk size for backup archive
|
|
set_fact:
|
|
total_size_estimation: "{{ total_size_estimation|default(1024*128)|int + item.stdout|int }}"
|
|
with_items: "{{ size_output.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
|
|
- name: Check if there is enough free space in the archive dir to create backup
|
|
shell: "df -k /opt/backups --output=avail | tail -1"
|
|
register: available_disk_size
|
|
|
|
- name: Fail if there is not enough free space in the archive dir to create backup
|
|
fail:
|
|
msg: >-
|
|
Not enough free space in {{ backup_dir }}. It has {{ available_disk_size }}K.
|
|
It needs at least {{ total_size_estimation }}K.
|
|
when: available_disk_size < total_size_estimation
|
|
|
|
- name: Create ldap temp dir
|
|
file:
|
|
path: "{{ tempdir.path }}/ldap"
|
|
state: directory
|
|
register: ldap_dir
|
|
|
|
- name: Name ldap db backup
|
|
set_fact:
|
|
ldap_db_backup: "{{ ldap_dir.path }}/ldap.db"
|
|
|
|
- name: Backup ldap db
|
|
command: "slapcat -d 0 -F /etc/openldap/schema -l {{ ldap_db_backup }}"
|
|
|
|
- name: Create ceph temp dir
|
|
file:
|
|
path: "{{ tempdir.path }}/ceph"
|
|
state: directory
|
|
register: ceph_dir
|
|
|
|
- name: Name ceph crushmap backup
|
|
set_fact:
|
|
crushmap_file: "{{ ceph_dir.path }}/crushmap.bin.backup"
|
|
|
|
- name: Create ceph crushmap backup
|
|
command: "ceph osd getcrushmap -o {{ crushmap_file }}"
|
|
|
|
- name: Create temp dir for override backup file
|
|
file:
|
|
path: "{{ tempdir.path }}/override"
|
|
state: directory
|
|
register: override_dir
|
|
|
|
- name: Name override backup file
|
|
set_fact:
|
|
override_backup_file: "{{ override_dir.path }}/{{ host_override_backup_file }}"
|
|
|
|
- name: Create the override backup file
|
|
command: "/usr/bin/sysinv-utils create-host-overrides {{ override_backup_file }}"
|
|
|
|
- name: Get docker registries information
|
|
include_role:
|
|
name: common/push-docker-images
|
|
tasks_from: get_docker_registries
|
|
|
|
- name: Append registries configuration
|
|
blockinfile:
|
|
path: "{{ override_backup_file }}"
|
|
marker: ""
|
|
block: "{{ registries|default({}) | to_nice_yaml(indent=2) }}"
|
|
|
|
- name: Attach timestamp to the platform backup filename
|
|
set_fact:
|
|
platform_backup_file: "{{ platform_backup_filename_prefix }}_{{ lookup('pipe', 'date +%Y_%m_%d_%H_%M_%S') }}.tgz"
|
|
|
|
- name: Set platform backup file absolute path
|
|
set_fact:
|
|
platform_backup_file_path: "{{ backup_dir }}/{{ platform_backup_file }}"
|
|
|
|
# Archive module has a known bug that doesn't handle empty symbolic links
|
|
# well. Restore to tar command. Can add -P option to keep the leading
|
|
# '/'s in file names in the tar file, so that the tasks that strip leading
|
|
# '/' from the directory names before untar won't be required.
|
|
- name: Create a tgz archive for platform backup
|
|
shell: "tar -czf {{ platform_backup_file_path }} $(ls -d \
|
|
{{ override_backup_file }} \
|
|
/etc \
|
|
/home \
|
|
{{ config_permdir }} \
|
|
{{ sysinv_permdir }} \
|
|
{{ puppet_permdir }}/hieradata \
|
|
{{ keyring_permdir }} \
|
|
{{ patching_permdir }} \
|
|
{{ patching_repo_permdir }} \
|
|
{{ extension_permdir }} \
|
|
{{ patch_vault_permdir }} \
|
|
{{ crushmap_file }} \
|
|
{{ ldap_db_backup }} \
|
|
{{ postgres_dir.path }} \
|
|
{{ armada_permdir }}/platform-integ-apps \
|
|
{{ armada_permdir }}/admin.conf \
|
|
{{ helm_charts_permdir }}/stx-platform 2>/dev/null)"
|
|
args:
|
|
warn: false
|
|
|
|
- block:
|
|
- name: Attach timestamp to the OpenStack backup filename
|
|
set_fact:
|
|
openstack_backup_file: "{{ openstack_backup_filename_prefix }}_{{ lookup('pipe', 'date +%Y_%m_%d_%H_%M_%S') }}.tgz"
|
|
|
|
- name: Set SpenStack backup file absolute path
|
|
set_fact:
|
|
openstack_backup_file_path: "{{ backup_dir }}/{{ openstack_backup_file }}"
|
|
|
|
- name: Create a tgz archive for OpenStack backup
|
|
shell: "tar -czf {{ openstack_backup_file_path }} $(ls -d \
|
|
{{ armada_permdir }}/stx-openstack \
|
|
{{ helm_charts_permdir }}/starlingx \
|
|
{{ mariadb_dir.path }} \
|
|
{{ helm_overrides_dir.path }} 2>/dev/null)"
|
|
args:
|
|
warn: false
|
|
when: check_mariadb_pod.rc == 0 or openstack_status.stdout == "uploaded"
|
|
|
|
- name: Notify the user backup tar file(s) are available
|
|
debug:
|
|
msg: >-
|
|
Backup tar file(s) are now available in {{ backup_dir }} on the active controller.
|
|
|
|
- block:
|
|
- name: Transfer platform backup tar file to the local machine
|
|
fetch:
|
|
src: "{{ platform_backup_file_path }}"
|
|
dest: "{{ host_backup_dir }}/"
|
|
flat: yes
|
|
|
|
- name: Transfer openstack backup tar files to the local machine if it exists
|
|
fetch:
|
|
src: "{{ openstack_backup_file_path}}"
|
|
dest: "{{ host_backup_dir }}/"
|
|
flat: yes
|
|
when: check_mariadb_pod.rc == 0 or openstack_status.stdout == "uploaded"
|
|
|
|
- name: Notify the user where the backup tar file(s) can be found
|
|
debug:
|
|
msg: >-
|
|
Backup tar file(s) have been transferred to {{ host_backup_dir }} on Ansible control host.
|
|
when: inventory_hostname != 'localhost'
|
|
|
|
always:
|
|
- name: Remove the temp dir
|
|
file:
|
|
path: "{{ tempdir.path }}"
|
|
state: absent
|
|
when: tempdir is defined
|
|
|
|
- name: Remove the backup in progress flag file
|
|
file:
|
|
path: "{{ backup_in_progress_flag }}"
|
|
state: absent
|
|
|
|
- name: Clear backup_in_progress alarm
|
|
script: fm_alarm.py "--clear" "--backup"
|
|
register: alarm_result
|
|
failed_when: false
|
|
|
|
- name: Fail if alarm script throws an exception
|
|
fail:
|
|
msg: "Failed to clear backup-in-progress alarm."
|
|
when: alarm_result.rc != 0
|