Merge pull request #39349 from tonistiigi/buildkit-userns-remap
builder-next: userns remap support
This commit is contained in:
commit
39c8e88068
11 changed files with 56 additions and 32 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
21
vendor/github.com/moby/buildkit/executor/oci/hosts.go
generated
vendored
21
vendor/github.com/moby/buildkit/executor/oci/hosts.go
generated
vendored
|
@ -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() {
|
||||
|
|
15
vendor/github.com/moby/buildkit/executor/oci/resolvconf.go
generated
vendored
15
vendor/github.com/moby/buildkit/executor/oci/resolvconf.go
generated
vendored
|
@ -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
|
||||
|
|
8
vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go
generated
vendored
8
vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go
generated
vendored
|
@ -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)
|
||||
|
|
7
vendor/github.com/moby/buildkit/solver/llbsolver/file/backend.go
generated
vendored
7
vendor/github.com/moby/buildkit/solver/llbsolver/file/backend.go
generated
vendored
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue