diff --git a/commands/util.go b/commands/util.go index 3bfaed85..68bfcaa9 100644 --- a/commands/util.go +++ b/commands/util.go @@ -325,7 +325,30 @@ func loadNodeGroupData(ctx context.Context, dockerCli command.Cli, ngi *nginfo) }(&ngi.drivers[i]) } - return eg.Wait() + if eg.Wait(); err != nil { + return err + } + for _, di := range ngi.drivers { + // dynamic nodes are used in Kubernetes driver. + // Kubernetes pods are dynamically mapped to BuildKit Nodes. + if di.info != nil && len(di.info.DynamicNodes) > 0 { + var drivers []dinfo + for i := 0; i < len(di.info.DynamicNodes); i++ { + // all []dinfo share *build.DriverInfo and *driver.Info + diClone := di + if pl := di.info.DynamicNodes[i].Platforms; len(pl) > 0 { + diClone.platforms = pl + } + drivers = append(drivers, di) + } + // not append (remove the static nodes in the store) + ngi.ng.Nodes = di.info.DynamicNodes + ngi.ng.Dynamic = true + ngi.drivers = drivers + return nil + } + } + return nil } func dockerAPI(dockerCli command.Cli) *api { diff --git a/driver/driver.go b/driver/driver.go index 6d73cff4..da66c6c7 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -3,6 +3,7 @@ package driver import ( "context" + "github.com/docker/buildx/store" "github.com/docker/buildx/util/progress" "github.com/moby/buildkit/client" "github.com/pkg/errors" @@ -39,6 +40,8 @@ func (s Status) String() string { type Info struct { Status Status + // DynamicNodes must be empty if the actual nodes are statically listed in the store + DynamicNodes []store.Node } type Driver interface { diff --git a/driver/kubernetes/driver.go b/driver/kubernetes/driver.go index 8d30d4fa..08f9e622 100644 --- a/driver/kubernetes/driver.go +++ b/driver/kubernetes/driver.go @@ -9,10 +9,10 @@ import ( "github.com/docker/buildx/driver" "github.com/docker/buildx/driver/kubernetes/execconn" "github.com/docker/buildx/driver/kubernetes/podchooser" + "github.com/docker/buildx/store" "github.com/docker/buildx/util/progress" "github.com/moby/buildkit/client" "github.com/pkg/errors" - "github.com/sirupsen/logrus" appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -94,13 +94,26 @@ func (d *Driver) Info(ctx context.Context) (*driver.Info, error) { Status: driver.Inactive, }, nil } - if depl.Status.ReadyReplicas > 0 { + if depl.Status.ReadyReplicas <= 0 { return &driver.Info{ - Status: driver.Running, + Status: driver.Stopped, }, nil } + pods, err := podchooser.ListRunningPods(d.podClient, depl) + if err != nil { + return nil, err + } + var dynNodes []store.Node + for _, p := range pods { + node := store.Node{ + Name: p.Name, + // Other fields are unset (TODO: detect real platforms) + } + dynNodes = append(dynNodes, node) + } return &driver.Info{ - Status: driver.Stopped, + Status: driver.Running, + DynamicNodes: dynNodes, }, nil } @@ -126,7 +139,6 @@ func (d *Driver) Client(ctx context.Context) (*client.Client, error) { if err != nil { return nil, err } - logrus.Infof("Using pod %q", pod.Name) if len(pod.Spec.Containers) == 0 { return nil, errors.Errorf("pod %s does not have any container", pod.Name) } diff --git a/go.mod b/go.mod index 3d0a5f3f..a869e601 100644 --- a/go.mod +++ b/go.mod @@ -95,5 +95,3 @@ require ( ) replace github.com/jaguilar/vt100 => github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305 - -go 1.13 diff --git a/store/nodegroup.go b/store/nodegroup.go index 04f8be82..5eb7c47c 100644 --- a/store/nodegroup.go +++ b/store/nodegroup.go @@ -10,9 +10,10 @@ import ( ) type NodeGroup struct { - Name string - Driver string - Nodes []Node + Name string + Driver string + Nodes []Node + Dynamic bool } type Node struct { @@ -25,6 +26,9 @@ type Node struct { } func (ng *NodeGroup) Leave(name string) error { + if ng.Dynamic { + return errors.New("dynamic node group does not support Leave") + } i := ng.findNode(name) if i == -1 { return errors.Errorf("node %q not found for %s", name, ng.Name) @@ -37,6 +41,9 @@ func (ng *NodeGroup) Leave(name string) error { } func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpointsSet bool, actionAppend bool, flags []string, configFile string, do map[string]string) error { + if ng.Dynamic { + return errors.New("dynamic node group does not support Update") + } i := ng.findNode(name) if i == -1 && !actionAppend { if len(ng.Nodes) > 0 {