HAL 0.4.0: 통합 설정 관제 — Webmaker·AriMail·Agent 서버 단위 설정을 HAL 이 관리(설정 목록·범위 global/server·비밀값 Vault·유효값 hash, /ops/api/settings·재인증, settings.apply → settings.apply.target → Agent module.configure(HMAC 설정 받기·hash 확인·hal-managed.json 0600·재시작·모듈 적용 확인), /ops/settings 화면·운영 현황 "설정 적용 필요", AI 도구 hal_settings_get/set/apply(비밀값 거부)), 도입 모듈 Webmaker 1.9.0·AriMail 1.1.0(HAL 0.4.0 대응 halCompat, hal-managed 적용·관리 항목 409 managed_by_hal 잠금·"HAL 관리" 표시) 재도입(pin 8f8716c·f959b65, import-sources 미수정 파일 갱신), Agent heartbeat 관리, module-as-user write --mode 600, 개발 지시 v0.4.0(Oz)·docs/HAL-SETTINGS.md·VERSION_HISTORY 0.4.0 — test/hal-040.test.mjs RED → GREEN 5/5, agent 11/11, 전체 31파일 통과
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
54db663531
commit
9f1e490b51
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# 사용: module-as-user.sh <하위 명령> --app-dir <모듈 디렉터리> [인자…]
|
||||
# extract --tgz <artifact.tar.gz> --dest <appDir/releases/<ver>> 릴리스 디렉터리를 비우고 artifact 를 푼다
|
||||
# write --file <appDir 아래 파일> 표준 입력을 파일로 쓴다(REVISION.json·.previous.json)
|
||||
# write --file <appDir 아래 파일> [--mode 600] 표준 입력을 파일로 쓴다(REVISION.json·.previous.json · 0.4.0 hal-managed.json 은 --mode 600)
|
||||
# switch --link <appDir/current> --target <릴리스 디렉터리> 심링크 원자 교체(ln → mv -T)
|
||||
# rename --dir <releases 아래 디렉터리> --target <releases 아래 새 이름> 디렉터리 이름 바꾸기(같은 버전 재설치 때 실행 중인 디렉터리 보존)
|
||||
# remove --dir <appDir/releases/<old>> 오래된 릴리스 삭제(releases 아래만)
|
||||
@@ -16,9 +16,9 @@
|
||||
# migrate --cwd <릴리스 디렉터리> --script <상대 경로> [--env-file <f>] [--node <node>] EnvironmentFile 을 읽어 마이그레이션 실행
|
||||
set -euo pipefail
|
||||
SUB="${1:-}"; shift || true
|
||||
APP_DIR=""; TGZ=""; DEST=""; FILE=""; LINK=""; TARGET=""; DIR=""; DB=""; OUT=""; NODE_BIN=""; CWD=""; SCRIPT=""; ENV_FILE=""
|
||||
MODE=""; APP_DIR=""; TGZ=""; DEST=""; FILE=""; LINK=""; TARGET=""; DIR=""; DB=""; OUT=""; NODE_BIN=""; CWD=""; SCRIPT=""; ENV_FILE=""
|
||||
while [ $# -gt 0 ]; do case "$1" in
|
||||
--app-dir) APP_DIR="$2"; shift 2;; --tgz) TGZ="$2"; shift 2;; --dest) DEST="$2"; shift 2;; --file) FILE="$2"; shift 2;; --link) LINK="$2"; shift 2;; --target) TARGET="$2"; shift 2;;
|
||||
--app-dir) APP_DIR="$2"; shift 2;; --mode) MODE="$2"; shift 2;; --tgz) TGZ="$2"; shift 2;; --dest) DEST="$2"; shift 2;; --file) FILE="$2"; shift 2;; --link) LINK="$2"; shift 2;; --target) TARGET="$2"; shift 2;;
|
||||
--dir) DIR="$2"; shift 2;; --db) DB="$2"; shift 2;; --out) OUT="$2"; shift 2;; --node) NODE_BIN="$2"; shift 2;; --cwd) CWD="$2"; shift 2;; --script) SCRIPT="$2"; shift 2;; --env-file) ENV_FILE="$2"; shift 2;;
|
||||
*) echo "알 수 없는 인자 $1" >&2; exit 2;; esac; done
|
||||
[ -n "$APP_DIR" ] && [ -d "$APP_DIR" ] || { echo "--app-dir <존재하는 디렉터리> 가 필요합니다" >&2; exit 2; }
|
||||
@@ -31,7 +31,10 @@ case "$SUB" in
|
||||
[ -f "$TGZ" ] || { echo "artifact 가 없습니다: $TGZ" >&2; exit 2; }; inside "$DEST"; case "$DEST" in "$APP_DIR"/releases/*) ;; *) echo "--dest 는 releases 아래여야 합니다" >&2; exit 3;; esac
|
||||
rm -rf "$DEST"; mkdir -p "$DEST"; tar -xzf "$TGZ" -C "$DEST"; echo "extracted $DEST";;
|
||||
write)
|
||||
inside "$FILE"; mkdir -p "$(dirname "$FILE")"; tmp="$FILE.tmp-$$"; cat > "$tmp"; mv -f "$tmp" "$FILE"; echo "written $FILE";;
|
||||
# --mode 600(0.4.0): 비밀값이 든 파일(hal-managed.json)은 처음부터 그 계정만 읽게 만든다(umask 077 → chmod 600 → 원자 교체)
|
||||
inside "$FILE"; mkdir -p "$(dirname "$FILE")"; tmp="$FILE.tmp-$$"
|
||||
if [ "$MODE" = "600" ]; then ( umask 077; cat > "$tmp" ); chmod 600 "$tmp"; elif [ -n "$MODE" ]; then echo "--mode 는 600 만 허용합니다" >&2; exit 2; else cat > "$tmp"; fi
|
||||
mv -f "$tmp" "$FILE"; echo "written $FILE";;
|
||||
switch)
|
||||
inside "$LINK"; inside "$TARGET"; [ -d "$TARGET" ] || { echo "대상 디렉터리가 없습니다: $TARGET" >&2; exit 2; }
|
||||
ln -sfn "$TARGET" "$LINK.tmp-$$"; mv -Tf "$LINK.tmp-$$" "$LINK"; echo "switched $LINK -> $TARGET";;
|
||||
|
||||
Reference in New Issue
Block a user