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

This refactors the driver handle to initialize the tracer delegate inside of the driver handle instead of the individual plugins. This provides more uniformity to how the tracer delegate is created by allowing the driver handle to pass additional client options to the drivers when they create the client. It also avoids creating the tracer delegate client multiple times because the driver handle will only initialize the client once. This prevents some drivers, like the remote driver, from accidentally registering multiple clients as tracer delegates. Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
170 lines
3.7 KiB
Go
170 lines
3.7 KiB
Go
package remote
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"net"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/docker/buildx/driver"
|
|
util "github.com/docker/buildx/driver/remote/util"
|
|
"github.com/docker/buildx/util/progress"
|
|
"github.com/moby/buildkit/client"
|
|
"github.com/moby/buildkit/client/connhelper"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type Driver struct {
|
|
factory driver.Factory
|
|
driver.InitConfig
|
|
|
|
// if you add fields, remember to update docs:
|
|
// https://github.com/docker/docs/blob/main/content/build/drivers/remote.md
|
|
*tlsOpts
|
|
}
|
|
|
|
type tlsOpts struct {
|
|
serverName string
|
|
caCert string
|
|
cert string
|
|
key string
|
|
}
|
|
|
|
func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
|
|
c, err := d.Client(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return progress.Wrap("[internal] waiting for connection", l, func(_ progress.SubLogger) error {
|
|
ctx, cancel := context.WithTimeout(ctx, 20*time.Second)
|
|
defer cancel()
|
|
return c.Wait(ctx)
|
|
})
|
|
}
|
|
|
|
func (d *Driver) Info(ctx context.Context) (*driver.Info, error) {
|
|
c, err := d.Client(ctx)
|
|
if err != nil {
|
|
return &driver.Info{
|
|
Status: driver.Inactive,
|
|
}, nil
|
|
}
|
|
|
|
if _, err := c.ListWorkers(ctx); err != nil {
|
|
return &driver.Info{
|
|
Status: driver.Inactive,
|
|
}, nil
|
|
}
|
|
|
|
return &driver.Info{
|
|
Status: driver.Running,
|
|
}, nil
|
|
}
|
|
|
|
func (d *Driver) Version(ctx context.Context) (string, error) {
|
|
return "", nil
|
|
}
|
|
|
|
func (d *Driver) Stop(ctx context.Context, force bool) error {
|
|
return nil
|
|
}
|
|
|
|
func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error {
|
|
return nil
|
|
}
|
|
|
|
func (d *Driver) Client(ctx context.Context, opts ...client.ClientOpt) (*client.Client, error) {
|
|
opts = append([]client.ClientOpt{
|
|
client.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) {
|
|
return d.Dial(ctx)
|
|
}),
|
|
}, opts...)
|
|
return client.New(ctx, "", opts...)
|
|
}
|
|
|
|
func (d *Driver) Dial(ctx context.Context) (net.Conn, error) {
|
|
addr := d.InitConfig.EndpointAddr
|
|
ch, err := connhelper.GetConnectionHelper(addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if ch != nil {
|
|
return ch.ContextDialer(ctx, addr)
|
|
}
|
|
|
|
network, addr, ok := strings.Cut(addr, "://")
|
|
if !ok {
|
|
return nil, errors.Errorf("invalid endpoint address: %s", d.InitConfig.EndpointAddr)
|
|
}
|
|
|
|
conn, err := util.DialContext(ctx, network, addr)
|
|
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
|
|
if d.tlsOpts != nil {
|
|
cfg, err := loadTLS(d.tlsOpts)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "error loading tls config")
|
|
}
|
|
conn = tls.Client(conn, cfg)
|
|
}
|
|
return conn, nil
|
|
}
|
|
|
|
func loadTLS(opts *tlsOpts) (*tls.Config, error) {
|
|
cfg := &tls.Config{
|
|
ServerName: opts.serverName,
|
|
RootCAs: x509.NewCertPool(),
|
|
}
|
|
|
|
if opts.caCert != "" {
|
|
ca, err := os.ReadFile(opts.caCert)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not read ca certificate")
|
|
}
|
|
if ok := cfg.RootCAs.AppendCertsFromPEM(ca); !ok {
|
|
return nil, errors.New("failed to append ca certs")
|
|
}
|
|
}
|
|
|
|
if opts.cert != "" || opts.key != "" {
|
|
cert, err := tls.LoadX509KeyPair(opts.cert, opts.key)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not read certificate/key")
|
|
}
|
|
cfg.Certificates = append(cfg.Certificates, cert)
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
|
return map[driver.Feature]bool{
|
|
driver.OCIExporter: true,
|
|
driver.DockerExporter: true,
|
|
driver.CacheExport: true,
|
|
driver.MultiPlatform: true,
|
|
}
|
|
}
|
|
|
|
func (d *Driver) HostGatewayIP(ctx context.Context) (net.IP, error) {
|
|
return nil, errors.New("host-gateway is not supported by the remote driver")
|
|
}
|
|
|
|
func (d *Driver) Factory() driver.Factory {
|
|
return d.factory
|
|
}
|
|
|
|
func (d *Driver) IsMobyDriver() bool {
|
|
return false
|
|
}
|
|
|
|
func (d *Driver) Config() driver.InitConfig {
|
|
return d.InitConfig
|
|
}
|