Files
llmgw/internal/cli/join.go
T
Ilker ManapandClaude Opus 5.5 f5c79052b1 Let a machine join a setup by code, dialling out, with nothing logging in
The setup screens can reach a database machine by a join code instead of
ssh: they listen on 7444 and show a short code; llmgw join dials out,
checks the setup by fingerprint, admits itself with the code's secret, and
runs what the setup sends until it is done. A joined machine is one more
onboard.Remote, so checks and the Patroni install run over it unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-03 21:49:15 +02:00

62 lines
2.1 KiB
Go

package cli
import (
"errors"
"fmt"
"os"
"runtime"
"github.com/spf13/cobra"
joinpkg "gitea.mynodes.xyz/ilker/llmgw/internal/join"
"gitea.mynodes.xyz/ilker/llmgw/internal/release"
"gitea.mynodes.xyz/ilker/llmgw/internal/version"
)
func newJoinCmd() *cobra.Command {
return &cobra.Command{
Use: "join <code>",
Short: "Let a setup on another machine set this one up, with the code it gave",
Long: "For a machine nothing may log into: the setup screens (sudo llmgw on\n" +
"the control plane) show a code for each machine they expect. Run this\n" +
"with it, as root, on that machine. It dials out to the setup — nothing\n" +
"dials in — checks it is the setup the code was made by, and runs what\n" +
"the setup sends until it is done: the same checks and installs ssh\n" +
"would carry. Each step is printed here as it runs.\n\n" +
"A code is good for one machine, for an hour, and only while the setup\n" +
"that made it is waiting.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if runtime.GOOS != "linux" {
return fmt.Errorf("join sets up a Linux machine; this is %s", runtime.GOOS)
}
if os.Geteuid() != 0 {
return errors.New("run it as root — sudo llmgw join … — since the setup installs software here")
}
code, err := joinpkg.Parse(args[0])
if err != nil {
return err
}
out := cmd.OutOrStdout()
role := code.Role
if role == "" {
role = "part of a cluster"
}
fmt.Fprintf(out, "Joining the setup at %s, as %s. It runs as root here until it is done.\n", code.Addr, role)
return joinpkg.Serve(cmd.Context(), code, func(s string) { fmt.Fprintln(out, s) })
},
}
}
// joinInstall is what to run on a machine that has no llmgw yet, to fetch
// this version for its architecture: short lines, since it is copied from a
// screen that cuts long ones off.
func joinInstall() []string {
v := version.Version
return []string{
`a=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')`,
fmt.Sprintf("sudo curl -fsSL -o /usr/local/bin/llmgw \\\n %s/%s/llmgw-%s-linux-$a", release.DefaultBase, v, v),
"sudo chmod 755 /usr/local/bin/llmgw",
}
}