From 37cb3837c4c5f156b15e65f6166dbc2af4f8d6b2 Mon Sep 17 00:00:00 2001 From: joe miller Date: Wed, 23 Aug 2023 14:30:24 -0700 Subject: [PATCH 1/2] fix: publish cmd --sbom-path not writing files fixes #804 Signed-off-by: joe miller --- internal/cli/publish.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/internal/cli/publish.go b/internal/cli/publish.go index 60a3eceea..b8b664907 100644 --- a/internal/cli/publish.go +++ b/internal/cli/publish.go @@ -19,6 +19,7 @@ import ( "fmt" "io" "os" + "path/filepath" "regexp" "sort" "strings" @@ -122,6 +123,7 @@ in a keychain.`, remoteOpts = append(remoteOpts, remote.Reuse(puller)) if err := PublishCmd(cmd.Context(), imageRefs, archs, remoteOpts, + sbomPath, []build.Option{ build.WithLogger(logger), build.WithConfig(args[0]), @@ -186,7 +188,7 @@ in a keychain.`, return cmd } -func PublishCmd(ctx context.Context, outputRefs string, archs []types.Architecture, ropt []remote.Option, buildOpts []build.Option, publishOpts []PublishOption) error { +func PublishCmd(ctx context.Context, outputRefs string, archs []types.Architecture, ropt []remote.Option, sbomPath string, buildOpts []build.Option, publishOpts []PublishOption) error { ctx, span := otel.Tracer("apko").Start(ctx, "PublishCmd") defer span.End() @@ -353,6 +355,16 @@ func PublishCmd(ctx context.Context, outputRefs string, archs []types.Architectu } } + // copy sboms over to the sbomPath target directory + if sbomPath != "" { + for _, sbom := range sboms { + // because os.Rename fails across partitions, we do our own + if err := rename(sbom.Path, filepath.Join(sbomPath, filepath.Base(sbom.Path))); err != nil { + return fmt.Errorf("moving sbom: %w", err) + } + } + } + // Write the image digest to STDOUT in order to enable command // composition e.g. kn service create --image=$(apko publish ...) fmt.Println(finalDigest) From 14487c644f9a57619c7c6518c7b68aa59344ecff Mon Sep 17 00:00:00 2001 From: joe miller Date: Mon, 28 Aug 2023 22:48:48 +0000 Subject: [PATCH 2/2] add tests to publishCmd for --sbom-path Signed-off-by: joe miller --- internal/cli/publish_test.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/internal/cli/publish_test.go b/internal/cli/publish_test.go index 5c4388793..571dc0d4b 100644 --- a/internal/cli/publish_test.go +++ b/internal/cli/publish_test.go @@ -20,6 +20,7 @@ import ( "net/http" "net/http/httptest" "net/url" + "os" "path/filepath" "strings" "testing" @@ -38,6 +39,7 @@ import ( func TestPublish(t *testing.T) { ctx := context.Background() + tmp := t.TempDir() // Set up a registry that requires we see a magic header. // This allows us to make sure that remote options are getting passed @@ -63,7 +65,11 @@ func TestPublish(t *testing.T) { opts := []build.Option{build.WithConfig(config), build.WithTags(dst), build.WithSBOMFormats(sbom.DefaultOptions.Formats)} publishOpts := []cli.PublishOption{cli.WithTags(dst)} - err = cli.PublishCmd(ctx, outputRefs, archs, ropt, opts, publishOpts) + sbomPath := filepath.Join(tmp, "sboms") + err = os.MkdirAll(sbomPath, 0o750) + require.NoError(t, err) + + err = cli.PublishCmd(ctx, outputRefs, archs, ropt, sbomPath, opts, publishOpts) require.NoError(t, err) ref, err := name.ParseReference(dst) @@ -125,6 +131,11 @@ func TestPublish(t *testing.T) { got := m.Layers[0].Digest.String() require.Equal(t, wantBoms[i], got) } + + // Check that the sbomPath is not empty. + sboms, err := os.ReadDir(sbomPath) + require.NoError(t, err) + require.NotEmpty(t, sboms) } type sentinel struct {