diff --git a/builder/builder-next/adapters/snapshot/snapshot.go b/builder/builder-next/adapters/snapshot/snapshot.go index 93af8f3426a10..3a722e5923306 100644 --- a/builder/builder-next/adapters/snapshot/snapshot.go +++ b/builder/builder-next/adapters/snapshot/snapshot.go @@ -26,9 +26,10 @@ var keySize = []byte("size") // Opt defines options for creating the snapshotter type Opt struct { - GraphDriver graphdriver.Driver - LayerStore layer.Store - Root string + GraphDriver graphdriver.Driver + LayerStore layer.Store + Root string + IdentityMapping *idtools.IdentityMapping } type graphIDRegistrar interface { @@ -79,7 +80,7 @@ func (s *snapshotter) Name() string { } func (s *snapshotter) IdentityMapping() *idtools.IdentityMapping { - return nil + return s.opt.IdentityMapping } func (s *snapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) error { @@ -253,6 +254,7 @@ func (s *snapshotter) Mounts(ctx context.Context, key string) (snapshot.Mountabl id := identity.NewID() var rwlayer layer.RWLayer return &mountable{ + idmap: s.opt.IdentityMapping, acquire: func() ([]mount.Mount, error) { rwlayer, err = s.opt.LayerStore.CreateRWLayer(id, l.ChainID(), nil) if err != nil { @@ -278,6 +280,7 @@ func (s *snapshotter) Mounts(ctx context.Context, key string) (snapshot.Mountabl id, _ := s.getGraphDriverID(key) return &mountable{ + idmap: s.opt.IdentityMapping, acquire: func() ([]mount.Mount, error) { rootfs, err := s.opt.GraphDriver.Get(id, "") if err != nil { @@ -440,6 +443,7 @@ type mountable struct { acquire func() ([]mount.Mount, error) release func() error refCount int + idmap *idtools.IdentityMapping } func (m *mountable) Mount() ([]mount.Mount, error) { @@ -480,5 +484,5 @@ func (m *mountable) Release() error { } func (m *mountable) IdentityMapping() *idtools.IdentityMapping { - return nil + return m.idmap } diff --git a/builder/builder-next/builder.go b/builder/builder-next/builder.go index b8a8faa8b2a6b..bb701106f637a 100644 --- a/builder/builder-next/builder.go +++ b/builder/builder-next/builder.go @@ -17,6 +17,7 @@ import ( "github.com/docker/docker/builder" "github.com/docker/docker/daemon/config" "github.com/docker/docker/daemon/images" + "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/pkg/system" "github.com/docker/libnetwork" @@ -73,6 +74,7 @@ type Opt struct { ResolverOpt resolver.ResolveOptionsFunc BuilderConfig config.BuilderConfig Rootless bool + IdentityMapping *idtools.IdentityMapping } // Builder can build using BuildKit backend @@ -88,6 +90,10 @@ type Builder struct { func New(opt Opt) (*Builder, error) { reqHandler := newReqBodyHandler(tracing.DefaultTransport) + if opt.IdentityMapping != nil && opt.IdentityMapping.Empty() { + opt.IdentityMapping = nil + } + c, err := newController(reqHandler, opt) if err != nil { return nil, err diff --git a/builder/builder-next/controller.go b/builder/builder-next/controller.go index 37b6c24440f09..dfc482e17bb2a 100644 --- a/builder/builder-next/controller.go +++ b/builder/builder-next/controller.go @@ -38,7 +38,7 @@ import ( ) func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) { - if err := os.MkdirAll(opt.Root, 0700); err != nil { + if err := os.MkdirAll(opt.Root, 0711); err != nil { return nil, err } @@ -55,9 +55,10 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) { } sbase, err := snapshot.NewSnapshotter(snapshot.Opt{ - GraphDriver: driver, - LayerStore: dist.LayerStore, - Root: root, + GraphDriver: driver, + LayerStore: dist.LayerStore, + Root: root, + IdentityMapping: opt.IdentityMapping, }) if err != nil { return nil, err @@ -112,7 +113,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) { return nil, err } - exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController, opt.Rootless) + exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController, opt.Rootless, opt.IdentityMapping) if err != nil { return nil, err } diff --git a/builder/builder-next/executor_unix.go b/builder/builder-next/executor_unix.go index 620ffb401de72..7cbc2569eb7a2 100644 --- a/builder/builder-next/executor_unix.go +++ b/builder/builder-next/executor_unix.go @@ -8,6 +8,7 @@ import ( "strconv" "sync" + "github.com/docker/docker/pkg/idtools" "github.com/docker/libnetwork" "github.com/moby/buildkit/executor" "github.com/moby/buildkit/executor/runcexecutor" @@ -20,7 +21,7 @@ import ( const networkName = "bridge" -func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, rootless bool) (executor.Executor, error) { +func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, rootless bool, idmap *idtools.IdentityMapping) (executor.Executor, error) { networkProviders := map[pb.NetMode]network.Provider{ pb.NetMode_UNSET: &bridgeProvider{NetworkController: net, Root: filepath.Join(root, "net")}, pb.NetMode_HOST: network.NewHostProvider(), @@ -32,6 +33,7 @@ func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, ro DefaultCgroupParent: cgroupParent, Rootless: rootless, NoPivot: os.Getenv("DOCKER_RAMDISK") != "", + IdentityMapping: idmap, }, networkProviders) } diff --git a/builder/builder-next/executor_windows.go b/builder/builder-next/executor_windows.go index e2cc9071607a4..b870abe6ce1a3 100644 --- a/builder/builder-next/executor_windows.go +++ b/builder/builder-next/executor_windows.go @@ -5,12 +5,13 @@ import ( "errors" "io" + "github.com/docker/docker/pkg/idtools" "github.com/docker/libnetwork" "github.com/moby/buildkit/cache" "github.com/moby/buildkit/executor" ) -func newExecutor(_, _ string, _ libnetwork.NetworkController, _ bool) (executor.Executor, error) { +func newExecutor(_, _ string, _ libnetwork.NetworkController, _ bool, _ *idtools.IdentityMapping) (executor.Executor, error) { return &winExecutor{}, nil } diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 539015e8990e9..196ca9923fb0e 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -318,6 +318,7 @@ func newRouterOptions(config *config.Config, d *daemon.Daemon) (routerOptions, e ResolverOpt: d.NewResolveOptionsFunc(), BuilderConfig: config.Builder, Rootless: d.Rootless(), + IdentityMapping: d.IdentityMapping(), }) if err != nil { return opts, err diff --git a/vendor.conf b/vendor.conf index 517512d28e78c..a1778a0bd8205 100644 --- a/vendor.conf +++ b/vendor.conf @@ -27,7 +27,7 @@ github.com/imdario/mergo 7c29201646fa3de8506f70121347 golang.org/x/sync e225da77a7e68af35c70ccbf71af2b83e6acac3c # buildkit -github.com/moby/buildkit 1f89ec125f84c097bdf3a063be622c4238dba5f8 +github.com/moby/buildkit c24275065aca6605bd83c57c6735510f4ebeb6d9 github.com/tonistiigi/fsutil 3bbb99cdbd76619ab717299830c60f6f2a533a6b github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746 github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 diff --git a/vendor/github.com/moby/buildkit/executor/oci/hosts.go b/vendor/github.com/moby/buildkit/executor/oci/hosts.go index c350a6de27c20..3b3f86db79cbe 100644 --- a/vendor/github.com/moby/buildkit/executor/oci/hosts.go +++ b/vendor/github.com/moby/buildkit/executor/oci/hosts.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" + "github.com/docker/docker/pkg/idtools" "github.com/moby/buildkit/executor" "github.com/moby/buildkit/identity" ) @@ -17,10 +18,10 @@ const hostsContent = ` ::1 localhost ip6-localhost ip6-loopback ` -func GetHostsFile(ctx context.Context, stateDir string, extraHosts []executor.HostIP) (string, func(), error) { +func GetHostsFile(ctx context.Context, stateDir string, extraHosts []executor.HostIP, idmap *idtools.IdentityMapping) (string, func(), error) { if len(extraHosts) == 0 { _, err := g.Do(ctx, stateDir, func(ctx context.Context) (interface{}, error) { - _, _, err := makeHostsFile(stateDir, nil) + _, _, err := makeHostsFile(stateDir, nil, idmap) return nil, err }) if err != nil { @@ -28,10 +29,10 @@ func GetHostsFile(ctx context.Context, stateDir string, extraHosts []executor.Ho } return filepath.Join(stateDir, "hosts"), func() {}, nil } - return makeHostsFile(stateDir, extraHosts) + return makeHostsFile(stateDir, extraHosts, idmap) } -func makeHostsFile(stateDir string, extraHosts []executor.HostIP) (string, func(), error) { +func makeHostsFile(stateDir string, extraHosts []executor.HostIP, idmap *idtools.IdentityMapping) (string, func(), error) { p := filepath.Join(stateDir, "hosts") if len(extraHosts) != 0 { p += "." + identity.NewID() @@ -56,11 +57,19 @@ func makeHostsFile(stateDir string, extraHosts []executor.HostIP) (string, func( } } - if err := ioutil.WriteFile(p+".tmp", b.Bytes(), 0644); err != nil { + tmpPath := p + ".tmp" + if err := ioutil.WriteFile(tmpPath, b.Bytes(), 0644); err != nil { return "", nil, err } - if err := os.Rename(p+".tmp", p); err != nil { + if idmap != nil { + root := idmap.RootPair() + if err := os.Chown(tmpPath, root.UID, root.GID); err != nil { + return "", nil, err + } + } + + if err := os.Rename(tmpPath, p); err != nil { return "", nil, err } return p, func() { diff --git a/vendor/github.com/moby/buildkit/executor/oci/resolvconf.go b/vendor/github.com/moby/buildkit/executor/oci/resolvconf.go index a65f2ddecf981..422f1ab9621b6 100644 --- a/vendor/github.com/moby/buildkit/executor/oci/resolvconf.go +++ b/vendor/github.com/moby/buildkit/executor/oci/resolvconf.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" + "github.com/docker/docker/pkg/idtools" "github.com/docker/libnetwork/resolvconf" "github.com/moby/buildkit/util/flightcontrol" ) @@ -14,7 +15,7 @@ var g flightcontrol.Group var notFirstRun bool var lastNotEmpty bool -func GetResolvConf(ctx context.Context, stateDir string) (string, error) { +func GetResolvConf(ctx context.Context, stateDir string, idmap *idtools.IdentityMapping) (string, error) { p := filepath.Join(stateDir, "resolv.conf") _, err := g.Do(ctx, stateDir, func(ctx context.Context) (interface{}, error) { generate := !notFirstRun @@ -65,11 +66,19 @@ func GetResolvConf(ctx context.Context, stateDir string) (string, error) { return "", err } - if err := ioutil.WriteFile(p+".tmp", f.Content, 0644); err != nil { + tmpPath := p + ".tmp" + if err := ioutil.WriteFile(tmpPath, f.Content, 0644); err != nil { return "", err } - if err := os.Rename(p+".tmp", p); err != nil { + if idmap != nil { + root := idmap.RootPair() + if err := os.Chown(tmpPath, root.UID, root.GID); err != nil { + return "", err + } + } + + if err := os.Rename(tmpPath, p); err != nil { return "", err } return "", nil diff --git a/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go b/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go index ceca9d8bec5ff..680bc7b346657 100644 --- a/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go +++ b/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go @@ -79,7 +79,7 @@ func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Ex root := opt.Root - if err := os.MkdirAll(root, 0700); err != nil { + if err := os.MkdirAll(root, 0711); err != nil { return nil, errors.Wrapf(err, "failed to create %s", root) } @@ -134,12 +134,12 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache. logrus.Info("enabling HostNetworking") } - resolvConf, err := oci.GetResolvConf(ctx, w.root) + resolvConf, err := oci.GetResolvConf(ctx, w.root, w.idmap) if err != nil { return err } - hostsFile, clean, err := oci.GetHostsFile(ctx, w.root, meta.ExtraHosts) + hostsFile, clean, err := oci.GetHostsFile(ctx, w.root, meta.ExtraHosts, w.idmap) if err != nil { return err } @@ -161,7 +161,7 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache. id := identity.NewID() bundle := filepath.Join(w.root, id) - if err := os.Mkdir(bundle, 0700); err != nil { + if err := os.Mkdir(bundle, 0711); err != nil { return err } defer os.RemoveAll(bundle) diff --git a/vendor/github.com/moby/buildkit/solver/llbsolver/file/backend.go b/vendor/github.com/moby/buildkit/solver/llbsolver/file/backend.go index 45d66d713e718..07044691f2c63 100644 --- a/vendor/github.com/moby/buildkit/solver/llbsolver/file/backend.go +++ b/vendor/github.com/moby/buildkit/solver/llbsolver/file/backend.go @@ -27,13 +27,9 @@ func timestampToTime(ts int64) *time.Time { } func mapUser(user *copy.ChownOpt, idmap *idtools.IdentityMapping) (*copy.ChownOpt, error) { - if idmap == nil { + if idmap == nil || user == nil { return user, nil } - if user == nil { - identity := idmap.RootPair() - return ©.ChownOpt{Uid: identity.UID, Gid: identity.GID}, nil - } identity, err := idmap.ToHost(idtools.Identity{ UID: user.Uid, GID: user.Gid, @@ -138,7 +134,6 @@ func docopy(ctx context.Context, src, dest string, action pb.FileActionCopy, u * return nil } - // TODO(tonistiigi): this is wrong. fsutil.Copy can't handle non-forced user u, err := mapUser(u, idmap) if err != nil { return err