From 540b3a131aec5f8a65f50573a362a0097227a250 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Tue, 22 Aug 2023 12:44:54 -0700 Subject: [PATCH] fix: Move bom to top level subcmd, simplify shouldSkipInternalUserns The bom commands are useful outside of stacker, and since they're exposed to the user, they should *not* be part of the hidden internal-go interface. So, change: - stacker internal-go bom-discover + stacker bom discover Also, shouldSkipInternalUserns was overly complicated as a result of iterative development. It is simpler now and based only on the subcommand name with a single special case for testsuite-check-overlay. Signed-off-by: Scott Moser --- cmd/stacker/bom.go | 109 +++++++++++++++++++++++++++++++++++++ cmd/stacker/internal_go.go | 93 ------------------------------- cmd/stacker/main.go | 17 +++--- pkg/stacker/bom.go | 5 +- pkg/stacker/build.go | 1 - test/bom.bats | 4 +- 6 files changed, 123 insertions(+), 106 deletions(-) create mode 100644 cmd/stacker/bom.go diff --git a/cmd/stacker/bom.go b/cmd/stacker/bom.go new file mode 100644 index 00000000..ef37ecd2 --- /dev/null +++ b/cmd/stacker/bom.go @@ -0,0 +1,109 @@ +package main + +import ( + "fmt" + "path" + "path/filepath" + + "github.com/pkg/errors" + cli "github.com/urfave/cli/v2" + "stackerbuild.io/stacker-bom/pkg/bom" + "stackerbuild.io/stacker-bom/pkg/distro" + "stackerbuild.io/stacker-bom/pkg/fs" +) + +var bomCmd = cli.Command{ + Name: "bom", + Usage: "work with a software bill of materials (BOM)", + Subcommands: []*cli.Command{ + &cli.Command{ + Name: "discover", + Action: doBomDiscover, + }, + &cli.Command{ + Name: "build", + Action: doBomBuild, + }, + &cli.Command{ + Name: "verify", + Action: doBomVerify, + }, + }, +} + +func doBomDiscover(ctx *cli.Context) error { + author := "stacker-internal" + org := "stacker-internal" + + if err := fs.Discover(author, org, "/stacker/artifacts/installed-packages.json"); err != nil { + return nil + } + + return nil +} + +func doBomGenerate(ctx *cli.Context) error { //nolint:unused // used when invoked inside "run:" + if ctx.Args().Len() != 1 { + return errors.Errorf("wrong number of args for umount") + } + + input := ctx.Args().Get(0) + + author := "stacker-internal" + org := "stacker-internal" + lic := "unknown" + + if err := distro.ParsePackage(input, author, org, lic, fmt.Sprintf("/stacker/artifacts/%s.json", filepath.Base(input))); err != nil { + return nil + } + + return nil +} + +// build/roll your own sbom document for a particular dest (file/dir) +// by specifying details such as author, org, license, etc. +func doBomBuild(ctx *cli.Context) error { + if ctx.Args().Len() < 7 { + return errors.Errorf("wrong number of args") + } + + dest := ctx.Args().Get(0) + author := ctx.Args().Get(1) + org := ctx.Args().Get(2) + license := ctx.Args().Get(3) + pkgname := ctx.Args().Get(4) + pkgversion := ctx.Args().Get(5) + paths := []string{} + for i := 6; i < ctx.Args().Len(); i++ { + paths = append(paths, ctx.Args().Get(i)) + } + out := path.Join(dest, fmt.Sprintf("doc-%s.spdx.json", pkgname)) + name := fmt.Sprintf("doc-%s", pkgname) + + return fs.BuildPackage(name, author, org, license, pkgname, pkgversion, paths, out) +} + +func doBomVerify(ctx *cli.Context) error { + if ctx.Args().Len() != 4 { + return errors.Errorf("wrong number of args") + } + + dest := ctx.Args().Get(0) + name := ctx.Args().Get(1) + author := ctx.Args().Get(2) + org := ctx.Args().Get(3) + + // first merge all individual sbom artifacts that may have been generated + if err := bom.MergeDocuments("/stacker/artifacts", name, author, org, dest); err != nil { + return err + } + + // check against inventory + if err := fs.GenerateInventory("/", + []string{"/proc", "/sys", "/dev", "/etc/resolv.conf", "/stacker"}, + "/stacker/artifacts/inventory.json"); err != nil { + return err + } + + return fs.Verify(dest, "/stacker/artifacts/inventory.json", "") +} diff --git a/cmd/stacker/internal_go.go b/cmd/stacker/internal_go.go index 3161715b..d7abeab4 100644 --- a/cmd/stacker/internal_go.go +++ b/cmd/stacker/internal_go.go @@ -4,16 +4,12 @@ import ( "fmt" "os" "path" - "path/filepath" "runtime" "strings" "github.com/pkg/errors" cli "github.com/urfave/cli/v2" "golang.org/x/sys/unix" - "stackerbuild.io/stacker-bom/pkg/bom" - "stackerbuild.io/stacker-bom/pkg/distro" - "stackerbuild.io/stacker-bom/pkg/fs" "stackerbuild.io/stacker/pkg/atomfs" "stackerbuild.io/stacker/pkg/lib" "stackerbuild.io/stacker/pkg/log" @@ -65,18 +61,6 @@ var internalGoCmd = cli.Command{ }, }, }, - &cli.Command{ - Name: "bom-discover", - Action: doBomDiscover, - }, - &cli.Command{ - Name: "bom-build", - Action: doBomBuild, - }, - &cli.Command{ - Name: "bom-verify", - Action: doBomVerify, - }, }, Before: doBeforeUmociSubcommand, } @@ -224,80 +208,3 @@ func doAtomfsUmount(ctx *cli.Context) error { mountpoint := ctx.Args().Get(0) return atomfs.Umount(mountpoint) } - -func doBomDiscover(ctx *cli.Context) error { - author := "stacker-internal" - org := "stacker-internal" - - if err := fs.Discover(author, org, "/stacker/artifacts/installed-packages.json"); err != nil { - return nil - } - - return nil -} - -func doBomGenerate(ctx *cli.Context) error { //nolint:unused // used when invoked inside "run:" - if ctx.Args().Len() != 1 { - return errors.Errorf("wrong number of args for umount") - } - - input := ctx.Args().Get(0) - - author := "stacker-internal" - org := "stacker-internal" - lic := "unknown" - - if err := distro.ParsePackage(input, author, org, lic, fmt.Sprintf("/stacker/artifacts/%s.json", filepath.Base(input))); err != nil { - return nil - } - - return nil -} - -// build/roll your own sbom document for a particular dest (file/dir) -// by specifying details such as author, org, license, etc. -func doBomBuild(ctx *cli.Context) error { - if ctx.Args().Len() < 7 { - return errors.Errorf("wrong number of args") - } - - dest := ctx.Args().Get(0) - author := ctx.Args().Get(1) - org := ctx.Args().Get(2) - license := ctx.Args().Get(3) - pkgname := ctx.Args().Get(4) - pkgversion := ctx.Args().Get(5) - paths := []string{} - for i := 6; i < ctx.Args().Len(); i++ { - paths = append(paths, ctx.Args().Get(i)) - } - out := path.Join(dest, fmt.Sprintf("doc-%s.spdx.json", pkgname)) - name := fmt.Sprintf("doc-%s", pkgname) - - return fs.BuildPackage(name, author, org, license, pkgname, pkgversion, paths, out) -} - -func doBomVerify(ctx *cli.Context) error { - if ctx.Args().Len() != 4 { - return errors.Errorf("wrong number of args") - } - - dest := ctx.Args().Get(0) - name := ctx.Args().Get(1) - author := ctx.Args().Get(2) - org := ctx.Args().Get(3) - - // first merge all individual sbom artifacts that may have been generated - if err := bom.MergeDocuments("/stacker/artifacts", name, author, org, dest); err != nil { - return err - } - - // check against inventory - if err := fs.GenerateInventory("/", - []string{"/proc", "/sys", "/dev", "/etc/resolv.conf", "/stacker"}, - "/stacker/artifacts/inventory.json"); err != nil { - return err - } - - return fs.Verify(dest, "/stacker/artifacts/inventory.json", "") -} diff --git a/cmd/stacker/main.go b/cmd/stacker/main.go index 62ea2464..ae4bf4b5 100644 --- a/cmd/stacker/main.go +++ b/cmd/stacker/main.go @@ -66,16 +66,18 @@ func stackerResult(err error) { } func shouldSkipInternalUserns(ctx *cli.Context) bool { - args := ctx.Args() - if args.Len() >= 1 && args.Get(0) == "unpriv-setup" { + if ctx.Args().Len() < 1 { + // no subcommand, no need for namespace return true } + arg0 := ctx.Args().Get(0) - if args.Len() >= 2 && args.Get(0) == "internal-go" { - if args.Get(1) == "atomfs" || args.Get(1) == "cp" || args.Get(1) == "chown" || args.Get(1) == "chmod" || - args.Get(1) == "bom-discover" || args.Get(1) == "bom-build" || args.Get(1) == "bom-verify" { - return true - } + if arg0 == "internal-go" && ctx.Args().Get(1) == "testsuite-check-overlay" { + return false + } + + if arg0 == "bom" || arg0 == "unpriv-setup" || arg0 == "internal-go" { + return true } return false @@ -108,6 +110,7 @@ func main() { app.Commands = []*cli.Command{ &buildCmd, + &bomCmd, &recursiveBuildCmd, &convertCmd, &publishCmd, diff --git a/pkg/stacker/bom.go b/pkg/stacker/bom.go index 166f68bd..0cfe3eab 100644 --- a/pkg/stacker/bom.go +++ b/pkg/stacker/bom.go @@ -44,8 +44,7 @@ func BuildLayerArtifacts(sc types.StackerConfig, storage types.Storage, l types. cmd = append(cmd, "--debug") } - cmd = append(cmd, "internal-go", "bom-build", - "/stacker/artifacts", + cmd = append(cmd, "bom", "build", "/stacker/artifacts", l.Annotations[types.AuthorAnnotation], l.Annotations[types.OrgAnnotation], l.Annotations[types.LicenseAnnotation], @@ -89,7 +88,7 @@ func VerifyLayerArtifacts(sc types.StackerConfig, storage types.Storage, l types cmd = append(cmd, "--debug") } - cmd = append(cmd, "internal-go", "bom-verify", + cmd = append(cmd, "bom", "verify", fmt.Sprintf("/stacker/artifacts/%s.json", tag), tag, l.Annotations[types.AuthorAnnotation], l.Annotations[types.OrgAnnotation]) diff --git a/pkg/stacker/build.go b/pkg/stacker/build.go index fed86872..2866a5cb 100644 --- a/pkg/stacker/build.go +++ b/pkg/stacker/build.go @@ -638,7 +638,6 @@ func runInternalGoSubcommand(config types.StackerConfig, args []string) error { "--roots-dir", config.RootFSDir, "--stacker-dir", config.StackerDir, "--storage-type", config.StorageType, - "--internal-userns", } if config.Debug { diff --git a/test/bom.bats b/test/bom.bats index 293a2cb4..3cb5bf5c 100644 --- a/test/bom.bats +++ b/test/bom.bats @@ -27,7 +27,7 @@ bom-parent: paths: [/pkg2] run: | # discover installed pkgs - /stacker/tools/static-stacker internal-go bom-discover + /stacker/tools/static-stacker bom discover # our own custom packages mkdir -p /pkg1 touch /pkg1/file @@ -84,7 +84,7 @@ bom-parent: paths: [/pkg2] run: | # discover installed pkgs - /stacker/tools/static-stacker internal-go bom-discover + /stacker/tools/static-stacker bom discover # our own custom packages mkdir -p /pkg1 touch /pkg1/file