Browse code

add support of registry-mirrors and insecure-registries to buildkit

Signed-off-by: Anda Xu <anda.xu@docker.com>

Anda Xu authored on 2018/09/15 08:07:16
Showing 5 changed files
... ...
@@ -34,6 +34,7 @@ import (
34 34
 	"github.com/moby/buildkit/util/flightcontrol"
35 35
 	"github.com/moby/buildkit/util/imageutil"
36 36
 	"github.com/moby/buildkit/util/progress"
37
+	"github.com/moby/buildkit/util/resolver"
37 38
 	"github.com/moby/buildkit/util/tracing"
38 39
 	digest "github.com/opencontainers/go-digest"
39 40
 	"github.com/opencontainers/image-spec/identity"
... ...
@@ -51,6 +52,7 @@ type SourceOpt struct {
51 51
 	DownloadManager distribution.RootFSDownloadManager
52 52
 	MetadataStore   metadata.V2MetadataService
53 53
 	ImageStore      image.Store
54
+	ResolverOpt     resolver.ResolveOptionsFunc
54 55
 }
55 56
 
56 57
 type imageSource struct {
... ...
@@ -71,11 +73,16 @@ func (is *imageSource) ID() string {
71 71
 	return source.DockerImageScheme
72 72
 }
73 73
 
74
-func (is *imageSource) getResolver(ctx context.Context) remotes.Resolver {
75
-	return docker.NewResolver(docker.ResolverOptions{
74
+func (is *imageSource) getResolver(ctx context.Context, rfn resolver.ResolveOptionsFunc, ref string) remotes.Resolver {
75
+	opt := docker.ResolverOptions{
76 76
 		Client:      tracing.DefaultClient,
77 77
 		Credentials: is.getCredentialsFromSession(ctx),
78
-	})
78
+	}
79
+	if rfn != nil {
80
+		opt = rfn(ref)
81
+	}
82
+	r := docker.NewResolver(opt)
83
+	return r
79 84
 }
80 85
 
81 86
 func (is *imageSource) getCredentialsFromSession(ctx context.Context) func(string) (string, string, error) {
... ...
@@ -118,7 +125,7 @@ func (is *imageSource) resolveRemote(ctx context.Context, ref string, platform *
118 118
 		dt   []byte
119 119
 	}
120 120
 	res, err := is.g.Do(ctx, ref, func(ctx context.Context) (interface{}, error) {
121
-		dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx), is.ContentStore, platform)
121
+		dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx, is.ResolverOpt, ref), is.ContentStore, platform)
122 122
 		if err != nil {
123 123
 			return nil, err
124 124
 		}
... ...
@@ -181,7 +188,7 @@ func (is *imageSource) Resolve(ctx context.Context, id source.Identifier) (sourc
181 181
 	p := &puller{
182 182
 		src:      imageIdentifier,
183 183
 		is:       is,
184
-		resolver: is.getResolver(ctx),
184
+		resolver: is.getResolver(ctx, is.ResolverOpt, imageIdentifier.Reference.String()),
185 185
 		platform: platform,
186 186
 	}
187 187
 	return p, nil
... ...
@@ -23,6 +23,7 @@ import (
23 23
 	"github.com/moby/buildkit/session"
24 24
 	"github.com/moby/buildkit/solver/llbsolver"
25 25
 	"github.com/moby/buildkit/util/entitlements"
26
+	"github.com/moby/buildkit/util/resolver"
26 27
 	"github.com/moby/buildkit/util/tracing"
27 28
 	"github.com/pkg/errors"
28 29
 	"golang.org/x/sync/errgroup"
... ...
@@ -55,6 +56,7 @@ type Opt struct {
55 55
 	Dist                images.DistributionServices
56 56
 	NetworkController   libnetwork.NetworkController
57 57
 	DefaultCgroupParent string
58
+	ResolverOpt         resolver.ResolveOptionsFunc
58 59
 }
59 60
 
60 61
 // Builder can build using BuildKit backend
... ...
@@ -97,6 +97,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
97 97
 		MetadataStore:   dist.V2MetadataService,
98 98
 		ImageStore:      dist.ImageStore,
99 99
 		ReferenceStore:  dist.ReferenceStore,
100
+		ResolverOpt:     opt.ResolverOpt,
100 101
 	})
101 102
 	if err != nil {
102 103
 		return nil, err
... ...
@@ -160,7 +161,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
160 160
 		WorkerController:         wc,
161 161
 		Frontends:                frontends,
162 162
 		CacheKeyStorage:          cacheStorage,
163
-		ResolveCacheImporterFunc: registryremotecache.ResolveCacheImporterFunc(opt.SessionManager),
163
+		ResolveCacheImporterFunc: registryremotecache.ResolveCacheImporterFunc(opt.SessionManager, opt.ResolverOpt),
164 164
 		// TODO: set ResolveCacheExporterFunc for exporting cache
165 165
 	})
166 166
 }
... ...
@@ -291,6 +291,7 @@ func newRouterOptions(config *config.Config, d *daemon.Daemon) (routerOptions, e
291 291
 		Dist:                d.DistributionServices(),
292 292
 		NetworkController:   d.NetworkController(),
293 293
 		DefaultCgroupParent: cgroupParent,
294
+		ResolverOpt:         d.NewResolveOptionsFunc(),
294 295
 	})
295 296
 	if err != nil {
296 297
 		return opts, err
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"context"
10 10
 	"fmt"
11 11
 	"io/ioutil"
12
+	"math/rand"
12 13
 	"net"
13 14
 	"os"
14 15
 	"path"
... ...
@@ -23,6 +24,8 @@ import (
23 23
 	"github.com/containerd/containerd"
24 24
 	"github.com/containerd/containerd/defaults"
25 25
 	"github.com/containerd/containerd/pkg/dialer"
26
+	"github.com/containerd/containerd/remotes/docker"
27
+	"github.com/docker/distribution/reference"
26 28
 	"github.com/docker/docker/api/types"
27 29
 	containertypes "github.com/docker/docker/api/types/container"
28 30
 	"github.com/docker/docker/api/types/swarm"
... ...
@@ -36,6 +39,8 @@ import (
36 36
 	"github.com/docker/docker/daemon/logger"
37 37
 	"github.com/docker/docker/daemon/network"
38 38
 	"github.com/docker/docker/errdefs"
39
+	"github.com/moby/buildkit/util/resolver"
40
+	"github.com/moby/buildkit/util/tracing"
39 41
 	"github.com/sirupsen/logrus"
40 42
 	// register graph drivers
41 43
 	_ "github.com/docker/docker/daemon/graphdriver/register"
... ...
@@ -141,6 +146,57 @@ func (daemon *Daemon) Features() *map[string]bool {
141 141
 	return &daemon.configStore.Features
142 142
 }
143 143
 
144
+// NewResolveOptionsFunc returns a call back function to resolve "registry-mirrors" and
145
+// "insecure-registries" for buildkit
146
+func (daemon *Daemon) NewResolveOptionsFunc() resolver.ResolveOptionsFunc {
147
+	return func(ref string) docker.ResolverOptions {
148
+		var (
149
+			registryKey = "docker.io"
150
+			mirrors     = make([]string, len(daemon.configStore.Mirrors))
151
+			m           = map[string]resolver.RegistryConf{}
152
+		)
153
+		// must trim "https://" or "http://" prefix
154
+		for i, v := range daemon.configStore.Mirrors {
155
+			v = strings.TrimPrefix(v, "https://")
156
+			v = strings.TrimPrefix(v, "http://")
157
+			mirrors[i] = v
158
+		}
159
+		// set "registry-mirrors"
160
+		m[registryKey] = resolver.RegistryConf{Mirrors: mirrors}
161
+		// set "insecure-registries"
162
+		for _, v := range daemon.configStore.InsecureRegistries {
163
+			v = strings.TrimPrefix(v, "http://")
164
+			m[v] = resolver.RegistryConf{
165
+				PlainHTTP: true,
166
+			}
167
+		}
168
+		def := docker.ResolverOptions{
169
+			Client: tracing.DefaultClient,
170
+		}
171
+
172
+		parsed, err := reference.ParseNormalizedNamed(ref)
173
+		if err != nil {
174
+			return def
175
+		}
176
+		host := reference.Domain(parsed)
177
+
178
+		c, ok := m[host]
179
+		if !ok {
180
+			return def
181
+		}
182
+
183
+		if len(c.Mirrors) > 0 {
184
+			def.Host = func(string) (string, error) {
185
+				return c.Mirrors[rand.Intn(len(c.Mirrors))], nil
186
+			}
187
+		}
188
+
189
+		def.PlainHTTP = c.PlainHTTP
190
+
191
+		return def
192
+	}
193
+}
194
+
144 195
 func (daemon *Daemon) restore() error {
145 196
 	containers := make(map[string]*container.Container)
146 197