diff --git a/src/moby/build.go b/src/moby/build.go index 10acc5d04..70c900a75 100644 --- a/src/moby/build.go +++ b/src/moby/build.go @@ -414,6 +414,8 @@ func filesystem(m Moby, tw *tar.Writer) error { Name: root, Typeflag: tar.TypeDir, Mode: dirMode, + Uid: int(f.UID), + Gid: int(f.GID), } err := tw.WriteHeader(hdr) if err != nil { @@ -423,36 +425,30 @@ func filesystem(m Moby, tw *tar.Writer) error { } } addedFiles[f.Path] = true + hdr := &tar.Header{ + Name: f.Path, + Mode: mode, + Uid: int(f.UID), + Gid: int(f.GID), + } if f.Directory { if f.Contents != nil { return errors.New("Directory with contents not allowed") } - hdr := &tar.Header{ - Name: f.Path, - Typeflag: tar.TypeDir, - Mode: mode, - } + hdr.Typeflag = tar.TypeDir err := tw.WriteHeader(hdr) if err != nil { return err } } else if f.Symlink != "" { - hdr := &tar.Header{ - Name: f.Path, - Typeflag: tar.TypeSymlink, - Mode: mode, - Linkname: f.Symlink, - } + hdr.Typeflag = tar.TypeSymlink + hdr.Linkname = f.Symlink err := tw.WriteHeader(hdr) if err != nil { return err } } else { - hdr := &tar.Header{ - Name: f.Path, - Mode: mode, - Size: int64(len(contents)), - } + hdr.Size = int64(len(contents)) err := tw.WriteHeader(hdr) if err != nil { return err diff --git a/src/moby/config.go b/src/moby/config.go index b74303cd5..e3d3a0b13 100644 --- a/src/moby/config.go +++ b/src/moby/config.go @@ -27,15 +27,7 @@ type Moby struct { Onboot []Image Services []Image Trust TrustConfig - Files []struct { - Path string - Directory bool - Symlink string - Contents *string - Source string - Optional bool - Mode string - } + Files []File } // TrustConfig is the type of a content trust config @@ -44,11 +36,25 @@ type TrustConfig struct { Org []string } +// File is the type of a file specification +type File struct { + Path string + Directory bool + Symlink string + Contents *string + Source string + Optional bool + Mode string + UID uint32 `yaml:"uid" json:"uid"` + GID uint32 `yaml:"gid" json:"gid"` +} + // Image is the type of an image config type Image struct { Name string `yaml:"name" json:"name"` Image string `yaml:"image" json:"image"` Capabilities *[]string `yaml:"capabilities" json:"capabilities,omitempty"` + Ambient *[]string `yaml:"ambient" json:"ambient,omitempty"` Mounts *[]specs.Mount `yaml:"mounts" json:"mounts,omitempty"` Binds *[]string `yaml:"binds" json:"binds,omitempty"` Tmpfs *[]string `yaml:"tmpfs" json:"tmpfs,omitempty"` @@ -619,25 +625,13 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect) (specs.Spec, err // TODO user, cgroup namespaces - caps := assignStrings(label.Capabilities, yaml.Capabilities) - for _, capability := range caps { - if capability == "none" || capability == "all" { - continue - } - - found := false - for _, ac := range allCaps { - if ac == capability { - found = true - break - } - } - - if !found { - return oci, fmt.Errorf("unknown capability: %s", capability) - } + // Capabilities + capCheck := map[string]bool{} + for _, capability := range allCaps { + capCheck[capability] = true } - + boundingSet := map[string]bool{} + caps := assignStrings(label.Capabilities, yaml.Capabilities) if len(caps) == 1 { switch cap := strings.ToLower(caps[0]); cap { case "none": @@ -646,6 +640,31 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect) (specs.Spec, err caps = allCaps[:] } } + for _, capability := range caps { + if !capCheck[capability] { + return oci, fmt.Errorf("unknown capability: %s", capability) + } + boundingSet[capability] = true + } + ambient := assignStrings(label.Ambient, yaml.Ambient) + if len(ambient) == 1 { + switch cap := strings.ToLower(ambient[0]); cap { + case "none": + ambient = []string{} + case "all": + ambient = allCaps[:] + } + } + for _, capability := range ambient { + if !capCheck[capability] { + return oci, fmt.Errorf("unknown capability: %s", capability) + } + boundingSet[capability] = true + } + bounding := []string{} + for capability := range boundingSet { + bounding = append(bounding, capability) + } rlimitsString := assignStrings(label.Rlimits, yaml.Rlimits) rlimits := []specs.LinuxRlimit{} @@ -727,11 +746,11 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect) (specs.Spec, err Env: env, Cwd: cwd, Capabilities: &specs.LinuxCapabilities{ - Bounding: caps, + Bounding: bounding, Effective: caps, - Inheritable: caps, - Permitted: caps, - Ambient: []string{}, + Inheritable: bounding, + Permitted: bounding, + Ambient: ambient, }, Rlimits: rlimits, NoNewPrivileges: assignBool(label.NoNewPrivileges, yaml.NoNewPrivileges), diff --git a/src/moby/schema.go b/src/moby/schema.go index 92ed70c76..94c7e77e5 100644 --- a/src/moby/schema.go +++ b/src/moby/schema.go @@ -24,7 +24,9 @@ var schema = string(` "contents": {"type": "string"}, "source": {"type": "string"}, "optional": {"type": "boolean"}, - "mode": {"type": "string"} + "mode": {"type": "string"}, + "uid": {"type": "integer"}, + "gid": {"type": "integer"} } }, "files": { @@ -65,6 +67,7 @@ var schema = string(` "name": {"type": "string"}, "image": {"type": "string"}, "capabilities": { "$ref": "#/definitions/strings" }, + "ambient": { "$ref": "#/definitions/strings" }, "mounts": { "$ref": "#/definitions/mounts" }, "binds": { "$ref": "#/definitions/strings" }, "tmpfs": { "$ref": "#/definitions/strings" },