github.com/pdmccormick/importable-docker-buildx@v0.0.0-20240426161518-e47091289030/monitor/commands/reload.go (about) 1 package commands 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 8 controllererrors "github.com/docker/buildx/controller/errdefs" 9 controllerapi "github.com/docker/buildx/controller/pb" 10 "github.com/docker/buildx/monitor/types" 11 "github.com/docker/buildx/util/progress" 12 "github.com/moby/buildkit/solver/errdefs" 13 "github.com/pkg/errors" 14 ) 15 16 type ReloadCmd struct { 17 m types.Monitor 18 19 stdout io.WriteCloser 20 progress *progress.Printer 21 22 options *controllerapi.BuildOptions 23 invokeConfig controllerapi.InvokeConfig 24 } 25 26 func NewReloadCmd(m types.Monitor, stdout io.WriteCloser, progress *progress.Printer, options *controllerapi.BuildOptions, invokeConfig controllerapi.InvokeConfig) types.Command { 27 return &ReloadCmd{m, stdout, progress, options, invokeConfig} 28 } 29 30 func (cm *ReloadCmd) Info() types.CommandInfo { 31 return types.CommandInfo{ 32 Name: "reload", 33 HelpMessage: "reloads the context and build it", 34 HelpMessageLong: ` 35 Usage: 36 reload 37 `, 38 } 39 } 40 41 func (cm *ReloadCmd) Exec(ctx context.Context, args []string) error { 42 var bo *controllerapi.BuildOptions 43 if ref := cm.m.AttachedSessionID(); ref != "" { 44 // Rebuilding an existing session; Restore the build option used for building this session. 45 res, err := cm.m.Inspect(ctx, ref) 46 if err != nil { 47 fmt.Printf("failed to inspect the current build session: %v\n", err) 48 } else { 49 bo = res.Options 50 } 51 } else { 52 bo = cm.options 53 } 54 if bo == nil { 55 return errors.Errorf("no build option is provided") 56 } 57 if ref := cm.m.AttachedSessionID(); ref != "" { 58 if err := cm.m.Disconnect(ctx, ref); err != nil { 59 fmt.Println("disconnect error", err) 60 } 61 } 62 var resultUpdated bool 63 cm.progress.Unpause() 64 ref, _, err := cm.m.Build(ctx, *bo, nil, cm.progress) // TODO: support stdin, hold build ref 65 cm.progress.Pause() 66 if err != nil { 67 var be *controllererrors.BuildError 68 if errors.As(err, &be) { 69 ref = be.Ref 70 resultUpdated = true 71 } else { 72 fmt.Printf("failed to reload: %v\n", err) 73 } 74 // report error 75 for _, s := range errdefs.Sources(err) { 76 s.Print(cm.stdout) 77 } 78 fmt.Fprintf(cm.stdout, "ERROR: %v\n", err) 79 } else { 80 resultUpdated = true 81 } 82 cm.m.AttachSession(ref) 83 if resultUpdated { 84 // rollback the running container with the new result 85 id := cm.m.Rollback(ctx, cm.invokeConfig) 86 fmt.Fprintf(cm.stdout, "Interactive container was restarted with process %q. Press Ctrl-a-c to switch to the new container\n", id) 87 } 88 return nil 89 }