diff --git a/.yakcloud/agent.py b/.yakcloud/agent.py index 6e9babe..c141446 100644 --- a/.yakcloud/agent.py +++ b/.yakcloud/agent.py @@ -369,7 +369,8 @@ def _h_kube(action: str, params: dict) -> dict: except (ValueError, ZeroDivisionError, TypeError): pass out.append({ - "name": name, "roles": roles or ["control-plane"], "joined": ready, "ready": ready, + # kind 워커는 node-role 라벨이 없음 → role 없으면 worker(과거 control-plane fallback 은 워커를 CP 로 오분류). + "name": name, "roles": roles or ["worker"], "joined": ready, "ready": ready, "pending": False, "maas_status": None, # kind 노드 — MAAS 프로비저닝 개념 없음 "phase": "Ready" if ready else "NotReady", # NodeMetricDTO.phase(필수) — 상태 배지 "cpu_cap": round(_cpu_m(cap.get("cpu")) / 1000.0, 2), "cpu_alloc": cpu_alloc, diff --git a/bin/yakcloud b/bin/yakcloud index fd026d5..bddba98 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.22.0" +VERSION="0.22.1" # 로컬 개발 클러스터(kind) — 개발 후 운영까지 '직선 배포'의 dev 구간. DEV_CTX="${YAK_DEV_CONTEXT:-kind-yak-dev}" DEV_CLUSTER="${YAK_DEV_CLUSTER:-yak-dev}" @@ -192,12 +192,13 @@ cmd_project_init() { # 매니페스트 채우기 마법사 — ctl 은 API 미접속(YAKCLOUD_TOKEN 비움)으로 매니페스트만 편집. _init_wizard() { - local dflt_app="$1" app devc devp valc prodc pdom port health cpu mem reps path kv + local dflt_app="$1" app devc devp devw valc prodc pdom port health cpu mem reps path kv echo "── 프로젝트 설정 (엔터=기본값) · 개발(로컬 kind) → 검증/운영(관리형) ──" printf "앱 이름 [%s]: " "$dflt_app"; read -r app; app="$(_sanitize_name "${app:-$dflt_app}")" printf "개발 클러스터 = 로컬 kind, 이름 [dev]: "; read -r devc; devc="$(_sanitize_name "${devc:-dev}")" devp=80 if [ "$devc" != "dev" ]; then printf "로컬 인그레스 포트 [8080]: "; read -r devp; devp="${devp:-8080}"; fi + printf "워커 노드 수 [1]: "; read -r devw; devw="${devw:-1}"; case "$devw" in ''|*[!0-9]*) devw=1 ;; esac printf "검증 클러스터(관리형, 선택, 엔터=생략): "; read -r valc printf "운영 클러스터(관리형, 선택, 엔터=생략): "; read -r prodc printf "운영 도메인(선택, 예 app.example.com): "; read -r pdom @@ -209,8 +210,8 @@ _init_wizard() { printf "노출 경로(ingress path) [/]: "; read -r path; path="${path:-/}" sed -i.bak "s/my-app/$app/g" yakcloud.yaml && rm -f yakcloud.yaml.bak # project·워크로드명·image = 앱(프로젝트)명 [ -n "${GITEA_USER:-}" ] && { sed -i.bak "s#CHANGE_ME_GITEA_USER#${GITEA_USER}#" yakcloud.yaml 2>/dev/null; rm -f yakcloud.yaml.bak; } - # dev = 로컬 kind: environments.dev 줄의 cluster/port 를 치환(주석·나머지 보존). - sed -i.bak -E "s#^( dev:[[:space:]]*\{ cluster: )[^,}]*(, port: )[0-9]+#\1$devc\2$devp#" yakcloud.yaml && rm -f yakcloud.yaml.bak + # dev = 로컬 kind: environments.dev 줄 전체를 입력값(cluster/port/workers)으로 재작성. (구분자 | — 치환문의 # 주석과 충돌 회피) + sed -i.bak -E "s|^ dev:.*| dev: { cluster: $devc, port: $devp, workers: $devw } # 로컬 kind (project deploy)|" yakcloud.yaml && rm -f yakcloud.yaml.bak [ -n "$prodc" ] && { sed -i.bak "s#my-prod-cluster#$prodc#" yakcloud.yaml && rm -f yakcloud.yaml.bak; } [ -n "$pdom" ] && { sed -i.bak "s#domains: \[\]#domains: [$pdom]#" yakcloud.yaml && rm -f yakcloud.yaml.bak; } if [ -n "$valc" ]; then sed -i.bak "s#my-val-cluster#$valc#" yakcloud.yaml && rm -f yakcloud.yaml.bak @@ -226,7 +227,7 @@ _init_wizard() { printf " env> "; read -r kv || break; [ -z "$kv" ] && break YAKCLOUD_TOKEN= python3 "$(_engine ctl)" env "$app" "$kv" >/dev/null 2>&1 || echo " (형식: KEY=VALUE)" done - echo "✓ 매니페스트 반영: app=$app · dev(로컬 kind)=$devc:$devp · val=${valc:-<생략>} · prod=${prodc:-<생략>} · port=$port path=$path cpu=$cpu mem=$mem replicas=$reps" + echo "✓ 매니페스트 반영: app=$app · dev(로컬 kind)=$devc:$devp(워커 $devw) · val=${valc:-<생략>} · prod=${prodc:-<생략>} · port=$port path=$path cpu=$cpu mem=$mem replicas=$reps" } _maybe_login_prompt() { diff --git a/yakcloud.yaml b/yakcloud.yaml index 0b2a72a..94be62c 100644 --- a/yakcloud.yaml +++ b/yakcloud.yaml @@ -12,7 +12,7 @@ project: my-app # 프로젝트 이름(이미지 경로/표 # val/prod = **관리형**. yakcloud project promote --to val|prod → 이미지 build+push(이미 있으면 재빌드 없이) 후 리컨실 + 도메인. # (기본 도메인 c-xxxx.yakenator.io 은 자동. 운영 커스텀 도메인은 prod.domains 에.) environments: - dev: { cluster: dev, port: 80 } # 로컬 kind (project deploy). cluster=로컬 이름, port=인그레스 포트(이름!=dev면 비80). 워커 추가는 workers: N (기본 0=CP만) + dev: { cluster: dev, port: 80, workers: 1 } # 로컬 kind (project deploy). cluster=로컬 이름, port=인그레스 포트(이름!=dev면 비80), workers=워커 노드 수(0=CP만) val: { cluster: my-val-cluster } # 관리형 (promote --to val) prod: { cluster: my-prod-cluster, domains: [] } # 관리형 (promote --to prod, domains 예: [app.example.com])