Remove system job, replace with scheduled task

This commit is contained in:
Seth Foster 2021-04-15 13:47:37 -04:00
parent 33567f8729
commit fa61ec6b3c
No known key found for this signature in database
GPG Key ID: 86E90D96F7184028
3 changed files with 20 additions and 83 deletions

View File

@ -1,83 +0,0 @@
# Copyright (c) 2015 Ansible, Inc.
# All Rights Reserved.
# Python
import subprocess
import logging
import json
# Django
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
# AWX
from awx.main.models import ExecutionEnvironment
class Command(BaseCommand):
"""
Management command to cleanup unused execution environment images.
"""
help = 'Remove unused execution environment images'
def init_logging(self):
log_levels = dict(enumerate([logging.ERROR, logging.INFO, logging.DEBUG, 0]))
self.logger = logging.getLogger('awx.main.commands.cleanup_images')
self.logger.setLevel(log_levels.get(self.verbosity, 0))
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(message)s'))
self.logger.addHandler(handler)
self.logger.propagate = False
def add_arguments(self, parser):
parser.add_argument('--dry-run', dest='dry_run', action='store_true', default=False, help='Dry run mode (show items that would ' 'be removed)')
def delete_images(self, images_json):
if self.dry_run:
delete_prefix = "Would delete"
else:
delete_prefix = "Deleting"
for e in images_json:
if 'Names' in e:
image_names = e['Names']
else:
image_names = [e["Id"]]
image_size = e['Size'] / 1e6
for i in image_names:
if i not in self.images_in_use and i not in self.deleted:
self.deleted.append(i)
self.logger.info(f"{delete_prefix} {i}: {image_size:.0f} MB")
if not self.dry_run:
subprocess.run(['podman', 'rmi', i, '-f'], stdout=subprocess.DEVNULL)
def cleanup_images(self):
self.images_in_use = [ee.image for ee in ExecutionEnvironment.objects.all()]
if self.images_in_use:
self.logger.info("Execution environment images in use:")
for i in self.images_in_use:
self.logger.info(f"\t{i}")
self.deleted = []
# find and remove unused images
images_system = subprocess.run("podman images -a --format json".split(" "), capture_output=True)
if len(images_system.stdout) > 0:
images_system = json.loads(images_system.stdout)
self.delete_images(images_system)
# find and remove dangling images
images_system = subprocess.run('podman images -a --filter "dangling=true" --format json'.split(" "), capture_output=True)
if len(images_system.stdout) > 0:
images_system = json.loads(images_system.stdout)
self.delete_images(images_system)
if not self.deleted:
self.logger.info("Did not find unused images to remove")
def handle(self, *args, **options):
self.verbosity = int(options.get('verbosity', 1))
self.init_logging()
self.dry_run = bool(options.get('dry_run', False))
if self.dry_run:
self.logger.info("Dry run enabled, images will not be deleted")
if settings.IS_K8S:
raise CommandError("Cannot run cleanup tool on k8s installations")
self.cleanup_images()

View File

@ -27,6 +27,7 @@ import socket
import threading
import concurrent.futures
from base64 import b64encode
import subprocess
# Django
from django.conf import settings
@ -59,6 +60,7 @@ from awx.main.constants import PRIVILEGE_ESCALATION_METHODS, STANDARD_INVENTORY_
from awx.main.access import access_registry
from awx.main.redact import UriCleaner
from awx.main.models import (
ExecutionEnvironment,
Schedule,
TowerScheduleState,
Instance,
@ -396,6 +398,23 @@ def purge_old_stdout_files():
logger.debug("Removing {}".format(os.path.join(settings.JOBOUTPUT_ROOT, f)))
@task(queue=get_local_queuename)
def cleanup_execution_environment_images():
images_in_use = [ee.image for ee in ExecutionEnvironment.objects.all()]
images_system = subprocess.run("podman images -a --format json".split(" "), capture_output=True)
if len(images_system.stdout) > 0:
images_system = json.loads(images_system.stdout)
for e in images_system:
if 'Names' in e:
image_name = e['Names'][0]
else:
image_name = e["Id"]
image_size = e['Size'] / 1e6
if image_name not in images_in_use:
logger.debug(f"Cleanup execution environment images: deleting {image_name}, {image_size:.0f} MB")
subprocess.run(['podman', 'rmi', image_name, '-f'], stdout=subprocess.DEVNULL)
@task(queue=get_local_queuename)
def cluster_node_heartbeat():
logger.debug("Cluster node heartbeat task.")

View File

@ -439,6 +439,7 @@ CELERYBEAT_SCHEDULE = {
'task_manager': {'task': 'awx.main.scheduler.tasks.run_task_manager', 'schedule': timedelta(seconds=20), 'options': {'expires': 20}},
'k8s_reaper': {'task': 'awx.main.tasks.awx_k8s_reaper', 'schedule': timedelta(seconds=60), 'options': {'expires': 50}},
'send_subsystem_metrics': {'task': 'awx.main.analytics.analytics_tasks.send_subsystem_metrics', 'schedule': timedelta(seconds=20)},
'cleanup_images': {'task': 'awx.main.tasks.cleanup_execution_environment_images', 'schedule': timedelta(hours=8)},
# 'isolated_heartbeat': set up at the end of production.py and development.py
}