mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
commands: add implementations for create, use, rm, stop
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
@ -12,7 +12,6 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/tonistiigi/buildx/build"
|
||||
"github.com/tonistiigi/buildx/driver"
|
||||
"github.com/tonistiigi/buildx/util/progress"
|
||||
)
|
||||
|
||||
@ -103,7 +102,7 @@ func runBuild(dockerCli command.Cli, in buildOptions) error {
|
||||
}
|
||||
|
||||
func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]build.Options, progressMode string) error {
|
||||
d, err := driver.GetDriver(ctx, "buildx-buildkit-default", nil, dockerCli.Client())
|
||||
dis, err := getDefaultDrivers(ctx, dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -112,7 +111,7 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]bu
|
||||
defer cancel()
|
||||
pw := progress.NewPrinter(ctx2, os.Stderr, progressMode)
|
||||
|
||||
_, err = build.Build(ctx, []driver.Driver{d}, opts, pw)
|
||||
_, err = build.Build(ctx, dis, opts, pw)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,16 @@ package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/moby/buildkit/util/appcontext"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tonistiigi/buildx/driver"
|
||||
"github.com/tonistiigi/buildx/store"
|
||||
)
|
||||
|
||||
type createOptions struct {
|
||||
@ -15,11 +21,119 @@ type createOptions struct {
|
||||
platform []string
|
||||
actionAppend bool
|
||||
actionLeave bool
|
||||
use bool
|
||||
// upgrade bool // perform upgrade of the driver
|
||||
}
|
||||
|
||||
func runCreate(dockerCli command.Cli, in createOptions) error {
|
||||
fmt.Printf("%+v\n", in)
|
||||
func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
||||
ctx := appcontext.Context()
|
||||
|
||||
if in.name == "default" {
|
||||
return errors.Errorf("default is a reserved name and can't be used to identify builder instance")
|
||||
}
|
||||
|
||||
if in.actionLeave {
|
||||
if in.name == "" {
|
||||
return errors.Errorf("leave requires instance name")
|
||||
}
|
||||
if in.nodeName == "" {
|
||||
return errors.Errorf("leave requires node name but --node not set")
|
||||
}
|
||||
}
|
||||
|
||||
if in.actionAppend {
|
||||
if in.name == "" {
|
||||
logrus.Warnf("append used without name, creating a new instance instead")
|
||||
}
|
||||
}
|
||||
|
||||
driverName := in.driver
|
||||
if driverName == "" {
|
||||
f, err := driver.GetDefaultFactory(ctx, dockerCli.Client(), true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if f == nil {
|
||||
return errors.Errorf("no valid drivers found")
|
||||
}
|
||||
driverName = f.Name()
|
||||
}
|
||||
|
||||
if driver.GetFactory(driverName, true) == nil {
|
||||
return errors.Errorf("failed to find driver %q", in.driver)
|
||||
}
|
||||
|
||||
txn, release, err := getStore(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer release()
|
||||
|
||||
name := in.name
|
||||
if name == "" {
|
||||
name, err = store.GenerateName(txn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ng, err := txn.NodeGroupByName(name)
|
||||
if err != nil {
|
||||
if os.IsNotExist(errors.Cause(err)) {
|
||||
if in.actionAppend && in.name != "" {
|
||||
logrus.Warnf("failed to find %q for append, creating a new instance instead", in.name)
|
||||
}
|
||||
if in.actionLeave {
|
||||
return errors.Errorf("failed to find instance %q for leave", name)
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if ng == nil {
|
||||
ng = &store.NodeGroup{
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
if ng.Driver == "" || in.driver != "" {
|
||||
ng.Driver = driverName
|
||||
}
|
||||
|
||||
var ep string
|
||||
if in.actionLeave {
|
||||
if err := ng.Leave(in.nodeName); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if len(args) > 0 {
|
||||
ep, err = validateEndpoint(dockerCli, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
ep, err = getCurrentEndpoint(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := ng.Update(in.nodeName, ep, in.platform, len(args) > 0, in.actionAppend); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := txn.Save(ng); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if in.use && ep != "" {
|
||||
if err := txn.SetCurrent(ep, ng.Name, false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", ng.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -31,7 +145,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command {
|
||||
Short: "Create a new builder instance",
|
||||
Args: cli.RequiresMaxArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runCreate(dockerCli, options)
|
||||
return runCreate(dockerCli, options, args)
|
||||
},
|
||||
}
|
||||
|
||||
@ -44,6 +158,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
flags.BoolVar(&options.actionAppend, "append", false, "Append a node to builder instead of changing it")
|
||||
flags.BoolVar(&options.actionLeave, "leave", false, "Remove a node from builder instead of changing it")
|
||||
flags.BoolVar(&options.use, "use", false, "Set the current builder instance")
|
||||
|
||||
_ = flags
|
||||
|
||||
|
@ -1,19 +1,53 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tonistiigi/buildx/store"
|
||||
)
|
||||
|
||||
type inspectOptions struct {
|
||||
bootstrap bool
|
||||
}
|
||||
|
||||
func runInspect(dockerCli command.Cli, in inspectOptions) error {
|
||||
fmt.Printf("%+v\n", in)
|
||||
func runInspect(dockerCli command.Cli, in inspectOptions, args []string) error {
|
||||
txn, release, err := getStore(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer release()
|
||||
|
||||
var ng *store.NodeGroup
|
||||
|
||||
if len(args) > 0 {
|
||||
ng, err = txn.NodeGroupByName(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
ng, err = getCurrentInstance(txn, dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if ng == nil {
|
||||
ep, err := getCurrentEndpoint(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ng = &store.NodeGroup{
|
||||
Name: "default",
|
||||
Nodes: []store.Node{
|
||||
{
|
||||
Name: "default",
|
||||
Endpoint: ep,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -25,7 +59,7 @@ func inspectCmd(dockerCli command.Cli) *cobra.Command {
|
||||
Short: "Inspect current builder instance",
|
||||
Args: cli.RequiresMaxArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runInspect(dockerCli, options)
|
||||
return runInspect(dockerCli, options, args)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,11 @@ type lsOptions struct {
|
||||
}
|
||||
|
||||
func runLs(dockerCli command.Cli, in lsOptions) error {
|
||||
fmt.Printf("current config file: %+v\n", dockerCli.ConfigFile().Filename)
|
||||
fmt.Printf("current context: %+v\n", dockerCli.CurrentContext())
|
||||
ep, err := getCurrentEndpoint(dockerCli)
|
||||
fmt.Printf("current endpoint: %+v %v\n", ep, err)
|
||||
|
||||
fmt.Printf("current config file: %+v\n", dockerCli.ConfigFile())
|
||||
fmt.Printf("current config file: %+v\n", dockerCli)
|
||||
|
||||
list, err := dockerCli.ContextStore().ListContexts()
|
||||
if err != nil {
|
||||
@ -23,6 +26,20 @@ func runLs(dockerCli command.Cli, in lsOptions) error {
|
||||
fmt.Printf("context%d: %+v\n", i, l)
|
||||
}
|
||||
|
||||
txn, release, err := getStore(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer release()
|
||||
|
||||
ll, err := txn.List()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i, l := range ll {
|
||||
fmt.Printf("store %d: %+v\n", i, l)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,49 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/moby/buildkit/util/appcontext"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tonistiigi/buildx/store"
|
||||
)
|
||||
|
||||
type rmOptions struct {
|
||||
}
|
||||
|
||||
func runRm(dockerCli command.Cli, in rmOptions) error {
|
||||
func runRm(dockerCli command.Cli, in rmOptions, args []string) error {
|
||||
ctx := appcontext.Context()
|
||||
|
||||
txn, release, err := getStore(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer release()
|
||||
|
||||
if len(args) > 0 {
|
||||
ng, err := getNodeGroup(txn, dockerCli, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := stop(ctx, dockerCli, ng, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return txn.Remove(ng.Name)
|
||||
}
|
||||
|
||||
ng, err := getCurrentInstance(txn, dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ng != nil {
|
||||
if err := stop(ctx, dockerCli, ng, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return txn.Remove(ng.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -18,17 +53,57 @@ func rmCmd(dockerCli command.Cli) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "rm [NAME]",
|
||||
Short: "Remove a builder instance",
|
||||
// Args: cli.ExactArgs(1),
|
||||
Args: cli.RequiresMaxArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runRm(dockerCli, options)
|
||||
return runRm(dockerCli, options, args)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
// flags.StringArrayVarP(&options.outputs, "output", "o", []string{}, "Output destination (format: type=local,dest=path)")
|
||||
|
||||
_ = flags
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func stop(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, rm bool) error {
|
||||
dis, err := driversForNodeGroup(ctx, dockerCli, ng)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, di := range dis {
|
||||
if di.Driver != nil {
|
||||
if err := di.Driver.Stop(ctx, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if rm {
|
||||
if err := di.Driver.Rm(ctx, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if di.Err != nil {
|
||||
err = di.Err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func stopCurrent(ctx context.Context, dockerCli command.Cli, rm bool) error {
|
||||
dis, err := getDefaultDrivers(ctx, dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, di := range dis {
|
||||
if di.Driver != nil {
|
||||
if err := di.Driver.Stop(ctx, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if rm {
|
||||
if err := di.Driver.Rm(ctx, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if di.Err != nil {
|
||||
err = di.Err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -30,6 +30,6 @@ func addCommands(cmd *cobra.Command, dockerCli command.Cli) {
|
||||
lsCmd(dockerCli),
|
||||
useCmd(dockerCli),
|
||||
inspectCmd(dockerCli),
|
||||
viewCmd(dockerCli),
|
||||
stopCmd(dockerCli),
|
||||
)
|
||||
}
|
||||
|
63
commands/stop.go
Normal file
63
commands/stop.go
Normal file
@ -0,0 +1,63 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/moby/buildkit/util/appcontext"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type stopOptions struct {
|
||||
}
|
||||
|
||||
func runStop(dockerCli command.Cli, in stopOptions, args []string) error {
|
||||
ctx := appcontext.Context()
|
||||
|
||||
txn, release, err := getStore(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer release()
|
||||
|
||||
if len(args) > 0 {
|
||||
ng, err := getNodeGroup(txn, dockerCli, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := stop(ctx, dockerCli, ng, false); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
ng, err := getCurrentInstance(txn, dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ng != nil {
|
||||
return stop(ctx, dockerCli, ng, false)
|
||||
}
|
||||
|
||||
return stopCurrent(ctx, dockerCli, false)
|
||||
}
|
||||
|
||||
func stopCmd(dockerCli command.Cli) *cobra.Command {
|
||||
var options stopOptions
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "stop [NAME]",
|
||||
Short: "Stop builder instance",
|
||||
Args: cli.RequiresMaxArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runStop(dockerCli, options, args)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
// flags.StringArrayVarP(&options.outputs, "output", "o", []string{}, "Output destination (format: type=local,dest=path)")
|
||||
|
||||
_ = flags
|
||||
|
||||
return cmd
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@ -13,8 +14,47 @@ type useOptions struct {
|
||||
isDefault bool
|
||||
}
|
||||
|
||||
func runUse(dockerCli command.Cli, in useOptions) error {
|
||||
fmt.Printf("%+v\n", in)
|
||||
func runUse(dockerCli command.Cli, in useOptions, name string) error {
|
||||
txn, release, err := getStore(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer release()
|
||||
|
||||
if _, err := txn.NodeGroupByName(name); err != nil {
|
||||
if os.IsNotExist(errors.Cause(err)) {
|
||||
if name == "default" || name == dockerCli.CurrentContext() {
|
||||
ep, err := getCurrentEndpoint(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := txn.SetCurrent(ep, "", false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
list, err := dockerCli.ContextStore().ListContexts()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, l := range list {
|
||||
if l.Name == name {
|
||||
return errors.Errorf("to switch to context %s use `docker context use %s`", name, name)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return errors.Wrapf(err, "failed to find instance %q", name)
|
||||
}
|
||||
|
||||
ep, err := getCurrentEndpoint(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := txn.SetCurrent(ep, name, in.isGlobal, in.isDefault); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -26,7 +66,7 @@ func useCmd(dockerCli command.Cli) *cobra.Command {
|
||||
Short: "Set the current builder instance",
|
||||
Args: cli.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runUse(dockerCli, options)
|
||||
return runUse(dockerCli, options, args[0])
|
||||
},
|
||||
}
|
||||
|
||||
|
252
commands/util.go
Normal file
252
commands/util.go
Normal file
@ -0,0 +1,252 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/context/docker"
|
||||
dopts "github.com/docker/cli/opts"
|
||||
dockerclient "github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tonistiigi/buildx/build"
|
||||
"github.com/tonistiigi/buildx/driver"
|
||||
"github.com/tonistiigi/buildx/store"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// getStore returns current builder instance store
|
||||
func getStore(dockerCli command.Cli) (*store.Txn, func(), error) {
|
||||
dir := filepath.Dir(dockerCli.ConfigFile().Filename)
|
||||
s, err := store.New(dir)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return s.Txn()
|
||||
}
|
||||
|
||||
// getCurrentEndpoint returns the current default endpoint value
|
||||
func getCurrentEndpoint(dockerCli command.Cli) (string, error) {
|
||||
name := dockerCli.CurrentContext()
|
||||
if name != "default" {
|
||||
return name, nil
|
||||
}
|
||||
de, err := getDockerEndpoint(dockerCli, name)
|
||||
if err != nil {
|
||||
return "", errors.Errorf("docker endpoint for %q not found", name)
|
||||
}
|
||||
return de, nil
|
||||
}
|
||||
|
||||
// getDockerEndpoint returns docker endpoint string for given context
|
||||
func getDockerEndpoint(dockerCli command.Cli, name string) (string, error) {
|
||||
list, err := dockerCli.ContextStore().ListContexts()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, l := range list {
|
||||
if l.Name == name {
|
||||
ep, ok := l.Endpoints["docker"]
|
||||
if !ok {
|
||||
return "", errors.Errorf("context %q does not have a Docker endpoint", name)
|
||||
}
|
||||
typed, ok := ep.(docker.EndpointMeta)
|
||||
if !ok {
|
||||
return "", errors.Errorf("endpoint %q is not of type EndpointMeta, %T", ep, ep)
|
||||
}
|
||||
return typed.Host, nil
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// validateEndpoint validates that endpoint is either a context or a docker host
|
||||
func validateEndpoint(dockerCli command.Cli, ep string) (string, error) {
|
||||
de, err := getDockerEndpoint(dockerCli, ep)
|
||||
if err == nil && de != "" {
|
||||
if ep == "default" {
|
||||
return de, nil
|
||||
}
|
||||
return ep, nil
|
||||
}
|
||||
h, err := dopts.ParseHost(true, ep)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to parse endpoint %s", ep)
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// getCurrentInstance finds the current builder instance
|
||||
func getCurrentInstance(txn *store.Txn, dockerCli command.Cli) (*store.NodeGroup, error) {
|
||||
ep, err := getCurrentEndpoint(dockerCli)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ng, err := txn.Current(ep)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ng, nil
|
||||
}
|
||||
|
||||
// getNodeGroup returns nodegroup based on the name
|
||||
func getNodeGroup(txn *store.Txn, dockerCli command.Cli, name string) (*store.NodeGroup, error) {
|
||||
ng, err := txn.NodeGroupByName(name)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(errors.Cause(err)) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if ng != nil {
|
||||
return ng, nil
|
||||
}
|
||||
|
||||
if name == "default" {
|
||||
name = dockerCli.CurrentContext()
|
||||
}
|
||||
|
||||
list, err := dockerCli.ContextStore().ListContexts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, l := range list {
|
||||
if l.Name == name {
|
||||
return &store.NodeGroup{
|
||||
Name: "default",
|
||||
Nodes: []store.Node{
|
||||
{
|
||||
Name: "default",
|
||||
Endpoint: name,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("no builder %q found", name)
|
||||
}
|
||||
|
||||
// driversForNodeGroup returns drivers for a nodegroup instance
|
||||
func driversForNodeGroup(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup) ([]build.DriverInfo, error) {
|
||||
eg, _ := errgroup.WithContext(ctx)
|
||||
|
||||
dis := make([]build.DriverInfo, len(ng.Nodes))
|
||||
|
||||
var f driver.Factory
|
||||
if ng.Driver != "" {
|
||||
f = driver.GetFactory(ng.Driver, true)
|
||||
if f == nil {
|
||||
return nil, errors.Errorf("failed to find driver %q", f)
|
||||
}
|
||||
} else {
|
||||
dockerapi, err := clientForEndpoint(dockerCli, ng.Nodes[0].Endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err = driver.GetDefaultFactory(ctx, dockerapi, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for i, n := range ng.Nodes {
|
||||
func(i int, n store.Node) {
|
||||
eg.Go(func() error {
|
||||
di := build.DriverInfo{
|
||||
Name: n.Name,
|
||||
Platform: n.Platforms,
|
||||
}
|
||||
defer func() {
|
||||
dis[i] = di
|
||||
}()
|
||||
dockerapi, err := clientForEndpoint(dockerCli, n.Endpoint)
|
||||
if err != nil {
|
||||
di.Err = err
|
||||
return nil
|
||||
}
|
||||
|
||||
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, f, dockerapi)
|
||||
if err != nil {
|
||||
di.Err = err
|
||||
return nil
|
||||
}
|
||||
di.Driver = d
|
||||
return nil
|
||||
})
|
||||
}(i, n)
|
||||
}
|
||||
|
||||
if err := eg.Wait(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dis, nil
|
||||
}
|
||||
|
||||
// clientForEndpoint returns a docker client for an endpoint
|
||||
func clientForEndpoint(dockerCli command.Cli, name string) (dockerclient.APIClient, error) {
|
||||
list, err := dockerCli.ContextStore().ListContexts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, l := range list {
|
||||
if l.Name == name {
|
||||
dep, ok := l.Endpoints["docker"]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("context %q does not have a Docker endpoint", name)
|
||||
}
|
||||
epm, ok := dep.(docker.EndpointMeta)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("endpoint %q is not of type EndpointMeta, %T", dep, dep)
|
||||
}
|
||||
ep, err := docker.WithTLSData(dockerCli.ContextStore(), name, epm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientOpts, err := ep.ClientOpts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dockerclient.NewClientWithOpts(clientOpts...)
|
||||
}
|
||||
}
|
||||
return dockerclient.NewClientWithOpts(dockerclient.WithHost(name))
|
||||
}
|
||||
|
||||
// getDefaultDrivers returns drivers based on current cli config
|
||||
func getDefaultDrivers(ctx context.Context, dockerCli command.Cli) ([]build.DriverInfo, error) {
|
||||
txn, release, err := getStore(dockerCli)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer release()
|
||||
|
||||
ng, err := getCurrentInstance(txn, dockerCli)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ng != nil {
|
||||
return driversForNodeGroup(ctx, dockerCli, ng)
|
||||
}
|
||||
|
||||
d, err := driver.GetDriver(ctx, "buildx_buildkit_default", nil, dockerCli.Client())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []build.DriverInfo{
|
||||
{
|
||||
Name: "default",
|
||||
Driver: d,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// type ngInfo struct {
|
||||
// ng *store.NodeGroup
|
||||
// }
|
||||
//
|
||||
// func (i *ngInfo) init(ctx context.Context, boot bool) {
|
||||
//
|
||||
// }
|
@ -1,35 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type viewOptions struct {
|
||||
}
|
||||
|
||||
func runView(dockerCli command.Cli, in viewOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func viewCmd(dockerCli command.Cli) *cobra.Command {
|
||||
var options viewOptions
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "view REF",
|
||||
Short: "Show metadata for image in registry",
|
||||
Args: cli.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runView(dockerCli, options)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
// flags.StringArrayVarP(&options.outputs, "output", "o", []string{}, "Output destination (format: type=local,dest=path)")
|
||||
|
||||
_ = flags
|
||||
|
||||
return cmd
|
||||
}
|
Reference in New Issue
Block a user