update ctr run to support multiple uid/gid mappings
Signed-off-by: Henry Wang <henwang@amazon.com>
This commit is contained in:
		@@ -37,6 +37,7 @@ import (
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/oci"
 | 
			
		||||
	"github.com/containerd/log"
 | 
			
		||||
	"github.com/containerd/platforms"
 | 
			
		||||
 | 
			
		||||
	"github.com/intel/goresctrl/pkg/blockio"
 | 
			
		||||
	"github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	"github.com/urfave/cli/v2"
 | 
			
		||||
@@ -45,13 +46,13 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var platformRunFlags = []cli.Flag{
 | 
			
		||||
	&cli.StringFlag{
 | 
			
		||||
	&cli.StringSliceFlag{
 | 
			
		||||
		Name:  "uidmap",
 | 
			
		||||
		Usage: "Run inside a user namespace with the specified UID mapping range; specified with the format `container-uid:host-uid:length`",
 | 
			
		||||
		Usage: "Run inside a user namespace with the specified UID mapping ranges; specified with the format `container-uid:host-uid:length`",
 | 
			
		||||
	},
 | 
			
		||||
	&cli.StringFlag{
 | 
			
		||||
	&cli.StringSliceFlag{
 | 
			
		||||
		Name:  "gidmap",
 | 
			
		||||
		Usage: "Run inside a user namespace with the specified GID mapping range; specified with the format `container-gid:host-gid:length`",
 | 
			
		||||
		Usage: "Run inside a user namespace with the specified GID mapping ranges; specified with the format `container-gid:host-gid:length`",
 | 
			
		||||
	},
 | 
			
		||||
	&cli.BoolFlag{
 | 
			
		||||
		Name:  "remap-labels",
 | 
			
		||||
@@ -159,26 +160,28 @@ func NewContainer(ctx context.Context, client *containerd.Client, cliContext *cl
 | 
			
		||||
				containerd.WithImageConfigLabels(image),
 | 
			
		||||
				containerd.WithAdditionalContainerLabels(labels),
 | 
			
		||||
				containerd.WithSnapshotter(snapshotter))
 | 
			
		||||
			if uidmap, gidmap := cliContext.String("uidmap"), cliContext.String("gidmap"); uidmap != "" && gidmap != "" {
 | 
			
		||||
				uidMap, err := parseIDMapping(uidmap)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
 | 
			
		||||
			if uidmaps, gidmaps := cliContext.StringSlice("uidmap"), cliContext.StringSlice("gidmap"); len(uidmaps) > 0 && len(gidmaps) > 0 {
 | 
			
		||||
				var uidSpec, gidSpec []specs.LinuxIDMapping
 | 
			
		||||
				if uidSpec, err = parseIDMappingOption(uidmaps); err != nil {
 | 
			
		||||
					return nil, err
 | 
			
		||||
				}
 | 
			
		||||
				gidMap, err := parseIDMapping(gidmap)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
				if gidSpec, err = parseIDMappingOption(gidmaps); err != nil {
 | 
			
		||||
					return nil, err
 | 
			
		||||
				}
 | 
			
		||||
				opts = append(opts,
 | 
			
		||||
					oci.WithUserNamespace([]specs.LinuxIDMapping{uidMap}, []specs.LinuxIDMapping{gidMap}))
 | 
			
		||||
				opts = append(opts, oci.WithUserNamespace(uidSpec, gidSpec))
 | 
			
		||||
				// use snapshotter opts or the remapped snapshot support to shift the filesystem
 | 
			
		||||
				// currently the snapshotters known to support the labels are:
 | 
			
		||||
				// fuse-overlayfs - https://github.com/containerd/fuse-overlayfs-snapshotter
 | 
			
		||||
				// overlay - in case of idmapped mount points are supported by host kernel (Linux kernel 5.19)
 | 
			
		||||
				if cliContext.Bool("remap-labels") {
 | 
			
		||||
					cOpts = append(cOpts, containerd.WithNewSnapshot(id, image,
 | 
			
		||||
						containerd.WithRemapperLabels(0, uidMap.HostID, 0, gidMap.HostID, uidMap.Size)))
 | 
			
		||||
					// TODO: the optimization code path on id mapped mounts only supports single mapping entry today.
 | 
			
		||||
					if len(uidSpec) > 1 || len(gidSpec) > 1 {
 | 
			
		||||
						return nil, errors.New("'remap-labels' option does not support multiple mappings")
 | 
			
		||||
					}
 | 
			
		||||
					cOpts = append(cOpts, containerd.WithNewSnapshot(id, image, containerd.WithRemapperLabels(0, uidSpec[0].HostID, 0, gidSpec[0].HostID, uidSpec[0].Size)))
 | 
			
		||||
				} else {
 | 
			
		||||
					cOpts = append(cOpts, containerd.WithRemappedSnapshot(id, image, uidMap.HostID, gidMap.HostID))
 | 
			
		||||
					cOpts = append(cOpts, containerd.WithUserNSRemappedSnapshot(id, image, uidSpec, gidSpec))
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				// Even when "read-only" is set, we don't use KindView snapshot here. (#1495)
 | 
			
		||||
@@ -415,6 +418,18 @@ func NewContainer(ctx context.Context, client *containerd.Client, cliContext *cl
 | 
			
		||||
	return client.NewContainer(ctx, id, cOpts...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseIDMappingOption(stringSlices []string) ([]specs.LinuxIDMapping, error) {
 | 
			
		||||
	var res []specs.LinuxIDMapping
 | 
			
		||||
	for _, str := range stringSlices {
 | 
			
		||||
		m, err := parseIDMapping(str)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		res = append(res, m)
 | 
			
		||||
	}
 | 
			
		||||
	return res, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseIDMapping(mapping string) (specs.LinuxIDMapping, error) {
 | 
			
		||||
	// We expect 3 parts, but limit to 4 to allow detection of invalid values.
 | 
			
		||||
	parts := strings.SplitN(mapping, ":", 4)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user