Files

4.1 KiB

포털 ↔ HAL 작업 계약(HAL-JOBS)

포털 어댑터 portal/hal/client.mjs(deps.hal) 와 HAL /portal/v1/* 가 공유하는 계약. 인증은 lib/serviceauth(키 id portal).

deps.hal (포털 쪽 인터페이스)

hal.createJob({ kind, target, payload, idempotencyKey, groupId, subjectType, subjectId }) → { halJobId, status }
hal.getJob(halJobId) → { id, kind, status(lib/status JOB_STATUS 코드), steps:[{id,title,state,detail}], progress, result, error, errorCode, updatedAt, children? }
hal.cancelJob(halJobId) / hal.retryJob(halJobId) / hal.revertJob(halJobId) / hal.resumeJob(halJobId)
hal.listServers({ role }) → [{ id, name, role:'web'|'mail'|'backup'|'control', location, status:'ready'|'maintenance'|'isolated'|'offline', acceptsNew, health, lastSeenAt, capacity:{ diskFreeBytes, diskTotalBytes, memFreeBytes, cpuLoad, sitesHosted, reservedBytes }, version:{ agent, modules:{} } }]
hal.pickServer({ role:'web', needBytes }) → { serverId } | null   // 신규 배치 허용·여유 있는 서버
hal.issueExternalAgentToken({ groupId, siteId, label }) → { agentId, token(1회), expiresAt, installCommand }
hal.getExternalAgent(agentId) → { id, status:'pending'|'connected'|'offline'|'revoked', lastSeenAt, version, lastDeploy:{...} }
hal.revokeExternalAgent(agentId)
hal.health() → { ok, version, uptime }   // 실패 시 code 'service_unreachable'

HAL 이 응답하지 않으면 어댑터는 service_unreachable 을 던지고 호출자는 정보 확인 지연 을 표시하며 신규 증가를 허용하지 않는다. HAL 은 작업 상태 변화를 포털 POST /internal/hal-events (키 id hal) 로 민다: { halJobId, status, steps, result, error, updatedAt }. 포털은 5초 주기 조회로도 맞춘다.

작업 종류와 payload (target = 관리 서버 id 또는 외부 Agent id)

kind payload result
site.deploy `{ siteId, versionRef, bundleUrl(포털이 Webmaker 저장본을 tar.gz 로 내놓는 서명 URL) 또는 bundleFromWebmaker:{projectId, versionRef}, runtime:'static' 'node', env:{}, domains:[...], primaryDomain, previousVersion, external:bool }`
site.rollback { siteId, toVersion } { version }
site.remove { siteId, keepData:bool } { removed:true, leftovers:[] }
site.check { siteId, urls:[...], expectMarker } { checks:[{url,status,ok,ms,tls:{valid,expiresAt}}] }
site.usage { siteIds:[...] } { sites:{ [siteId]: { diskBytes, dbBytes, uploadsBytes, outBytesDay, outBytesMonth, outBytesTotal, inBytesDay, inBytesMonth, inBytesTotal, req24h, pv24h, series7d:[...], series30d:[...], errorRate, p95ms, measuredAt } } }
domain.vhost { siteId, domains:[...], primaryDomain, redirectOld:bool, maintenance:bool } { applied:[...], certs:{domain:{state,expiresAt}} }
domain.cert { siteId, domains:[...], email } { issued:[...], failed:[{domain,reason}], expiresAt }
domain.probe { name, expectA:[...], expectTxt:{name,value}? } { a:[...], txtOk, resolvedAt }
backup.create { siteId, scope:{files,db,uploads,config}, storeServerId, retentionTag } { backupId, location, sizeBytes, checksum, verified:true, createdAt }
backup.verify { location, checksum } { ok }
backup.restore { siteId, location, checksum, protectPoint:true, isolatedVerify:true } { protectPointLocation, restoredVersion, externalCheck }
backup.delete { location } { deleted }
site.relocate `{ siteId, fromServerId, toServerId, kind:'static' 'dynamic', writeFreeze:bool, domains, primaryDomain }`
module.deploy / module.update / module.rollback / module.health HAL 내부(운영자 콘솔) 대상별 자식 작업

External Pull Agent(외부 서버)는 site.deploy·site.remove·site.check 만 받는다.