fix(dev): dev ls/down 런타임 인지(런타임 컬럼 + docker·podman 모두) — 0.21.4

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 18:16:34 +09:00
parent 53881b85ae
commit 922f8157fd

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.21.3" VERSION="0.21.4"
# 로컬 개발 클러스터(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}"
@ -568,46 +568,65 @@ _dev_deregister() {
return 0 return 0
} }
# 로컬 dev 클러스터 목록 — kind 이름 / --name / 콘솔 등록명 매핑. 파괴적 명령(down) 전 대상 확인용. # 사용 가능한 런타임(docker·podman) 전체에서 yak-* kind 클러스터 나열 — "<runtime> <cluster>" 줄.
# 여러 런타임을 섞어 써도 한 번에 보이도록(감지된 하나만 보던 문제).
_dev_all_clusters() {
local rt kenv cs c
for rt in docker podman; do
command -v "$rt" >/dev/null 2>&1 || continue
"$rt" ps -q >/dev/null 2>&1 || continue # 데몬/머신 미동작이면 스킵
kenv=""; [ "$rt" = podman ] && kenv="KIND_EXPERIMENTAL_PROVIDER=podman"
cs="$(env $kenv kind get clusters 2>/dev/null | grep '^yak-' || true)"
while IFS= read -r c; do [ -n "$c" ] && echo "$rt $c"; done <<EOF
$cs
EOF
done
}
# 로컬 dev 클러스터 목록 — 런타임 / kind 이름 / --name / 콘솔 등록명 매핑. 파괴적 명령(down) 전 대상 확인용.
# 콘솔에 보이는 '등록명'(예 imac192)이 아니라 여기 '--name'(예 dev) 으로 지정해야 한다. # 콘솔에 보이는 '등록명'(예 imac192)이 아니라 여기 '--name'(예 dev) 으로 지정해야 한다.
cmd_dev_ls() { cmd_dev_ls() {
command -v kind >/dev/null 2>&1 || die "kind 필요" command -v kind >/dev/null 2>&1 || die "kind 필요"
local rt kenv=""; rt="$(_dev_runtime)"; [ "$rt" = podman ] && kenv="KIND_EXPERIMENTAL_PROVIDER=podman" local all; all="$(_dev_all_clusters)"
local cs; cs="$(env $kenv kind get clusters 2>/dev/null | grep '^yak-' || true)" [ -z "$all" ] && { echo "로컬 dev 클러스터 없음 — 'yakcloud dev up' 으로 생성."; return 0; }
[ -z "$cs" ] && { echo "로컬 dev 클러스터 없음 — 'yakcloud dev up' 으로 생성."; return 0; } printf " %-9s %-18s %-14s %s\n" "런타임" "kind 클러스터" "--name" "콘솔 등록명"
printf " %-18s %-14s %s\n" "kind 클러스터" "--name" "콘솔 등록명" local rt c nm
local c nm while read -r rt c; do
while IFS= read -r c; do
[ -z "$c" ] && continue [ -z "$c" ] && continue
nm="${c#yak-}"; DEV_NAME="$nm" nm="${c#yak-}"; DEV_NAME="$nm"
printf " %-18s %-14s %s\n" "$c" "$nm" "$(_local_reg_name)" printf " %-9s %-18s %-14s %s\n" "$rt" "$c" "$nm" "$(_local_reg_name)"
done <<EOF done <<EOF
$cs $all
EOF EOF
} }
# 로컬 dev 클러스터 삭제 — 파괴적. 대상 안전 해석: --name 없으면 0/1/다수 판정, 없는 클러스터면 가짜 삭제 금지. # 로컬 dev 클러스터 삭제 — 파괴적. 대상 안전 해석: --name 없으면 0/1/다수 판정, 없는 클러스터면 가짜 삭제 금지.
# 런타임 교차 인지 — --name 이 docker·podman 어디에 있든 찾아 그 런타임으로 삭제.
cmd_dev_down() { cmd_dev_down() {
local name_given="$1" local name_given="$1"
command -v kind >/dev/null 2>&1 || die "kind 필요" command -v kind >/dev/null 2>&1 || die "kind 필요"
local rt kenv=""; rt="$(_dev_runtime)"; [ "$rt" = podman ] && kenv="KIND_EXPERIMENTAL_PROVIDER=podman" local all; all="$(_dev_all_clusters)" # "<rt> <cluster>" 줄들(양쪽 런타임)
local rt=""
if [ "$name_given" = 0 ]; then if [ "$name_given" = 0 ]; then
# --name 미지정: 정확히 하나면 그것, 여럿이면 지정 요구(엉뚱한 삭제 방지). 매니페스트 자동선택 안 함(파괴적). local n; n="$(printf '%s\n' "$all" | grep -c . 2>/dev/null || echo 0)"
local all n; all="$(env $kenv kind get clusters 2>/dev/null | grep '^yak-' || true)"
n="$(printf '%s\n' "$all" | grep -c . 2>/dev/null || echo 0)"
if [ "$n" -eq 0 ]; then die "로컬 dev 클러스터가 없습니다 — 'yakcloud dev ls'."; fi if [ "$n" -eq 0 ]; then die "로컬 dev 클러스터가 없습니다 — 'yakcloud dev ls'."; fi
if [ "$n" -gt 1 ]; then if [ "$n" -gt 1 ]; then
echo "로컬 클러스터가 여러 개입니다 — 삭제할 것을 --name 으로 지정하세요:"; echo; cmd_dev_ls echo "로컬 클러스터가 여러 개입니다 — 삭제할 것을 --name 으로 지정하세요:"; echo; cmd_dev_ls
die "예: yakcloud dev down --name <이름>" die "예: yakcloud dev down --name <이름>"
fi fi
DEV_CLUSTER="$(printf '%s' "$all" | head -1)"; DEV_NAME="${DEV_CLUSTER#yak-}"; DEV_CTX="kind-$DEV_CLUSTER" rt="$(printf '%s' "$all" | awk '{print $1}')"; DEV_CLUSTER="$(printf '%s' "$all" | awk '{print $2}')"
fi DEV_NAME="${DEV_CLUSTER#yak-}"; DEV_CTX="kind-$DEV_CLUSTER"
# 존재 확인 — 없으면 가짜 삭제/해제 금지(오타·'등록명 vs --name' 혼동 방지). else
if ! env $kenv kind get clusters 2>/dev/null | grep -qx "$DEV_CLUSTER"; then # --name 지정: 양쪽 런타임에서 yak-<name> 찾기(없으면 가짜 삭제 금지).
local line; line="$(printf '%s\n' "$all" | awk -v c="$DEV_CLUSTER" '$2==c{print; exit}')"
if [ -z "$line" ]; then
echo "로컬 클러스터 '$DEV_CLUSTER' (--name $DEV_NAME) 이(가) 없습니다."; echo; cmd_dev_ls echo "로컬 클러스터 '$DEV_CLUSTER' (--name $DEV_NAME) 이(가) 없습니다."; echo; cmd_dev_ls
die "콘솔 '등록명'(예 imac192)이 아니라 위 '--name' 값으로 지정하세요." die "콘솔 '등록명'(예 imac192)이 아니라 위 '--name' 값으로 지정하세요."
fi fi
info "kind 클러스터 '$DEV_CLUSTER' 삭제 (콘솔 등록명 '$(_local_reg_name)')" rt="$(printf '%s' "$line" | awk '{print $1}')"
fi
local kenv=""; [ "$rt" = podman ] && kenv="KIND_EXPERIMENTAL_PROVIDER=podman"
info "kind 클러스터 '$DEV_CLUSTER' 삭제 [$rt] (콘솔 등록명 '$(_local_reg_name)')…"
env $kenv kind delete cluster --name "$DEV_CLUSTER" && echo "✓ 삭제 완료" env $kenv kind delete cluster --name "$DEV_CLUSTER" && echo "✓ 삭제 완료"
# 이 클러스터의 릴레이 에이전트만 정리(pidfile <name>.pid, 클러스터 단위). 다른 dev 클러스터는 건드리지 않음. # 이 클러스터의 릴레이 에이전트만 정리(pidfile <name>.pid, 클러스터 단위). 다른 dev 클러스터는 건드리지 않음.
local agd="${YAK_CONFIG_DIR:-$HOME/.config/yakcloud}/agent" local agd="${YAK_CONFIG_DIR:-$HOME/.config/yakcloud}/agent"