From 757b12b57f7c93f81bc1da9d3a8913c7f47b0e98 Mon Sep 17 00:00:00 2001 From: Cristian Mondo Date: Tue, 29 Oct 2024 15:40:07 -0300 Subject: [PATCH] Support prestage N release --for-sw-deploy on subclouds N-1 without USM This commit improves the prestage logic to be able to prestage an N release on an N-1 subcloud with or without USM support. Test Plan: Setup: - Bring up a SC with 24.09. PASS - Bring up an N-1 subcloud without USM support. - Prestage the subcloud for software deploy. - Verify that the 24.09 release is prestaged on the subcloud. PASS - Create and apply a prestage strategy for software deploy. - Verify that the 24.09 release is prestaged on the subcloud. PASS - Bring up an N-1 subcloud with USM support. - Prestage the subcloud for software deploy. - Verify that the 24.09 release is prestaged on the subcloud. PASS - Create and apply a prestage strategy for software deploy. - Verify that the 24.09 release is prestaged on the subcloud. PASS - Bring up a subcloud with 24.09. - Upload and deploy patch 24.09.1 on SC. - Prestage the subcloud for software deploy. - Verify that the 24.09.1 patch is prestaged on the subcloud. PASS - Create and apply a prestage strategy for software deploy. - Verify that the 24.09.1 patch is prestaged on the subcloud. Story: 2010676 Task: 51414 Change-Id: I750cf8479a0ebab8e9abbb910c4d3ce55952d1c3 Signed-off-by: Cristian Mondo --- .../roles/prestage/prepare-env/tasks/main.yml | 1 + .../prepare-sw-packages-prestage-env.yml | 30 +- .../files/ostree-metadata-sync.sh | 17 +- .../sync-software-metadata/tasks/main.yml | 312 ++---------------- .../tasks/perform_full_ostree_dir_sync.yml | 63 ++++ .../sync_patches_to_non_usm_subcloud.yml | 106 ++++++ .../tasks/sync_patches_to_usm_subcloud.yml | 268 +++++++++++++++ 7 files changed, 504 insertions(+), 293 deletions(-) create mode 100644 playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/perform_full_ostree_dir_sync.yml create mode 100644 playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/sync_patches_to_non_usm_subcloud.yml create mode 100644 playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/sync_patches_to_usm_subcloud.yml diff --git a/playbookconfig/src/playbooks/roles/prestage/prepare-env/tasks/main.yml b/playbookconfig/src/playbooks/roles/prestage/prepare-env/tasks/main.yml index 26f2a33eb..b1fc450dd 100644 --- a/playbookconfig/src/playbooks/roles/prestage/prepare-env/tasks/main.yml +++ b/playbookconfig/src/playbooks/roles/prestage/prepare-env/tasks/main.yml @@ -36,6 +36,7 @@ - name: Set prestage dir and subdirectory facts set_fact: prestage_source: remote + software_bin: "/usr/bin/software" prestage_dir: "{{ platform_backup_dir }}/{{ software_version }}" host_software_metadata_dir: "/opt/software/metadata" patches_prestage_dir: "{{ platform_backup_dir }}/{{ software_version }}/patches" diff --git a/playbookconfig/src/playbooks/roles/prestage/prepare-env/tasks/prepare-sw-packages-prestage-env.yml b/playbookconfig/src/playbooks/roles/prestage/prepare-env/tasks/prepare-sw-packages-prestage-env.yml index d2d87d152..9945de26b 100644 --- a/playbookconfig/src/playbooks/roles/prestage/prepare-env/tasks/prepare-sw-packages-prestage-env.yml +++ b/playbookconfig/src/playbooks/roles/prestage/prepare-env/tasks/prepare-sw-packages-prestage-env.yml @@ -52,18 +52,32 @@ set_fact: host_patches_exist: "{{ host_patch_dir_result.stat.exists }}" +- name: Check if {{ software_bin }} exists on {{ inventory_hostname }} + stat: + path: "{{ software_bin }}" + register: software_bin_result + +- name: Set flag to indicate usm is enabled in the host + set_fact: + usm_enabled_on_subcloud: "{{ software_bin_result.stat.exists }}" + +# The subcloud_is_previous_release flag determines whether the subcloud release +# corresponds to an N-1 release. +- name: Set flag to indicate if subcloud prestage is for N-1 scenario + set_fact: + subcloud_is_previous_release: "{{ 'true' if (prestage_source == 'remote' and + host_software_version is version('22.12', '=')) + else 'false' }}" + # The force_ostree_dir_sync flag determines whether the entire N release ostree # directory should be copied to the subcloud or not. This flag is only relevant # if the subcloud is running N-1 release. # The condition for it to be true must meet: -# - The release of the subcloud must be different from the release being -# prestaged. -# - The release of the subcloud must be a N-1 release that is USM enabled. +# - The release of the subcloud must be an N-1 release (subcloud_is_previous_release) # - The N release ostree directory does not already exist on the N-1 subcloud. -- name: Set flag to indicate if subcloud prestage is for N-1 scenario +- name: Set flag to indicate if the ostree directory should be copied to the subcloud set_fact: - force_ostree_dir_sync: "{{ 'true' if (prestage_source == 'remote' and - host_software_version is version('22.12', '=') and + force_ostree_dir_sync: "{{ 'true' if (subcloud_is_previous_release and not host_ostree_dir_exist) else 'false' }}" - debug: @@ -72,5 +86,7 @@ Prestaging reason: {{ prestage_reason }} Prestaging source: {{ prestage_source }} Prestaging os type: {{ prestage_os_type }} - Prestaging for N-1 subcloud: {{ force_ostree_dir_sync }} + Prestaging for N-1 subcloud: {{ subcloud_is_previous_release }} + Force ostree dir sync for N-1 subcloud: {{ force_ostree_dir_sync }} + USM enabled on subcloud: {{ usm_enabled_on_subcloud }} Release feed directory (on target): {{ release_feed|default('N/A') }} diff --git a/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/files/ostree-metadata-sync.sh b/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/files/ostree-metadata-sync.sh index 6ed9ec651..050e6c12b 100755 --- a/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/files/ostree-metadata-sync.sh +++ b/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/files/ostree-metadata-sync.sh @@ -38,9 +38,6 @@ SW_VERSION=${SW_VERSION:-} DEBUG=${DEBUG:-} DRY_RUN=${DRY_RUN:-} -USM_SOFTWARE_DIR=/opt/software -USM_METADATA_DIR=${USM_SOFTWARE_DIR}/metadata - help() { cat< system_controller_current_patch %} - Skipping for software deploy prestage as the subcloud has a higher patch level - than the system controller. - {% endif %} - - - name: "Subcloud does not require software prestage. Exiting..." - meta: end_play - when: subcloud_current_patch >= system_controller_current_patch - when: subcloud_releases | length > 0 - -- block: - - debug: - msg: The system controller has a patch level higher than the subcloud - - - name: Gather system controller metadata commits - # - # Use the existing ostree_metadata_commits_central file if: - # 1) It exists, and - # 2) There are no new commits. Compare last line of the ostree_metadata_commits_central - # file against current ostree repo commit. - # Otherwise, we generate a new ostree_metadata_commits_central file using the - # get-commits target to our script. - # - # Get the commits from the metadata, in the same way that software list does, - # avoiding ambiguous queries. - # Parallel operations (for orchestration): - # We use flock here because there may be many prestaging operations running - # in parallel on system controller. flock behaviour: - # - acquire lock on /tmp/ostree_metadata_commits_central.lock - # - the timeout is long just to ensure we never deadlock for any reason - shell: | - exec 3>/tmp/ostree_metadata_commits_central.lock - flock --exclusive --timeout 180 3 || \ - { echo "ERROR: $? - flock failed while trying to get the commits."; exit 1; } - if [ ! -f "{{ ostree_metadata_commits_central }}" ] \ - || ! diff -q <(echo {{ ostree_commit_system_controller.stdout }}) \ - <(tail --lines=1 "{{ ostree_metadata_commits_central }}" | awk -F':' '{ print $2; }') > \ - /dev/null 2>&1 ; then - {{ role_path }}/files/ostree-metadata-sync.sh --sw-version "{{ software_version }}" \ - --output "{{ ostree_metadata_commits_central }}" get-commits - else - cat "{{ ostree_metadata_commits_central }}" - fi - exec 3>&- # release the lock - register: system_controller_software_metadata_commits - delegate_to: localhost - - - name: Show ostree metadata commits on system controller - debug: - var: system_controller_software_metadata_commits - - # Switch from command to script module to run the ostree-metadata-sync.sh script - # on the system controller as it does not exist on N-1 release e.g. 22.12 - - name: Gather subcloud metadata commits - script: "{{ role_path }}/files/ostree-metadata-sync.sh --sw-version {{ software_version }} - --output {{ ostree_metadata_commits_subcloud }} get-commits" - register: subcloud_software_metadata_commits - - - name: Show ostree metadata commits on subcloud - debug: - var: subcloud_software_metadata_commits - - - block: - # It's necessary to temporarily change the owner to sysadmin so that - # the system controller can push the files to the subcloud, since the files - # are in the folders only the root can access but the synchronize only - # support passwordless sysadmin to execute ssh and rsync. - - name: Temporarily change the ownership of {{ usm_software_dir }} - file: - path: "{{ usm_software_dir }}" - state: directory - owner: sysadmin - recurse: yes - - - name: Copy system controller {{ usm_metadata_dir }} to subcloud {{ tmp_metadata_sync_dir }} - copy: - src: "{{ usm_metadata_dir }}" - dest: "{{ tmp_metadata_sync_dir }}" - force: true - - - name: Copy system controller {{ ostree_metadata_commits_central }} to subcloud {{ tmp_metadata_sync_dir }} - copy: - src: "{{ ostree_metadata_commits_central }}" - dest: "{{ tmp_metadata_sync_dir }}" - force: true - - # Switch from command to script module to run the ostree-metadata-sync.sh script - # on the system controller as it does not exist on N-1 release e.g. 22.12 - - name: Synchronizing system controller ostree commits on subcloud - script: "{{ role_path }}/files/ostree-metadata-sync.sh --sw-version {{ software_version }} - sync-subcloud" - register: sync_software_commits - become: true - - - name: Show sync output - debug: - msg: - - "sync_software_commits:" - - "rc: {{ sync_software_commits.rc }}" - - "stderr: {{ sync_software_commits.stderr }}" - - "stdout: {{ sync_software_commits.stdout }}" - - - name: Copy system controller deployed release directory to subcloud - synchronize: - mode: "push" - src: "{{ usm_software_dir }}/rel-{{ item }}" - dest: "{{ usm_software_dir }}" - with_items: "{{ system_controller_releases }}" - failed_when: false - - - name: Copy system controller {{ usm_software_dir }}/software-scripts to subcloud - synchronize: - mode: "push" - src: "{{ usm_software_dir }}/software-scripts" - dest: "{{ usm_software_dir }}" - failed_when: false - - always: - - block: - - name: Restore the ownership of {{ usm_software_dir }} - file: - path: "{{ usm_software_dir }}" - state: directory - owner: root - recurse: yes - - - name: Restore the ownership of {{ tmp_metadata_sync_dir }} - file: - path: "{{ tmp_metadata_sync_dir }}" - state: directory - owner: sysadmin - recurse: yes - - - name: Synchronize software between controllers - command: "{{ usm_scripts_dir }}/controllers-software-sync" - - - name: Synchronize {{ release_feed }} directory between controllers - command: "{{ usm_scripts_dir }}/sync-controllers-feed --feed={{ release_feed }}" - become: true +- name: Sync patches to non USM enabled subcloud + include_tasks: sync_patches_to_non_usm_subcloud.yml + when: not usm_enabled_on_subcloud diff --git a/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/perform_full_ostree_dir_sync.yml b/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/perform_full_ostree_dir_sync.yml new file mode 100644 index 000000000..00390d368 --- /dev/null +++ b/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/perform_full_ostree_dir_sync.yml @@ -0,0 +1,63 @@ +--- +# +# Copyright (c) 2024 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# ROLE DESCRIPTION: +# +# This role is only executed when the subcloud has an N-1 release, where the +# ostree repository for N release will be transferred entirely to prepare +# the subcloud. It is executed at least once as long as the release N ostree +# directory does not exist in the subcloud and if the subcloud is N-1. +# Once the ostree N directory was transferred, if the playbook were to be +# executed again, the file will not be executed. +# The force_ostree_dir_sync variable must be set to true in order to execute +# this role. +# + +- name: Perform full ostree repo sync + block: + # It's necessary to temporarily change the owner to sysadmin so that + # the system controller can push the files to the subcloud, since the files + # are in the folders only the root can access but the synchronize only + # support passwordless sysadmin to execute ssh and rsync. + - name: Temporarily change the ownership of feed directory {{ release_feed }} + file: + path: "{{ release_feed }}" + state: directory + owner: sysadmin + recurse: yes + + - name: Copy feed directory from system controller to subcloud + synchronize: + mode: push + src: "{{ release_feed }}/" + dest: "{{ release_feed }}/" + rsync_opts: "--delete" + register: prestage_transfer + retries: 3 + delay: 5 + until: prestage_transfer.rc == 0 + + - name: Check if install_uuid file exists in {{ host_software_version }} feed directory + stat: + path: "{{ release_feed | dirname }}/rel-{{ host_software_version }}/install_uuid" + register: install_uuid_exists + + - name: Copy install_uuid file from {{ host_software_version }} to {{ software_version }} feed directory + copy: + src: "{{ release_feed | dirname }}/rel-{{ host_software_version }}/install_uuid" + dest: "{{ release_feed }}/install_uuid" + force: true + remote_src: yes + when: install_uuid_exists.stat.exists + + always: + - name: Restore the ownership of the feed directory {{ release_feed }} + file: + path: "{{ release_feed }}" + state: directory + owner: root + recurse: yes + become: true diff --git a/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/sync_patches_to_non_usm_subcloud.yml b/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/sync_patches_to_non_usm_subcloud.yml new file mode 100644 index 000000000..a8f772492 --- /dev/null +++ b/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/sync_patches_to_non_usm_subcloud.yml @@ -0,0 +1,106 @@ +--- +# +# Copyright (c) 2024 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# ROLE DESCRIPTION: +# +# This role is executed when there is no USM support, generally in subclouds that +# have release N-1 but without USM support. +# It is commonly executed after perform_full_ostree_dir_sync role, since +# both share the N-1 configuration. +# It is adapted to be able to carry out the upgrade from release N-1 without USM +# support to release N, prestaging release N files to the subcloud. +# The upgrade to release N cannot be carried out until the patch with USM support +# is deployed in the subcloud. Once the patch with USM support is installed, the +# deploy can be executed with the prestaged data. +# The usm_enabled_on_subcloud variable must be set to false in order to execute +# this role. +# + +- name: Perform sync patches to non USM subcloud + block: + - debug: + msg: The subcloud has N-1 release without USM support. Prestaging release {{ software_version }} + + # It's necessary to temporarily change the owner to sysadmin so that + # the system controller can push the files to the subcloud, since the files + # are in the folders only the root can access but the synchronize only + # support passwordless sysadmin to execute ssh and rsync. + - name: Temporarily change the ownership of {{ usm_software_dir }} + file: + path: "{{ usm_software_dir }}" + state: directory + owner: sysadmin + recurse: yes + + - name: Ensure subcloud {{ usm_metadata_dir }}/available exists (sysadmin) + file: + path: "{{ usm_metadata_dir }}/available" + owner: sysadmin + group: root + state: directory + mode: 0755 + recurse: yes + + - name: Find deployed metadata files on system controller + command: find {{ usm_metadata_dir }} -type f -name "*{{ software_version }}*" + register: system_controller_metadata_files + delegate_to: localhost + + - name: Copy system controller deployed metadata files as available state to subcloud + copy: + src: "{{ item }}" + dest: "{{ usm_metadata_dir }}/available/{{ item | basename }}" + with_items: "{{ system_controller_metadata_files.stdout_lines }}" + + # We want to transfer the rel-MM-mm directories that may exist in the system + # controller to the subcloud. There will always be at least one, which corresponds + # to the deployed base release, for example rel-24.09.0. This task should not fail, + # if it fails the playbook should be aborted. + - name: Copy system controller deployed release directory to subcloud + synchronize: + mode: "push" + src: "{{ usm_software_dir }}/rel-{{ item }}" + dest: "{{ usm_software_dir }}/" + rsync_opts: "--delete" + with_items: "{{ system_controller_releases }}" + register: releases_transfer + retries: 3 + delay: 2 + until: releases_transfer.rc == 0 + + # We want to check if the software-script directory exists on the system controller + # to ensure copying to the subcloud. This directory is created when a new patch is + # deployed, so it does not exist if only the base release is deployed, for example + # 24.09.0. + - name: Check if {{ usm_software_scripts_dir }} directory exists + stat: + path: "{{ usm_software_scripts_dir }}" + register: software_scripts_exists + delegate_to: localhost + + # Only if the directory exists, it will be transferred to the subcloud. + # We cannot deploy a patch if the directory does not exist, therefore the playbook + # must abort if the transfer fails. + - name: Copy system controller {{ usm_software_scripts_dir }} to subcloud + synchronize: + mode: "push" + src: "{{ usm_software_scripts_dir }}" + dest: "{{ usm_software_dir }}/" + rsync_opts: "--delete" + register: scripts_transfer + retries: 3 + delay: 2 + until: scripts_transfer.rc == 0 + when: software_scripts_exists.stat.exists + + always: + - name: Restore the ownership of {{ usm_software_dir }} + file: + path: "{{ usm_software_dir }}" + state: directory + owner: root + recurse: yes + become: true diff --git a/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/sync_patches_to_usm_subcloud.yml b/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/sync_patches_to_usm_subcloud.yml new file mode 100644 index 000000000..c46cb6fe4 --- /dev/null +++ b/playbookconfig/src/playbooks/roles/prestage/sync-software-metadata/tasks/sync_patches_to_usm_subcloud.yml @@ -0,0 +1,268 @@ +--- +# +# Copyright (c) 2024 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# ROLE DESCRIPTION: +# +# This role is executed only if USM is supported, both in an N and an N-1 release. +# It compares the releases from the software utility and determines if the system +# controller has a patch level higher than that of the subcloud. If that happens, +# the patch deployed on the system controller will be prestaged incrementally +# to the subcloud. The usm_enabled_on_subcloud variable must be set to true in +# order to execute this role +# +# Note: Much of the work is done by the ostree-metadata-sync.sh script, which has +# two targets: get-commits and sync-subcloud. +# +# Procedure: +# - On system controller, run ostree-metadata-sync.sh --sw-version 24.09 get-commits +# - Creates /opt/software/tmp/metadata-sync/ostree-metadata-commits.central +# which contains list of sw_version:ostree commit for all +# software updates matching prestaging software release +# - this file is transferred to subcloud for use during the sync-subcloud stage +# - On subcloud, run ostree-metadata-sync.sh --sw-version 24.09 get-commits +# - Creates /opt/software/tmp/metadata-sync/ostree-metadata-commits.subcloud +# which contains list of sw_version:ostree commit for all software +# updates matching prestaging software release +# - As long as the patch level of the system controller is higher than that of the subcloud +# - Transfer the following from system controller to subcloud at +# /opt/software/tmp/metadata-sync: +# - /opt/software/tmp/metadata-sync/ostree-metadata-commits.central +# - the full /opt/software/metadata hierarchy +# - The above data is used on the subcloud to synchronize the commits on the subcloud +# by invoking: ostree-metadata-sync.sh --sw-version 24.09 sync-subcloud +# - operates on the data in /opt/software/tmp/metadata-sync +# plus the state on subcloud to run the sync algorithm for each commit +# - Otherwise, the prestage should not be executed. +# + +- name: Perform sync patches to USM subcloud + # This block is executed for subcloud N and even N-1 scenario with USM support. + block: + - name: Gather subcloud deployed software list + shell: software list --release {{ software_version }} --state deployed | \ + grep {{ software_version }} | sed 's/ //g;' + register: subcloud_software_list + + - name: Show subcloud deployed software list for release {{ software_version }} + debug: + var: subcloud_software_list.stdout + + - name: Ensure system controller {{ tmp_metadata_sync_dir }} exists (sysadmin) + file: + path: "{{ tmp_metadata_sync_dir }}" + owner: sysadmin + group: root + state: directory + mode: 0755 + recurse: yes + delegate_to: localhost + + - name: Ensure subcloud {{ tmp_metadata_sync_dir }} exists (sysadmin) + file: + path: "{{ tmp_metadata_sync_dir }}" + owner: sysadmin + group: root + state: directory + mode: 0755 + recurse: yes + + - name: Extract release part from subcloud release list + set_fact: + subcloud_releases: "{{ subcloud_software_list.stdout_lines | \ + map('regex_replace', '.*?-([0-9\\.]+).*', '\\1') | list }}" + + # The subcloud must have at least one release for the given software version to be able + # to compare with the system controller version. Otherwise, it is assumed that the + # release does not exist in the subcloud and the prestage is executed. + - block: + # It is necessary to compare the current patch level between the SC and the subcloud + # to determine if prestage should be executed. In this way all scenarios are covered, + # including pre-patched scenario. + - name: Extract current patch number from system controller release list + set_fact: + system_controller_current_patch: "{{ system_controller_releases[-1] | \ + regex_replace('.*\\.', '') | int }}" + + - name: Extract current patch number from subcloud release list + set_fact: + subcloud_current_patch: "{{ subcloud_releases[-1] | regex_replace('.*\\.', '') | int }}" + + # We need to compare the patch level, since we must take into account even the + # pre-patched scenario. + - debug: + msg: | + ostree revision from: {{ ostree_repo_release_feed }}: + system controller current patch: {{ system_controller_releases[-1] }} + subcloud current patch: {{ subcloud_releases[-1] }} + system controller current commit: {{ ostree_commit_system_controller.stdout }} + subcloud current commit: {{ ostree_commit_subcloud.stdout }} + + {% if system_controller_current_patch == subcloud_current_patch %} + Skipping for software deploy prestage as the subcloud has the same patch level + than the system controller. + {% elif subcloud_current_patch > system_controller_current_patch %} + Skipping for software deploy prestage as the subcloud has a higher patch level + than the system controller. + {% endif %} + + - name: "Subcloud does not require software prestage. Exiting..." + meta: end_play + when: subcloud_current_patch >= system_controller_current_patch + become: true + when: subcloud_releases | length > 0 + + - block: + - debug: + msg: The system controller has a patch level higher than the subcloud + + - name: Gather system controller metadata commits + # + # Use the existing ostree_metadata_commits_central file if: + # 1) It exists, and + # 2) There are no new commits. Compare last line of the ostree_metadata_commits_central + # file against current ostree repo commit. + # Otherwise, we generate a new ostree_metadata_commits_central file using the + # get-commits target to our script. + # + # Get the commits from the metadata, in the same way that software list does, + # avoiding ambiguous queries. + # Parallel operations (for orchestration): + # We use flock here because there may be many prestaging operations running + # in parallel on system controller. flock behaviour: + # - acquire lock on /tmp/ostree_metadata_commits_central.lock + # - the timeout is long just to ensure we never deadlock for any reason + shell: | + exec 3>/tmp/ostree_metadata_commits_central.lock + flock --exclusive --timeout 180 3 || \ + { echo "ERROR: $? - flock failed while trying to get the commits."; exit 1; } + if [ ! -f "{{ ostree_metadata_commits_central }}" ] \ + || ! diff -q <(echo {{ ostree_commit_system_controller.stdout }}) \ + <(tail --lines=1 "{{ ostree_metadata_commits_central }}" | awk -F':' '{ print $2; }') > \ + /dev/null 2>&1 ; then + {{ role_path }}/files/ostree-metadata-sync.sh --sw-version "{{ software_version }}" \ + --output "{{ ostree_metadata_commits_central }}" get-commits + else + cat "{{ ostree_metadata_commits_central }}" + fi + exec 3>&- # release the lock + register: system_controller_software_metadata_commits + delegate_to: localhost + + - name: Show ostree metadata commits on system controller + debug: + var: system_controller_software_metadata_commits + + # Switch from command to script module to run the ostree-metadata-sync.sh script + # on the system controller as it does not exist on N-1 release e.g. 22.12 + - name: Gather subcloud metadata commits + script: "{{ role_path }}/files/ostree-metadata-sync.sh --sw-version {{ software_version }} + --output {{ ostree_metadata_commits_subcloud }} get-commits" + register: subcloud_software_metadata_commits + + - name: Show ostree metadata commits on subcloud + debug: + var: subcloud_software_metadata_commits + + # It's necessary to temporarily change the owner to sysadmin so that + # the system controller can push the files to the subcloud, since the files + # are in the folders only the root can access but the synchronize only + # support passwordless sysadmin to execute ssh and rsync. + - name: Temporarily change the ownership of {{ usm_software_dir }} + file: + path: "{{ usm_software_dir }}" + state: directory + owner: sysadmin + recurse: yes + + - name: Copy system controller {{ usm_metadata_dir }} to subcloud {{ tmp_metadata_sync_dir }} + copy: + src: "{{ usm_metadata_dir }}" + dest: "{{ tmp_metadata_sync_dir }}" + force: true + + - name: Copy system controller {{ ostree_metadata_commits_central }} to subcloud {{ tmp_metadata_sync_dir }} + copy: + src: "{{ ostree_metadata_commits_central }}" + dest: "{{ tmp_metadata_sync_dir }}" + force: true + + # Switch from command to script module to run the ostree-metadata-sync.sh script + # on the system controller as it does not exist on N-1 release e.g. 22.12 + - name: Synchronizing system controller ostree commits on subcloud + script: "{{ role_path }}/files/ostree-metadata-sync.sh --sw-version {{ software_version }} + sync-subcloud" + register: sync_software_commits + + - name: Show sync output + debug: + msg: + - "sync_software_commits:" + - "rc: {{ sync_software_commits.rc }}" + - "stderr: {{ sync_software_commits.stderr }}" + - "stdout: {{ sync_software_commits.stdout }}" + + # We want to transfer the rel-MM-mm directories that may exist in the system + # controller to the subcloud. There will always be at least one, which corresponds + # to the deployed base release, for example rel-24.09.0. This task should not fail, + # if it fails the playbook should be aborted. + - name: Copy system controller deployed release directory to subcloud + synchronize: + mode: "push" + src: "{{ usm_software_dir }}/rel-{{ item }}" + dest: "{{ usm_software_dir }}/" + rsync_opts: "--delete" + with_items: "{{ system_controller_releases }}" + register: releases_transfer + retries: 3 + delay: 2 + until: releases_transfer.rc == 0 + + # We want to check if the software-script directory exists on the system controller + # to ensure copying to the subcloud. This directory is created when a new patch is + # deployed, so it does not exist if only the base release is deployed, for example + # 24.09.0. + - name: Check if {{ usm_software_scripts_dir }} directory exists + stat: + path: "{{ usm_software_scripts_dir }}" + register: software_scripts_exists + delegate_to: localhost + + # Only if the directory exists, it will be transferred to the subcloud. + # We cannot deploy a patch if the directory does not exist, therefore the playbook + # must abort if the transfer fails. + - name: Copy system controller {{ usm_software_scripts_dir }} to subcloud + synchronize: + mode: "push" + src: "{{ usm_software_scripts_dir }}" + dest: "{{ usm_software_dir }}/" + rsync_opts: "--delete" + register: scripts_transfer + retries: 3 + delay: 2 + until: scripts_transfer.rc == 0 + when: software_scripts_exists.stat.exists + + always: + - name: Restore the ownership of {{ usm_software_dir }} + file: + path: "{{ usm_software_dir }}" + state: directory + owner: root + recurse: yes + + - name: Restore the ownership of {{ tmp_metadata_sync_dir }} + file: + path: "{{ tmp_metadata_sync_dir }}" + state: directory + owner: sysadmin + recurse: yes + + - name: Synchronize software between controllers + command: "{{ usm_scripts_dir }}/controllers-software-sync" + + - name: Synchronize {{ release_feed }} directory between controllers + command: "{{ usm_scripts_dir }}/sync-controllers-feed --feed={{ release_feed }}" + become: true