11 KiB
11 KiB
운영자 콘솔 "부트스트랩 미완료" 배너 결함 수정·배포 검증 기록 — 2026-10-27 (bear hal21.ariweb.net, Hera)
비밀값(토큰·비밀번호·Vault 값·운영자 자격)은 이 문서에 없다. 시각은 UTC.
1. 증상과 원인
- 오즈 보고: HAL21 운영 콘솔 모든 화면 상단에
! 부트스트랩 미완료(HAL 실행 버전 확인 전, 첫 Agent 미등록)…경고가 계속 보임. - 실제 readback(수정 전, 14:2xZ
curl http://127.0.0.1:8900/api/health):bootstrap.complete=true · halRunningVersion=0.1.1 · firstAgent=ag_01a17bd7201c9a73c157e29968 · manualInstallLocked=true, Agent 2대 active. - 원인(코드):
hal/ui.mjsshell 배너가core.selfHealth(d).bootstrap의 실제 계약(camelCasecomplete·halRunningVersion·firstAgent,hal/core.mjsselfHealth)이 아니라 존재하지 않는 snake_casecompleted_at·hal_running_version·first_agent_id를 읽어 항상undefined→ "미완료·확인 전·미등록". 같은 파일/ops/releases라우트는releasesView(hal/ui/render.mjs, bootstrap 행의hal_running_version·manual_install_locked기대)에 camelCase 객체를 넘겨HAL 실행 버전: 확인 전 · 부트스트랩 미완료로 그려짐. - 서버 렌더(HTML) 결함이다.
hal/ui/public/ops.js·ops.css는 bootstrap 필드를 읽지 않으며(grep 0건) 변경하지 않았다 → 브라우저 캐시와 무관.
2. RED (수정 전 실패 증명)
- 회귀 테스트
test/hal-ui.test.mjs"부트스트랩 배너는 selfHealth().bootstrap 의 실제 계약…": (0)selfHealth.bootstrap에 snake_case 필드가 없음을 고정 (1) 초기확인 전·미등록(2)core.claimLive뒤HAL 실행 버전 0.1.1, 첫 Agent 미등록(3) 첫 Agent 등록(POST /agent/v1/register)·core.approveServer→ 완료 뒤/ops/·/ops/servers·/ops/releases에 경고 없음 + 릴리스 화면HAL 실행 버전: <b>0.1.1</b> · 수동 설치 잠김(4) Agent 만 승인된 새 HAL 은확인 전·등록됨. - 수정 전 실행 결과(
node --no-warnings test/hal-ui.test.mjs): 통과 6 · 실패 1 —Error: 실행 버전 0.1.1 표시: 부트스트랩 미완료(HAL 실행 버전 확인 전, 첫 Agent 미등록) (실제 false)(test/hal-ui.test.mjs:50). - 완료 상태 증상도 수정 전 코드로 기록(scratchpad
g7/red-evidence.mjs):selfHealth.bootstrap.complete=true인데/ops/배너부트스트랩 미완료(HAL 실행 버전 확인 전, 첫 Agent 미등록),/ops/releasesHAL 실행 버전: <b>확인 전</b>.
3. GREEN (수정, hal/ui.mjs 만 2곳)
- 배너:
!health.bootstrap.complete/health.bootstrap.halRunningVersion/health.bootstrap.firstAgent. /ops/releases:running: core.bootstrapState(d)(렌더러가 기대하는 bootstrap 행). snake_case fallback 없음, 다른 기능 변경 없음.- 수정 뒤
test/hal-ui.test.mjs통과 7 · 실패 0.
4. 리비전·테스트·빌드
| 항목 | 값 |
|---|---|
작업 시작 origin/main = HEAD(fetch 뒤 동일, worktree clean — e2e 테스트가 재생성한 docs/verification/local-e2e-2026-10-27.* 는 HEAD 로 복원) |
d8e7beeb861ae5edb45fd56d6950fd8a50ba204e |
수정 커밋(hal/ui.mjs + test/hal-ui.test.mjs + VERSION_HISTORY, author Hera (헤라) <hera@mp.local>) |
648247f2241579e947d61ab2928176f678f4b141 |
전체 테스트 node test/run.mjs(수정 뒤, 2m37s) |
22파일 150건 통과 · 실패 0(기존 149 + 신규 1) |
release build(scripts/release.mjs build, 커밋 648247f, 테스트 재실행 150건) |
0.1.1, testsPassed=true, dirty=false; verify 5 artifact ✔ |
| hal artifact sha256 | ed957a0aeb8f065085e3163cf3f367a240e90b55f6221844c93fa4404de8512f (portal 32c76a60…, agent cf2e52fe…, webmaker 9490b59d…, arimail b22868c0… 는 이전 빌드와 동일) |
bash -n deploy/*.sh |
4개 통과(agent-install·bootstrap-hal·hal-restore·module-as-user); shellcheck 미설치 |
소스 hal/ui.mjs sha256 |
904059364106888cab17609e3e9f743d96ea239bae87c0af856980a673eed92d |
5. bear 배포 (코드 릴리스만, data/config/DB/Vault 무변경)
- 사전 상태: current
/srv/ariweb/hal/releases/0.1.1-dfb708e933e5, PID 1792203(14:21:13Z 다른 세션의 opsAllowCidrs 변경·재시작, config.jsonupdatedBy cli:hera-ops-access14:21:12Z,config.json.pre-ops-cidrs-20261027T142020Z존재). - 사설 백업
/srv/ariweb/backups/hal-pre-banner-fix-20261027T143608Z/(root 0700, 파일 0600,sha256sum -cOK, stage 추출 검증 halVault 4·integrity ok·servers 2·configKeys [publicUrl, portalUrl, opsAllowCidrs], 경로 검증 6/6): archive.tgz5c0e91f8530403061adf108ec1dbcab684c58854ccd7b60eed20e08aa81490c3(7: config.json·pre-ops-cidrs 사본·vault.json·vault.key·unit·nginx conf), db.tgz5182f1a65bb99d8dc084590e3993408fc7dd2129998be14bd536ec03e21c7bd0(hal.sqlite VACUUM 835,584 B, integrity ok, 28표: servers 2·agents 2·releases 1·jobs 4·agent_jobs 2·mail_services 7), code.tgz0ec00cb9c4698e4e228d31ffa5432ab0a55e6847da1ff8db721700b1e165b73a(81, 0.1.1-dfb708e933e5), meta.tgz75d7ff23f1ebeeccb7ad8da8518c5bbe440c39bd4088197a2d3e236a7d466166, RESTORE.md78769ba25e4033a310d9b5c348863946603130fc430ed8356713758e3eaaa1f7, hal-verify.json2435b0eb87252cb42a589d98a83b55442f3720c898e51b08c3e81ce1e8d4148d. - 적용(
~/hera-deploy/bear-apply-g7.sh, 14:36:34Z): artifact sha 확인 OK →/srv/ariweb/hal/releases/0.1.1-648247f22415추출 → stage 검증: 추출된hal/ui.mjssha256 = 소스(90405936…) OK,node --checkOK,health.bootstrap.complete참조 1, snake_case 참조 0 →REVISION.json(by hera-ops-banner-fix) →register-release --manifest … --approve --by hera-ops-banner-fix(릴리스 0.1.1 approved, 감사 release.register·release.approve 14:36:34.403Z) →bootstrap-release --version 0.1.1 --commit 648247f… --sha256 ed957a0a…→ln -sfncurrent 전환 →systemctl restart ariweb-hal. config-set 없음. - 결과: restart→health 1.08초, PID 1816086, ActiveState active, NRestarts 0, ActiveEnter 14:36:35Z, 프로세스 cwd
/proc/<pid>/cwd=/srv/ariweb/hal/releases/0.1.1-648247f22415, journal 오류 0, 기동 로그 "부트스트랩 완료". - 보존 확인(sha256 전=후): config.json
ae5963d29ae899bc77fcb7c03df7d5802bd493b61fc4b2ab2b7a263a525ba0b7, vault.json0e2dc9875f2779a0e7a3c1a56c00321dd2a45b0613a3952b62a8c7505be50bb7, vault.key345d92e77c3fcd7853b01024d4aaa3f07d27977ea04a30a287070048afe1bf81; config readbackopsAllowCidrs=["127.0.0.1/32","::1/128","192.168.10.0/24","192.168.20.0/24","119.203.225.42/32"], publicUrlhttps://hal21.ariweb.net, portalUrlhttps://my.ariweb.net, updatedAt 14:21:12.623Z 그대로. data 디렉터리 0700, hal.sqlite 860,160 B·wal 4,132,392 B·shm 32,768 B 그대로. 이전 릴리스 디렉터리 전부 보존(0.1.1, -12958ab6952e, -79b45ca96102, -ac072e6f12a9, -dfb708e933e5).
6. readback
/api/health(로컬·https://hal21.ariweb.net): ok, version 0.1.1, db true, jobs true, bootstrapcomplete=true · releaseVersion 0.1.1 · mainCommit 648247f2241579e947d61ab2928176f678f4b141 · artifactSha256 ed957a0a… · halRunningVersion 0.1.1 · firstAgent ag_01a17bd7201c9a73c157e29968 · manualInstallLocked=true, instanceIdhal_01a17dcaa5d2cb7866a47b3fa3.- HAL DB(읽기 전용): bootstrap_state
release_version 0.1.1 · main_commit 648247f… · hal_running_version 0.1.1 · hal_started_at 14:36:35.156Z · first_agent_id ag_01a17bd7… · completed_at 07:21:53.139Z · manual_install_locked 1; releases 1행 0.1.1 approved by hera-ops-banner-fix(hal_deployed_at null — module.deploy hal 작업이 아닌 CLI bootstrap-release 경로, 이전과 동일); 열린 작업 0; mail_services 7. - Agent heartbeat: 서버 2대 ready, last_seen 14:36:59.073Z(hostinger ag_01a17c99…)·14:36:59.619Z(jitsi ag_01a17bd7…) — 재시작(14:36:35Z) 뒤 재개, 14:38:10Z 까지 heartbeat 6회(bear nginx log). 재시작 순간 Agent long-poll
GET /agent/v1/jobs/next?wait=25502 1회(14:36:35Z, 재시작 창) 외 Agent 요청 비-2xx 없음. - 배포된 코드 서버 렌더 검증(운영자 자격 없음 →
~/hera-deploy/deployed-render.mjs가/srv/ariweb/hal/current의 app/deps/core 만 import, in-memory DB·임시 data dir, 운영 데이터·Vault 미접근): 초기부트스트랩 미완료(HAL 실행 버전 확인 전, 첫 Agent 미등록)→ claimLive 뒤(HAL 실행 버전 0.1.1, 첫 Agent 미등록)→ 첫 Agent 등록·승인(complete=true) 뒤/ops/·/ops/servers·/ops/releases모두 배너 없음, 릴리스 화면HAL 실행 버전: <b>0.1.1</b> · 수동 설치 잠김(HAL 전용 운영). - 외부(14:37Z):
https://hal21.ariweb.net/api/health200 ·/ops/200(세션 없음 → 로그인 화면, 본문에 "부트스트랩 미완료" 0건) ·/ops/login200 ·/portal/v1/health무인증 401; TLS CN=hal21.ariweb.net 만료 2027-01-25, verify 0. - 회귀:
https://my.ariweb.net/api/health200 ok 0.1.1(로컬 8910 동일),/302→/login,/login200, http→https 301; hostinger 유닛 ariweb-portal 1500968·ariweb-agent 1483523·webmaker 1041361·arihakdang-mail 1046648·nginx 1414934·(구) ariweb-hal 1059540 모두 active NRestarts 0,nginx -t성공, Agent/포털 journal 오류 0(14:36Z 이후);https://webmaker.ariweb.net/302(첫 프로브 4.5~5.0초, 이후 0.29초 — hostinger 측 콜드 응답, HAL 무관);https://mail.arihakdang.com/200·/api/healthok 1.0.11 domains 6;https://webmail.ibit.kr/200·ok 1.0.11 domains 1.
7. 되돌리기
- 코드만:
ln -sfn /srv/ariweb/hal/releases/0.1.1-dfb708e933e5 /srv/ariweb/hal/current && sudo systemctl restart ariweb-hal(이전 릴리스 디렉터리 보존됨). 릴리스 행·bootstrap 행의 main_commit/artifact 는cd /srv/ariweb/hal/releases/0.1.1-dfb708e933e5 && ARIWEB_HAL_DATA=/srv/ariweb/hal/data node hal/index.mjs register-release --manifest ~/hera-deploy/dist-dfb708e/manifest.json --approve --by <who> && node hal/index.mjs bootstrap-release --version 0.1.1 --commit dfb708e933e524894822719bce0169008285f4fd --sha256 4e419a7293dc5be07936db58c8cf70dc1c7972f52c11787a9455029eff677377. - 데이터까지:
/srv/ariweb/backups/hal-pre-banner-fix-20261027T143608Z/RESTORE.md(검증sudo sha256sum -c SHA256SUMS).
8. blocker / unknown
- 운영자 자격 증명이 없어 실제 운영자 세션으로 콘솔 화면을 열어 보지는 못했다 — 배포된 코드의 서버 렌더 harness(§6)와 회귀 테스트, 배포 파일 sha 일치로 판단. 오즈가 로그인하면 경고가 보이지 않아야 한다(서버 렌더이므로 새로고침만으로 충분, 캐시 삭제 불필요).
releases.hal_deployed_at은 null(HAL 자체는 module.deploy 작업이 아니라 CLI bootstrap-release + current 전환으로 교체) — 이전 배포와 같은 방식.