mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 00:47:48 +08:00

These commands allow working with build records of completed and running builds. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
152 lines
3.0 KiB
Go
152 lines
3.0 KiB
Go
package history
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
|
|
"github.com/docker/buildx/builder"
|
|
"github.com/docker/buildx/util/cobrautil/completion"
|
|
"github.com/docker/cli/cli/command"
|
|
"github.com/hashicorp/go-multierror"
|
|
controlapi "github.com/moby/buildkit/api/services/control"
|
|
"github.com/pkg/errors"
|
|
"github.com/spf13/cobra"
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
type rmOptions struct {
|
|
builder string
|
|
refs []string
|
|
all bool
|
|
}
|
|
|
|
func runRm(ctx context.Context, dockerCli command.Cli, opts rmOptions) error {
|
|
b, err := builder.New(dockerCli, builder.WithName(opts.builder))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
nodes, err := b.LoadNodes(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, node := range nodes {
|
|
if node.Err != nil {
|
|
return node.Err
|
|
}
|
|
}
|
|
|
|
errs := make([][]error, len(opts.refs))
|
|
for i := range errs {
|
|
errs[i] = make([]error, len(nodes))
|
|
}
|
|
|
|
eg, ctx := errgroup.WithContext(ctx)
|
|
for i, node := range nodes {
|
|
node := node
|
|
eg.Go(func() error {
|
|
if node.Driver == nil {
|
|
return nil
|
|
}
|
|
c, err := node.Driver.Client(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
refs := opts.refs
|
|
|
|
if opts.all {
|
|
serv, err := c.ControlClient().ListenBuildHistory(ctx, &controlapi.BuildHistoryRequest{
|
|
EarlyExit: true,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer serv.CloseSend()
|
|
|
|
for {
|
|
resp, err := serv.Recv()
|
|
if err != nil {
|
|
if errors.Is(err, io.EOF) {
|
|
break
|
|
}
|
|
return err
|
|
}
|
|
if resp.Type == controlapi.BuildHistoryEventType_COMPLETE {
|
|
refs = append(refs, resp.Record.Ref)
|
|
}
|
|
}
|
|
}
|
|
|
|
for j, ref := range refs {
|
|
_, err = c.ControlClient().UpdateBuildHistory(ctx, &controlapi.UpdateBuildHistoryRequest{
|
|
Ref: ref,
|
|
Delete: true,
|
|
})
|
|
if opts.all {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
errs[j][i] = err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
if err := eg.Wait(); err != nil {
|
|
return err
|
|
}
|
|
|
|
var out []error
|
|
loop0:
|
|
for _, nodeErrs := range errs {
|
|
var nodeErr error
|
|
for _, err1 := range nodeErrs {
|
|
if err1 == nil {
|
|
continue loop0
|
|
}
|
|
if nodeErr == nil {
|
|
nodeErr = err1
|
|
} else {
|
|
nodeErr = multierror.Append(nodeErr, err1)
|
|
}
|
|
}
|
|
out = append(out, nodeErr)
|
|
}
|
|
if len(out) == 0 {
|
|
return nil
|
|
}
|
|
if len(out) == 1 {
|
|
return out[0]
|
|
}
|
|
return multierror.Append(out[0], out[1:]...)
|
|
}
|
|
|
|
func rmCmd(dockerCli command.Cli, rootOpts RootOptions) *cobra.Command {
|
|
var options rmOptions
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "rm [OPTIONS] [REF...]",
|
|
Short: "Remove build records",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
if len(args) == 0 && !options.all {
|
|
return errors.New("rm requires at least one argument")
|
|
}
|
|
if len(args) > 0 && options.all {
|
|
return errors.New("rm requires either --all or at least one argument")
|
|
}
|
|
options.refs = args
|
|
options.builder = *rootOpts.Builder
|
|
return runRm(cmd.Context(), dockerCli, options)
|
|
},
|
|
ValidArgsFunction: completion.Disable,
|
|
}
|
|
|
|
flags := cmd.Flags()
|
|
flags.BoolVar(&options.all, "all", false, "Remove all build records")
|
|
|
|
return cmd
|
|
}
|