From 4c35c805e6f2c4cb0f55123889b3b33cd447f70f Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 28 Mar 2026 13:05:08 +0200 Subject: Add pkg targets for FreeBSD/OpenBSD package repo New mage targets: - pkgFreebsd: cross-compile, package on f0, upload to repo - pkgOpenbsd: cross-compile, package on fishfinger, upload to repo via f0 - pkg: both of the above - buildFreebsd: cross-compile for FreeBSD amd64 Legacy openbsd/deployOpenbsd targets preserved for backward compat. Co-Authored-By: Claude Opus 4.6 --- Magefile.go | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 246 insertions(+), 16 deletions(-) diff --git a/Magefile.go b/Magefile.go index 0ddb7bc..c6b04c9 100644 --- a/Magefile.go +++ b/Magefile.go @@ -7,11 +7,41 @@ import ( "fmt" "os" "os/exec" + "strings" "github.com/magefile/mage/mg" ) -// Build builds the gogios binary. +const ( + // SSH targets for native packaging + freebsdHost = "f0.lan.buetow.org" + freebsdSSH = "-p 22" + openbsdHost = "rex@fishfinger.buetow.org" + + // NFS path on freebsdHost where the PV is mounted + pvBase = "/data/nfs/k3svolumes/pkgrepo" + + // Repo URL paths + freebsdRepoPath = "freebsd/FreeBSD:15:amd64/latest" + openbsdRepoPath = "openbsd/7.8/packages/amd64" +) + +// version reads the version from internal/version.go, stripping the "v" prefix. +func version() (string, error) { + data, err := os.ReadFile("internal/version.go") + if err != nil { + return "", fmt.Errorf("reading version.go: %w", err) + } + for _, line := range strings.Split(string(data), "\n") { + if strings.Contains(line, "Version") && strings.Contains(line, "=") { + v := strings.Trim(strings.Split(line, "\"")[1], "v") + return v, nil + } + } + return "", fmt.Errorf("version not found in internal/version.go") +} + +// Build builds the gogios binary for the current platform. func Build() error { fmt.Println("Building...") cmd := exec.Command("go", "build", "-o", "gogios", "cmd/gogios/main.go") @@ -74,32 +104,232 @@ func Test() error { return testCmd.Run() } -// Openbsd builds and deploys the gogios binary for OpenBSD. -// Runs sequentially to ensure build completes before deploy. -func Openbsd() error { - if err := BuildOpenbsd(); err != nil { - return err +// crossBuild compiles gogios for the given GOOS and outputs to the given path. +func crossBuild(goos, output string) error { + fmt.Printf("Cross-compiling for %s/amd64...\n", goos) + env := os.Environ() + env = append(env, "GOOS="+goos, "GOARCH=amd64") + cmd := exec.Command("go", "build", "-o", output, "cmd/gogios/main.go") + cmd.Env = env + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} + +// sshRun executes a command on a remote host via SSH. +func sshRun(host, command string) error { + args := []string{} + if host == freebsdHost { + args = append(args, "-p", "22") } - return DeployOpenbsd() + args = append(args, host, command) + cmd := exec.Command("ssh", args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() } -// BuildOpenbsd builds the gogios binary for OpenBSD. -func BuildOpenbsd() error { - fmt.Println("Building for OpenBSD...") - env := os.Environ() - env = append(env, "GOOS=openbsd", "GOARCH=amd64") - cmd := exec.Command("go", "build", "-o", "gogios", "cmd/gogios/main.go") - cmd.Env = env +// scpTo copies a local file to a remote host via SCP. +func scpTo(localPath, host, remotePath string) error { + args := []string{} + if host == freebsdHost { + args = append(args, "-P", "22") + } + args = append(args, localPath, host+":"+remotePath) + cmd := exec.Command("scp", args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() } -// DeployOpenbsd copies the gogios binary for OpenBSD. +// scpFrom copies a remote file to a local path via SCP. +func scpFrom(host, remotePath, localPath string) error { + args := []string{} + if host == freebsdHost { + args = append(args, "-P", "22") + } + args = append(args, host+":"+remotePath, localPath) + cmd := exec.Command("scp", args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} + +// BuildFreebsd cross-compiles gogios for FreeBSD amd64. +func BuildFreebsd() error { + return crossBuild("freebsd", "gogios-freebsd") +} + +// BuildOpenbsd cross-compiles gogios for OpenBSD amd64. +func BuildOpenbsd() error { + return crossBuild("openbsd", "gogios-openbsd") +} + +// PkgFreebsd builds the FreeBSD package on f0 and uploads it to the repo. +// Cross-compiles locally, ships the binary to f0, packages with pkg create, +// regenerates repo metadata, and copies to the PV. +func PkgFreebsd() error { + if err := BuildFreebsd(); err != nil { + return err + } + + ver, err := version() + if err != nil { + return err + } + + fmt.Printf("Packaging gogios %s for FreeBSD...\n", ver) + + // Write a local temp script, scp it, then execute via /bin/sh on f0 + script := fmt.Sprintf(`#!/bin/sh +set -e +cd /tmp && rm -rf gogios-pkg +mkdir -p gogios-pkg/stage/usr/local/bin gogios-pkg/out/All +cp /tmp/gogios gogios-pkg/stage/usr/local/bin/gogios +chmod 755 gogios-pkg/stage/usr/local/bin/gogios + +printf 'bin/gogios\n' > gogios-pkg/plist + +cat > gogios-pkg/+MANIFEST < gogios-pkg/plist + +cat > gogios-pkg/desc <