From 3670519952bd076f6ec8145a24bd9f14f9a9473a Mon Sep 17 00:00:00 2001 From: hank-pilot Date: Fri, 29 May 2026 06:59:33 +0000 Subject: [PATCH] feat(cmd/updater): add standalone updater binary with --pin flag Creates the cmd/updater/main.go entrypoint previously referenced by install.sh and the release workflow but which did not exist yet. Flags: --install-dir path to pilot binaries (required) --repo GitHub owner/repo (default: TeoSlayer/pilotprotocol) --pin pin to a specific release tag (e.g. --pin v1.10.5) empty = follow latest --interval check interval (default: 1h) --version print version and exit Depends on: github.com/pilot-protocol/updater (pinned-version feature from PR #4) --- cmd/updater/main.go | 88 +++++++++++++++++++++++++++++++++++++++++++++ go.mod | 3 +- go.sum | 4 +++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 cmd/updater/main.go diff --git a/cmd/updater/main.go b/cmd/updater/main.go new file mode 100644 index 00000000..0f45252a --- /dev/null +++ b/cmd/updater/main.go @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +package main + +import ( + "flag" + "fmt" + "log/slog" + "os" + "os/signal" + "syscall" + "time" + + "github.com/pilot-protocol/updater" +) + +var version = "dev" + +func main() { + installDir := flag.String("install-dir", "", "directory containing pilot binaries (required)") + repo := flag.String("repo", "TeoSlayer/pilotprotocol", "GitHub owner/repo for releases") + pin := flag.String("pin", "", "pin to a specific release tag (e.g. v1.10.5); empty = follow latest") + interval := flag.Duration("interval", 1*time.Hour, "check interval") + logLevel := flag.String("log-level", "info", "log level (debug, info, warn, error)") + logFormat := flag.String("log-format", "text", "log format (text, json)") + showVersion := flag.Bool("version", false, "print version and exit") + flag.Parse() + + if *showVersion { + fmt.Println(version) + os.Exit(0) + } + + if *installDir == "" { + fmt.Fprintln(os.Stderr, "error: --install-dir is required") + os.Exit(2) + } + + setupLogging(*logLevel, *logFormat) + + u := updater.New(updater.Config{ + CheckInterval: *interval, + Repo: *repo, + InstallDir: *installDir, + Version: version, + PinnedVersion: *pin, + }) + + u.Start() + slog.Info("updater started", + "install_dir", *installDir, + "repo", *repo, + "interval", interval.String(), + ) + if *pin != "" { + slog.Info("version pinned", "tag", *pin) + } + + sig := make(chan os.Signal, 1) + signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) + <-sig + + slog.Info("shutting down") + u.Stop() +} + +func setupLogging(level, format string) { + var lvl slog.Level + switch level { + case "debug": + lvl = slog.LevelDebug + case "warn": + lvl = slog.LevelWarn + case "error": + lvl = slog.LevelError + default: + lvl = slog.LevelInfo + } + + opts := &slog.HandlerOptions{Level: lvl} + var h slog.Handler + if format == "json" { + h = slog.NewJSONHandler(os.Stderr, opts) + } else { + h = slog.NewTextHandler(os.Stderr, opts) + } + slog.SetDefault(slog.New(h)) +} diff --git a/go.mod b/go.mod index 2aa2003a..9c51dce7 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/coder/websocket v1.8.14 github.com/pilot-protocol/app-store v0.1.0 github.com/pilot-protocol/beacon v0.1.0 - github.com/pilot-protocol/common v0.1.0 + github.com/pilot-protocol/common v0.4.0 github.com/pilot-protocol/dataexchange v0.1.0 github.com/pilot-protocol/eventstream v0.1.0 github.com/pilot-protocol/gateway v0.1.0 @@ -22,6 +22,7 @@ require ( require ( github.com/expr-lang/expr v1.17.8 // indirect + github.com/pilot-protocol/updater v0.2.2-0.20260529065627-220ed5b8383f // indirect golang.org/x/net v0.55.0 // indirect golang.org/x/sys v0.45.0 // indirect ) diff --git a/go.sum b/go.sum index b19df09c..f861b561 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/pilot-protocol/beacon v0.1.0 h1:jXO8duAzzpB8K+9It0QwR9BRupgKZ8IQhuwqy github.com/pilot-protocol/beacon v0.1.0/go.mod h1:PejZP5sZ4s5Lrtc0wdYHSEJVc7cn6E8yqo0R4CV+iUo= github.com/pilot-protocol/common v0.1.0 h1:m8mZZATgeBiFoqhWXPnskw2u0lNkWxHp0IagZK35V1g= github.com/pilot-protocol/common v0.1.0/go.mod h1:4YZWHK5nhM+4RLmYTspLxxAFbyBII7yzQDAHq3Ul2ck= +github.com/pilot-protocol/common v0.4.0 h1:lH1WdQBU5Zan1rAqF/kYpcJO6vBoYVWXrWUNwMX10jA= +github.com/pilot-protocol/common v0.4.0/go.mod h1:yrAwPXGVMbXU+SADvOCmbdXjK/wJ3uA0KshyLvRlej4= github.com/pilot-protocol/dataexchange v0.1.0 h1:JJ29lL/LxDd1+szKFoEVxakzT93Tid3zoaAUBVGNKV4= github.com/pilot-protocol/dataexchange v0.1.0/go.mod h1:mXD17Vh0Eup+M//YhCm4j6D/DyFaZM7JzN5xexBdfLs= github.com/pilot-protocol/eventstream v0.1.0 h1:uHNTNTMA9MasBBpi2nCRkvFmFvTxbKCk7azPfuILkvY= @@ -28,6 +30,8 @@ github.com/pilot-protocol/skillinject v0.1.0 h1:gs912gqmxl0ifIvswefjx8BzPCmoBWS7 github.com/pilot-protocol/skillinject v0.1.0/go.mod h1:303GIB6j95ZhnoYeTlYzlBDhUbO01PB/6KGohm4DcJs= github.com/pilot-protocol/trustedagents v0.1.0 h1:rCX0IQxfZ84Q4dSgw01WJgjHUODRnI3iAon1t+NuFGE= github.com/pilot-protocol/trustedagents v0.1.0/go.mod h1:uVySmuMPb6N7AOCnvLHN2I9C9ggqEpfBmAZwVuP5Xaw= +github.com/pilot-protocol/updater v0.2.2-0.20260529065627-220ed5b8383f h1:1dyunPeEOriqTv1xbt0fuDwieA5V5NLU1nVSC2714jU= +github.com/pilot-protocol/updater v0.2.2-0.20260529065627-220ed5b8383f/go.mod h1:/I0uhVk1SljAOEYmjTdI/6CP7UmemmV4WB22ai1FxUw= github.com/pilot-protocol/webhook v0.1.0 h1:SnIcn+IdHvzoJt+OFzGJbkBHurjNBD0xSc6HAUvExAg= github.com/pilot-protocol/webhook v0.1.0/go.mod h1:c0du05MMy8FYnlc2YGqUWxRgTP8pRWTrtIdNuRhf6uk= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=