From 793fcc58ddf5f57d1aa664f2ad87405d07645af5 Mon Sep 17 00:00:00 2001 From: Seth Hollandsworth Date: Tue, 10 Jan 2023 21:20:11 -0500 Subject: [PATCH] adding tarball support for generating root layer hashes (#1600) This will be used in a "clean-room" scenario for use to security policy generation. Clean-room in this instance is for generating a security policy on computers without internet access or the docker daemon (or similar) running. The &tag passed in defaults to "latest" if only the image name is passed in. If the value of the tag is nil, the tarball must only have one image in it. Otherwise, many images can be stored in the tarball and be searched by their image name and tag. Signed-off-by: Seth Hollandsworth --- cmd/dmverity-vhd/README.md | 8 ++++++++ cmd/dmverity-vhd/main.go | 29 +++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/cmd/dmverity-vhd/README.md b/cmd/dmverity-vhd/README.md index d1955cadc8..330a7e196f 100644 --- a/cmd/dmverity-vhd/README.md +++ b/cmd/dmverity-vhd/README.md @@ -23,11 +23,19 @@ generator. ## Example usage Create VHDs: + ```bash dmverity-vhd create -i alpine:3.12 -o alpine_3_12_layers ``` Compute root hashes: + ```bash dmverity-vhd --docker roothash -i alpine:3.12 ``` + +Compute root hashes with tarball: + +```bash +dmverity-vhd --tarball /path/to/tarball.tar roothash -i alpine:3.12 +``` diff --git a/cmd/dmverity-vhd/main.go b/cmd/dmverity-vhd/main.go index c95fa2dda8..439a750352 100644 --- a/cmd/dmverity-vhd/main.go +++ b/cmd/dmverity-vhd/main.go @@ -10,6 +10,7 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/daemon" "github.com/google/go-containerregistry/pkg/v1/remote" + "github.com/google/go-containerregistry/pkg/v1/tarball" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "github.com/urfave/cli" @@ -26,7 +27,8 @@ const ( imageFlag = "image" verboseFlag = "verbose" outputDirFlag = "out-dir" - sourceFlag = "docker" + dockerFlag = "docker" + tarballFlag = "tarball" hashDeviceVhdFlag = "hash-dev-vhd" maxVHDSize = dmverity.RecommendedVHDSizeGB ) @@ -59,9 +61,13 @@ func main() { Usage: "Optional: verbose output", }, cli.BoolFlag{ - Name: sourceFlag + ",d", + Name: dockerFlag + ",d", Usage: "Optional: use local docker daemon", }, + cli.StringFlag{ + Name: tarballFlag + ",t", + Usage: "Optional: path to tarball containing image info", + }, } if err := app.Run(os.Args); err != nil { @@ -72,16 +78,31 @@ func main() { func fetchImageLayers(ctx *cli.Context) (layers []v1.Layer, err error) { image := ctx.String(imageFlag) + tarballPath := ctx.GlobalString(tarballFlag) ref, err := name.ParseReference(image) if err != nil { return nil, errors.Wrapf(err, "failed to parse image reference: %s", image) } - local := ctx.GlobalBool(sourceFlag) + dockerDaemon := ctx.GlobalBool(dockerFlag) + + // error check to make sure docker and tarball are not both defined + if dockerDaemon && tarballPath != "" { + return nil, errors.Errorf("cannot use both docker and tarball for image source") + } // by default, using remote as source var img v1.Image - if local { + if tarballPath != "" { + // create a tag and search the tarball for the image specified + var imageNameAndTag name.Tag + imageNameAndTag, err = name.NewTag(image) + if err != nil { + return nil, errors.Wrapf(err, "failed to failed to create a tag to search tarball for: %s", image) + } + // if only an image name is provided and not a tag, the default is "latest" + img, err = tarball.ImageFromPath(tarballPath, &imageNameAndTag) + } else if dockerDaemon { img, err = daemon.Image(ref) } else { var remoteOpts []remote.Option