feat(hololake): render bounded release front door config
This commit is contained in:
parent
9006075310
commit
461517c25f
6 changed files with 131 additions and 0 deletions
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"schema": "hololake.jd-release-public-path-acceptance-receipt/v1",
|
||||||
|
"receiptId": "GH-HOLOLAKE-JD-RELEASE-PUBLIC-PATH-20260813-004",
|
||||||
|
"observedAt": "2026-08-13T19:13:32+08:00",
|
||||||
|
"state": "JD_LOOPBACK_PUBLIC_NAMESPACE_READY_FRONT_DOOR_NOT_DEPLOYED",
|
||||||
|
"target": "JD-FD-PRIMARY",
|
||||||
|
"sourceCommit": "9006075310729cb7c266decff529066053969f18",
|
||||||
|
"immutableSourcePath": "/opt/guanghu/hololake-release-broadcast-candidate/9006075310729cb7c266decff529066053969f18",
|
||||||
|
"serverOwnedReceipt": "/var/lib/guanghu/architecture-provision/receipts/GH-HOLOLAKE-JD-RELEASE-PUBLIC-PATH-20260813-001.json",
|
||||||
|
"serverOwnedReceiptSha256": "923564c7f624921bcab247e9e27fc007953bbd6c06733356be1bdd9420f5ef1d",
|
||||||
|
"liveReadback": {
|
||||||
|
"serviceActive": true,
|
||||||
|
"serviceEnabled": true,
|
||||||
|
"listener": "127.0.0.1:3940",
|
||||||
|
"publicPathPrefix": "/hololake/releases",
|
||||||
|
"releaseEndpointPath": "/hololake/releases/latest.json",
|
||||||
|
"legacyLatestStatus": 204,
|
||||||
|
"publicLatestStatus": 204,
|
||||||
|
"broadcastState": "EMPTY_FAIL_CLOSED",
|
||||||
|
"updateAvailable": false,
|
||||||
|
"stateFileCount": 0,
|
||||||
|
"automaticUpload": false,
|
||||||
|
"automaticActivation": false,
|
||||||
|
"automaticRestart": false,
|
||||||
|
"existingDiscoveryServiceActive": true,
|
||||||
|
"existingLivingControllerActive": true,
|
||||||
|
"existingMotherBrainActive": true
|
||||||
|
},
|
||||||
|
"publicObservation": {
|
||||||
|
"url": "https://guanghulab.com/hololake/releases/latest.json",
|
||||||
|
"httpStatus": 200,
|
||||||
|
"contentType": "text/html",
|
||||||
|
"matchesReleaseProtocol": false,
|
||||||
|
"inference": "BS_GZ_006_HOMEPAGE_FALLBACK_NO_HOLOLAKE_PROXY"
|
||||||
|
},
|
||||||
|
"productionBoundary": {
|
||||||
|
"frontDoorLoopbackPortAssigned": false,
|
||||||
|
"frontDoorProxyDeployed": false,
|
||||||
|
"publicHttpsReleaseEndpointProvisioned": false,
|
||||||
|
"updaterPublicKeyProvisioned": false,
|
||||||
|
"desktopReleaseTrustProvisioned": false,
|
||||||
|
"publicDistributionReady": false,
|
||||||
|
"repositoryPublicationClaimed": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
"release_public_route_contract": "server/release-broadcast/public-route.json",
|
"release_public_route_contract": "server/release-broadcast/public-route.json",
|
||||||
"release_public_path_prefix": "/hololake/releases",
|
"release_public_path_prefix": "/hololake/releases",
|
||||||
"release_public_route_deployed": false,
|
"release_public_route_deployed": false,
|
||||||
|
"release_front_door_bounded_config_renderer_implemented": true,
|
||||||
"release_broadcast_explicit_operator_activation_implemented": true,
|
"release_broadcast_explicit_operator_activation_implemented": true,
|
||||||
"release_broadcast_activation_requires_exact_human_approval": true,
|
"release_broadcast_activation_requires_exact_human_approval": true,
|
||||||
"release_broadcast_activation_requires_repeated_expected_facts": true,
|
"release_broadcast_activation_requires_repeated_expected_facts": true,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ test('release activation remains explicitly human controlled', () => {
|
||||||
assert.equal(publicRoute.proxyRequestUriPolicy, 'PRESERVE_FULL_PUBLIC_PATH')
|
assert.equal(publicRoute.proxyRequestUriPolicy, 'PRESERVE_FULL_PUBLIC_PATH')
|
||||||
assert.equal(publicRoute.frontDoorLoopbackPort, null)
|
assert.equal(publicRoute.frontDoorLoopbackPort, null)
|
||||||
assert.equal(publicRoute.deployed, false)
|
assert.equal(publicRoute.deployed, false)
|
||||||
|
assert.equal(foundation.release_front_door_bounded_config_renderer_implemented, true)
|
||||||
assert.equal(foundation.release_pipeline_automatic_upload_allowed, false)
|
assert.equal(foundation.release_pipeline_automatic_upload_allowed, false)
|
||||||
assert.equal(
|
assert.equal(
|
||||||
foundation.release_production_activation_state,
|
foundation.release_production_activation_state,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import test from 'node:test'
|
||||||
|
|
||||||
|
import { renderFrontDoorSnippet } from '../server/release-broadcast/render-front-door.mjs'
|
||||||
|
|
||||||
|
test('front-door renderer refuses an unassigned or privileged loopback port', () => {
|
||||||
|
assert.throws(() => renderFrontDoorSnippet(null), /PORT_REQUIRED/)
|
||||||
|
assert.throws(() => renderFrontDoorSnippet(443), /PORT_REQUIRED|PORT_INVALID/)
|
||||||
|
assert.throws(() => renderFrontDoorSnippet('not-a-port'), /PORT_REQUIRED/)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('rendered proxy preserves the public path and strips request authority', () => {
|
||||||
|
const snippet = renderFrontDoorSnippet(23940)
|
||||||
|
assert.match(snippet, /location \^~ \/hololake\/releases\//)
|
||||||
|
assert.match(snippet, /proxy_pass http:\/\/127\.0\.0\.1:23940;/)
|
||||||
|
assert.doesNotMatch(snippet, /proxy_pass http:\/\/127\.0\.0\.1:23940\//)
|
||||||
|
assert.match(snippet, /limit_except GET HEAD \{ deny all; \}/)
|
||||||
|
assert.match(snippet, /proxy_pass_request_body off;/)
|
||||||
|
assert.match(snippet, /proxy_set_header Authorization "";/)
|
||||||
|
assert.match(snippet, /proxy_set_header Cookie "";/)
|
||||||
|
assert.match(snippet, /proxy_set_header X-Forwarded-For "";/)
|
||||||
|
})
|
||||||
|
|
@ -23,6 +23,14 @@ preserve the full request URI. Its loopback tunnel port remains deliberately
|
||||||
unassigned until the BS-GZ-006 route owner returns the live, non-conflicting
|
unassigned until the BS-GZ-006 route owner returns the live, non-conflicting
|
||||||
topology.
|
topology.
|
||||||
|
|
||||||
|
Once that port is returned and independently verified, `render-front-door.mjs
|
||||||
|
--loopback-port PORT` renders the bounded Nginx location. It refuses an omitted
|
||||||
|
port, preserves the full public request path by leaving `proxy_pass` without a
|
||||||
|
URI suffix, accepts only GET and HEAD, forwards no request body, and strips
|
||||||
|
authorization, cookies, and client forwarding headers. Rendering is not
|
||||||
|
deployment; Nginx validation, transactional install, public certificate/readback,
|
||||||
|
and a separate server receipt remain required.
|
||||||
|
|
||||||
`operator.mjs` supplies the separate, root-operated verification and activation
|
`operator.mjs` supplies the separate, root-operated verification and activation
|
||||||
boundary. `verify` reconstructs a private candidate tree and accepts it only when
|
boundary. `verify` reconstructs a private candidate tree and accepts it only when
|
||||||
the broadcast, pipeline receipt, package bytes, Developer ID receipt, Apple
|
the broadcast, pipeline receipt, package bytes, Developer ID receipt, Apple
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const PORT_PATTERN = /^(?:[1-9]\d{3,4})$/
|
||||||
|
|
||||||
|
const fail = (code) => {
|
||||||
|
throw new Error(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderFrontDoorSnippet(portValue) {
|
||||||
|
const text = String(portValue ?? '')
|
||||||
|
if (!PORT_PATTERN.test(text)) fail('HOLOLAKE_RELEASE_FRONT_DOOR_PORT_REQUIRED')
|
||||||
|
const port = Number(text)
|
||||||
|
if (!Number.isInteger(port) || port < 1024 || port > 65535) fail('HOLOLAKE_RELEASE_FRONT_DOOR_PORT_INVALID')
|
||||||
|
return `location = /hololake/releases {
|
||||||
|
return 308 /hololake/releases/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /hololake/releases/ {
|
||||||
|
limit_except GET HEAD { deny all; }
|
||||||
|
client_max_body_size 0;
|
||||||
|
proxy_pass http://127.0.0.1:${port};
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
proxy_set_header Authorization "";
|
||||||
|
proxy_set_header Cookie "";
|
||||||
|
proxy_set_header X-Forwarded-For "";
|
||||||
|
proxy_set_header X-Forwarded-Host "";
|
||||||
|
proxy_set_header X-Forwarded-Proto "";
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
proxy_connect_timeout 2s;
|
||||||
|
proxy_send_timeout 10s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function main(argv = process.argv.slice(2)) {
|
||||||
|
const portIndex = argv.indexOf('--loopback-port')
|
||||||
|
if (portIndex < 0 || portIndex + 1 >= argv.length || argv.length !== 2) {
|
||||||
|
fail('HOLOLAKE_RELEASE_FRONT_DOOR_USAGE:--loopback-port PORT')
|
||||||
|
}
|
||||||
|
process.stdout.write(renderFrontDoorSnippet(argv[portIndex + 1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv[1] && import.meta.url === new URL(`file://${process.argv[1]}`).href) {
|
||||||
|
try {
|
||||||
|
main()
|
||||||
|
} catch (error) {
|
||||||
|
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`)
|
||||||
|
process.exitCode = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue