github.com/pdmccormick/importable-docker-buildx@v0.0.0-20240426161518-e47091289030/driver/docker/driver.go (about) 1 package docker 2 3 import ( 4 "context" 5 "net" 6 "strings" 7 "sync" 8 9 "github.com/docker/buildx/driver" 10 "github.com/docker/buildx/util/progress" 11 "github.com/moby/buildkit/client" 12 "github.com/pkg/errors" 13 ) 14 15 type Driver struct { 16 factory driver.Factory 17 driver.InitConfig 18 19 // if you add fields, remember to update docs: 20 // https://github.com/docker/docs/blob/main/content/build/drivers/docker.md 21 features features 22 hostGateway hostGateway 23 } 24 25 func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error { 26 return nil 27 } 28 29 func (d *Driver) Info(ctx context.Context) (*driver.Info, error) { 30 _, err := d.DockerAPI.ServerVersion(ctx) 31 if err != nil { 32 return nil, errors.Wrapf(driver.ErrNotConnecting, err.Error()) 33 } 34 return &driver.Info{ 35 Status: driver.Running, 36 }, nil 37 } 38 39 func (d *Driver) Version(ctx context.Context) (string, error) { 40 v, err := d.DockerAPI.ServerVersion(ctx) 41 if err != nil { 42 return "", errors.Wrapf(driver.ErrNotConnecting, err.Error()) 43 } 44 if bkversion, _ := resolveBuildKitVersion(v.Version); bkversion != "" { 45 return bkversion, nil 46 } 47 // https://github.com/moby/moby/blob/efc7a2abc3ab6dfa7d8d5d8c1c3b99138989b0f1/builder/builder-next/worker/worker.go#L176 48 return strings.TrimSuffix(v.Version, "-moby"), nil 49 } 50 51 func (d *Driver) Stop(ctx context.Context, force bool) error { 52 return nil 53 } 54 55 func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error { 56 return nil 57 } 58 59 func (d *Driver) Dial(ctx context.Context) (net.Conn, error) { 60 return d.DockerAPI.DialHijack(ctx, "/grpc", "h2c", d.DialMeta) 61 } 62 63 func (d *Driver) Client(ctx context.Context, opts ...client.ClientOpt) (*client.Client, error) { 64 opts = append([]client.ClientOpt{ 65 client.WithContextDialer(func(context.Context, string) (net.Conn, error) { 66 return d.Dial(ctx) 67 }), client.WithSessionDialer(func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error) { 68 return d.DockerAPI.DialHijack(ctx, "/session", proto, meta) 69 }), 70 }, opts...) 71 return client.New(ctx, "", opts...) 72 } 73 74 type features struct { 75 once sync.Once 76 list map[driver.Feature]bool 77 } 78 79 func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool { 80 d.features.once.Do(func() { 81 var useContainerdSnapshotter bool 82 if c, err := d.Client(ctx); err == nil { 83 workers, _ := c.ListWorkers(ctx) 84 for _, w := range workers { 85 if _, ok := w.Labels["org.mobyproject.buildkit.worker.snapshotter"]; ok { 86 useContainerdSnapshotter = true 87 } 88 } 89 c.Close() 90 } 91 d.features.list = map[driver.Feature]bool{ 92 driver.OCIExporter: useContainerdSnapshotter, 93 driver.DockerExporter: useContainerdSnapshotter, 94 driver.CacheExport: useContainerdSnapshotter, 95 driver.MultiPlatform: useContainerdSnapshotter, 96 driver.DefaultLoad: true, 97 } 98 }) 99 return d.features.list 100 } 101 102 type hostGateway struct { 103 once sync.Once 104 ip net.IP 105 err error 106 } 107 108 func (d *Driver) HostGatewayIP(ctx context.Context) (net.IP, error) { 109 d.hostGateway.once.Do(func() { 110 c, err := d.Client(ctx) 111 if err != nil { 112 d.hostGateway.err = err 113 return 114 } 115 defer c.Close() 116 workers, err := c.ListWorkers(ctx) 117 if err != nil { 118 d.hostGateway.err = errors.Wrap(err, "listing workers") 119 return 120 } 121 for _, w := range workers { 122 // should match github.com/docker/docker/builder/builder-next/worker/label.HostGatewayIP const 123 if v, ok := w.Labels["org.mobyproject.buildkit.worker.moby.host-gateway-ip"]; ok && v != "" { 124 ip := net.ParseIP(v) 125 if ip == nil { 126 d.hostGateway.err = errors.Errorf("failed to parse host-gateway IP: %s", v) 127 return 128 } 129 d.hostGateway.ip = ip 130 return 131 } 132 } 133 d.hostGateway.err = errors.New("host-gateway IP not found") 134 }) 135 return d.hostGateway.ip, d.hostGateway.err 136 } 137 138 func (d *Driver) Factory() driver.Factory { 139 return d.factory 140 } 141 142 func (d *Driver) IsMobyDriver() bool { 143 return true 144 } 145 146 func (d *Driver) Config() driver.InitConfig { 147 return d.InitConfig 148 }