feat(cli): dev deploy 가 로컬 소스·앱을 콘솔에 리포트(내 로컬 클러스터 3탭) — 0.17.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-29 12:32:08 +09:00
parent 05c1afe718
commit d8874eaed7
2 changed files with 35 additions and 2 deletions

View File

@ -16,7 +16,7 @@ set -uo pipefail # -e 미사용: 'test && action' 관용구가 값 없을 때
REPO="${YAKCLOUD_STARTER_REPO:-https://gitea.yakenator.io/yakenator/yakcloud-starter}" REPO="${YAKCLOUD_STARTER_REPO:-https://gitea.yakenator.io/yakenator/yakcloud-starter}"
BRANCH="${YAKCLOUD_STARTER_BRANCH:-main}" BRANCH="${YAKCLOUD_STARTER_BRANCH:-main}"
VERSION="0.16.0" VERSION="0.17.0"
# 로컬 개발 클러스터(kind) — 개발 후 운영까지 '직선 배포'의 dev 구간. # 로컬 개발 클러스터(kind) — 개발 후 운영까지 '직선 배포'의 dev 구간.
DEV_CTX="${YAK_DEV_CONTEXT:-kind-yak-dev}" DEV_CTX="${YAK_DEV_CONTEXT:-kind-yak-dev}"
DEV_CLUSTER="${YAK_DEV_CLUSTER:-yak-dev}" DEV_CLUSTER="${YAK_DEV_CLUSTER:-yak-dev}"
@ -470,7 +470,7 @@ cmd_dev() {
for a in "$@"; do case "$a" in -*) : ;; *) [ -z "$tag" ] && tag="$a" ;; esac; done for a in "$@"; do case "$a" in -*) : ;; *) [ -z "$tag" ] && tag="$a" ;; esac; done
local pysub="$sub"; [ "$sub" = clean ] && pysub="down" local pysub="$sub"; [ "$sub" = clean ] && pysub="down"
YAK_DEV_CONTEXT="$DEV_CTX" YAK_DEV_CLUSTER="$DEV_CLUSTER" YAK_DEV_RUNTIME="${rt:-docker}" \ YAK_DEV_CONTEXT="$DEV_CTX" YAK_DEV_CLUSTER="$DEV_CLUSTER" YAK_DEV_RUNTIME="${rt:-docker}" \
TAG="${tag:-${TAG:-dev}}" python3 scripts/yakcloud_dev.py "$pysub" yakcloud.yaml YAK_REG_NAME="$(_local_reg_name)" TAG="${tag:-${TAG:-dev}}" python3 scripts/yakcloud_dev.py "$pysub" yakcloud.yaml
[ "$sub" = deploy ] && _dev_register || true [ "$sub" = deploy ] && _dev_register || true
;; ;;
down) down)

View File

@ -26,6 +26,7 @@ import os
import secrets import secrets
import subprocess import subprocess
import sys import sys
import urllib.request
from urllib.parse import quote from urllib.parse import quote
try: try:
@ -351,6 +352,36 @@ def _prune(ns: str, role: str, label_key: str, desired: set) -> None:
kubectl(["delete", kind, nm, "-n", ns, "--ignore-not-found"], check=False) kubectl(["delete", kind, nm, "-n", ns, "--ignore-not-found"], check=False)
def _wl_hosts(project: str, w: dict) -> list:
ex = w.get("expose", {}) or {}
hosts = ex.get("hosts") or ([ex["host"]] if ex.get("host") else [])
return hosts or [f"{project}.{HOST_SUFFIX}"]
def _report_to_console(project: str, reqs: list, wls: list) -> None:
"""dev deploy 결과(소스·워크로드 요약)를 콘솔에 best-effort 리포트 — LOCAL 클러스터 데이터소스·앱 탭 렌더용.
로그인(URL+TOKEN)+등록명(YAK_REG_NAME) 없으면 조용히 스킵(오프라인 dev 불변식)."""
url = os.environ.get("YAKCLOUD_URL")
tok = os.environ.get("YAKCLOUD_TOKEN")
name = os.environ.get("YAK_REG_NAME")
if not (url and tok and name):
return
report = {
"project": project,
"sources": [{"name": r["name"], "type": str(r.get("type", "")).upper()} for r in reqs],
"workloads": [{"name": sanitize(w["name"]), "image": w["image"].replace("${TAG}", TAG),
"hosts": _wl_hosts(project, w), "port": int(w.get("port", 8080))} for w in wls],
}
body = json.dumps({"name": name, "displayName": "로컬 개발 (kind)", "report": report}).encode()
req = urllib.request.Request(url.rstrip("/") + "/api/v1/clusters/local", data=body, method="POST",
headers={"Authorization": "Bearer " + tok, "content-type": "application/json"})
try:
with urllib.request.urlopen(req, timeout=6):
log("콘솔 로컬 클러스터 목록에 데이터소스·앱 리포트 반영")
except Exception: # noqa: BLE001 — best-effort(오프라인/미로그인/네트워크)
pass
def cmd_deploy(m: dict) -> None: def cmd_deploy(m: dict) -> None:
context_ok() context_ok()
project = sanitize(m.get("project", "app")) project = sanitize(m.get("project", "app"))
@ -383,6 +414,8 @@ def cmd_deploy(m: dict) -> None:
_prune(ns, "source", "yakcloud.dev/source", {sanitize(r["name"]) for r in reqs}) _prune(ns, "source", "yakcloud.dev/source", {sanitize(r["name"]) for r in reqs})
_prune(ns, "workload", "app", {sanitize(w["name"]) for w in wls}) _prune(ns, "workload", "app", {sanitize(w["name"]) for w in wls})
_report_to_console(project, reqs, wls) # 콘솔 LOCAL 클러스터 탭(데이터소스·앱) 리포트
failed = [h for h, ok in results if not ok] failed = [h for h, ok in results if not ok]
print() print()
if failed: if failed: