Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lock image configs before building #1441

Merged
merged 1 commit into from
Dec 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 32 additions & 44 deletions internal/cli/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"log/slog"
"os"
"path/filepath"
"slices"
"sync"

"github.com/google/go-containerregistry/pkg/v1/layout"
Expand All @@ -38,6 +39,7 @@ import (
"chainguard.dev/apko/pkg/build/oci"
"chainguard.dev/apko/pkg/build/types"
"chainguard.dev/apko/pkg/sbom"
"chainguard.dev/apko/pkg/tarfs"
)

func buildCmd() *cobra.Command {
Expand Down Expand Up @@ -236,6 +238,7 @@ func buildImageComponents(ctx context.Context, workDir string, archs []types.Arc
// computation.
multiArchBDE := o.SourceDateEpoch

configs, _, err := build.LockImageConfiguration(ctx, *ic, opts...)
mc, err := build.NewMultiArch(ctx, archs, opts...)
if err != nil {
return nil, nil, err
Expand All @@ -247,26 +250,27 @@ func buildImageComponents(ctx context.Context, workDir string, archs []types.Arc
}
}

// This is a little different, but we use a multiarch builder to call BuildLayers because we want
// each architecture to be aware of the other architectures during the solve stage. We don't want
// to select any packages unless they are available on every architecture because we want solutions
// to match across architectures.
//
// Eventually, we probably want to do something similar for all this logic around stitching images together.
layers, err := mc.BuildLayers(ctx)
if err != nil {
return nil, nil, fmt.Errorf("building layers: %w", err)
}

for _, arch := range archs {
arch := arch

for arch, ic := range configs {
errg.Go(func() error {
if arch == "index" {
return nil
}

arch := types.ParseArchitecture(arch)
log := clog.New(slog.Default().Handler()).With("arch", arch.ToAPK())
ctx := clog.WithLogger(ctx, log)

bc := mc.Contexts[arch]
layer := layers[arch]
opts := slices.Clone(opts)
opts = append(opts, build.WithArch(arch), build.WithImageConfiguration(*ic))

bc, err := build.New(ctx, tarfs.New(), opts...)
if err != nil {
return fmt.Errorf("new build for arch %s: %w", arch, err)
}
_, layer, err := bc.BuildLayer(ctx)
if err != nil {
return fmt.Errorf("building %q layer: %w", arch, err)
}

// Compute the "build date epoch" from the packages that were
// installed. The "build date epoch" is the MAX of the builddate
Expand All @@ -285,6 +289,14 @@ func buildImageComponents(ctx context.Context, workDir string, archs []types.Arc
return fmt.Errorf("failed to build OCI image for %q: %w", arch, err)
}

var outputs []types.SBOM
if len(o.SBOMFormats) != 0 {
outputs, err = bc.GenerateImageSBOM(ctx, arch, img)
if err != nil {
return fmt.Errorf("generating sbom for %s: %w", arch, err)
}
}

mtx.Lock()
defer mtx.Unlock()

Expand All @@ -294,6 +306,10 @@ func buildImageComponents(ctx context.Context, workDir string, archs []types.Arc
multiArchBDE = bde
}

if len(o.SBOMFormats) != 0 {
sboms = append(sboms, outputs...)
}

return nil
})
}
Expand Down Expand Up @@ -323,34 +339,6 @@ func buildImageComponents(ctx context.Context, workDir string, archs []types.Arc

// the sboms are saved to the same working directory as the image components
if len(o.SBOMFormats) != 0 {
var (
g errgroup.Group
mtx sync.Mutex
)
for arch, img := range imgs {
arch, img := arch, img
bc := mc.Contexts[arch]

g.Go(func() error {
log := clog.New(slog.Default().Handler()).With("arch", arch.ToAPK())
ctx := clog.WithLogger(ctx, log)

outputs, err := bc.GenerateImageSBOM(ctx, arch, img)
if err != nil {
return fmt.Errorf("generating sbom for %s: %w", arch, err)
}
mtx.Lock()
defer mtx.Unlock()

sboms = append(sboms, outputs...)
return nil
})
}

if err := g.Wait(); err != nil {
return nil, nil, err
}

files, err := build.GenerateIndexSBOM(ctx, *o, *ic, finalDigest, imgs)
if err != nil {
return nil, nil, fmt.Errorf("generating index SBOM: %w", err)
Expand Down
8 changes: 4 additions & 4 deletions internal/cli/publish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func TestPublish(t *testing.T) {

// This test will fail if we ever make a change in apko that changes the image.
// Sometimes, this is intentional, and we need to change this and bump the version.
want := "sha256:df77d3071fed05b55a2c76ce0af54b4e8174404ee29962162b627aaa42b43b91"
want := "sha256:df086c6b126032e9ed1b4aa6fecdb6988b45d86d9c1e8d2eb81dea647f4c7a7f"
require.Equal(t, want, digest.String())

sdst := fmt.Sprintf("%s:%s.sbom", dst, strings.ReplaceAll(want, ":", "-"))
Expand All @@ -109,7 +109,7 @@ func TestPublish(t *testing.T) {

// This test will fail if we ever make a change in apko that changes the SBOM.
// Sometimes, this is intentional, and we need to change this and bump the version.
swant := "sha256:18b8dc7cd228ab657a248b94c256ec4b3e12a69901161d027ee4b6bbee0e87b6"
swant := "sha256:d1faff2316aa480d1400e6c86af431402cee84f980b97a06f096bdab9a52075f"
require.Equal(t, swant, got)

im, err := idx.IndexManifest()
Expand All @@ -118,8 +118,8 @@ func TestPublish(t *testing.T) {
// We also want to check the children SBOMs because the index SBOM does not have
// references to the children SBOMs, just the children!
wantBoms := []string{
"sha256:b30707314d196b3f65b1e9b05f34b795588f0031343bf3e3e75f256aff3fc7e6",
"sha256:1449715ad955e02f8a8f8f5b9adff17d89c2443e199af2555f8336df18720fe7",
"sha256:c483478580314a253c2170b32de7686d1664ec936be3a4df51ef2bba92c46261",
"sha256:18d9c631ac5656d52d2595bc80195ad1c68c517db8bded1ec229f775ee682d98",
}

for i, m := range im.Manifests {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":593,"digest":"sha256:5e0be8f8dbc1497d60148df3be08869342df17c951370416999e19cda0d36624"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3272,"digest":"sha256:89c9e3bd4d4968247bdf82182560718f22427628a3c112902377fa7ff897f9f7"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":593,"digest":"sha256:cff7a34bf75690ef289b741fd026cb52cac94ff0f057996c829ac546f6819c75"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3273,"digest":"sha256:fab53f6bbeb155d8f33acb6e7a1d961317ffb6352fc775b133b1af8656a6d0bb"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"architecture":"amd64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:b606e55d50a4a23dd4092a9983b45887dd7c979a38acd5dc9736a09cc899e600"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}}
{"architecture":"amd64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:8f9c734d8ec1cd189067042886090e052d1e32c6622124061dd7baf8be1c1e56"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"architecture":"arm64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:568821083896751c424c849bd0222c7026e123b72906839f4123d4be014bfead"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}}
{"architecture":"arm64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:ae5eac0428855226d637f784d90664e537cb40a42871dc7e58daabf93cfe86ca"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}}

This file was deleted.

Binary file not shown.
2 changes: 1 addition & 1 deletion internal/cli/testdata/golden/index.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":476,"digest":"sha256:43e3f561cb0910cb25ea304331454f74315d2edbcf68e2af172f8efa5c95fe19","platform":{"architecture":"amd64","os":"linux"}},{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":476,"digest":"sha256:dcc96a7dc51e9f68b3402c82332b61325ae8e6f8ddc49159e7bafc30453bfc17","platform":{"architecture":"arm64","os":"linux"}}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":476,"digest":"sha256:0c3a3431cb3d08f1de9b3ebd19671fe54c227a6cfd33c1164cb8f67a86baadea","platform":{"architecture":"amd64","os":"linux"}},{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":476,"digest":"sha256:2daa2a0b7c784bbda06b9a342d2b70e72d4f213642f488250fdb62ccd65a4ba7","platform":{"architecture":"arm64","os":"linux"}}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}
24 changes: 12 additions & 12 deletions internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"SPDXID": "SPDXRef-DOCUMENT",
"name": "sbom-sha256:82c91678ac0f40848c5cdac918022ba897a381c264722a6b1d5c986471e9751e",
"name": "sbom-sha256:fab53f6bbeb155d8f33acb6e7a1d961317ffb6352fc775b133b1af8656a6d0bb",
"spdxVersion": "SPDX-2.3",
"creationInfo": {
"created": "1970-01-01T00:00:00Z",
Expand All @@ -13,13 +13,13 @@
"dataLicense": "CC0-1.0",
"documentNamespace": "https://spdx.org/spdxdocs/apko/",
"documentDescribes": [
"SPDXRef-Package-sha256-dcc96a7dc51e9f68b3402c82332b61325ae8e6f8ddc49159e7bafc30453bfc17"
"SPDXRef-Package-sha256-2daa2a0b7c784bbda06b9a342d2b70e72d4f213642f488250fdb62ccd65a4ba7"
],
"packages": [
{
"SPDXID": "SPDXRef-Package-sha256-dcc96a7dc51e9f68b3402c82332b61325ae8e6f8ddc49159e7bafc30453bfc17",
"name": "sha256:dcc96a7dc51e9f68b3402c82332b61325ae8e6f8ddc49159e7bafc30453bfc17",
"versionInfo": "sha256:dcc96a7dc51e9f68b3402c82332b61325ae8e6f8ddc49159e7bafc30453bfc17",
"SPDXID": "SPDXRef-Package-sha256-2daa2a0b7c784bbda06b9a342d2b70e72d4f213642f488250fdb62ccd65a4ba7",
"name": "sha256:2daa2a0b7c784bbda06b9a342d2b70e72d4f213642f488250fdb62ccd65a4ba7",
"versionInfo": "sha256:2daa2a0b7c784bbda06b9a342d2b70e72d4f213642f488250fdb62ccd65a4ba7",
"filesAnalyzed": false,
"description": "apko container image",
"downloadLocation": "NOASSERTION",
Expand All @@ -28,20 +28,20 @@
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "dcc96a7dc51e9f68b3402c82332b61325ae8e6f8ddc49159e7bafc30453bfc17"
"checksumValue": "2daa2a0b7c784bbda06b9a342d2b70e72d4f213642f488250fdb62ccd65a4ba7"
}
],
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceLocator": "pkg:oci/golden@sha256%3Adcc96a7dc51e9f68b3402c82332b61325ae8e6f8ddc49159e7bafc30453bfc17?arch=arm64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
"referenceLocator": "pkg:oci/golden@sha256%3A2daa2a0b7c784bbda06b9a342d2b70e72d4f213642f488250fdb62ccd65a4ba7?arch=arm64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
"referenceType": "purl"
}
]
},
{
"SPDXID": "SPDXRef-Package-sha256-82c91678ac0f40848c5cdac918022ba897a381c264722a6b1d5c986471e9751e",
"name": "sha256:82c91678ac0f40848c5cdac918022ba897a381c264722a6b1d5c986471e9751e",
"SPDXID": "SPDXRef-Package-sha256-fab53f6bbeb155d8f33acb6e7a1d961317ffb6352fc775b133b1af8656a6d0bb",
"name": "sha256:fab53f6bbeb155d8f33acb6e7a1d961317ffb6352fc775b133b1af8656a6d0bb",
"versionInfo": "1.0.0",
"filesAnalyzed": false,
"description": "apko operating system layer",
Expand All @@ -50,7 +50,7 @@
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceLocator": "pkg:oci/golden@sha256%3A82c91678ac0f40848c5cdac918022ba897a381c264722a6b1d5c986471e9751e?arch=arm64\u0026mediaType=application%2Fvnd.oci.image.layer.v1.tar%2Bgzip\u0026os=linux",
"referenceLocator": "pkg:oci/golden@sha256%3Afab53f6bbeb155d8f33acb6e7a1d961317ffb6352fc775b133b1af8656a6d0bb?arch=arm64\u0026mediaType=application%2Fvnd.oci.image.layer.v1.tar%2Bgzip\u0026os=linux",
"referenceType": "purl"
}
]
Expand Down Expand Up @@ -96,9 +96,9 @@
],
"relationships": [
{
"spdxElementId": "SPDXRef-Package-sha256-dcc96a7dc51e9f68b3402c82332b61325ae8e6f8ddc49159e7bafc30453bfc17",
"spdxElementId": "SPDXRef-Package-sha256-2daa2a0b7c784bbda06b9a342d2b70e72d4f213642f488250fdb62ccd65a4ba7",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-Package-sha256-82c91678ac0f40848c5cdac918022ba897a381c264722a6b1d5c986471e9751e"
"relatedSpdxElement": "SPDXRef-Package-sha256-fab53f6bbeb155d8f33acb6e7a1d961317ffb6352fc775b133b1af8656a6d0bb"
}
]
}
Loading
Loading