utils_devops 0.1.172__py3-none-any.whl → 0.1.174__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- utils_devops/extras/docker_ops.py +76 -2
- {utils_devops-0.1.172.dist-info → utils_devops-0.1.174.dist-info}/METADATA +1 -1
- {utils_devops-0.1.172.dist-info → utils_devops-0.1.174.dist-info}/RECORD +5 -5
- {utils_devops-0.1.172.dist-info → utils_devops-0.1.174.dist-info}/WHEEL +0 -0
- {utils_devops-0.1.172.dist-info → utils_devops-0.1.174.dist-info}/entry_points.txt +0 -0
|
@@ -3811,7 +3811,7 @@ def _perform_post_deployment_cleanup(
|
|
|
3811
3811
|
|
|
3812
3812
|
try:
|
|
3813
3813
|
# Cleanup old images
|
|
3814
|
-
removed_images =
|
|
3814
|
+
removed_images = cleanup_old_images_by_compose(keep_count=keep_image_versions,compose_file=compose_file)
|
|
3815
3815
|
cleanup_results["images_removed"] = removed_images
|
|
3816
3816
|
logger.info(f"Cleaned up {len(removed_images)} old images")
|
|
3817
3817
|
|
|
@@ -4002,6 +4002,80 @@ def get_compose_status(compose_file: str, env_file: Optional[str] = None) -> Dic
|
|
|
4002
4002
|
|
|
4003
4003
|
return status
|
|
4004
4004
|
|
|
4005
|
+
|
|
4006
|
+
def cleanup_old_images_by_compose(keep_count: int = 3, dry_run: bool = False, compose_file: Optional[str] = None, env_file: Optional[str] = None) -> List[str]:
|
|
4007
|
+
"""Clean up old Docker images, optionally limited to those in a compose file from compose"""
|
|
4008
|
+
removed = []
|
|
4009
|
+
|
|
4010
|
+
try:
|
|
4011
|
+
# Get all images
|
|
4012
|
+
result = run_docker_command(["docker", "images", "--format", "{{.ID}}|{{.Repository}}|{{.Tag}}|{{.CreatedAt}}"])
|
|
4013
|
+
|
|
4014
|
+
images = []
|
|
4015
|
+
for line in result.stdout.strip().splitlines():
|
|
4016
|
+
if line.strip():
|
|
4017
|
+
parts = line.split('|', 3)
|
|
4018
|
+
if len(parts) == 4:
|
|
4019
|
+
images.append({
|
|
4020
|
+
'id': parts[0],
|
|
4021
|
+
'repository': parts[1],
|
|
4022
|
+
'tag': parts[2],
|
|
4023
|
+
'created': parts[3]
|
|
4024
|
+
})
|
|
4025
|
+
|
|
4026
|
+
# Group by repository
|
|
4027
|
+
all_repos = {}
|
|
4028
|
+
for img in images:
|
|
4029
|
+
repo = img['repository']
|
|
4030
|
+
if repo not in all_repos:
|
|
4031
|
+
all_repos[repo] = []
|
|
4032
|
+
all_repos[repo].append(img)
|
|
4033
|
+
|
|
4034
|
+
# Determine which repos to clean
|
|
4035
|
+
repos_to_clean = all_repos # Default: all
|
|
4036
|
+
|
|
4037
|
+
if compose_file:
|
|
4038
|
+
try:
|
|
4039
|
+
compose_data = read_compose_file(compose_file, env_file)
|
|
4040
|
+
services = list(compose_data.get('services', {}).keys())
|
|
4041
|
+
|
|
4042
|
+
compose_repos = set()
|
|
4043
|
+
for service in services:
|
|
4044
|
+
image = get_service_image(compose_file, service, env_file)
|
|
4045
|
+
if image:
|
|
4046
|
+
repo_tag = image.split(':')
|
|
4047
|
+
repo = repo_tag[0]
|
|
4048
|
+
compose_repos.add(repo)
|
|
4049
|
+
|
|
4050
|
+
# Filter to only compose repos
|
|
4051
|
+
repos_to_clean = {repo: imgs for repo, imgs in all_repos.items() if repo in compose_repos}
|
|
4052
|
+
|
|
4053
|
+
if not compose_repos:
|
|
4054
|
+
logger.warning("No services/images found in compose file, falling back to all images")
|
|
4055
|
+
repos_to_clean = all_repos
|
|
4056
|
+
except Exception as e:
|
|
4057
|
+
logger.warning(f"Error reading compose file: {e}, falling back to all images")
|
|
4058
|
+
repos_to_clean = all_repos
|
|
4059
|
+
|
|
4060
|
+
# Clean up
|
|
4061
|
+
for repo, repo_images in repos_to_clean.items():
|
|
4062
|
+
# Sort by creation date (newest first)
|
|
4063
|
+
repo_images.sort(key=lambda x: x['created'], reverse=True)
|
|
4064
|
+
|
|
4065
|
+
# Remove old images
|
|
4066
|
+
for old_img in repo_images[keep_count:]:
|
|
4067
|
+
if dry_run:
|
|
4068
|
+
logger.info(f"Would remove: {old_img['repository']}:{old_img['tag']}")
|
|
4069
|
+
else:
|
|
4070
|
+
remove_result = run_docker_command(["docker", "rmi", old_img['id']])
|
|
4071
|
+
if remove_result.rc == 0:
|
|
4072
|
+
removed.append(f"{old_img['repository']}:{old_img['tag']}")
|
|
4073
|
+
|
|
4074
|
+
except Exception as e:
|
|
4075
|
+
logger.error(f"Image cleanup failed: {e}")
|
|
4076
|
+
|
|
4077
|
+
return removed
|
|
4078
|
+
|
|
4005
4079
|
def cleanup_old_images(keep_count: int = 3, dry_run: bool = False) -> List[str]:
|
|
4006
4080
|
"""Clean up old Docker images"""
|
|
4007
4081
|
removed = []
|
|
@@ -4923,7 +4997,7 @@ __all__ = [
|
|
|
4923
4997
|
# Backup & restore
|
|
4924
4998
|
"backup_compose", "restore_compose",
|
|
4925
4999
|
# Utilities
|
|
4926
|
-
"get_compose_status", "cleanup_old_images",
|
|
5000
|
+
"get_compose_status", "cleanup_old_images", "cleanup_old_images_by_compose",
|
|
4927
5001
|
# Data classes
|
|
4928
5002
|
"ExecResult", "LogLine", "ContainerInfo",
|
|
4929
5003
|
# Exceptions
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: utils_devops
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.174
|
|
4
4
|
Summary: Lightweight DevOps utilities for automation scripts: config editing (YAML/JSON/INI/.env), templating, diffing, and CLI tools
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: devops,automation,nginx,cli,jinja2,yaml,config,diff,templating,logging,docker,compose,file-ops
|
|
@@ -9,7 +9,7 @@ utils_devops/core/strings.py,sha256=8s0GSjcyTKwLjJjsJ_XfOJxPtyb549icDlU9SUxSvHI,
|
|
|
9
9
|
utils_devops/core/systems.py,sha256=wNbEFUAvbMPdqWN-iXvTzvj5iE9xaWfjZYYvD0EZAH0,47577
|
|
10
10
|
utils_devops/extras/__init__.py,sha256=ZXHeVLHO3_qiW9AY-UQ_YA9cQzmkLGv54a2UbyvtlM0,3571
|
|
11
11
|
utils_devops/extras/aws_ops.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
utils_devops/extras/docker_ops.py,sha256=
|
|
12
|
+
utils_devops/extras/docker_ops.py,sha256=vH8LmUNUyFj5D3tLuFUERMdpUTtxJXjsdoKPo1bYRjU,201890
|
|
13
13
|
utils_devops/extras/git_ops.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
utils_devops/extras/interaction_ops.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
utils_devops/extras/metrics_ops.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -19,7 +19,7 @@ utils_devops/extras/notification_ops.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
|
|
|
19
19
|
utils_devops/extras/performance_ops.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
utils_devops/extras/ssh_ops.py,sha256=hTOYzyWmnZWzOLeZbCoZRLxSJiBmr0QgS_87qks-CYk,76305
|
|
21
21
|
utils_devops/extras/vault_ops.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
utils_devops-0.1.
|
|
23
|
-
utils_devops-0.1.
|
|
24
|
-
utils_devops-0.1.
|
|
25
|
-
utils_devops-0.1.
|
|
22
|
+
utils_devops-0.1.174.dist-info/METADATA,sha256=Xzmk7zfD03BT8zkZgdrtl1UH2rMU6ynit-ws5oCiPUo,1903
|
|
23
|
+
utils_devops-0.1.174.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
24
|
+
utils_devops-0.1.174.dist-info/entry_points.txt,sha256=ei3B6ZL5yu6dOq-U1r8wsBdkXeg63RAyV7m8_ADaE6k,53
|
|
25
|
+
utils_devops-0.1.174.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|