diff --git a/bin/yakcloud b/bin/yakcloud index e8b3bbf..d834d1c 100755 --- a/bin/yakcloud +++ b/bin/yakcloud @@ -16,7 +16,7 @@ set -uo pipefail # -e 미사용: 'test && action' 관용구가 값 없을 때 REPO="${YAKCLOUD_STARTER_REPO:-https://gitea.yakenator.io/yakenator/yakcloud-starter}" BRANCH="${YAKCLOUD_STARTER_BRANCH:-main}" -VERSION="0.16.0" +VERSION="0.17.0" # 로컬 개발 클러스터(kind) — 개발 후 운영까지 '직선 배포'의 dev 구간. DEV_CTX="${YAK_DEV_CONTEXT:-kind-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 local pysub="$sub"; [ "$sub" = clean ] && pysub="down" 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 ;; down) diff --git a/scripts/yakcloud_dev.py b/scripts/yakcloud_dev.py index 922098c..b3d2ccf 100644 --- a/scripts/yakcloud_dev.py +++ b/scripts/yakcloud_dev.py @@ -26,6 +26,7 @@ import os import secrets import subprocess import sys +import urllib.request from urllib.parse import quote 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) +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: context_ok() 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, "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] print() if failed: