mirror of
https://github.com/ansible/awx.git
synced 2026-01-13 02:50:02 -03:30
Remove system job, replace with scheduled task
This commit is contained in:
parent
33567f8729
commit
fa61ec6b3c
@ -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()
|
||||
@ -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.")
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user