Add spawn_esphome.py
This commit is contained in:
103
spawn_esphome.py
Normal file
103
spawn_esphome.py
Normal 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()
|
Reference in New Issue
Block a user