From ef29ef65a28678f49335b3ee4bc78683e51a28a3 Mon Sep 17 00:00:00 2001 From: Kohei Tokunaga Date: Tue, 27 Jun 2023 22:10:53 +0900 Subject: [PATCH 1/2] monitor: on-error: support long-form for allowing changing the shell Signed-off-by: Kohei Tokunaga --- commands/build.go | 52 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/commands/build.go b/commands/build.go index 7feee06e1f45..0d097e7a25d1 100644 --- a/commands/build.go +++ b/commands/build.go @@ -437,7 +437,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { return err } options.invoke = &invoke - options.noBuild = invokeFlag == "debug-shell" + options.noBuild = invoke.isNoBuild() } return runBuild(dockerCli, options) }, @@ -681,34 +681,59 @@ func updateLastActivity(dockerCli command.Cli, ng *store.NodeGroup) error { type invokeConfig struct { controllerapi.InvokeConfig - invokeFlag string + invokeType string +} + +const ( + // invokeTypeDefault is a type of invoking that runs the monitor and the interactive container + // with the default configuration of the build step, after the build finished. + invokeTypeDefault = "default" + + // invokeTypeConfig is a type of invoking that runs the monitor and the interactive container + // with the specified configuration of the build step, after the build finished. + invokeTypeConfig = "config" + + // invokeTypeDebugShell is a type of invoking that doesn't perform a build but immediately + // launch the monitor. + invokeTypeDebugShell = "debug-shell" + + // invokeTypeOnError is a type of invoking that starts the monitor and the interactive container + // when the build finished with error. + invokeTypeOnError = "on-error" +) + +func (cfg *invokeConfig) isNoBuild() bool { + return cfg.invokeType == invokeTypeDebugShell } func (cfg *invokeConfig) needsMonitor(retErr error) bool { - switch cfg.invokeFlag { - case "debug-shell": + switch cfg.invokeType { + case invokeTypeDebugShell: return true - case "on-error": + case invokeTypeOnError: return retErr != nil default: - return cfg.invokeFlag != "" + return cfg.invokeType != "" } } func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) { - cfg.invokeFlag = invoke cfg.Tty = true switch invoke { - case "default", "debug-shell": + case invokeTypeDefault, invokeTypeDebugShell: + cfg.invokeType = invoke return cfg, nil - case "on-error": - // NOTE: we overwrite the command to run because the original one should fail on the failed step. - // TODO: make this configurable via flags or restorable from LLB. + case invokeTypeOnError: + // NOTE: We overwrite the command to run because the original one should fail on the failed step. + // User can use long-form (w/ "type=on-error") to customize the command. + // TODO: make this restorable from LLB if needed. // Discussion: https://github.com/docker/buildx/pull/1640#discussion_r1113295900 cfg.Cmd = []string{"/bin/sh"} + cfg.invokeType = invoke return cfg, nil } + cfg.invokeType = invokeTypeConfig csvReader := csv.NewReader(strings.NewReader(invoke)) csvReader.LazyQuotes = true fields, err := csvReader.Read() @@ -749,6 +774,11 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) { if err != nil { return cfg, errors.Errorf("failed to parse tty: %v", err) } + case "type": + if value != invokeTypeOnError && value != invokeTypeConfig { + return cfg, errors.Errorf("\"on-error\" or \"config\" are only supported as the custom type") + } + cfg.invokeType = value default: return cfg, errors.Errorf("unknown key %q", key) } From 0e4b938d0dbf2420f858e9ca0a84c5d8a16a4c97 Mon Sep 17 00:00:00 2001 From: Kohei Tokunaga Date: Tue, 27 Jun 2023 22:11:34 +0900 Subject: [PATCH 2/2] monitor: on-error: add docs for long form Signed-off-by: Kohei Tokunaga --- docs/guides/debugging.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/guides/debugging.md b/docs/guides/debugging.md index 08e686316b0c..10262dd423f0 100644 --- a/docs/guides/debugging.md +++ b/docs/guides/debugging.md @@ -51,14 +51,19 @@ dev home media opt root sbin sys usr work Optional long form allows you specifying detailed configurations of the process. It must be CSV-styled comma-separated key-value pairs. -Supported keys are `args` (can be JSON array format), `entrypoint` (can be JSON array format), `env` (can be JSON array format), `user`, `cwd` and `tty` (bool). +Supported keys for configuring containers are `args` (can be JSON array format), `entrypoint` (can be JSON array format), `env` (can be JSON array format), `user`, `cwd` and `tty` (bool). +You can also specify `type=on-error` if you want to change the configuration of the container (e.g. commands to execute) that will be executed from the failed step. -Example: +Examples: ``` $ docker buildx build --invoke 'entrypoint=["sh"],"args=[""-c"", ""env | grep -e FOO -e AAA""]","env=[""FOO=bar"", ""AAA=bbb""]"' . ``` +``` +$ docker buildx build --invoke 'type=on-error,args=bash' . +``` + #### `on-error` If you want to start a debug session when a build fails, you can use @@ -85,6 +90,12 @@ Interactive container was restarted with process "edmzor60nrag7rh1mbi4o9lm8". Pr This allows you to explore the state of the image when the build failed. +You can also use long-form flag with `type=on-error` option. + +``` +$ docker buildx build --invoke 'type=on-error,args=bash' . +``` + #### `debug-shell` If you want to drop into a debug session without first starting the build, you