mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-19 01:47:43 +08:00
cli: add --all-inactive and --force flags for rm command
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
parent
33c121df01
commit
378f0b45c6
@ -2,36 +2,53 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/docker/buildx/store"
|
"github.com/docker/buildx/store"
|
||||||
"github.com/docker/buildx/store/storeutil"
|
"github.com/docker/buildx/store/storeutil"
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/moby/buildkit/util/appcontext"
|
"github.com/moby/buildkit/util/appcontext"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
type rmOptions struct {
|
type rmOptions struct {
|
||||||
builder string
|
builder string
|
||||||
keepState bool
|
keepState bool
|
||||||
keepDaemon bool
|
keepDaemon bool
|
||||||
|
allInactive bool
|
||||||
|
force bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
rmInactiveWarning = `WARNING! This will remove all builders that are not in running state. Are you sure you want to continue?`
|
||||||
|
)
|
||||||
|
|
||||||
func runRm(dockerCli command.Cli, in rmOptions) error {
|
func runRm(dockerCli command.Cli, in rmOptions) error {
|
||||||
ctx := appcontext.Context()
|
ctx := appcontext.Context()
|
||||||
|
|
||||||
|
if in.allInactive && !in.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), rmInactiveWarning) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
txn, release, err := storeutil.GetStore(dockerCli)
|
txn, release, err := storeutil.GetStore(dockerCli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
|
if in.allInactive {
|
||||||
|
return rmAllInactive(ctx, txn, dockerCli, in)
|
||||||
|
}
|
||||||
|
|
||||||
if in.builder != "" {
|
if in.builder != "" {
|
||||||
ng, err := storeutil.GetNodeGroup(txn, dockerCli, in.builder)
|
ng, err := storeutil.GetNodeGroup(txn, dockerCli, in.builder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err1 := rm(ctx, dockerCli, ng, in.keepState, in.keepDaemon)
|
err1 := rm(ctx, dockerCli, in, ng)
|
||||||
if err := txn.Remove(ng.Name); err != nil {
|
if err := txn.Remove(ng.Name); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -43,7 +60,7 @@ func runRm(dockerCli command.Cli, in rmOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if ng != nil {
|
if ng != nil {
|
||||||
err1 := rm(ctx, dockerCli, ng, in.keepState, in.keepDaemon)
|
err1 := rm(ctx, dockerCli, in, ng)
|
||||||
if err := txn.Remove(ng.Name); err != nil {
|
if err := txn.Remove(ng.Name); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -63,6 +80,9 @@ func rmCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
|||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
options.builder = rootOpts.builder
|
options.builder = rootOpts.builder
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
|
if options.allInactive {
|
||||||
|
return errors.New("cannot specify builder name when --all-inactive is set")
|
||||||
|
}
|
||||||
options.builder = args[0]
|
options.builder = args[0]
|
||||||
}
|
}
|
||||||
return runRm(dockerCli, options)
|
return runRm(dockerCli, options)
|
||||||
@ -72,11 +92,13 @@ func rmCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
|||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
flags.BoolVar(&options.keepState, "keep-state", false, "Keep BuildKit state")
|
flags.BoolVar(&options.keepState, "keep-state", false, "Keep BuildKit state")
|
||||||
flags.BoolVar(&options.keepDaemon, "keep-daemon", false, "Keep the buildkitd daemon running")
|
flags.BoolVar(&options.keepDaemon, "keep-daemon", false, "Keep the buildkitd daemon running")
|
||||||
|
flags.BoolVar(&options.allInactive, "all-inactive", false, "Remove all inactive builders")
|
||||||
|
flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func rm(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, keepState, keepDaemon bool) error {
|
func rm(ctx context.Context, dockerCli command.Cli, in rmOptions, ng *store.NodeGroup) error {
|
||||||
dis, err := driversForNodeGroup(ctx, dockerCli, ng, "")
|
dis, err := driversForNodeGroup(ctx, dockerCli, ng, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -86,12 +108,12 @@ func rm(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, keepSta
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Do not stop the buildkitd daemon when --keep-daemon is provided
|
// Do not stop the buildkitd daemon when --keep-daemon is provided
|
||||||
if !keepDaemon {
|
if !in.keepDaemon {
|
||||||
if err := di.Driver.Stop(ctx, true); err != nil {
|
if err := di.Driver.Stop(ctx, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := di.Driver.Rm(ctx, true, !keepState, !keepDaemon); err != nil {
|
if err := di.Driver.Rm(ctx, true, !in.keepState, !in.keepDaemon); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if di.Err != nil {
|
if di.Err != nil {
|
||||||
@ -100,3 +122,42 @@ func rm(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, keepSta
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func rmAllInactive(ctx context.Context, txn *store.Txn, dockerCli command.Cli, in rmOptions) error {
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 20*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
ll, err := txn.List()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
builders := make([]*nginfo, len(ll))
|
||||||
|
for i, ng := range ll {
|
||||||
|
builders[i] = &nginfo{ng: ng}
|
||||||
|
}
|
||||||
|
|
||||||
|
eg, _ := errgroup.WithContext(ctx)
|
||||||
|
for _, b := range builders {
|
||||||
|
func(b *nginfo) {
|
||||||
|
eg.Go(func() error {
|
||||||
|
if err := loadNodeGroupData(ctx, dockerCli, b); err != nil {
|
||||||
|
return errors.Wrapf(err, "cannot load %s", b.ng.Name)
|
||||||
|
}
|
||||||
|
if b.ng.Dynamic {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if b.inactive() {
|
||||||
|
rmerr := rm(ctx, dockerCli, in, b.ng)
|
||||||
|
if err := txn.Remove(b.ng.Name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return rmerr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
return eg.Wait()
|
||||||
|
}
|
||||||
|
@ -389,6 +389,17 @@ type nginfo struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inactive checks if all nodes are inactive for this builder
|
||||||
|
func (n *nginfo) inactive() bool {
|
||||||
|
for idx := range n.ng.Nodes {
|
||||||
|
d := n.drivers[idx]
|
||||||
|
if d.info != nil && d.info.Status == driver.Running {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func boot(ctx context.Context, ngi *nginfo) (bool, error) {
|
func boot(ctx context.Context, ngi *nginfo) (bool, error) {
|
||||||
toBoot := make([]int, 0, len(ngi.drivers))
|
toBoot := make([]int, 0, len(ngi.drivers))
|
||||||
for i, d := range ngi.drivers {
|
for i, d := range ngi.drivers {
|
||||||
|
@ -11,7 +11,9 @@ Remove a builder instance
|
|||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|
| [`--all-inactive`](#all-inactive) | Remove all inactive builders |
|
||||||
| [`--builder string`](#builder) | Override the configured builder instance |
|
| [`--builder string`](#builder) | Override the configured builder instance |
|
||||||
|
| [`-f`](#force), [`--force`](#force) | Do not prompt for confirmation |
|
||||||
| [`--keep-daemon`](#keep-daemon) | Keep the buildkitd daemon running |
|
| [`--keep-daemon`](#keep-daemon) | Keep the buildkitd daemon running |
|
||||||
| [`--keep-state`](#keep-state) | Keep BuildKit state |
|
| [`--keep-state`](#keep-state) | Keep BuildKit state |
|
||||||
|
|
||||||
@ -25,16 +27,33 @@ default builder.
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
### <a name="all-inactive"></a> Remove all inactive builders (--all-inactive)
|
||||||
|
|
||||||
|
Remove builders that are not in running state.
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker buildx rm --all-inactive
|
||||||
|
WARNING! This will remove all builders that are not in running state. Are you sure you want to continue? [y/N] y
|
||||||
|
```
|
||||||
|
|
||||||
### <a name="builder"></a> Override the configured builder instance (--builder)
|
### <a name="builder"></a> Override the configured builder instance (--builder)
|
||||||
|
|
||||||
Same as [`buildx --builder`](buildx.md#builder).
|
Same as [`buildx --builder`](buildx.md#builder).
|
||||||
|
|
||||||
### <a name="keep-state"></a> Keep BuildKit state (--keep-state)
|
### <a name="force"></a> Do not prompt for confirmation (--force)
|
||||||
|
|
||||||
Keep BuildKit state, so it can be reused by a new builder with the same name.
|
Do not prompt for confirmation before removing inactive builders.
|
||||||
Currently, only supported by the [`docker-container` driver](buildx_create.md#driver).
|
|
||||||
|
```console
|
||||||
|
$ docker buildx rm --all-inactive --force
|
||||||
|
```
|
||||||
|
|
||||||
### <a name="keep-daemon"></a> Keep the buildkitd daemon running (--keep-daemon)
|
### <a name="keep-daemon"></a> 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.
|
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).
|
Currently, only supported by the [`docker-container` and `kubernetes` drivers](buildx_create.md#driver).
|
||||||
|
|
||||||
|
### <a name="keep-state"></a> Keep BuildKit state (--keep-state)
|
||||||
|
|
||||||
|
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).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user