From 72dab552b5b94a4d9e639a60d589060595d437b9 Mon Sep 17 00:00:00 2001 From: Mayeul Blanzat Date: Wed, 17 Nov 2021 13:56:42 +0100 Subject: [PATCH] Add an option to buildx rm to keep the buildkitd daemon running Add --keep-daemon to the `rm` command option to preserve the buildkitd daemon after the buildx context is deleted. Signed-off-by: Mayeul Blanzat --- commands/rm.go | 24 +++++++++++++++--------- docs/reference/buildx_rm.md | 6 ++++++ driver/docker-container/driver.go | 22 ++++++++++++---------- driver/docker/driver.go | 2 +- driver/driver.go | 2 +- driver/kubernetes/driver.go | 6 +++++- 6 files changed, 40 insertions(+), 22 deletions(-) diff --git a/commands/rm.go b/commands/rm.go index 1acb1ab7f37..ab19bbef9a5 100644 --- a/commands/rm.go +++ b/commands/rm.go @@ -12,8 +12,9 @@ import ( ) type rmOptions struct { - builder string - keepState bool + builder string + keepState bool + keepDaemon bool } func runRm(dockerCli command.Cli, in rmOptions) error { @@ -30,7 +31,7 @@ func runRm(dockerCli command.Cli, in rmOptions) error { if err != nil { return err } - err1 := rm(ctx, dockerCli, ng, in.keepState) + err1 := rm(ctx, dockerCli, ng, in.keepState, in.keepDaemon) if err := txn.Remove(ng.Name); err != nil { return err } @@ -42,7 +43,7 @@ func runRm(dockerCli command.Cli, in rmOptions) error { return err } if ng != nil { - err1 := rm(ctx, dockerCli, ng, in.keepState) + err1 := rm(ctx, dockerCli, ng, in.keepState, in.keepDaemon) if err := txn.Remove(ng.Name); err != nil { return err } @@ -70,23 +71,28 @@ func rmCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { flags := cmd.Flags() flags.BoolVar(&options.keepState, "keep-state", false, "Keep BuildKit state") + flags.BoolVar(&options.keepDaemon, "keep-daemon", false, "Keep the buildkitd daemon running") return cmd } -func rm(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, keepState bool) error { +func rm(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, keepState, keepDaemon bool) error { dis, err := driversForNodeGroup(ctx, dockerCli, ng, "") if err != nil { return err } for _, di := range dis { - if di.Driver != nil { + if di.Driver == nil { + continue + } + // Do not stop the buildkitd daemon when --keep-daemon is provided + if !keepDaemon { if err := di.Driver.Stop(ctx, true); err != nil { return err } - if err := di.Driver.Rm(ctx, true, !keepState); err != nil { - return err - } + } + if err := di.Driver.Rm(ctx, true, !keepState, !keepDaemon); err != nil { + return err } if di.Err != nil { err = di.Err diff --git a/docs/reference/buildx_rm.md b/docs/reference/buildx_rm.md index 8f4895a674c..28ac60cb0ee 100644 --- a/docs/reference/buildx_rm.md +++ b/docs/reference/buildx_rm.md @@ -12,6 +12,7 @@ Remove a builder instance | Name | Description | | --- | --- | | [`--builder string`](#builder) | Override the configured builder instance | +| [`--keep-daemon`](#keep-daemon) | Keep the buildkitd daemon running | | [`--keep-state`](#keep-state) | Keep BuildKit state | @@ -32,3 +33,8 @@ Same as [`buildx --builder`](buildx.md#builder). Keep BuildKit state, so it can be reused by a new builder with the same name. Currently, only supported by the [`docker-container` driver](buildx_create.md#driver). + +### Keep the buildkitd daemon running (--keep-daemon) + +Keep the buildkitd daemon running after the buildx context is removed. This is useful when you manage buildkitd daemons and buildx contexts independently. +Currently, only supported by the [`docker-container` and `kubernetes` drivers](buildx_create.md#driver). diff --git a/driver/docker-container/driver.go b/driver/docker-container/driver.go index 9ea1a78ae7c..912a878bf6d 100644 --- a/driver/docker-container/driver.go +++ b/driver/docker-container/driver.go @@ -295,7 +295,7 @@ func (d *Driver) Stop(ctx context.Context, force bool) error { return nil } -func (d *Driver) Rm(ctx context.Context, force bool, rmVolume bool) error { +func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error { info, err := d.Info(ctx) if err != nil { return err @@ -305,20 +305,22 @@ func (d *Driver) Rm(ctx context.Context, force bool, rmVolume bool) error { if err != nil { return err } - if err := d.DockerAPI.ContainerRemove(ctx, d.Name, dockertypes.ContainerRemoveOptions{ - RemoveVolumes: true, - Force: force, - }); err != nil { - return err - } - for _, v := range container.Mounts { - if v.Name == d.Name+volumeStateSuffix { + if rmDaemon { + if err := d.DockerAPI.ContainerRemove(ctx, d.Name, dockertypes.ContainerRemoveOptions{ + RemoveVolumes: true, + Force: force, + }); err != nil { + return err + } + for _, v := range container.Mounts { + if v.Name != d.Name+volumeStateSuffix { + continue + } if rmVolume { return d.DockerAPI.VolumeRemove(ctx, d.Name+volumeStateSuffix, false) } } } - } return nil } diff --git a/driver/docker/driver.go b/driver/docker/driver.go index f38ec165082..26b6198bde4 100644 --- a/driver/docker/driver.go +++ b/driver/docker/driver.go @@ -33,7 +33,7 @@ func (d *Driver) Stop(ctx context.Context, force bool) error { return nil } -func (d *Driver) Rm(ctx context.Context, force bool, rmVolume bool) error { +func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error { return nil } diff --git a/driver/driver.go b/driver/driver.go index b9272a505a9..1eceb5aac87 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -54,7 +54,7 @@ type Driver interface { Bootstrap(context.Context, progress.Logger) error Info(context.Context) (*Info, error) Stop(ctx context.Context, force bool) error - Rm(ctx context.Context, force bool, rmVolume bool) error + Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error Client(ctx context.Context) (*client.Client, error) Features() map[Feature]bool IsMobyDriver() bool diff --git a/driver/kubernetes/driver.go b/driver/kubernetes/driver.go index 7e524e4b79e..92725dff03f 100644 --- a/driver/kubernetes/driver.go +++ b/driver/kubernetes/driver.go @@ -165,7 +165,11 @@ func (d *Driver) Stop(ctx context.Context, force bool) error { return nil } -func (d *Driver) Rm(ctx context.Context, force bool, rmVolume bool) error { +func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error { + if !rmDaemon { + return nil + } + if err := d.deploymentClient.Delete(ctx, d.deployment.Name, metav1.DeleteOptions{}); err != nil { if !apierrors.IsNotFound(err) { return errors.Wrapf(err, "error while calling deploymentClient.Delete for %q", d.deployment.Name)