Debian: Patch Commit Implementation

The patch storage in Debian holds software.tar files
associated with each patch as well as it's restart scripts.
Once a patch is committed, these files are expected to be
deleted to free up disk space in patch storage. This action
is irreversible (similar to the behavior in CentOS).

Test:
1) Verify software.tar and restart scripts (if any) are
deleted
2) Verify metadata is moved to committed directory
3) Verify that patch can only be committed if it has a
REL status
4) Verify that once a patch is committed, it cannot be
removed

Story: 2009969
Task: 45943
Signed-off-by: Jessica Castelino <jessica.castelino@windriver.com>
Change-Id: Iea89c4404d1a55a2ae12fc7dffaeb96486fb27e5
This commit is contained in:
Jessica Castelino 2022-08-03 14:32:07 +00:00
parent 0cada3c8ba
commit d454d2e312
2 changed files with 22 additions and 50 deletions

View File

@ -825,12 +825,6 @@ class PatchController(PatchService):
patch_dependency_list = patch_dependency_list + self.get_patch_dependency_list(req_patch) patch_dependency_list = patch_dependency_list + self.get_patch_dependency_list(req_patch)
return patch_dependency_list return patch_dependency_list
def get_store_filename(self, patch_sw_version, contentname):
"""Returns the path of a content file from the store"""
content_dir = package_dir[patch_sw_version]
contentfile = "%s/%s" % (content_dir, contentname)
return contentfile
def get_ostree_tar_filename(self, patch_sw_version, patch_id): def get_ostree_tar_filename(self, patch_sw_version, patch_id):
''' '''
Returns the path of the ostree tarball Returns the path of the ostree tarball
@ -858,17 +852,6 @@ class PatchController(PatchService):
LOG.exception(msg) LOG.exception(msg)
raise PatchError(msg) raise PatchError(msg)
def get_repo_filename(self, patch_sw_version, contentname):
contentfile = self.get_store_filename(patch_sw_version, contentname)
if not os.path.isfile(contentfile):
msg = "Could not find content: %s" % contentfile
LOG.error(msg)
return None
# OSTREE: need to determine the actual path for the content ie: Content
repo_filename = "%s/Content/%s" % (repo_dir[patch_sw_version], contentname)
return repo_filename
def run_semantic_check(self, action, patch_list): def run_semantic_check(self, action, patch_list):
if not os.path.exists(INITIAL_CONFIG_COMPLETE_FLAG): if not os.path.exists(INITIAL_CONFIG_COMPLETE_FLAG):
# Skip semantic checks if initial configuration isn't complete # Skip semantic checks if initial configuration isn't complete
@ -1817,11 +1800,7 @@ class PatchController(PatchService):
failure = False failure = False
recursive = True recursive = True
keep = {}
cleanup = {}
cleanup_files = set() cleanup_files = set()
results = {"info": "", results = {"info": "",
"error": ""} "error": ""}
@ -1874,22 +1853,26 @@ class PatchController(PatchService):
results["error"] += errormsg results["error"] += errormsg
return results return results
# Get list of packages with self.patch_data_lock:
self.patch_data_lock.acquire() for patch_id in commit_list:
for patch_id in commit_list: # Fetch file paths that need to be cleaned up to
patch_sw_version = self.patch_data.metadata[patch_id]["sw_version"] # free patch storage disk space
if self.patch_data.metadata[patch_id].get("restart_script"):
if patch_sw_version not in keep: restart_script_path = "%s/%s" % \
keep[patch_sw_version] = {} (root_scripts_dir,
if patch_sw_version not in cleanup: self.patch_data.metadata[patch_id]["restart_script"])
cleanup[patch_sw_version] = {} if os.path.exists(restart_script_path):
cleanup_files.add(restart_script_path)
self.patch_data_lock.release() patch_sw_version = self.patch_data.metadata[patch_id]["sw_version"]
abs_ostree_tar_dir = package_dir[patch_sw_version]
software_tar_path = "%s/%s-software.tar" % (abs_ostree_tar_dir, patch_id)
if os.path.exists(software_tar_path):
cleanup_files.add(software_tar_path)
# Calculate disk space # Calculate disk space
disk_space = 0 disk_space = 0
for rpmfile in cleanup_files: for file in cleanup_files:
statinfo = os.stat(rpmfile) statinfo = os.stat(file)
disk_space += statinfo.st_size disk_space += statinfo.st_size
if dry_run: if dry_run:
@ -1912,26 +1895,14 @@ class PatchController(PatchService):
raise MetadataFail(msg) raise MetadataFail(msg)
# Delete the files # Delete the files
for contentfile in cleanup_files: for file in cleanup_files:
try: try:
os.remove(contentfile) os.remove(file)
except OSError: except OSError:
msg = "Failed to remove: %s" % contentfile msg = "Failed to remove: %s" % file
LOG.exception(msg) LOG.exception(msg)
raise MetadataFail(msg) raise MetadataFail(msg)
# OSTREE: this repo update code needs to be re-examined
for ver, rdir in repo_dir.items():
try:
# todo(jcasteli) determine if ostree change needs additional actions
# old code was calling 'createrepo' for rpms
output = "OSTREE determined a change occurred rdir=%s" % rdir
LOG.info("Repo[%s] updated:\n%s", ver, output)
except Exception:
msg = "Failed to update the repo for %s" % ver
LOG.exception(msg)
raise PatchFail(msg)
self.patch_data.load_all() self.patch_data.load_all()
results["info"] = "The patches have been committed." results["info"] = "The patches have been committed."

View File

@ -557,7 +557,8 @@ class PatchFile(object):
@staticmethod @staticmethod
def write_patch(patchfile, cert_type=None): def write_patch(patchfile, cert_type=None):
# Write the patch file. Assumes we are in a directory containing metadata.tar, and software.tar. # Write the patch file. Assumes we are in a directory containing
# metadata.tar and software.tar.
# Generate the metadata tarfile # Generate the metadata tarfile
tar = tarfile.open("metadata.tar", "w") tar = tarfile.open("metadata.tar", "w")