Skip to content

Deploy blockers: tailnet door binds in a service-owned directory; grant-list probe reads its whole listing - #13705

Merged
briansrls merged 1 commit into
mainfrom
bright-moth-475/deploy-blockers
Oct 10, 2026
Merged

briansrls merged 1 commit into
mainfrom
bright-moth-475/deploy-blockers

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

These are the two confirmed blockers for the srv1 `dashboard_deploy` step, found by smart-gull-336's precondition sweep and verified live on srv1 on 2026-10-10. The operator's deploy is waiting on this PR, because all four fleet-converge runs pin one revision R.

1. The tailnet door could not create its socket

  • What failed: `gunbc-roadmap-tailnet-door` runs `User=briansrls --unix-socket /opt/gunbc/tailnet-door.sock`. The deploy re-asserts `/opt/gunbc` as `root:root 0755` (`sudo -u briansrls test -w /opt/gunbc` answers no). So the door can't bind, and readiness, which requires the door, can never hold.
  • Earliest unjustified boundary: `dashboard_instance_tailnet_door_socket`'s own annotation assumed "the instance root, which the service principal owns". That's false for srv1-live.
  • Repair (the same move v1 closeout mega branch #13641 made for the event worktree):
    • The socket now lives in `<instance_root>/tailnet-door/door.sock`.
    • The directory is an owned-directory target (`dashboard_instance_tailnet_door_directory`). `gunbc.live_deploy.spec` `deployment_spec_for` appends it through `deployment_tailnet_door_directories`, but only for a deployment whose serve route targets a unix socket.
    • The one directory provider ensures it and reads it back before the unit binds.
    • It's a deployment demand, not an instance one: lab instances route to a port. The `dashboard_instance_directories` annotation says so rather than claiming to be the only list.
  • Consumers of the socket path, all read through `dashboard_instance_tailnet_door_socket`: the spec's serve backend (`srv1_live_deployment_names`), the door unit (via `deployment_tailnet_door_socket`), `tailnet_door_witness_test`, `tailnet_door_cutover_witness_test` and `workspace_allocation_http_witness_test`. No literal path needed changing.

2. The tailscale grant probe read a present grant as absent

  • What failed: `extdeps.sudo` `sudo_nopasswd_grant_list_shell_condition` ended `sudo -n -l | grep -v | sed | sed | grep -Fqx` under `pipefail`. `grep -q` exits at its first match while `sed` is still writing. After tonight's `gunbc-ghrunner` drop-in the listing is ~13 KB, so the writer takes SIGPIPE and the pipeline exits 141 (20/20 runs as ghrunner).
  • Repair: the last stage is `grep -Fx -- >/dev/null`. It consumes the whole listing and still answers by exit status.
  • Neighbours swept: no other `grep -q` ends a pipeline. `extdeps.tools.grep` reads a file path.

Evidence

`gunbc test` on srv1 at this head: results to follow as a comment (deploy_mutation_gate, live_deploy/emit, deploy_access_privilege, tailnet_door, tailnet_door_cutover, workspace_allocation_http, desired_roster, member_identity).

Not executed here: the wet door bind and the readiness readback. Those are the deploy itself.

🤖 Generated with Claude Code

… the grant-list probe reads its whole listing

srv1 precondition sweep (2026-10-10), both confirmed live:
- The door unit (User=briansrls) bound /opt/gunbc/tailnet-door.sock, but the
  deploy keeps /opt/gunbc root:root 0755, so the socket could never be created
  and readiness (which requires the door) could never hold. The socket now
  lives in <instance_root>/tailnet-door/, an owned-directory demand the spec
  adds for any deployment whose serve route targets a unix socket
  (deployment_tailnet_door_directories), ensured and read back by the one
  directory provider before the unit binds -- the same move #13641 made for
  the event worktree.
- sudo_nopasswd_grant_list_shell_condition ended its pipeline in grep -Fqx
  under pipefail; grep exited at its first match while sed was still writing
  the ~13 KB listing, so a present grant read as absent (exit 141, 20/20).
  The last stage is now grep -Fx with stdout discarded.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls merged commit 4a09439 into main Oct 10, 2026
1 check passed
@briansrls
briansrls deleted the bright-moth-475/deploy-blockers branch October 10, 2026 22:16
gunbai-bot Bot pushed a commit that referenced this pull request Oct 10, 2026
…ht operand poisoned the sudoers install

#13705 replaced grep -Fqx with grep -Fx >/dev/null. The bash serializer
refuses a redirect on a pipeline's right operand, so deploy_sudoers_install_shell
emitted its refusal marker and every deploy stopped there (srv1 lab apply,
2026-10-10). deploy_mutation_gate_witness and live_deploy/emit each went red
on it. grep -Fx without -q still reads its whole input, so the SIGPIPE fix holds.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Oct 11, 2026
… (absorbs main's drift from #13690/#13705/#13710)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
gunbai-bot Bot added a commit that referenced this pull request Oct 11, 2026
…role holder (#13688)

* Deployment risk D2 layer 1: role-following singletons resolve the prod-role holder (re-derives #13217)

ProdRoleHolder token and resolver in roadmap_dashboard_instance, actuated join in live_deploy.desired,
fabric placement, approval broker placement and emit repointed off the srv1 pin. Claims in
test.claim.prod_role_realization_witness_test.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Deployment risk D2 layer 1: witness fixtures follow the role-following signatures

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Deployment risk D2 layer 1: enrolment-code issuer follows the placed broker host; apply witness stays at main's fixture

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Deployment risk D2 layer 1: emit_test and release fixture follow RoleSingletonHolding and instance-keyed fabric paths

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Deployment risk D2 layer 1: drop unconsumed shell.Stat GroupOf; pin ProdRoleHolderUnactuatable in the actuated-join claim (review 78458)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Deployment risk D2 layer 1: unit-emission oracle follows role_singletons and the broker base-url environment

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Regenerate fleet-converge.yml and gunbc-ghrunner.sudoers via main_wet (absorbs main's drift from #13690/#13705/#13710)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Cite approval_broker_host_under at its home module (review 78559)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Drop the L2-only role_singleton_disposition fixture edit from the launch receipt witness (not a field on main's LiveDeployApplyReceipt)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant