Force cleanup of checkout directory on deploy start
This commit checks if checkout directory exists on deploy start,
and if it does, then run the cleanup script to remove the directory
forcefully and proceeds with the upgrade, instead of just returning
an error.
The configparser method to get the sw_version is replaced with a
simpler approach.
Two robustness improvements are also added to the cleanup script:
1. Since it needs to determine the to-release major release version
to execute the cleanup tasks (like stopping the to-release database),
but it will fail if the checkout directory is empty or partially
checked out; so in this case, a fallback mechanism will try to get
the major release version from the temporary script path;
2. Check if the major release version to be cleaned up is not the
same as the one running in the system, in case any leftovers of the
previous upgrade are left in the system, so that the deploy cleanup
script doesn't end breaking the current running system.
Test Plan
PASS: deploy start (regression)
PASS: deploy start with checked out to-release ostree-repo,
verify the cleanup script is executed and deploy start
proceeds
PASS: deploy start with empty/partially checked out to-release
ostree-repo, verify the cleanup script is executed and
deploy start proceeds
PASS: deploy start with checked out ostree-repo from the same
major release version as the running release, verify the
cleanup script doesn't execute
Closes-bug: 2126797
Change-Id: I18294c4009da157140aa10091f9a9b3087c9107b
Signed-off-by: Heitor Matsui <heitorvieira.matsui@windriver.com>
This commit is contained in:
@@ -57,10 +57,10 @@ class DeployStart:
|
||||
def _check_directories(self):
|
||||
for directory in [self.SYSROOT_DIR]:
|
||||
if os.path.isdir(directory):
|
||||
error_msg = (f"{directory} already exists. Please ensure to "
|
||||
f"clean up the environment before proceeding")
|
||||
LOG.error(error_msg)
|
||||
raise OSError(error_msg)
|
||||
warning_msg = (f"{directory} already exists. Cleanup will "
|
||||
"be executed before proceeding")
|
||||
LOG.warning(warning_msg)
|
||||
self._remove_temporary_data()
|
||||
|
||||
def _checkout_ostree_repo(self):
|
||||
# TODO(bqian) make commit_id mandatory once the commit-id is built to metadata.xml for major releases
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
# automatic cleanup process fails.
|
||||
#
|
||||
|
||||
import configparser
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -28,18 +28,32 @@ LOG = logging.getLogger('main_logger')
|
||||
|
||||
|
||||
class RemoveTemporaryData:
|
||||
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) # this script location
|
||||
|
||||
def __init__(self, checkout_dir):
|
||||
self._checkout_dir = checkout_dir
|
||||
|
||||
try:
|
||||
default_section = configparser.DEFAULTSECT
|
||||
cp = configparser.ConfigParser()
|
||||
with open(os.path.join(self._checkout_dir, "usr/etc/build.info"), "r") as fp:
|
||||
cp.read_string(f"[{default_section}]\n" + fp.read())
|
||||
self._sw_version = cp.get(default_section, "SW_VERSION").strip('"')
|
||||
except Exception as e:
|
||||
LOG.error(f"Error getting SW_VERSION: {str(e)}")
|
||||
checkout_usr_etc = os.path.join(self._checkout_dir, "usr/etc")
|
||||
self._sw_version = self.get_sw_version(checkout_usr_etc)
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOG.warning("Attempting to get SW_VERSION it from the script path...")
|
||||
match = re.match(r".*rel-(\d+.\d+)/", self.SCRIPT_DIR)
|
||||
if match is None:
|
||||
LOG.error(f"Failed to get SW_VERSION, won't proceed with the cleanup")
|
||||
raise
|
||||
self._sw_version = match.group(1)
|
||||
|
||||
@staticmethod
|
||||
def get_sw_version(etc_dir="/etc"):
|
||||
try:
|
||||
p = subprocess.run(f"source {etc_dir}/build.info; echo $SW_VERSION",
|
||||
shell=True, check=True, capture_output=True, text=True)
|
||||
running_sw_version = p.stdout.strip()
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOG.error(f"Error getting SW_VERSION from {etc_dir}: {e.stderr.strip()}")
|
||||
raise
|
||||
return running_sw_version
|
||||
|
||||
def stop_database(self):
|
||||
db_dir = os.path.join(self._checkout_dir, "var/lib/postgresql", self._sw_version)
|
||||
@@ -98,6 +112,13 @@ class RemoveTemporaryData:
|
||||
LOG.info(f"{temp_dir} removed successfully")
|
||||
|
||||
def run(self):
|
||||
running_sw_version = self.get_sw_version()
|
||||
if running_sw_version == self._sw_version:
|
||||
LOG.error(f"Cannot proceed with cleanup, running software version "
|
||||
f"{running_sw_version} is the same as the requested cleanup "
|
||||
f"version, please remove {self._checkout_dir} manually")
|
||||
return 1
|
||||
|
||||
LOG.info("Starting temporary data cleanup...")
|
||||
try:
|
||||
self.stop_database()
|
||||
|
||||
Reference in New Issue
Block a user