diff --git a/docs/yaml.md b/docs/yaml.md index 52e149706..396106931 100644 --- a/docs/yaml.md +++ b/docs/yaml.md @@ -96,6 +96,14 @@ Specifying the `mode` is optional, and will default to `0600`. Leading directori created if not specified. You can use `~/path` in `source` to specify a path in the build user's home directory. +In addition there is a `metadata` option that will generate the file. Currently the only value +supported here is `"yaml"` which will output the yaml used to generate the image into the specified +file: +``` + - path: etc/linuxkit.yml + metadata:yaml +``` + ## `trust` The `trust` section specifies which build components are to be cryptographically verified with diff --git a/src/moby/build.go b/src/moby/build.go index d2fcf266b..9312733ed 100644 --- a/src/moby/build.go +++ b/src/moby/build.go @@ -3,6 +3,7 @@ package moby import ( "archive/tar" "bytes" + "encoding/json" "errors" "fmt" "io" @@ -359,6 +360,16 @@ func tarAppend(iw *tar.Writer, tr *tar.Reader) error { return nil } +// this allows inserting metadata into a file in the image +func metadata(m Moby, md string) ([]byte, error) { + switch md { + case "yaml": + return json.MarshalIndent(m, "", " ") + default: + return []byte{}, fmt.Errorf("Unsupported metadata type: %s", md) + } +} + func filesystem(m Moby, tw *tar.Writer, idMap map[string]uint32) error { // TODO also include the files added in other parts of the build var addedFiles = map[string]bool{} @@ -410,25 +421,43 @@ func filesystem(m Moby, tw *tar.Writer, idMap map[string]uint32) error { if f.Contents != nil { contents = []byte(*f.Contents) } - if !f.Directory && f.Contents == nil && f.Symlink == "" { - if f.Source == "" { - return errors.New("Contents of file not specified") + if !f.Directory && f.Symlink == "" && f.Contents == nil { + if f.Source == "" && f.Metadata == "" { + return fmt.Errorf("Contents of file (%s) not specified", f.Path) } - if len(f.Source) > 2 && f.Source[:2] == "~/" { - f.Source = homeDir() + f.Source[1:] + if f.Source != "" && f.Metadata != "" { + return fmt.Errorf("Specified Source and Metadata for file: %s", f.Path) } - if f.Optional { - _, err := os.Stat(f.Source) + if f.Source != "" { + source := f.Source + if len(source) > 2 && source[:2] == "~/" { + source = homeDir() + source[1:] + } + if f.Optional { + _, err := os.Stat(source) + if err != nil { + // skip if not found or readable + log.Debugf("Skipping file [%s] as not readable and marked optional", source) + continue + } + } + var err error + contents, err = ioutil.ReadFile(source) if err != nil { - // skip if not found or readable - log.Debugf("Skipping file [%s] as not readable and marked optional", f.Source) - continue + return err + } + } else { + contents, err = metadata(m, f.Metadata) + if err != nil { + return err } } - var err error - contents, err = ioutil.ReadFile(f.Source) - if err != nil { - return err + } else { + if f.Metadata != "" { + return fmt.Errorf("Specified Contents and Metadata for file: %s", f.Path) + } + if f.Source != "" { + return fmt.Errorf("Specified Contents and Source for file: %s", f.Path) } } // we need all the leading directories diff --git a/src/moby/config.go b/src/moby/config.go index d790d3cf9..a2d87fc4c 100644 --- a/src/moby/config.go +++ b/src/moby/config.go @@ -29,29 +29,30 @@ type Moby struct { // KernelConfig is the type of the config for a kernel type KernelConfig struct { - Image string - Cmdline string - Binary string - Tar *string + Image string `yaml:"image" json:"image"` + Cmdline string `yaml:"cmdline" json:"cmdline,omitempty"` + Binary string `yaml:"binary" json:"binary,omitempty"` + Tar *string `yaml:"tar" json:"tar,omitempty"` } // TrustConfig is the type of a content trust config type TrustConfig struct { - Image []string - Org []string + Image []string `yaml:"image" json:"image,omitempty"` + Org []string `yaml:"org" json:"org,omitempty"` } // 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 interface{} `yaml:"uid" json:"uid"` - GID interface{} `yaml:"gid" json:"gid"` + Path string `yaml:"path" json:"path"` + Directory bool `yaml:"directory" json:"directory"` + Symlink string `yaml:"symlink" json:"symlink,omitempty"` + Contents *string `yaml:"contents" json:"contents,omitempty"` + Source string `yaml:"source" json:"source,omitempty"` + Metadata string `yaml:"metadata" json:"metadata,omitempty"` + Optional bool `yaml:"optional" json:"optional"` + Mode string `yaml:"mode" json:"mode,omitempty"` + UID interface{} `yaml:"uid" json:"uid,omitempty"` + GID interface{} `yaml:"gid" json:"gid,omitempty"` } // Image is the type of an image config @@ -65,13 +66,13 @@ type Image struct { Tmpfs *[]string `yaml:"tmpfs" json:"tmpfs,omitempty"` Command *[]string `yaml:"command" json:"command,omitempty"` Env *[]string `yaml:"env" json:"env,omitempty"` - Cwd string `yaml:"cwd" json:"cwd"` - Net string `yaml:"net" json:"net"` - Pid string `yaml:"pid" json:"pid"` - Ipc string `yaml:"ipc" json:"ipc"` - Uts string `yaml:"uts" json:"uts"` - Userns string `yaml:"userns" json:"userns"` - Hostname string `yaml:"hostname" json:"hostname"` + Cwd string `yaml:"cwd" json:"cwd,omitempty"` + Net string `yaml:"net" json:"net,omitempty"` + Pid string `yaml:"pid" json:"pid,omitempty"` + Ipc string `yaml:"ipc" json:"ipc,omitempty"` + Uts string `yaml:"uts" json:"uts,omitempty"` + Userns string `yaml:"userns" json:"userns,omitempty"` + Hostname string `yaml:"hostname" json:"hostname,omitempty"` Readonly *bool `yaml:"readonly" json:"readonly,omitempty"` MaskedPaths *[]string `yaml:"maskedPaths" json:"maskedPaths,omitempty"` ReadonlyPaths *[]string `yaml:"readonlyPaths" json:"readonlyPaths,omitempty"` diff --git a/src/moby/schema.go b/src/moby/schema.go index e5ca5b785..700ba936a 100644 --- a/src/moby/schema.go +++ b/src/moby/schema.go @@ -25,6 +25,7 @@ var schema = string(` "symlink": {"type": "string"}, "contents": {"type": "string"}, "source": {"type": "string"}, + "metadata": {"type": "string"}, "optional": {"type": "boolean"}, "mode": {"type": "string"}, "uid": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, diff --git a/test/test.yml b/test/test.yml index 3a91b06e7..fadf86e9f 100644 --- a/test/test.yml +++ b/test/test.yml @@ -31,6 +31,8 @@ files: contents: '{"debug": true}' - path: /empty contents: "" + - path: etc/moby-config + metadata: yaml trust: org: - library