Files
skrypty_narzedzia/update_docker_project.py
2025-07-18 13:36:47 +02:00

111 lines
3.7 KiB
Python

#!/usr/bin/env python3
import subprocess
import argparse
import os
import shutil
import sys
import re
# Sprawdzenie PyYAML
try:
import yaml
except ImportError:
print("Błąd: brak modułu 'pyyaml'.")
print("Zainstaluj go komendą: pip install pyyaml / zypper in python312-pyaml / apt install python3-yaml")
sys.exit(1)
def detect_compose_command():
if shutil.which("docker-compose"):
return "docker-compose"
elif shutil.which("docker"):
result = subprocess.run("docker compose version", shell=True, stdout=subprocess.DEVNULL)
if result.returncode == 0:
return "docker compose"
print("Nie znaleziono docker compose ani docker-compose.")
sys.exit(1)
def run(cmd, capture_output=False):
result = subprocess.run(cmd, shell=True, capture_output=capture_output, text=True)
if result.returncode != 0:
print(f"Błąd: {cmd}")
if result.stderr:
print(result.stderr)
return result.stdout.strip() if capture_output else None
def stop_containers(compose_cmd, compose_file, project_name):
print("Zatrzymywanie kontenerów...")
run(f"{compose_cmd} -p {project_name} -f {compose_file} down")
def resolve_env_var(value: str) -> str:
pattern = re.compile(r'\$\{([^}:\-]+)(?::-([^}]+))?\}')
def replacer(match):
var, default = match.groups()
return os.environ.get(var, default or "")
return pattern.sub(replacer, value)
def get_images_from_compose(compose_path):
with open(compose_path, "r") as f:
data = yaml.safe_load(f)
services = data.get("services", {})
resolved_images = []
for svc in services.values():
image = svc.get("image")
if image:
resolved_images.append(resolve_env_var(image))
return resolved_images
def check_for_updates(images):
print("Sprawdzanie aktualizacji...")
updates = {}
for image in images:
print(f"- Sprawdzanie obrazu: {image}")
pull_result = run(f"docker pull {image}", capture_output=True)
if pull_result and "Downloaded newer image" in pull_result:
updates[image] = image
return updates
def remove_conflicting_containers(images):
print("Usuwanie kolidujących kontenerów (jeśli istnieją)...")
for image in images:
name = image.split(":")[0].split("/")[-1]
run(f"docker rm -f {name}", capture_output=True)
def prune_images():
print("Czyszczenie nieużywanych obrazów...")
run("docker image prune -f")
def start_containers(compose_cmd, compose_file, project_name):
print("Uruchamianie kontenerów...")
run(f"{compose_cmd} -p {project_name} -f {compose_file} up -d")
def main():
parser = argparse.ArgumentParser(description="Aktualizacja i restart docker-compose projektu.")
parser.add_argument('--project-folder', required=True, help='Ścieżka do folderu projektu')
parser.add_argument('--compose-file', required=True, help='Ścieżka do pliku docker-compose.yml')
parser.add_argument('--project-name', required=True, help='Nazwa projektu docker-compose')
args = parser.parse_args()
os.chdir(args.project_folder)
compose_cmd = detect_compose_command()
images = get_images_from_compose(args.compose_file)
stop_containers(compose_cmd, args.compose_file, args.project_name)
updated = check_for_updates(images)
if updated:
print("Zaktualizowane obrazy:")
for img in updated:
print(f"- {img}")
prune_images()
remove_conflicting_containers(images)
start_containers(compose_cmd, args.compose_file, args.project_name)
else:
print("Obrazy aktualne. Nie uruchamiam kontenerów.")
print("Zakończono.")
if __name__ == "__main__":
main()