mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-20 17:49:10 +00:00
Merge pull request #117 from justincormack/uid
Allow uid, gid fields to be numeric or names
This commit is contained in:
commit
f255d671c6
@ -15,8 +15,8 @@ Each section adds file to the root file system. Sections may be omitted.
|
|||||||
|
|
||||||
Each container that is specified is allocated a unique `uid` and `gid` that it may use if it
|
Each container that is specified is allocated a unique `uid` and `gid` that it may use if it
|
||||||
wishes to run as an isolated user (or user namespace). Anywhere you specify a `uid` or `gid`
|
wishes to run as an isolated user (or user namespace). Anywhere you specify a `uid` or `gid`
|
||||||
field you specify a string that can either be the numeric id, or if you use a name it will
|
field you specify either the numeric id, or if you use a name it will refer to the id allocated
|
||||||
refer to the id allocated to the container with that name.
|
to the container with that name.
|
||||||
|
|
||||||
```
|
```
|
||||||
services:
|
services:
|
||||||
|
@ -50,8 +50,8 @@ type File struct {
|
|||||||
Source string
|
Source string
|
||||||
Optional bool
|
Optional bool
|
||||||
Mode string
|
Mode string
|
||||||
UID string `yaml:"uid" json:"uid"`
|
UID interface{} `yaml:"uid" json:"uid"`
|
||||||
GID string `yaml:"gid" json:"gid"`
|
GID interface{} `yaml:"gid" json:"gid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image is the type of an image config
|
// Image is the type of an image config
|
||||||
@ -75,9 +75,9 @@ type Image struct {
|
|||||||
Readonly *bool `yaml:"readonly" json:"readonly,omitempty"`
|
Readonly *bool `yaml:"readonly" json:"readonly,omitempty"`
|
||||||
MaskedPaths *[]string `yaml:"maskedPaths" json:"maskedPaths,omitempty"`
|
MaskedPaths *[]string `yaml:"maskedPaths" json:"maskedPaths,omitempty"`
|
||||||
ReadonlyPaths *[]string `yaml:"readonlyPaths" json:"readonlyPaths,omitempty"`
|
ReadonlyPaths *[]string `yaml:"readonlyPaths" json:"readonlyPaths,omitempty"`
|
||||||
UID *string `yaml:"uid" json:"uid,omitempty"`
|
UID *interface{} `yaml:"uid" json:"uid,omitempty"`
|
||||||
GID *string `yaml:"gid" json:"gid,omitempty"`
|
GID *interface{} `yaml:"gid" json:"gid,omitempty"`
|
||||||
AdditionalGids *[]string `yaml:"additionalGids" json:"additionalGids,omitempty"`
|
AdditionalGids *[]interface{} `yaml:"additionalGids" json:"additionalGids,omitempty"`
|
||||||
NoNewPrivileges *bool `yaml:"noNewPrivileges" json:"noNewPrivileges,omitempty"`
|
NoNewPrivileges *bool `yaml:"noNewPrivileges" json:"noNewPrivileges,omitempty"`
|
||||||
OOMScoreAdj *int `yaml:"oomScoreAdj" json:"oomScoreAdj,omitempty"`
|
OOMScoreAdj *int `yaml:"oomScoreAdj" json:"oomScoreAdj,omitempty"`
|
||||||
DisableOOMKiller *bool `yaml:"disableOOMKiller" json:"disableOOMKiller,omitempty"`
|
DisableOOMKiller *bool `yaml:"disableOOMKiller" json:"disableOOMKiller,omitempty"`
|
||||||
@ -369,6 +369,29 @@ func assignUint32Array(v1, v2 *[]uint32) []uint32 {
|
|||||||
return []uint32{}
|
return []uint32{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// assignInterface does ordered overrides from Go interfaces
|
||||||
|
// we return 0 as we are using this for uid and this is the default
|
||||||
|
func assignInterface(v1, v2 *interface{}) interface{} {
|
||||||
|
if v2 != nil {
|
||||||
|
return *v2
|
||||||
|
}
|
||||||
|
if v1 != nil {
|
||||||
|
return *v1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// assignInterfaceArray does ordered overrides from arrays of Go interfaces
|
||||||
|
func assignInterfaceArray(v1, v2 *[]interface{}) []interface{} {
|
||||||
|
if v2 != nil {
|
||||||
|
return *v2
|
||||||
|
}
|
||||||
|
if v1 != nil {
|
||||||
|
return *v1
|
||||||
|
}
|
||||||
|
return []interface{}{}
|
||||||
|
}
|
||||||
|
|
||||||
// assignStrings does ordered overrides from JSON string array pointers
|
// assignStrings does ordered overrides from JSON string array pointers
|
||||||
func assignStrings(v1, v2 *[]string) []string {
|
func assignStrings(v1, v2 *[]string) []string {
|
||||||
if v2 != nil {
|
if v2 != nil {
|
||||||
@ -424,7 +447,7 @@ func assignString(v1, v2 *string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// assignMappings does prdered overrides from UID, GID maps
|
// assignMappings does ordered overrides from UID, GID maps
|
||||||
func assignMappings(v1, v2 *[]specs.LinuxIDMapping) []specs.LinuxIDMapping {
|
func assignMappings(v1, v2 *[]specs.LinuxIDMapping) []specs.LinuxIDMapping {
|
||||||
if v2 != nil {
|
if v2 != nil {
|
||||||
return *v2
|
return *v2
|
||||||
@ -512,20 +535,25 @@ var allCaps = []string{
|
|||||||
"CAP_WAKE_ALARM",
|
"CAP_WAKE_ALARM",
|
||||||
}
|
}
|
||||||
|
|
||||||
func idNumeric(id string, idMap map[string]uint32) (uint32, error) {
|
func idNumeric(v interface{}, idMap map[string]uint32) (uint32, error) {
|
||||||
if id == "" || id == "root" {
|
switch id := v.(type) {
|
||||||
return 0, nil
|
case nil:
|
||||||
}
|
return uint32(0), nil
|
||||||
for k, v := range idMap {
|
case int:
|
||||||
if id == k {
|
return uint32(id), nil
|
||||||
return v, nil
|
case string:
|
||||||
|
if id == "" || id == "root" {
|
||||||
|
return uint32(0), nil
|
||||||
}
|
}
|
||||||
|
for k, v := range idMap {
|
||||||
|
if id == k {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("Cannot find id: %s", id)
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("Bad type for uid or gid")
|
||||||
}
|
}
|
||||||
v, err := strconv.ParseUint(id, 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("Cannot find or parse id (%s): %v", id, err)
|
|
||||||
}
|
|
||||||
return uint32(v), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigInspectToOCI converts a config and the output of image inspect to an OCI config
|
// ConfigInspectToOCI converts a config and the output of image inspect to an OCI config
|
||||||
@ -797,19 +825,19 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect, idMap map[string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle mapping of named uid, gid to numbers
|
// handle mapping of named uid, gid to numbers
|
||||||
uidString := assignString(label.UID, yaml.UID)
|
uidIf := assignInterface(label.UID, yaml.UID)
|
||||||
gidString := assignString(label.GID, yaml.GID)
|
gidIf := assignInterface(label.GID, yaml.GID)
|
||||||
agStrings := assignStrings(label.AdditionalGids, yaml.AdditionalGids)
|
agIf := assignInterfaceArray(label.AdditionalGids, yaml.AdditionalGids)
|
||||||
uid, err := idNumeric(uidString, idMap)
|
uid, err := idNumeric(uidIf, idMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return oci, err
|
return oci, err
|
||||||
}
|
}
|
||||||
gid, err := idNumeric(gidString, idMap)
|
gid, err := idNumeric(gidIf, idMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return oci, err
|
return oci, err
|
||||||
}
|
}
|
||||||
additionalGroups := []uint32{}
|
additionalGroups := []uint32{}
|
||||||
for _, id := range agStrings {
|
for _, id := range agIf {
|
||||||
ag, err := idNumeric(id, idMap)
|
ag, err := idNumeric(id, idMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return oci, err
|
return oci, err
|
||||||
|
@ -81,8 +81,8 @@ func TestInvalidCap(t *testing.T) {
|
|||||||
func TestIdMap(t *testing.T) {
|
func TestIdMap(t *testing.T) {
|
||||||
idMap := map[string]uint32{"test": 199}
|
idMap := map[string]uint32{"test": 199}
|
||||||
|
|
||||||
uid := "test"
|
var uid interface{} = "test"
|
||||||
gid := "76"
|
var gid interface{} = 76
|
||||||
|
|
||||||
yaml := Image{
|
yaml := Image{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
|
@ -27,8 +27,8 @@ var schema = string(`
|
|||||||
"source": {"type": "string"},
|
"source": {"type": "string"},
|
||||||
"optional": {"type": "boolean"},
|
"optional": {"type": "boolean"},
|
||||||
"mode": {"type": "string"},
|
"mode": {"type": "string"},
|
||||||
"uid": {"type": "string"},
|
"uid": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
|
||||||
"gid": {"type": "string"}
|
"gid": {"anyOf": [{"type": "string"}, {"type": "integer"}]}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
@ -97,11 +97,11 @@ var schema = string(`
|
|||||||
"readonly": { "type": "boolean"},
|
"readonly": { "type": "boolean"},
|
||||||
"maskedPaths": { "$ref": "#/definitions/strings" },
|
"maskedPaths": { "$ref": "#/definitions/strings" },
|
||||||
"readonlyPaths": { "$ref": "#/definitions/strings" },
|
"readonlyPaths": { "$ref": "#/definitions/strings" },
|
||||||
"uid": {"type": "string"},
|
"uid": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
|
||||||
"gid": {"type": "string"},
|
"gid": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
|
||||||
"additionalGids": {
|
"additionalGids": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": { "type": "string" }
|
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}
|
||||||
},
|
},
|
||||||
"noNewPrivileges": {"type": "boolean"},
|
"noNewPrivileges": {"type": "boolean"},
|
||||||
"hostname": {"type": "string"},
|
"hostname": {"type": "string"},
|
||||||
|
Loading…
Reference in New Issue
Block a user