metadata: Allow simple string keys

If a file is a simple string (as opposed to a map) then write it with the
default perms. This makes for slightly terser metadata when creating a simple
datafile.

Signed-off-by: Ian Campbell <ian.campbell@docker.com>
This commit is contained in:
Ian Campbell 2017-05-09 23:52:04 +01:00
parent 8fd1a3cbdb
commit 800badea42
2 changed files with 33 additions and 20 deletions

View File

@ -29,10 +29,7 @@ For example, the following userdata file:
} }
}, },
"foo" : { "foo" : {
"bar" : { "bar" : "foobar",
"perm": "0644",
"content": "foobar"
},
"baz" : { "baz" : {
"perm": "0600", "perm": "0600",
"content": "bar" "content": "bar"
@ -47,6 +44,16 @@ will generate the following files:
/var/config/foo/baz /var/config/foo/baz
``` ```
Each file can either be:
- a simple string (as for `foo/bar` above) in which case the file will
be created with the given contents and read/write (but not execute)
permissions for user and read permissions for group and everyone else (in octal format `0644`).
- a map (as for `ssh/sshd_config` and `foo/baz` above) with the
following mandatory keys:
- `content`: the contents of the file.
- `perm`: the permissions to create the file with.
This hierarchy can then be used by individual containers, who can bind This hierarchy can then be used by individual containers, who can bind
mount the config sub-directory into their namespace where it is mount the config sub-directory into their namespace where it is
needed. needed.

View File

@ -167,25 +167,31 @@ func processUserData(data []byte) error {
continue continue
} }
for f, i := range files { for f, i := range files {
fi, ok := i.(map[string]interface{}) p := uint64(0644)
if !ok { var c string
switch fi := i.(type) {
case map[string]interface{}:
if _, ok := fi["perm"]; !ok {
log.Printf("No permission provided %s:%s", f, fi)
continue
}
if _, ok := fi["content"]; !ok {
log.Printf("No content provided %s:%s", f, fi)
continue
}
c = fi["content"].(string)
if p, err = strconv.ParseUint(fi["perm"].(string), 8, 32); err != nil {
log.Printf("Failed to parse permission %s: %s", fi, err)
continue
}
case string:
c = fi
default:
log.Printf("Couldn't convert JSON for items: %s", i) log.Printf("Couldn't convert JSON for items: %s", i)
continue continue
} }
if _, ok := fi["perm"]; !ok {
log.Printf("No permission provided %s:%s", f, fi)
continue
}
if _, ok := fi["content"]; !ok {
log.Printf("No content provided %s:%s", f, fi)
continue
}
c := fi["content"].(string)
p, err := strconv.ParseUint(fi["perm"].(string), 8, 32)
if err != nil {
log.Printf("Failed to parse permission %s: %s", fi, err)
continue
}
if err := ioutil.WriteFile(path.Join(dir, f), []byte(c), os.FileMode(p)); err != nil { if err := ioutil.WriteFile(path.Join(dir, f), []byte(c), os.FileMode(p)); err != nil {
log.Printf("Failed to write %s/%s: %s", dir, f, err) log.Printf("Failed to write %s/%s: %s", dir, f, err)
continue continue