github.com/pdmccormick/importable-docker-buildx@v0.0.0-20240426161518-e47091289030/commands/create.go (about)

     1  package commands
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  
     8  	"github.com/docker/buildx/builder"
     9  	"github.com/docker/buildx/driver"
    10  	"github.com/docker/buildx/store/storeutil"
    11  	"github.com/docker/buildx/util/cobrautil"
    12  	"github.com/docker/buildx/util/cobrautil/completion"
    13  	"github.com/docker/cli/cli"
    14  	"github.com/docker/cli/cli/command"
    15  	"github.com/spf13/cobra"
    16  )
    17  
    18  type createOptions struct {
    19  	name                string
    20  	driver              string
    21  	nodeName            string
    22  	platform            []string
    23  	actionAppend        bool
    24  	actionLeave         bool
    25  	use                 bool
    26  	driverOpts          []string
    27  	buildkitdFlags      string
    28  	buildkitdConfigFile string
    29  	bootstrap           bool
    30  	// upgrade      bool // perform upgrade of the driver
    31  }
    32  
    33  func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, args []string) error {
    34  	txn, release, err := storeutil.GetStore(dockerCli)
    35  	if err != nil {
    36  		return err
    37  	}
    38  	// Ensure the file lock gets released no matter what happens.
    39  	defer release()
    40  
    41  	if in.actionLeave {
    42  		return builder.Leave(ctx, txn, dockerCli, builder.LeaveOpts{
    43  			Name:     in.name,
    44  			NodeName: in.nodeName,
    45  		})
    46  	}
    47  
    48  	var ep string
    49  	if len(args) > 0 {
    50  		ep = args[0]
    51  	}
    52  
    53  	b, err := builder.Create(ctx, txn, dockerCli, builder.CreateOpts{
    54  		Name:                in.name,
    55  		Driver:              in.driver,
    56  		NodeName:            in.nodeName,
    57  		Platforms:           in.platform,
    58  		DriverOpts:          in.driverOpts,
    59  		BuildkitdFlags:      in.buildkitdFlags,
    60  		BuildkitdConfigFile: in.buildkitdConfigFile,
    61  		Use:                 in.use,
    62  		Endpoint:            ep,
    63  		Append:              in.actionAppend,
    64  	})
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	// The store is no longer used from this point.
    70  	// Release it so we aren't holding the file lock during the boot.
    71  	release()
    72  
    73  	if in.bootstrap {
    74  		if _, err = b.Boot(ctx); err != nil {
    75  			return err
    76  		}
    77  	}
    78  
    79  	fmt.Printf("%s\n", b.Name)
    80  	return nil
    81  }
    82  
    83  func createCmd(dockerCli command.Cli) *cobra.Command {
    84  	var options createOptions
    85  
    86  	var drivers bytes.Buffer
    87  	for _, d := range driver.GetFactories(true) {
    88  		if len(drivers.String()) > 0 {
    89  			drivers.WriteString(", ")
    90  		}
    91  		drivers.WriteString(fmt.Sprintf(`"%s"`, d.Name()))
    92  	}
    93  
    94  	cmd := &cobra.Command{
    95  		Use:   "create [OPTIONS] [CONTEXT|ENDPOINT]",
    96  		Short: "Create a new builder instance",
    97  		Args:  cli.RequiresMaxArgs(1),
    98  		RunE: func(cmd *cobra.Command, args []string) error {
    99  			return runCreate(cmd.Context(), dockerCli, options, args)
   100  		},
   101  		ValidArgsFunction: completion.Disable,
   102  	}
   103  
   104  	flags := cmd.Flags()
   105  
   106  	flags.StringVar(&options.name, "name", "", "Builder instance name")
   107  	flags.StringVar(&options.driver, "driver", "", fmt.Sprintf("Driver to use (available: %s)", drivers.String()))
   108  	flags.StringVar(&options.nodeName, "node", "", "Create/modify node with given name")
   109  	flags.StringArrayVar(&options.platform, "platform", []string{}, "Fixed platforms for current node")
   110  	flags.StringArrayVar(&options.driverOpts, "driver-opt", []string{}, "Options for the driver")
   111  	flags.StringVar(&options.buildkitdFlags, "buildkitd-flags", "", "BuildKit daemon flags")
   112  
   113  	// we allow for both "--config" and "--buildkitd-config", although the latter is the recommended way to avoid ambiguity.
   114  	flags.StringVar(&options.buildkitdConfigFile, "buildkitd-config", "", "BuildKit daemon config file")
   115  	flags.StringVar(&options.buildkitdConfigFile, "config", "", "BuildKit daemon config file")
   116  	flags.MarkHidden("config")
   117  
   118  	flags.BoolVar(&options.bootstrap, "bootstrap", false, "Boot builder after creation")
   119  	flags.BoolVar(&options.actionAppend, "append", false, "Append a node to builder instead of changing it")
   120  	flags.BoolVar(&options.actionLeave, "leave", false, "Remove a node from builder instead of changing it")
   121  	flags.BoolVar(&options.use, "use", false, "Set the current builder instance")
   122  
   123  	// hide builder persistent flag for this command
   124  	cobrautil.HideInheritedFlags(cmd, "builder")
   125  
   126  	return cmd
   127  }