diff --git a/docs/metadata.md b/docs/metadata.md index 17d37607e..81d660c38 100644 --- a/docs/metadata.md +++ b/docs/metadata.md @@ -29,10 +29,7 @@ For example, the following userdata file: } }, "foo" : { - "bar" : { - "perm": "0644", - "content": "foobar" - }, + "bar" : "foobar", "baz" : { "perm": "0600", "content": "bar" @@ -47,6 +44,16 @@ will generate the following files: /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 mount the config sub-directory into their namespace where it is needed. diff --git a/pkg/metadata/main.go b/pkg/metadata/main.go index b6de5918b..97aba9967 100644 --- a/pkg/metadata/main.go +++ b/pkg/metadata/main.go @@ -167,25 +167,31 @@ func processUserData(data []byte) error { continue } for f, i := range files { - fi := i.(map[string]interface{}) - if !ok { - log.Printf("Could convert JSON for items: %s", i) - 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) + p := uint64(0644) + 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) continue } + 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) continue