|
2 | 2 |
|
3 | 3 | import argparse |
4 | 4 | import contextlib |
| 5 | +import json |
5 | 6 | import os |
6 | 7 | import subprocess |
| 8 | +import sys |
7 | 9 | import tempfile |
| 10 | +import time |
8 | 11 | from collections.abc import Mapping |
9 | 12 | from collections.abc import Sequence |
| 13 | +from datetime import datetime |
| 14 | +from datetime import timezone |
10 | 15 | from typing import Any |
11 | 16 |
|
12 | 17 | import ruamel.yaml |
@@ -74,7 +79,61 @@ def do_shellcheck( |
74 | 79 | return True |
75 | 80 |
|
76 | 81 |
|
| 82 | +def check_and_update_melange_image(image: str) -> None: |
| 83 | + """Check if melange image is older than 30 days and pull if needed.""" |
| 84 | + try: |
| 85 | + # Get image creation date |
| 86 | + result = subprocess.run( |
| 87 | + ["docker", "image", "inspect", image, "--format", "{{json .Created}}"], |
| 88 | + capture_output=True, |
| 89 | + text=True, |
| 90 | + check=False, |
| 91 | + ) |
| 92 | + |
| 93 | + if result.returncode != 0: |
| 94 | + # Image doesn't exist locally, pull it |
| 95 | + print( |
| 96 | + f"Melange image not found locally, pulling {image}...", |
| 97 | + file=sys.stderr, |
| 98 | + ) |
| 99 | + subprocess.run(["docker", "pull", image], check=True) |
| 100 | + return |
| 101 | + |
| 102 | + # Parse the creation date |
| 103 | + created_str = json.loads(result.stdout.strip()) |
| 104 | + created_date = datetime.fromisoformat(created_str.replace("Z", "+00:00")) |
| 105 | + now = datetime.now(timezone.utc) |
| 106 | + age_days = (now - created_date).days |
| 107 | + |
| 108 | + if age_days > 30: |
| 109 | + print( |
| 110 | + f"⚠️ Melange image is {age_days} days old (created {created_date.strftime('%Y-%m-%d')})", |
| 111 | + file=sys.stderr, |
| 112 | + ) |
| 113 | + print(f"⚠️ Pulling updated melange image: {image}", file=sys.stderr) |
| 114 | + print( |
| 115 | + "⚠️ Press Ctrl+C now to abort or wait 15 seconds to continue...", |
| 116 | + file=sys.stderr, |
| 117 | + ) |
| 118 | + |
| 119 | + # Give user 15 seconds to abort |
| 120 | + time.sleep(15) |
| 121 | + |
| 122 | + print(f"Pulling {image}...", file=sys.stderr) |
| 123 | + subprocess.run(["docker", "pull", image], check=True) |
| 124 | + print("✓ Melange image updated successfully", file=sys.stderr) |
| 125 | + |
| 126 | + except KeyboardInterrupt: |
| 127 | + print("\n⚠️ Update aborted by user, using existing image", file=sys.stderr) |
| 128 | + except Exception as e: |
| 129 | + print(f"Warning: Failed to check/update melange image: {e}", file=sys.stderr) |
| 130 | + print("Continuing with existing image...", file=sys.stderr) |
| 131 | + |
| 132 | + |
77 | 133 | def main(argv: Sequence[str] | None = None) -> int: |
| 134 | + # Check and update melange image if needed |
| 135 | + check_and_update_melange_image(MelangeImage) |
| 136 | + |
78 | 137 | parser = argparse.ArgumentParser() |
79 | 138 | parser.add_argument( |
80 | 139 | "filenames", |
|
0 commit comments