github.com/pdmccormick/importable-docker-buildx@v0.0.0-20240426161518-e47091289030/driver/remote/factory.go (about)

     1  package remote
     2  
     3  import (
     4  	"context"
     5  	"net/url"
     6  	"path/filepath"
     7  	"strconv"
     8  	"strings"
     9  
    10  	// import connhelpers for special url schemes
    11  	_ "github.com/moby/buildkit/client/connhelper/dockercontainer"
    12  	_ "github.com/moby/buildkit/client/connhelper/kubepod"
    13  	_ "github.com/moby/buildkit/client/connhelper/ssh"
    14  
    15  	"github.com/docker/buildx/driver"
    16  	util "github.com/docker/buildx/driver/remote/util"
    17  	dockerclient "github.com/docker/docker/client"
    18  	"github.com/pkg/errors"
    19  )
    20  
    21  const prioritySupported = 20
    22  const priorityUnsupported = 90
    23  
    24  func init() {
    25  	driver.Register(&factory{})
    26  }
    27  
    28  type factory struct {
    29  }
    30  
    31  func (*factory) Name() string {
    32  	return "remote"
    33  }
    34  
    35  func (*factory) Usage() string {
    36  	return "remote"
    37  }
    38  
    39  func (*factory) Priority(ctx context.Context, endpoint string, api dockerclient.APIClient, dialMeta map[string][]string) int {
    40  	if util.IsValidEndpoint(endpoint) != nil {
    41  		return priorityUnsupported
    42  	}
    43  	return prioritySupported
    44  }
    45  
    46  func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver, error) {
    47  	if len(cfg.Files) > 0 {
    48  		return nil, errors.Errorf("setting config file is not supported for remote driver")
    49  	}
    50  	if len(cfg.BuildkitdFlags) > 0 {
    51  		return nil, errors.Errorf("setting buildkit flags is not supported for remote driver")
    52  	}
    53  
    54  	d := &Driver{
    55  		factory:    f,
    56  		InitConfig: cfg,
    57  	}
    58  
    59  	tls := &tlsOpts{}
    60  	tlsEnabled := false
    61  	for k, v := range cfg.DriverOpts {
    62  		switch k {
    63  		case "servername":
    64  			tls.serverName = v
    65  			tlsEnabled = true
    66  		case "cacert":
    67  			if !filepath.IsAbs(v) {
    68  				return nil, errors.Errorf("non-absolute path '%s' provided for %s", v, k)
    69  			}
    70  			tls.caCert = v
    71  			tlsEnabled = true
    72  		case "cert":
    73  			if !filepath.IsAbs(v) {
    74  				return nil, errors.Errorf("non-absolute path '%s' provided for %s", v, k)
    75  			}
    76  			tls.cert = v
    77  			tlsEnabled = true
    78  		case "key":
    79  			if !filepath.IsAbs(v) {
    80  				return nil, errors.Errorf("non-absolute path '%s' provided for %s", v, k)
    81  			}
    82  			tls.key = v
    83  			tlsEnabled = true
    84  		case "default-load":
    85  			parsed, err := strconv.ParseBool(v)
    86  			if err != nil {
    87  				return nil, err
    88  			}
    89  			d.defaultLoad = parsed
    90  		default:
    91  			return nil, errors.Errorf("invalid driver option %s for remote driver", k)
    92  		}
    93  	}
    94  
    95  	if tlsEnabled {
    96  		if tls.serverName == "" {
    97  			// guess servername as hostname of target address
    98  			uri, err := url.Parse(cfg.EndpointAddr)
    99  			if err != nil {
   100  				return nil, err
   101  			}
   102  			tls.serverName = uri.Hostname()
   103  		}
   104  		missing := []string{}
   105  		if tls.caCert == "" {
   106  			missing = append(missing, "cacert")
   107  		}
   108  		if tls.cert != "" && tls.key == "" {
   109  			missing = append(missing, "key")
   110  		}
   111  		if tls.key != "" && tls.cert == "" {
   112  			missing = append(missing, "cert")
   113  		}
   114  		if len(missing) > 0 {
   115  			return nil, errors.Errorf("tls enabled, but missing keys %s", strings.Join(missing, ", "))
   116  		}
   117  		d.tlsOpts = tls
   118  	}
   119  
   120  	return d, nil
   121  }
   122  
   123  func (f *factory) AllowsInstances() bool {
   124  	return true
   125  }