monitor: Enable to run build and invoke in background by ktock · Pull Request #1296 · docker/buildx (original) (raw)

#1104

This commit enables to launch builds in a background process and adds some related commands.
Please give me feedbacks on the design of the detaching and the CLI.

This covers PR4 and PR5 of #1104.

PR4
Refactor build command to invoke builds in a background process. This is important as we don't want the lifecycle of "debugging session" to be locked into a single process. A socket should be created under ~/.buildx and even if the current process (unexpectedly) dies its state can be accessed again via the socket.

PR5
Add list and attach commands to the monitor mode. List would show all the current active sessions (via the socket described in the previous section). Attach would make that session active in current process. If the session is already active in another process these processes would detach and go to the monitor mode.

Example:

BUILDX_EXPERIMENTAL=1 is required to enable detached buildx.

FROM ghcr.io/stargz-containers/busybox:1.32.0-org RUN echo hello > /hello

buildx build

$ BUILDX_EXPERIMENTAL=1 /tmp/out/buildx build --invoke sh /tmp/ctx [+] Building 3.8s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 111B 0.0s => [internal] load .dockerignore 0.1s => => transferring context: 2B 0.0s => [internal] load metadata for ghcr.io/stargz-containers/busybox:1.32.0-org 2.6s => [auth] stargz-containers/busybox:pull token for ghcr.io 0.0s => [1/2] FROM ghcr.io/stargz-containers/busybox:1.32.0-org@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678 0.9s => => resolve ghcr.io/stargz-containers/busybox:1.32.0-org@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678 0.0s => => sha256:ea97eb0eb3ec0bbe00d90be500431050af63c31dc0706c2e8fb53e16cff7761f 764.63kB / 764.63kB 0.8s => => extracting sha256:ea97eb0eb3ec0bbe00d90be500431050af63c31dc0706c2e8fb53e16cff7761f 0.1s => [2/2] RUN echo hello > /hello 0.1s Launching interactive container. Press Ctrl-a-c to switch to monitor console / #

The above command launches two buildx processes: client and server.
The server is detached in a separated session.
The detached buildx server actually runs the build and the foreground client buildx forwards I/O and provides monitor prompt.

ps command on the host:

$ ps -C buildx -o pid,ppid,pgid,sess,tty,comm PID PPID PGID SESS TT COMMAND 2175912 2172353 2175912 2172353 pts/7 buildx 2175934 3904 2175923 2175923 ? buildx

The detached server lives even after the client exits.

$ ps -C buildx -o pid,ppid,pgid,sess,tty,comm PID PPID PGID SESS TT COMMAND 2175934 3904 2175923 2175923 ? buildx

list

list lists available server instances.
USING will be ture if the current monitor connects to that instance.

(buildx) list ID PID STARTED USING buildx3846920277 2176183 40 seconds ago true buildx902825017 2175934 3 minutes ago false

attach

attach attaches to the specified instance.
Monitor commands like reload and rollback can be issued to the newly connected instance.

(buildx) attach buildx902825017 Interactive container was restarted. Press Ctrl-a-c to switch to the new container (buildx) list ID PID STARTED USING buildx3846920277 2176183 About a minute ago false buildx902825017 2175934 3 minutes ago true (buildx) reload [+] Building 0.4s (5/5) FINISHED
=> [internal] load .dockerignore 0.1s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 111B 0.0s => [internal] load metadata for ghcr.io/stargz-containers/busybox:1.32.0-org 0.3s => [1/2] FROM ghcr.io/stargz-containers/busybox:1.32.0-org@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678 0.0s => => resolve ghcr.io/stargz-containers/busybox:1.32.0-org@sha256:bde48e1751173b709090c2539fdf12d6ba64e88ec7a4301591227ce925f3c678 0.0s => CACHED [2/2] RUN echo hello > /hello 0.0s

Interactive container was restarted. Press Ctrl-a-c to switch to the new container (buildx) Switched IO

/ # cat hello hello

kill

kill kills the specified instance.
If no argument is provided, it kills the connecting instance.

(buildx) list ID PID STARTED USING buildx3846920277 2176183 About a minute ago false buildx902825017 2175934 4 minutes ago true (buildx) kill buildx3846920277 (buildx) list ID PID STARTED USING buildx902825017 2175934 4 minutes ago true (buildx) kill (buildx) list ID PID STARTED USING

How it works

buildx build forks and detaches itself as a server daemon. After launching the detached server, the foreground one continues running as a client.

Each buildx server instance provides gRPC API via socket (e.g. ~/.local/share/buildx/<instance-name>/buildx.sock) for serving build and invoke functionalities. buildx client provides monitor prompt and forwards I/O. It issues builds and invokes to the server everytime the user requests on the monitor.

I/O for the build (e.g. Dockerfile via stdin) and container (e.g. stdio) are forwarded via gRPC API similarly done by BuildKit's NewContainer gateway API.

Please note that the server doesn't support multiple clients as of now. Every time the user runs buildx build, it launches a new server process with a newly created socket. If a client requests a build to the server while another client's build is ongoing, the old one is cancelled and the new one starts. In the future, the server can support parallel multiple builds and invokes. Maybe we need some additional refactorings for the buildx build implementation for supporting parallel calls.

TODOs