site preview: choose ports automatically and tie both machines to one connection that ends by itself #238
Labels
No labels
blocked
bug
decision
duplicate
enhancement
help wanted
invalid
landed?
question
ready-to-merge
stale
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/tools#238
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Make
allod site previewchoose its own ports and tie everything it starts, on both machines, to one connection that ends by itself when either side goes away, so two previews never collide and no way of stopping one leaves a process, a forward, or a file behind.Primary goals:
--port, preview takes a port that is free, prints the address to open, and two previews running at once do not collide.--port <n>stays exact and is refused when taken.allodstops knowing that one version of one generator opens port1024. A server that needs more than the page port says so with--forward.--vmruns in the VM only while it keeps hearing from the command that asked for it. Silence, or the connection closing, stops it within a bounded time with no help from the VM's SSH configuration.Current state and specifics
allod/tools#236 is the starting point. What it already has, and this keeps: the server runs in its own process group; an interrupt, a terminate or a hangup takes the whole group down; the kernel signals the server if
allodis killed;--vmopens its own connection and never a shared one.What it leaves open:
1111and a taken port is refused--port--portswith the page port and10241024is what zola 0.21 opens; zola 0.23.6 was measured serving reload on the page port. Two zola previews at once both want1024, and--vmrefuses when it is taken on the hypervisor even for a site that does not use it--vmasks the VM for ports over one connection, then opens a second with the forwardsClientAliveIntervalis unset)The design
Three rules, each of which removes a cleanup task by never creating the thing that would need cleaning.
1. The kernel hands out ports; binding is the only lock. A port is free when binding it succeeds and at no other time, so nothing else is consulted: no reserved range, no registry, no file recording who has what. Without
--port, preview tries1111and, when that is taken, asks the kernel for a free port by binding port 0. Under--vmthe browser and the server must agree on the number, because a generator writes its own address into the pages it serves, so the hypervisor picks a port free there and the VM side must bind the same one. When the VM side cannot, it exits with a code that means exactly that, and the hypervisor picks again, up to a small fixed number of tries. The gap between choosing a port and the server binding it cannot be closed for a serveralloddoes not control; it is made harmless by failing loudly and trying again.2. One connection, and it is the lease.
--vmopens a single SSH connection with the forwards on it, runsallod site previewat the far end without a terminal, and keeps that command's standard input. The near side writes a short line on it every few seconds. The far side stops its server group when standard input closes or when three lines in a row are missed. The server's own standard input is/dev/null. An interrupt on the hypervisor closes the pipe and waits, bounded, for the far side to finish. Killing the nearallodoutright ends itssshby the parent-death signal, which closes the pipe. Ending the preview in the VM ends the remote command, which endsssh, which ends the forwards. There is no second connection and nothing to reconcile.This departs from allod/tools#234, which found that the tool must allocate a terminal on the VM side. That was measured with an
allodthat did not take its server down; with the group cleanup in allod/tools#236 and end-of-input as the hangup, the terminal is no longer what carries the stop. This is the exploratory part and is settled by measurement, not by reading: the manual runs below decide it, and if end-of-input does not arrive when the client dies, the terminal stays and only the heartbeat is added.3. Extra ports are declared, never guessed.
--portsanswers the page port alone.--forwardnames anything else. The1024constant is removed when the site repositories pin a zola that serves reload on the page port; until that is true of every site repository, it stays, and the forward for it becomes optional: taken on the hypervisor, it is skipped with a warning that live reload will need a manual refresh.Suspend: under
--vma suspended command stops sending, the lease runs out and the preview stops, which the help text says. Run directly, preview gets job control proper: notice the server stopped, hand the terminal back, stop, and reverse it on continue.Order of work
Each step lands by itself and leaves the command working.
--vm, replacing the terminal and the second connection, with the retry on a taken port.1024, on the trigger stated in rule 3.Step 2 starts once allod/tools#236 has merged and its manual
--vmruns have been done, so there is a measured baseline to compare against.Validation
--portand both serve.--vm; stop it from the hypervisor; start again and stop it from inside the VM; start again and drop the network between the machines. After each, both machines show no preview process and no port held, with nothing run to tidy up.Scope
In scope:
cmd/allod/site_preview*.go, the help text, the README section, and their tests.Out of scope, with the condition that would bring each in:
ClientAliveIntervalon dev VMs. The lease makes preview independent of it. It becomes its own change if other long-running remote commands show the same leftover.allodwhen the server has started children of its own that it does not take down: the kernel signals only the direct child. Closing that needs the server in a process namespace or control group that dies as a whole, which adds a dependency; it comes in if a real preview app is seen leaving a child behind.stopcommand. The running process is the handle; a command to find and stop previews would need the state file this design exists to avoid.Closed as superseded by allod/tools#240, before any of it was built.
This issue proposed automatic port choice, a heartbeat over standard input so the VM side stops when the hypervisor goes quiet, and job control for Ctrl-Z. All three were answers to problems created by one decision: that the command on the hypervisor owns the server in the VM. allod/tools#240 drops that decision. The agent owns the server as a user service in the VM, the hypervisor only forwards a port, and each site's port is written once in the repository registry, so there is no lifetime to tie together and no port to negotiate.
One idea from here survives: ports are never guessed and never probed. It survives as a registry field, not as code.
Closed as not planned.