gokrazy, clientupdate: add start of Gokrazy auto-updates, tests
This adds support for Gokrazy GAF (Gokrazy Archive Format) zip auto-updates, starting to wire up Tailscale's clientupdate mechanism to Gokrazy's update mechanism. Currently there's just a CLI command to update from a GAF URL, with an --unsigned flag for use in a new natlab vmtest. Next step would be publishing unstable track GAF files on pkgs.tailscale.com, with detached signatures, and then making the clientupdate mechanism also download those and check signatures. Updates #20002 Change-Id: Ib03c56f17a57f8a4638398ef83549dac4813323d Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
6ff761c5f8
commit
772be1b0cc
@@ -10,6 +10,7 @@ import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
@@ -67,8 +68,19 @@ var updateArgs struct {
|
||||
version string // explicit version; empty means auto
|
||||
}
|
||||
|
||||
const gokrazyUpdateFromURLMagicArg = "--gokrazy-update-from-url"
|
||||
|
||||
func runUpdate(ctx context.Context, args []string) error {
|
||||
if len(args) > 0 {
|
||||
if runtime.GOOS == "linux" && distro.Get() == distro.Gokrazy {
|
||||
gokArgs, err := gokrazyUpdateArgsFromMagicArg(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if gokArgs != nil {
|
||||
return clientupdate.GokrazyUpdateFromURL.Get()(ctx, *gokArgs)
|
||||
}
|
||||
}
|
||||
return flag.ErrHelp
|
||||
}
|
||||
if updateArgs.version != "" && updateArgs.track != "" {
|
||||
@@ -102,3 +114,39 @@ func confirmUpdate(ver string) bool {
|
||||
msg := fmt.Sprintf("This will update Tailscale from %v to %v. Continue?", version.Short(), ver)
|
||||
return prompt.YesNo(msg, true)
|
||||
}
|
||||
|
||||
// gokrazyUpdateArgsFromMagicArg parses the Gokrazy update-from-URL command-line
|
||||
// flow. It returns nil if args do not select that flow. A non-nil result means
|
||||
// the caller may safely invoke clientupdate.GokrazyUpdateFromURL.
|
||||
func gokrazyUpdateArgsFromMagicArg(args []string) (*clientupdate.GokrazyUpdateArgs, error) {
|
||||
var updateURL string
|
||||
var unsigned bool
|
||||
|
||||
fs := flag.NewFlagSet("gokrazy-update", flag.ContinueOnError)
|
||||
fs.SetOutput(io.Discard)
|
||||
// This flag path is exercised end-to-end by TestGokrazyUpdatesItselfToSameImage.
|
||||
fs.StringVar(&updateURL, gokrazyUpdateFromURLMagicArg[2:], "", "URL of the Gokrazy archive format file to install")
|
||||
fs.BoolVar(&unsigned, "unsigned", false, "allow an unsigned GAF; for tests only")
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fs.NArg() != 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if updateURL == "" {
|
||||
return nil, nil
|
||||
}
|
||||
if !unsigned {
|
||||
return nil, errors.New("signed GAF verification is not implemented yet; see https://github.com/tailscale/tailscale/issues/20002; pass --unsigned for test updates")
|
||||
}
|
||||
if !clientupdate.GokrazyUpdateFromURL.IsSet() {
|
||||
return nil, errors.New("gokrazy update support is not linked into this binary")
|
||||
}
|
||||
return &clientupdate.GokrazyUpdateArgs{
|
||||
URL: updateURL,
|
||||
AllowUnsigned: unsigned,
|
||||
Logf: func(format string, args ...any) {
|
||||
printf(format+"\n", args...)
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -372,6 +372,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
||||
vendor/golang.org/x/text/unicode/bidi from vendor/golang.org/x/net/idna+
|
||||
vendor/golang.org/x/text/unicode/norm from vendor/golang.org/x/net/idna
|
||||
archive/tar from tailscale.com/clientupdate
|
||||
L archive/zip from tailscale.com/clientupdate
|
||||
bufio from compress/flate+
|
||||
bytes from archive/tar+
|
||||
cmp from slices+
|
||||
|
||||
Reference in New Issue
Block a user