fix(indeehub): inspect nginx through fixed system service
This commit is contained in:
@@ -261,3 +261,35 @@ recaptured as a new baseline, never described as preserved across that shutdown.
|
|||||||
A direct-kernel initramfs-only recovery boot installed an absent-marker manager
|
A direct-kernel initramfs-only recovery boot installed an absent-marker manager
|
||||||
startup condition before normal boot, and `ConditionResult=no` verified the old
|
startup condition before normal boot, and `ConditionResult=no` verified the old
|
||||||
manager never started. The subsequent diagnostic boot shut down gracefully.
|
manager never started. The subsequent diagnostic boot shut down gracefully.
|
||||||
|
|
||||||
|
### Actual RPC preflight and nginx namespace evidence (2026-10-08 UTC)
|
||||||
|
|
||||||
|
Corrected VM executable built successfully from frozen inputs (normal binary
|
||||||
|
SHA256 `3cbe5a5c3a74e6463ab0874c74e23dfca68f0bfc3fe54883f0edf69abb37ac0d`;
|
||||||
|
stripped transfer SHA256 `753f8ba6ac342c8f4b9a19c8079a51dfd1da4dcb517d4ea4d0e54035c22f5788`).
|
||||||
|
Receipt: `/tmp/archy-indeehub-corrected-executable-20261007.json`. It predates the
|
||||||
|
later rental guard and nginx helper correction; not a release artifact.
|
||||||
|
|
||||||
|
Actual manager startup completed a62-app reconcile pass with all seven IndeeHub
|
||||||
|
members `NoOp`, every baseline container identity preserved, and API/manager
|
||||||
|
HTTP200. Subsequent real update attempts initially met the legitimate background
|
||||||
|
lifecycle lock. A temporary behavior-preserving fixture tracer confirmed later
|
||||||
|
admission succeeded. One early diagnostic teardown interrupted asynchronous
|
||||||
|
preflight and is invalid as source-defect evidence. The corrected diagnostic
|
||||||
|
waited for its terminal refusal before restoring the deliberately withheld plan
|
||||||
|
and removing the tracer; all seven original identities remained, no supervised
|
||||||
|
journal existed. No speculative lifecycle-lock patch was made.
|
||||||
|
|
||||||
|
The admitted reviewed-plan RPC then reached `Prepared → Editing → Restoring`.
|
||||||
|
All seven recovery images exist; target startup never began. The controller
|
||||||
|
remained `Prepared` because `sudo nginx -T` attempted to open `/run/nginx.pid`
|
||||||
|
inside the manager's read-only mount namespace. Holds and the unresolved journal
|
||||||
|
were preserved; this is not a successful rollback or migration receipt.
|
||||||
|
|
||||||
|
A manager-equivalent hardened VM probe passed with the fixed command
|
||||||
|
`sudo -n /usr/bin/systemd-run --quiet --wait --pipe --collect -- /usr/sbin/nginx -T`.
|
||||||
|
It validated the required ingress guards without printing effective configuration
|
||||||
|
or widening manager write access. The controller uses that fixed command now;
|
||||||
|
25 pure controller tests pass, including refusal before fence creation on dump
|
||||||
|
failure. A new helper hash requires a matching backend rebuild. Candidate-helper
|
||||||
|
qualification remains separate from actual backend transaction acceptance.
|
||||||
|
|||||||
@@ -167,7 +167,13 @@ class Controller:
|
|||||||
def close_ingress(self):
|
def close_ingress(self):
|
||||||
# The deployed native AppGate and legacy nginx guards consume this exact
|
# The deployed native AppGate and legacy nginx guards consume this exact
|
||||||
# sentinel. This code never edits arbitrary nginx configuration.
|
# sentinel. This code never edits arbitrary nginx configuration.
|
||||||
config=self.run(['sudo','-n','nginx','-T']).decode()
|
# nginx -T tests its pid file as well as reading configuration. The
|
||||||
|
# manager's strict mount namespace makes /run/nginx.pid read-only, even
|
||||||
|
# after sudo. Use one fixed read-only command in PID1's fresh service
|
||||||
|
# context; do not broaden the manager's writable paths or detach the
|
||||||
|
# controller that owns the inherited lifecycle lock.
|
||||||
|
config=self.run(['sudo','-n','/usr/bin/systemd-run','--quiet','--wait',
|
||||||
|
'--pipe','--collect','--','/usr/sbin/nginx','-T']).decode()
|
||||||
validate_nginx_guards(config)
|
validate_nginx_guards(config)
|
||||||
self.fence.parent.mkdir(mode=0o755,exist_ok=True)
|
self.fence.parent.mkdir(mode=0o755,exist_ok=True)
|
||||||
self.fence.parent.chmod(0o755)
|
self.fence.parent.chmod(0o755)
|
||||||
|
|||||||
@@ -155,6 +155,15 @@ class MaintenanceTests(unittest.TestCase):
|
|||||||
module.atomic(c.data/'update-transactions'/'supervised'/(self.operation+'.json'),{'phase':'Restored','target_startup_began':True})
|
module.atomic(c.data/'update-transactions'/'supervised'/(self.operation+'.json'),{'phase':'Restored','target_startup_began':True})
|
||||||
with self.assertRaisesRegex(RuntimeError,'Data compatibility'):c.release('restored')
|
with self.assertRaisesRegex(RuntimeError,'Data compatibility'):c.release('restored')
|
||||||
self.assertTrue(c.fence.exists())
|
self.assertTrue(c.fence.exists())
|
||||||
|
def test_nginx_namespace_failure_cannot_create_admission_fence(self):
|
||||||
|
def failed_dump(argv,timeout,output):
|
||||||
|
self.assertEqual(argv,['sudo','-n','/usr/bin/systemd-run','--quiet','--wait',
|
||||||
|
'--pipe','--collect','--','/usr/sbin/nginx','-T'])
|
||||||
|
raise module.subprocess.CalledProcessError(1,argv)
|
||||||
|
self.controller.runner=failed_dump
|
||||||
|
with self.assertRaises(module.subprocess.CalledProcessError):self.controller.close_ingress()
|
||||||
|
self.assertFalse(self.controller.fence.exists())
|
||||||
|
self.assertIsNone(self.controller.record)
|
||||||
def test_every_legacy_sublocation_must_be_fenced(self):
|
def test_every_legacy_sublocation_must_be_fenced(self):
|
||||||
guard='if (-f /var/lib/archipelago/app-maintenance/indeedhub) { return 503; }'
|
guard='if (-f /var/lib/archipelago/app-maintenance/indeedhub) { return 503; }'
|
||||||
blocks=[f'location /app/indeedhub/{suffix} {{\n {guard}\n proxy_pass http://127.0.0.1:7778/;\n}}' for suffix in ('','_next/','ws/')]
|
blocks=[f'location /app/indeedhub/{suffix} {{\n {guard}\n proxy_pass http://127.0.0.1:7778/;\n}}' for suffix in ('','_next/','ws/')]
|
||||||
|
|||||||
Reference in New Issue
Block a user