-
Notifications
You must be signed in to change notification settings - Fork 503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
debug: Add buildx debug
command
#2006
Conversation
80bb8e0
to
274c1ce
Compare
It seems that we need to fix https://github.com/docker/docs as well to pass the CI?
|
Ah right that's because we have a stub file upstream for |
commands/root.go
Outdated
@@ -87,8 +88,10 @@ func addCommands(cmd *cobra.Command, dockerCli command.Cli) { | |||
imagetoolscmd.RootCmd(dockerCli, imagetoolscmd.RootOptions{Builder: &opts.builder}), | |||
) | |||
if isExperimental() { | |||
cmd.AddCommand(debugcmd.RootCmd(dockerCli, func(dops debugcmd.DebugOptions) *cobra.Command { | |||
return buildCmd(dockerCli, opts, dops) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are just debugging the build
cmd so sounds good to have buildx debug
defaulting to build atm but could be any root cmd in the future such as bake
with buildx debug bake
so we might consider passing cmd
instead and have a "debug" interface for each command supporting debug. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion! It sounds good to me. I've fixed the patch to pass *cobra.Command
with the debugger interface to debugcmd.RootCmd
. PTAL 🙏
934e927
to
55691f3
Compare
commands/debug/shell.go
Outdated
var options control.ControlOptions | ||
var progressMode string | ||
|
||
cmd := &cobra.Command{ | ||
Use: "debug-shell", | ||
Use: "shell", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, we could just have shell
be the top-level command, so docker buildx debug
drops you directly into the shell.
Then we don't need a separate command for it, and it kind of acts as debug
is your portal to all debugging stuff. The top-level debug
command needs to do something anyways, and to me this makes the most sense.
Also, if we drop shell
, it means that we could potentially have every command after debug
can be run without the debug
- debug build
corresponds to build
, debug bake
corresponds to bake
, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion! Fixed the patch to launch the debugger directly by buildx debug
command.
Aha, thanks @ktock 🎉 This looks like a perfect start, just one real comment, otherwise looks good! |
commands/debug/root.go
Outdated
|
||
// DebugConfig is a user-specified configuration for the debugger. | ||
type DebugConfig struct { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: empty line (also below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Off-topic: is there any way we can get this linted / auto-formatted? I know that gofumpt
has a rule for this, but there's some other rules in there that are a bit more controversial IMO. @crazy-max any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at gofumpt
and wsl
linters and don't see any rules for this case 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah they have rules like this for functions at least in "No empty lines around function bodies" but not for generic blocks
@ktock Following @dvdksn comment in docker/docs#17947 (comment), I have disabled the |
Thanks! |
@@ -515,8 +515,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { | |||
flags.StringVar(&options.provenance, "provenance", "", `Shorthand for "--attest=type=provenance"`) | |||
|
|||
if isExperimental() { | |||
flags.StringVar(&invokeFlag, "invoke", "", "Invoke a command after the build") | |||
flags.SetAnnotation("invoke", "experimentalCLI", nil) | |||
// TODO: move this to debug command if needed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
root
, detach
and server-config
flags don't look necessary anymore for build
command right? Looks to be already available in debug
root cmd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe? Technically a non debugged build can still run on the remote controller, so maybe best to leave it here for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ktock!
This gets closer to what I was imagining 🎉
I wonder, (and maybe this is something to look into with the "extra" args after a --
component) if we should always drop into a shell when using a debug
subcommand? To me, that would feel like a logical default.
PTAL @tonistiigi
e18f57d
to
da87cb4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- When I run
buildx debug
(no arguments) and thenexec sh
I get
Process "i7xkjhw104urtoth9pboe0ug6" started. Press Ctrl-a-c to switch to that process.
(buildx) Switched IO
Switched IO
But there is no process, nor build context.
- I'm not sure if this is specifically in this PR but enabling debugger breaks stacktraces. Without the opt-in I get.
Dockerfile:60
--------------------
59 | ARG TARGETPLATFORM
60 | >>> RUN2 --mount=type=bind,target=. \
61 | >>> --mount=type=cache,target=/root/.cache \
62 | >>> --mount=type=cache,target=/go/pkg/mod \
63 | >>> --mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT
64 | set -e
--------------------
ERROR: failed to solve: dockerfile parse error on line 60: unknown instruction: RUN2 (did you mean RUN?)
but with this only
ERROR: dockerfile parse error on line 60: unknown instruction: RUN2 (did you mean RUN?)
This is without any extra flags, just with BUILDX_EXPERIMANTAL=1 docker buildx debug build .
-
docker buildx debug --on=error build .
with Dockerfile error I don't see any error printed at all, nor stacktrace. Only after I close the monitor I see the error printed. -
I think
--on
should default toerror
ondebug build
. Atm. I don't see any differences betweenbuildx build
andbuildx debug build
. -
Issuing
rollback
command always seems to returncontext canceled
error.
Interactive container was restarted with process "4qa81kfpppzkoawwhh052bbn4". Press Ctrl-a-c to switch to the new container
(buildx) Switched IO
ERROR: failed to exec process: context canceled
ERROR: failed to exec process: context canceled
-
Follow-up.
--on=error
on a container error gets me in the container but there is no context of what happened, what was the last command etc. I think the help command or monitor messages should give context about what is the current interactive context (build result for specific target, error result from command) so there is context of what gets run onexec/reload/rollback
. -
Follow-up. We need
ls
command that would list the files in the current dir. If I get error likerunc run failed: unable to start container process: exec: "sh": executable file not found in $PATH
then I have no idea what I'm missing. This could also be exec of debug image what has the current mounts mounted somewhere.
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
@tonistiigi Thanks for the comments!
In the future, we should create a new session for these cases with user-configured "default" image.
Fixed (8da8ee2)
Fixed(0dd89f6)
Fixed (5a0e4c1).
This is because The following-ups will be separated PRs.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I think we can merge this now in the current state, but some more follow-ups:
- Let's say I have two different types of errors. One is wrong Dockerfile command and another is process error.
Dockerfile:60
--------------------
59 | ARG TARGETPLATFORM
60 | >>> RUN2 --mount=type=bind,target=. \
61 | >>> --mount=type=cache,target=/root/.cache \
62 | >>> --mount=type=cache,target=/go/pkg/mod \
63 | >>> --mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT
64 | set -e
--------------------
ERROR: dockerfile parse error on line 60: unknown instruction: RUN2 (did you mean RUN?)
[+] Building 0.0s (0/0) docker:desktop-linux
Launching interactive container. Press Ctrl-a-c to switch to monitor console
Interactive container was restarted with process "o5e8x1ty9nn2j93m62b8zmhdn". Press Ctrl-a-c to switch to the new container
Switched IO
------
Dockerfile:60
--------------------
59 | ARG TARGETPLATFORM
60 | >>> RUN --mount=type=bind,target=. \
61 | >>> --mount=type=cache,target=/root/.cache \
62 | >>> --mount=type=cache,target=/go/pkg/mod \
63 | >>> --mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT
64 | >>> set -e
65 | >>> xx-go2 --wrap
66 | >>> DESTDIR=/usr/bin VERSION=$(cat /buildx-version/version) REVISION=$(cat /buildx-version/revision) GO_EXTRA_LDFLAGS="-s -w" ./hack/build
67 | >>> xx-verify --static /usr/bin/docker-buildx
68 | >>> EOT
69 |
--------------------
ERROR: process "/bin/sh -c set -e\n xx-go2 --wrap\n DESTDIR=/usr/bin VERSION=$(cat /buildx-version/version) REVISION=$(cat /buildx-version/revision) GO_EXTRA_LDFLAGS=\"-s -w\" ./hack/build\n xx-verify --static /usr/bin/docker-buildx\n" did not complete successfully: exit code: 127
[+] Building 0.0s (0/0) docker:desktop-linux
Launching interactive container. Press Ctrl-a-c to switch to monitor console
Interactive container was restarted with process "l3x31fm3i08owokoxwtazeuuw". Press Ctrl-a-c to switch to the new container
/ #
As expected only the second one is debuggable (only second one opens shell as well). But from the output they print same messages about interactive containers and switching IO. It should be more clear that these are different types of errors, why first one does not create execution context and what runs in the shell of second one.
- There is an error in Dockerfile command (eg. change
RUN
toRUN2
). I get an error. Now I runreload
. It builds up to the Dockerfile error again but this time I don't see any error. It just shows:
(buildx) reload
[+] Building 0.6s (4/4) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 4.74kB 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 45B 0.0s
=> resolve image config for docker.io/docker/dockerfile:1 0.5s
=> CACHED docker-image://docker.io/docker/dockerfile:1@sha256:ac85f380a63b13dfcefa89046420e1781752bab202122f8f50032edf31be0021 0.0s
Interactive container was restarted with process "p1zsu784bbr3orf8t1g5by9j7". Press Ctrl-a-c to switch to the new container
Switched IO
Switched IO
(buildx)
- I run
debug build .
and get an error. I fix the error and issuereload
. Now my build succeeds. I run some more interactive processes and eventually close the debugger. Now I get an error.
(buildx)
[+] Building 0.0s (0/0) docker:desktop-linux
Dockerfile:60
--------------------
59 | ARG TARGETPLATFORM
60 | >>> RUN2 --mount=type=bind,target=. \
61 | >>> --mount=type=cache,target=/root/.cache \
62 | >>> --mount=type=cache,target=/go/pkg/mod \
63 | >>> --mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT
64 | set -e
--------------------
ERROR: dockerfile parse error on line 60: unknown instruction: RUN2 (did you mean RUN?)
What I think is the error from the very first build invocation.
- (We can discuss this more in the issue before any actual work). When I reach an error I don't think there is a way to switch to the clean state before the failed command to try running it again. My options are to reload to rebuild from source or rollback that resets my local changes but I still seem to have the state that the command that failed generated before it errored.
Thanks for the feedback. The following will be fixed by #2086
I think the following is already done by
I've recorded Other following-up issues to #1104 (comment) |
This commit refactors the debugger flags by adding
buildx debug
command that can be used for launching the monitor.This implements the following features proposed by @jedevc and @crazy-max (#1104 (comment))
Examples
This launches a monitor after the build.
/bin/sh
will be invoked in the result image.This launches a monitor after the build only when the build fails.
/bin/sh
will be invoked in the result image.The following immediately launches the monitor.
Notes
buildx debug
and this commit introducesbuildx debug
for launching the monitor directly, this commit removedbuildx build --invoke=debug-shell
flag. Please let me know if we shouldn't remove this.I've implementedImplementedbuildx debug shell
for launching monitor but notbuildx debug
. Please let me know if we should have both of them.buildx debug
based on the comment debug: Addbuildx debug
command #2006 (comment) .buildx deubg
, the following proposal isn't included in this PR.