Skip to content

Commit

Permalink
feat(sbom): add a directive to generate SBOM for a layer (#420)
Browse files Browse the repository at this point in the history
* feat(bom): generate bom for a layer

A new bind-mount /stacker-artifacts is added to a container into which
all artifacts including sbom can be added. Once the container image is
built, then in the publish phase we push sbom along with the image as a
OCI dist-spec "reference".

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>

* feat(publish): add support for publishing OCI artifacts/references

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>

* fix: allow importing a parent sbom

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>

* refactor!: OCI artifact generation support uses different path layout

BREAKING CHANGE: Some paths per earlier stacker conventions are now
changed as follows.

/stacker/imports : ro mount for imports
/stacker/artifacts : rw mount to store output of next step
/stacker/tools : /proc/self mounted as /stacker/tools/bom
/stacker/oci-labels : where OCI label generation logic now resides

NOTE: Making this a separate commit if we want to revert

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>

* test: don't keep bom if failure

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>

* fix: address PR comments

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>

---------

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
  • Loading branch information
rchincha authored Aug 19, 2023
1 parent 684b586 commit c68147c
Show file tree
Hide file tree
Showing 30 changed files with 1,639 additions and 648 deletions.
6 changes: 3 additions & 3 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ build-env:
# json-c doesn't have static binaries in alpine
apk add cmake
tar -xf /stacker/json-c-*
tar -xf /stacker/imports/json-c-*
cd json-c-*
mkdir build
cd build
Expand All @@ -36,7 +36,7 @@ build-env:
cd /
# build libdevmapper.a
tar -xf /stacker/v2_03_18.tar.gz
tar -xf /stacker/imports/v2_03_18.tar.gz
cd lvm2-*
./configure --enable-static_link
make install_device-mapper
Expand All @@ -45,7 +45,7 @@ build-env:
# build static cryptsetup without all the command line tools
apk add gettext gettext-dev zlib-static lz4-static openssl-dev \
openssl-libs-static popt-dev bash
tar -xf /stacker/cryptsetup*
tar -xf /stacker/imports/cryptsetup*
cd cryptsetup*
./autogen.sh
CFLAGS="-D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE" \
Expand Down
93 changes: 93 additions & 0 deletions cmd/stacker/internal_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ 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"
Expand Down Expand Up @@ -61,6 +65,18 @@ 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,
}
Expand Down Expand Up @@ -208,3 +224,80 @@ 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", "")
}
3 changes: 2 additions & 1 deletion cmd/stacker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ func shouldSkipInternalUserns(ctx *cli.Context) bool {
}

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" {
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
}
}
Expand Down
Loading

0 comments on commit c68147c

Please sign in to comment.