Merge "Added post update removal of residual images"
This commit is contained in:
@ -94,6 +94,9 @@ class OpenstackAppLifecycleOperator(base.AppLifecycleOperator):
|
||||
if hook_info.operation == constants.APP_APPLY_OP and \
|
||||
hook_info.relative_timing == constants.APP_LIFECYCLE_TIMING_PRE:
|
||||
return self._pre_update_actions(app)
|
||||
elif hook_info.operation == constants.APP_APPLY_OP and \
|
||||
hook_info.relative_timing == constants.APP_LIFECYCLE_TIMING_POST:
|
||||
return self._post_update_image_actions(app)
|
||||
|
||||
# Default behavior
|
||||
super(OpenstackAppLifecycleOperator, self).app_lifecycle_actions(context, conductor_obj, app_op, app,
|
||||
@ -507,6 +510,20 @@ class OpenstackAppLifecycleOperator(base.AppLifecycleOperator):
|
||||
resource_name='mariadb'
|
||||
)
|
||||
|
||||
def _post_update_image_actions(self, app):
|
||||
"""Perform post update actions, deleting residual images.
|
||||
|
||||
:param app: AppOperator.Application object
|
||||
"""
|
||||
images_base_dir = app.sync_imgfile.split(app.name)[0]
|
||||
app_version_list = app_utils.get_app_version_list(images_base_dir, app.name)
|
||||
if len(app_version_list) > 1:
|
||||
LOG.info("Deleting unused images for app %s", app.name)
|
||||
residual_images = app_utils.get_residual_images(app.sync_imgfile, app.version, app_version_list)
|
||||
|
||||
if len(residual_images) > 0:
|
||||
app_utils.delete_residual_images(residual_images)
|
||||
|
||||
def _recover_backup_snapshot(self, app):
|
||||
"""Perform pre recover backup actions
|
||||
|
||||
|
@ -628,6 +628,128 @@ def update_helmrelease(release, patch):
|
||||
LOG.error(f"Unexpected error while updating helmrelease: {e}")
|
||||
|
||||
|
||||
def get_app_version_list(base_dir: str, app_name: str) -> list:
|
||||
"""
|
||||
Retrieve a list of versions for a given application from YAML files.
|
||||
|
||||
Args:
|
||||
base_dir (str): The base directory where application data is stored.
|
||||
app_name (str): The name of the application.
|
||||
|
||||
Returns:
|
||||
list: A list of versions for the specified application.
|
||||
"""
|
||||
return os.listdir(os.path.join(base_dir, app_name))
|
||||
|
||||
|
||||
def get_image_list(image_dir: str) -> list:
|
||||
"""
|
||||
Retrieve a list of images for a given application from YAML files.
|
||||
|
||||
Args:
|
||||
image_dir (str): The base directory where application data is stored.
|
||||
|
||||
Returns:
|
||||
list: A list of images for the specified application.
|
||||
"""
|
||||
with open(image_dir, 'r', encoding='utf-8') as f:
|
||||
return yaml.safe_load(f)["download_images"]
|
||||
|
||||
|
||||
def get_residual_images(image_file_dir: str, app_version: str, app_version_list: list) -> list:
|
||||
"""
|
||||
Retrieve a list of residual images for a given application.
|
||||
|
||||
Args:
|
||||
image_file_dir (str): The directory containing the image files.
|
||||
app_version (str): The specific version of the application.
|
||||
app_version_list (list): A list of all available application versions.
|
||||
|
||||
Returns:
|
||||
list: A list of residual images that are present in older versions
|
||||
but not in the current version.
|
||||
"""
|
||||
|
||||
new_images_list = get_image_list(image_file_dir)
|
||||
app_version_list.remove(app_version)
|
||||
|
||||
old_images_list = []
|
||||
last_version = app_version
|
||||
for version in app_version_list:
|
||||
file_name = image_file_dir.replace(last_version, version)
|
||||
old_images_list.extend(get_image_list(file_name))
|
||||
last_version = version
|
||||
|
||||
return list(set(old_images_list) - set(new_images_list))
|
||||
|
||||
|
||||
def delete_residual_images(image_list: list):
|
||||
"""Remove a list of images from the system registry.
|
||||
Args:
|
||||
image (list): A list of image names to be removed.
|
||||
"""
|
||||
|
||||
image_json = list_crictl_images()
|
||||
|
||||
for image in image_list:
|
||||
image_id = get_image_id(image, image_json)
|
||||
if not image_id:
|
||||
LOG.error(f"Image {image} not found in the system registry.")
|
||||
continue
|
||||
LOG.info(f"Removing residual image: {image}")
|
||||
cmd = [
|
||||
"crictl", "rmi", image_id
|
||||
]
|
||||
try:
|
||||
process = subprocess.run(
|
||||
args=["bash", "-c", f"source /etc/platform/openrc && {' '.join(cmd)}"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
shell=False)
|
||||
|
||||
LOG.info(f"Stdout: {process.stdout}")
|
||||
LOG.info(f"Stderr: {process.stderr}")
|
||||
process.check_returncode()
|
||||
except Exception as e:
|
||||
LOG.error(f"Unexpected error while removing image {image}: {e}")
|
||||
|
||||
|
||||
def list_crictl_images() -> json:
|
||||
"""List all images in the system registry.
|
||||
Returns: A dict of images in the system registry.
|
||||
"""
|
||||
cmd = [
|
||||
"crictl", "images", "--output", "json"
|
||||
]
|
||||
try:
|
||||
process = subprocess.run(
|
||||
args=["bash", "-c", f"source /etc/platform/openrc && {' '.join(cmd)}"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
shell=False)
|
||||
|
||||
LOG.info(f"Stderr: {process.stderr}")
|
||||
process.check_returncode()
|
||||
return json.loads(process.stdout)
|
||||
except Exception as e:
|
||||
LOG.error(f"Unexpected error while listing images: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def get_image_id(image_name: str, image_json: json) -> str:
|
||||
"""Get the image ID from the system registry.
|
||||
Args:
|
||||
image_name (str): The name of the image.
|
||||
image_json (json): The dict of images in the system registry.
|
||||
Returns:
|
||||
str: The image ID.
|
||||
"""
|
||||
for image in image_json["images"]:
|
||||
if image_name in image["repoTags"]:
|
||||
return image["id"]
|
||||
return None
|
||||
|
||||
|
||||
def get_number_of_controllers() -> int:
|
||||
"""Get the number of controllers in the system
|
||||
|
||||
|
Reference in New Issue
Block a user