feat(pi): update to the latest stable release by default

This commit is contained in:
2026-08-16 00:13:51 +02:00
parent 0cb6a3f915
commit 5a657a67e8
6 changed files with 586 additions and 55 deletions
+31 -7
View File
@@ -54,8 +54,10 @@ Commands:
Select closed backend defaults interactively on a TTY; all flags are required otherwise.
pi restart --yes [--drain]
Recreate only core with the currently selected Pi image and verify readiness.
pi update [--version V]
Rebuild the latest stable Pi release, or an explicit version, and recreate only core.
pi update --version V --source build --yes [--drain]
Rebuild a pinned Pi version and recreate only core.
Advanced explicit build form retained for compatibility.
pi update --version V --source pull --image IMAGE@sha256:DIGEST --yes [--drain]
Pull an immutable candidate and recreate only core.
pi rollback --yes Restore the image recorded by the latest Pi update.
@@ -75,6 +77,11 @@ Commands:
workspace preprocess run --workspace ID [--resume RUN] [--json]
`
var (
newPiRegistryClient = pi.NewNPMRegistryClient
readPiRuntimePackageName = pi.ReadRuntimePackageName
)
func main() {
os.Exit(run(context.Background(), os.Args[1:], os.Stdout, os.Stderr))
}
@@ -487,12 +494,21 @@ func piCommand(ctx context.Context, installation config.Installation, runner com
if err != nil {
return commandUsageError(stderr, err.Error())
}
result, err := pi.Update(ctx, controlled, request)
var registry pi.RegistryClient
packageName := ""
if request.Version == "" {
packageName, err = readPiRuntimePackageName(installation.ProjectDirectory)
if err != nil {
return commandUsageError(stderr, "pi update latest-version lookup is unavailable: "+err.Error())
}
registry = newPiRegistryClient()
}
result, err := pi.UpdateWithResolvedVersion(ctx, controlled, request, packageName, registry)
if err != nil {
return piFailure(stderr, err, secretValues)
}
if result.Phase == pi.PhaseNoop {
fmt.Fprintf(stdout, "Pi already runs requested version %s; no container was recreated.\n", request.Version)
fmt.Fprintf(stdout, "Pi already runs requested version %s; no container was recreated.\n", result.Version)
return 0
}
fmt.Fprintf(stdout, "Pi update verified. Recovery metadata: %s\n", result.StatePath)
@@ -647,6 +663,7 @@ func parsePiConfigureArgs(args []string) (pi.Defaults, error) {
func parsePiUpdateArgs(args []string, statePath, restartStatePath string) (pi.Request, error) {
request := pi.Request{StatePath: statePath, RestartStatePath: restartStatePath}
sourceSpecified := false
for len(args) > 0 {
switch args[0] {
case "--version":
@@ -659,6 +676,7 @@ func parsePiUpdateArgs(args []string, statePath, restartStatePath string) (pi.Re
return pi.Request{}, errors.New("--source requires build or pull")
}
request.Source, args = pi.Source(args[1]), args[2:]
sourceSpecified = true
case "--image":
if len(args) < 2 || request.Image != "" {
return pi.Request{}, errors.New("--image requires one digest-pinned image reference")
@@ -678,11 +696,17 @@ func parsePiUpdateArgs(args []string, statePath, restartStatePath string) (pi.Re
return pi.Request{}, fmt.Errorf("unknown pi update option %q", args[0])
}
}
if request.Version == "" {
return pi.Request{}, errors.New("pi update requires --version <pinned-version>")
if !sourceSpecified {
if request.Image != "" {
return pi.Request{}, errors.New("--image is valid only with --source pull")
}
request.Source = pi.BuildSource
request.Confirm = true
request.Drain = true
return request, nil
}
if request.Source == "" {
return pi.Request{}, errors.New("pi update requires explicit --source build or pull")
if request.Version == "" {
return pi.Request{}, errors.New("pi update with --source requires --version <pinned-version>")
}
if request.Source != pi.BuildSource && request.Source != pi.PullSource {
return pi.Request{}, errors.New("--source requires build or pull")