Skip to content

Commit

Permalink
Allow layer author, comment, and created-by metadata to be set
Browse files Browse the repository at this point in the history
  • Loading branch information
FenTiger committed Aug 22, 2024
1 parent 3853e5c commit 72932e9
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 11 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ Function arguments are:
building the layer. This is mainly useful to ignore the
configuration file from the container layer.
- **`metadata`** (defaults to `{ created-by = "nix2container"}`): an attribute
set containing this layer's `created-by`, `author` and `comment` values
## Isolate dependencies in dedicated layers
Expand Down
25 changes: 23 additions & 2 deletions cmd/layers.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var ignore string
var tarDirectory string
var permsFilepath string
var rewritesFilepath string
var metadataFilepath string
var maxLayers int

// layerCmd represents the layer command
Expand Down Expand Up @@ -62,7 +63,16 @@ var layersReproducibleCmd = &cobra.Command{
os.Exit(1)
}
}
layers, err := nix.NewLayers(storepaths, maxLayers, parents, rewrites, ignore, perms)
var metadata types.Metadata
if metadataFilepath != "" {
metadata, err = readMetadataFile(metadataFilepath)
if err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
os.Exit(1)
}
}

layers, err := nix.NewLayers(storepaths, maxLayers, parents, rewrites, ignore, perms, metadata)
if err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
os.Exit(1)
Expand Down Expand Up @@ -112,7 +122,16 @@ var layersNonReproducibleCmd = &cobra.Command{
os.Exit(1)
}
}
layers, err := nix.NewLayersNonReproducible(storepaths, maxLayers, tarDirectory, parents, rewrites, ignore, perms)
var metadata types.Metadata
if metadataFilepath != "" {
metadata, err = readMetadataFile(metadataFilepath)
if err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
os.Exit(1)
}
}

layers, err := nix.NewLayersNonReproducible(storepaths, maxLayers, tarDirectory, parents, rewrites, ignore, perms, metadata)
if err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
os.Exit(1)
Expand Down Expand Up @@ -157,12 +176,14 @@ func init() {

layersNonReproducibleCmd.Flags().StringVarP(&rewritesFilepath, "rewrites", "", "", "A JSON file containing a list of path rewrites. Each element of the list is a JSON object with the attributes path, regex and repl: for a given path, the regex is replaced by repl.")
layersNonReproducibleCmd.Flags().StringVarP(&permsFilepath, "perms", "", "", "A JSON file containing file permissions")
layersNonReproducibleCmd.Flags().StringVarP(&metadataFilepath, "metadata", "", "", "A JSON file containing layer metadata")
layersNonReproducibleCmd.Flags().IntVarP(&maxLayers, "max-layers", "", 1, "The maximum number of layers")

rootCmd.AddCommand(layersReproducibleCmd)
layersReproducibleCmd.Flags().StringVarP(&ignore, "ignore", "", "", "Ignore the path from the list of storepaths")
layersReproducibleCmd.Flags().StringVarP(&rewritesFilepath, "rewrites", "", "", "A JSON file containing path rewrites")
layersReproducibleCmd.Flags().StringVarP(&permsFilepath, "perms", "", "", "A JSON file containing file permissions")
layersReproducibleCmd.Flags().StringVarP(&metadataFilepath, "metadata", "", "", "A JSON file containing layer metadata")
layersReproducibleCmd.Flags().IntVarP(&maxLayers, "max-layers", "", 1, "The maximum number of layers")

}
12 changes: 12 additions & 0 deletions cmd/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,15 @@ func readRewritesFile(filename string) (rewritePaths []types.RewritePath, err er
}
return
}

func readMetadataFile(filename string) (metadata types.Metadata, err error) {
content, err := os.ReadFile(filename)
if err != nil {
return metadata, err
}
err = json.Unmarshal(content, &metadata)
if err != nil {
return metadata, err
}
return
}
5 changes: 5 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ let
maxLayers ? 1,
# Deprecated: will be removed on v1
contents ? null,
# Author, comment, command
metadata ? { created-by = "nix2container"; },
}: let
subcommand = if reproducible
then "layers-from-reproducible-storepaths"
Expand All @@ -269,6 +271,8 @@ let
rewritesFlag = "--rewrites ${rewritesFile}";
permsFile = pkgs.writeText "perms.json" (l.toJSON perms);
permsFlag = l.optionalString (perms != []) "--perms ${permsFile}";
metadataFile = pkgs.writeText "metadata.json" (l.toJSON metadata);
metadataFlag = l.optionalString (metadata != {}) "--metadata ${metadataFile}";
allDeps = deps ++ copyToRootList;
tarDirectory = l.optionalString (! reproducible) "--tar-directory $out";
layersJSON = pkgs.runCommand "layers.json" {} ''
Expand All @@ -279,6 +283,7 @@ let
--max-layers ${toString maxLayers} \
${rewritesFlag} \
${permsFlag} \
${metadataFlag} \
${tarDirectory} \
${l.concatMapStringsSep " " (l: l + "/layers.json") layers} \
'';
Expand Down
4 changes: 3 additions & 1 deletion nix/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ func getV1Image(image types.Image) (imageV1 v1.Image, err error) {
// need to add an history otherwise
// some toolings can complain:
// https://github.com/nlewo/nix2container/issues/57
CreatedBy: "nix2container",
CreatedBy: layer.CreatedBy,
Author: layer.Author,
Comment: layer.Comment,
})
}
return
Expand Down
1 change: 1 addition & 0 deletions nix/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func TestGetV1Image(t *testing.T) {
DiffIDs: "sha256:adf74a52f9e1bcd7dab77193455fa06743b979cf5955148010e5becedba4f72d",
Size: 10,
MediaType: "application/vnd.oci.image.layer.v1.tar",
CreatedBy: "nix2container",
},
},
}
Expand Down
13 changes: 8 additions & 5 deletions nix/layers.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func getPaths(storePaths []string, parents []types.Layer, rewrites []types.Rewri
// If tarDirectory is not an empty string, the tar layer is written to
// the disk. This is useful for layer containing non reproducible
// store paths.
func newLayers(paths types.Paths, tarDirectory string, maxLayers int) (layers []types.Layer, err error) {
func newLayers(paths types.Paths, tarDirectory string, maxLayers int, metadata types.Metadata) (layers []types.Layer, err error) {
offset := 0
for offset < len(paths) {
max := offset + 1
Expand All @@ -90,6 +90,9 @@ func newLayers(paths types.Paths, tarDirectory string, maxLayers int) (layers []
Size: size,
Paths: layerPaths,
MediaType: v1.MediaTypeImageLayer,
CreatedBy: metadata.CreatedBy,
Author: metadata.Author,
Comment: metadata.Comment,
}
if tarDirectory != "" {
// TODO: we should use v1.MediaTypeImageLayerGzip instead
Expand All @@ -104,14 +107,14 @@ func newLayers(paths types.Paths, tarDirectory string, maxLayers int) (layers []
return layers, nil
}

func NewLayers(storePaths []string, maxLayers int, parents []types.Layer, rewrites []types.RewritePath, exclude string, perms []types.PermPath) ([]types.Layer, error) {
func NewLayers(storePaths []string, maxLayers int, parents []types.Layer, rewrites []types.RewritePath, exclude string, perms []types.PermPath, metadata types.Metadata) ([]types.Layer, error) {
paths := getPaths(storePaths, parents, rewrites, exclude, perms)
return newLayers(paths, "", maxLayers)
return newLayers(paths, "", maxLayers, metadata)
}

func NewLayersNonReproducible(storePaths []string, maxLayers int, tarDirectory string, parents []types.Layer, rewrites []types.RewritePath, exclude string, perms []types.PermPath) (layers []types.Layer, err error) {
func NewLayersNonReproducible(storePaths []string, maxLayers int, tarDirectory string, parents []types.Layer, rewrites []types.RewritePath, exclude string, perms []types.PermPath, metadata types.Metadata) (layers []types.Layer, err error) {
paths := getPaths(storePaths, parents, rewrites, exclude, perms)
return newLayers(paths, tarDirectory, maxLayers)
return newLayers(paths, tarDirectory, maxLayers, metadata)
}

func isPathInLayers(layers []types.Layer, path types.Path) bool {
Expand Down
6 changes: 3 additions & 3 deletions nix/layers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestPerms(t *testing.T) {
Mode: "0641",
},
}
layer, err := NewLayers(paths, 1, []types.Layer{}, []types.RewritePath{}, "", perms)
layer, err := NewLayers(paths, 1, []types.Layer{}, []types.RewritePath{}, "", perms, types.Metadata{})
if err != nil {
t.Fatalf("%v", err)
}
Expand Down Expand Up @@ -50,7 +50,7 @@ func TestNewLayers(t *testing.T) {
paths := []string{
"../data/layer1/file1",
}
layer, err := NewLayers(paths, 1, []types.Layer{}, []types.RewritePath{}, "", []types.PermPath{})
layer, err := NewLayers(paths, 1, []types.Layer{}, []types.RewritePath{}, "", []types.PermPath{}, types.Metadata{})
if err != nil {
t.Fatalf("%v", err)
}
Expand All @@ -70,7 +70,7 @@ func TestNewLayers(t *testing.T) {
assert.Equal(t, expected, layer)

tmpDir := t.TempDir()
layer, err = NewLayersNonReproducible(paths, 1, tmpDir, []types.Layer{}, []types.RewritePath{}, "", []types.PermPath{})
layer, err = NewLayersNonReproducible(paths, 1, tmpDir, []types.Layer{}, []types.RewritePath{}, "", []types.PermPath{}, types.Metadata{})
if err != nil {
t.Fatalf("%v", err)
}
Expand Down
9 changes: 9 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ type Layer struct {
// https://github.com/opencontainers/image-spec/blob/8b9d41f48198a7d6d0a5c1a12dc2d1f7f47fc97f/specs-go/v1/mediatype.go
MediaType string `json:"mediatype"`
LayerPath string `json:"layer-path,omitempty"`
CreatedBy string `json:"created-by,omitempty"`
Author string `json:"author,omitempty"`
Comment string `json:"comment,omitempty"`
}

type Metadata struct {
CreatedBy string `json:"created-by,omitempty"`
Author string `json:"author,omitempty"`
Comment string `json:"comment,omitempty"`
}

func NewLayersFromFile(filename string) ([]Layer, error) {
Expand Down

0 comments on commit 72932e9

Please sign in to comment.