Add spawn_esphome.py

This commit is contained in:
gru
2025-07-22 13:47:55 +02:00
parent 0c423d4a50
commit ad7f74ce28

103
spawn_esphome.py Normal file
View File

@@ -0,0 +1,103 @@
#!/usr/bin/env python3
import argparse
import subprocess
import json
import re
import sys
from pathlib import Path
import requests
DOCKER_NAMESPACE = "esphome"
DOCKER_REPO = "esphome"
DOCKER_API = f"https://registry.hub.docker.com/v2/repositories/{DOCKER_NAMESPACE}/{DOCKER_REPO}/tags"
def parse_version(raw_version):
if len(raw_version) == 8 and raw_version.isdigit():
yyyy = raw_version[:4]
m = str(int(raw_version[4:6]))
d = str(int(raw_version[6:]))
return f"{yyyy}.{m}.{d}"
return raw_version
def list_tags(upto_year):
tags = []
pattern = re.compile(r"^(\d{4})\.(\d{1,2})\.(\d{1,2})$") # dokładnie 3 liczby rozdzielone kropkami
page = 1
while True:
resp = requests.get(DOCKER_API, params={"page_size": 100, "page": page})
resp.raise_for_status()
data = resp.json()
for entry in data.get("results", []):
name = entry["name"]
match = pattern.match(name)
if match:
year = int(match.group(1))
if year <= upto_year:
tags.append(name)
if not data.get("next"):
break
page += 1
tags.sort(key=lambda s: list(map(int, s.split('.'))))
return tags
def pull_image(tag):
full = f"{DOCKER_NAMESPACE}/{DOCKER_REPO}:{tag}"
subprocess.run(["docker", "pull", full], check=True)
return full
def run_container(version_tag, port):
container = f"esphome-{version_tag.replace('/', '_')}"
data_dir = f"/docker/data/esphome/{version_tag}"
image = f"{DOCKER_NAMESPACE}/{DOCKER_REPO}:{version_tag}"
Path(data_dir).mkdir(parents=True, exist_ok=True)
cmd = [
"docker", "run", "-d",
"--name", container,
"--restart", "always",
"-p", f"{port}:6052",
"-v", f"{data_dir}:/config",
image,
"dashboard", "/config"
]
print("Uruchamianie:", " ".join(cmd))
subprocess.run(cmd, check=True)
print("Kontener uruchomiony.")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--version", help="yyyymmdd lub yyyy.m.d")
parser.add_argument("--port", type=int, help="Port host →6052")
parser.add_argument("--list-available", type=int, metavar="YEAR",
help="Wyświetl tagi do danego roku (np. 2025)")
args = parser.parse_args()
if args.list_available is not None:
tags = list_tags(args.list_available)
print(f"Dostępne tagi do roku {args.list_available}:")
for t in tags:
print(" ", t)
sys.exit(0)
if not args.version or not args.port:
parser.error("Wymagane: --version i --port albo sam --list-available")
raw = args.version
tag = parse_version(raw)
# Sprawdź lokalnie
exists = subprocess.run(["docker", "images", "-q", f"{DOCKER_NAMESPACE}/{DOCKER_REPO}:{tag}"],
stdout=subprocess.DEVNULL).returncode == 0
if not exists:
print(f"Obraz {tag} nie znaleziony lokalnie. Pobieram z Docker Hub...")
try:
pull_image(tag)
except subprocess.CalledProcessError:
sys.exit(f"Nie udało się pobrać esphome/esphome:{tag}")
try:
run_container(tag, args.port)
except subprocess.CalledProcessError as e:
sys.exit(f"Błąd uruchamiania kontenera: {e}")
if __name__ == "__main__":
main()