Files
tools_scripts/update_docker_project.py
2026-04-02 19:47:58 +02:00

107 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 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 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 main():
parser = argparse.ArgumentParser(description="Pełna 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')
parser.add_argument('--only-updated', action='store_true', help='Restart tylko jeśli obrazy zostały zaktualizowane')
args = parser.parse_args()
os.chdir(args.project_folder)
compose_cmd = detect_compose_command()
images = get_images_from_compose(args.compose_file)
updated = False
print("Pobieranie najnowszych wersji obrazów...")
for image in images:
print(f"- docker pull {image}")
pull_result = run(f"docker pull {image}", capture_output=True)
if pull_result and "Downloaded newer image" in pull_result:
updated = True
if args.only_updated and not updated:
print("Obrazy aktualne. Stack nie zostanie zrestartowany (--only-updated).")
else:
stop_containers(compose_cmd, args.compose_file, args.project_name)
remove_conflicting_containers(images)
prune_images()
start_containers(compose_cmd, args.compose_file, args.project_name)
print("Stack zrestartowany.")
print("Zakończono.")
if __name__ == "__main__":
main()