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