From d5e5c8453c81c107ad273d344548b1d18a6441d3 Mon Sep 17 00:00:00 2001 From: Jessica Castelino Date: Thu, 19 May 2022 17:18:26 +0000 Subject: [PATCH] Pull from a remote repo during host install During the host-install step, the sysroot repo pulls from the remote defined inside /sysroot/ostree/repo/config file. This is a better approach than doing pull-local and it allows the sysroot repo to be a mirror of the feed repo. Test: Running host-install after sw-patch remove should get rid of the commits associated with the patch in the sysroot repo. Story: 2009969 Task: 45435 Depends-On: https://review.opendev.org/c/starlingx/metal/+/842568 Signed-off-by: Jessica Castelino Change-Id: If3e7db2a47f085bbc4abd59eb34565261e30c061 --- sw-patch/cgcs-patch/cgcs_patch/constants.py | 1 + .../cgcs-patch/cgcs_patch/ostree_utils.py | 33 ++++++++++++++++ sw-patch/cgcs-patch/cgcs_patch/patch_agent.py | 38 ++++++------------- .../cgcs-patch/cgcs_patch/patch_controller.py | 8 +++- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/sw-patch/cgcs-patch/cgcs_patch/constants.py b/sw-patch/cgcs-patch/cgcs_patch/constants.py index 44409b4d..fcf45dd4 100644 --- a/sw-patch/cgcs-patch/cgcs_patch/constants.py +++ b/sw-patch/cgcs-patch/cgcs_patch/constants.py @@ -43,6 +43,7 @@ CLI_OPT_RECURSIVE = '--recursive' CLI_OPT_RELEASE = '--release' OSTREE_REF = "starlingx" +OSTREE_REMOTE = "debian" FEED_OSTREE_BASE_DIR = "/var/www/pages/feed" SYSROOT_OSTREE = "/sysroot/ostree/repo" diff --git a/sw-patch/cgcs-patch/cgcs_patch/ostree_utils.py b/sw-patch/cgcs-patch/cgcs_patch/ostree_utils.py index 39deb6f7..3be8e69b 100644 --- a/sw-patch/cgcs-patch/cgcs_patch/ostree_utils.py +++ b/sw-patch/cgcs-patch/cgcs_patch/ostree_utils.py @@ -159,6 +159,23 @@ def reset_ostree_repo_head(commit, repo_path): raise OSTreeCommandFail(msg) +def pull_ostree_from_remote(): + """ + Pull from remote ostree to sysroot ostree + """ + + cmd = "ostree pull %s --depth=-1" % constants.OSTREE_REMOTE + + try: + subprocess.run(cmd, shell=True, check=True, capture_output=True) + except subprocess.CalledProcessError as e: + msg = "Failed to pull from %s remote into sysroot ostree" % constants.OSTREE_REMOTE + info_msg = "OSTree Pull Error: return code: %s , Output: %s" \ + % (e.returncode, e.stderr.decode("utf-8")) + LOG.info(info_msg) + raise OSTreeCommandFail(msg) + + def delete_ostree_repo_commit(commit, repo_path): """ Delete the specified commit from the ostree repo @@ -177,3 +194,19 @@ def delete_ostree_repo_commit(commit, repo_path): % (e.returncode, e.stderr.decode("utf-8")) LOG.info(info_msg) raise OSTreeCommandFail(msg) + + +def create_deployment(): + """ + Create a new deployment while retaining the previous ones + """ + + cmd = "ostree admin deploy %s --no-prune --retain" % constants.OSTREE_REF + try: + subprocess.run(cmd, shell=True, check=True, capture_output=True) + except subprocess.CalledProcessError as e: + msg = "Failed to create an ostree deployment for sysroot ref %s." % constants.OSTREE_REF + info_msg = "OSTree Deployment Error: return code: %s , Output: %s" \ + % (e.returncode, e.stderr.decode("utf-8")) + LOG.info(info_msg) + raise OSTreeCommandFail(msg) diff --git a/sw-patch/cgcs-patch/cgcs_patch/patch_agent.py b/sw-patch/cgcs-patch/cgcs_patch/patch_agent.py index d0c214e9..31ba9424 100644 --- a/sw-patch/cgcs-patch/cgcs_patch/patch_agent.py +++ b/sw-patch/cgcs-patch/cgcs_patch/patch_agent.py @@ -20,6 +20,7 @@ from cgcs_patch.patch_functions import configure_logging from cgcs_patch.patch_functions import LOG import cgcs_patch.config as cfg from cgcs_patch.base import PatchService +from cgcs_patch.exceptions import OSTreeCommandFail import cgcs_patch.utils as utils import cgcs_patch.messages as messages import cgcs_patch.constants as constants @@ -360,15 +361,6 @@ class PatchAgent(PatchService): "active controller's Feed Repo Commit: %s", active_sysroot_commit, self.latest_feed_commit) self.changes = True - active_deployment_commit = ostree_utils.get_latest_deployment_commit() - # strip off anything after a period. ex: 1234.1 becomes 1234 - active_deployment_commit = active_deployment_commit.split(".")[0] - - if active_sysroot_commit != active_deployment_commit: - LOG.info("Active Sysroot Commit:%s does not match " - "Active Deployment Commit: %s", - active_sysroot_commit, active_deployment_commit) - self.changes = True return True @@ -427,27 +419,21 @@ class PatchAgent(PatchService): changed = False success = True - sysroot_ostree = constants.SYSROOT_OSTREE - feed_ostree = "%s/rel-%s/ostree_repo" % (constants.FEED_OSTREE_BASE_DIR, SW_VERSION) if self.changes: - cmd = "ostree --repo=%s pull-local %s %s --depth=-1" % (sysroot_ostree, feed_ostree, constants.OSTREE_REF) try: - subprocess.run(cmd, shell=True, check=True, capture_output=True) - except subprocess.CalledProcessError as e: - LOG.exception("Failed to pull feed ostree in to the sysroot ostree.") - info_msg = "OSTree Pull Local Error: return code: %s , Output: %s" % (e.returncode, e.stderr.decode("utf-8")) - LOG.info(info_msg) - success = False + # Pull changes from remote to the sysroot ostree + # The remote value is configured inside + # "/sysroot/ostree/repo/config" file + ostree_utils.pull_ostree_from_remote() + + # Create a new deployment once the changes are pulled + ostree_utils.create_deployment() - # todo(jcasteli): Should we skip the deploy if pull-local fails - deployment_cmd = "ostree admin deploy %s" % constants.OSTREE_REF - try: - subprocess.run(deployment_cmd, shell=True, check=True, capture_output=True) changed = True - except subprocess.CalledProcessError as e: - LOG.exception("Failed to create an ostree deployment.") - info_msg = "OSTree Deployment Error: return code: %s , Output: %s" % (e.returncode, e.stderr.decode("utf-8")) - LOG.info(info_msg) + + except OSTreeCommandFail: + LOG.exception("Failed to pull changes and create deployment" + "during host-install.") success = False if changed: diff --git a/sw-patch/cgcs-patch/cgcs_patch/patch_controller.py b/sw-patch/cgcs-patch/cgcs_patch/patch_controller.py index ca3f4cb5..9f6946b0 100644 --- a/sw-patch/cgcs-patch/cgcs_patch/patch_controller.py +++ b/sw-patch/cgcs-patch/cgcs_patch/patch_controller.py @@ -470,7 +470,11 @@ class PatchMessageQueryDetailedResp(messages.PatchMessage): if len(pc.interim_state[patch_id]) == 0: del pc.interim_state[patch_id] pc.hosts_lock.release() - pc.check_patch_states() + # CentOS code has an additional call here for + # check_patch_states which was removed in Debian + # The call had to be removed since it was mangling + # pc.allow_insvc_patching value and making all + # patches treat like an in-service patch. else: pc.hosts_lock.release() @@ -1101,7 +1105,7 @@ class PatchController(PatchService): # Commit1 in patch metadata.xml file represents the latest commit # after this patch has been applied to the feed repo - self.latest_feed_commit = self.patch_data.contents[patch_id]["commit1"] + self.latest_feed_commit = self.patch_data.contents[patch_id]["commit1"]["commit"] self.hosts_lock.acquire() self.interim_state[patch_id] = list(self.hosts)