Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package apko for openSUSE:Factory checked in at 2023-11-30 22:01:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/apko (Old) and /work/SRC/openSUSE:Factory/.apko.new.25432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "apko" Thu Nov 30 22:01:41 2023 rev:4 rq:1129950 version:0.12.0 Changes: -------- --- /work/SRC/openSUSE:Factory/apko/apko.changes 2023-11-16 20:30:43.401151607 +0100 +++ /work/SRC/openSUSE:Factory/.apko.new.25432/apko.changes 2023-11-30 22:02:17.371199958 +0100 @@ -1,0 +2,11 @@ +Thu Nov 30 09:08:12 UTC 2023 - kastl@b1-systems.de + +- Update to version 0.12.0: + * Update NEWS.md for 0.12.0 + * Allow existing packages to replace installed pkg + * Fix packages with multiple Replaces + * Add binary to generate json schema. + * review feedback + * fix and continuously validate SBOMs + +------------------------------------------------------------------- Old: ---- apko-0.11.3.obscpio New: ---- apko-0.12.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apko.spec ++++++ --- /var/tmp/diff_new_pack.ply8hy/_old 2023-11-30 22:02:22.483389548 +0100 +++ /var/tmp/diff_new_pack.ply8hy/_new 2023-11-30 22:02:22.483389548 +0100 @@ -19,7 +19,7 @@ %define __arch_install_post export NO_BRP_STRIP_DEBUG=true Name: apko -Version: 0.11.3 +Version: 0.12.0 Release: 0 Summary: Build OCI images from APK packages directly without Dockerfile License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.ply8hy/_old 2023-11-30 22:02:22.511390613 +0100 +++ /var/tmp/diff_new_pack.ply8hy/_new 2023-11-30 22:02:22.515390766 +0100 @@ -3,7 +3,7 @@ <param name="url">https://github.com/chainguard-dev/apko</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v0.11.3</param> + <param name="revision">v0.12.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.ply8hy/_old 2023-11-30 22:02:22.535391526 +0100 +++ /var/tmp/diff_new_pack.ply8hy/_new 2023-11-30 22:02:22.535391526 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/chainguard-dev/apko</param> - <param name="changesrevision">4f9a4c617d079adc838c47303154d90a5ee4455e</param></service></servicedata> + <param name="changesrevision">691fe51dd1d536460f8a955d1357eaba974208b5</param></service></servicedata> (No newline at EOF) ++++++ apko-0.11.3.obscpio -> apko-0.12.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/.github/workflows/build-samples.yml new/apko-0.12.0/.github/workflows/build-samples.yml --- old/apko-0.11.3/.github/workflows/build-samples.yml 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/.github/workflows/build-samples.yml 2023-11-29 20:49:11.000000000 +0100 @@ -6,10 +6,12 @@ workflow_dispatch: jobs: + # Build a single-arch nginx image for each arch. build-nginx-on-all-arches: name: build-nginx-all-arches runs-on: ubuntu-latest strategy: + fail-fast: false matrix: arch: [x86_64, "386", armv7, aarch64, riscv64, s390x, ppc64le] @@ -20,16 +22,47 @@ go-version-file: 'go.mod' - name: Setup QEMU uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 + - run: | + make apko + ./apko build ./examples/nginx.yaml nginx:build /tmp/nginx-${{ matrix.arch }}.tar --debug --arch ${{ matrix.arch }} - - name: build + - name: Check SBOM Conformance run: | + set -euxo pipefail + if ! ls *.spdx.json; then + echo "no SBOMs found!" + exit 1 + fi + for f in *.spdx.json; do + echo ::group::sbom.json + cat $f + echo ::endgroup:: + docker run --rm -v $(pwd)/$f:/sbom.json cgr.dev/chainguard/ntia-conformance-checker -v --file /sbom.json + done + + # Build a multi-arch nginx image for all archs. + build-nginx-multiarch: + name: build-nginx-multiarch + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v2.1.5 + with: + go-version-file: 'go.mod' + - run: | make apko - ./apko version + ./apko build ./examples/nginx.yaml nginx:build /tmp/nginx.tar --debug - - name: build image - timeout-minutes: 15 + - name: Check SBOM Conformance run: | - ./apko build ./examples/nginx.yaml nginx:build /tmp/nginx-${{ matrix.arch }}.tar --debug --arch ${{ matrix.arch }} + set -euxo pipefail + for f in *.spdx.json; do + echo ::group::sbom.json + cat $f + echo ::endgroup:: + docker run --rm -v $(pwd)/$f:/sbom.json cgr.dev/chainguard/ntia-conformance-checker -v --file /sbom.json + done build-all-examples-one-arch: name: build-all-examples-amd64 @@ -43,16 +76,9 @@ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v2.1.5 with: - go-version: "1.21" - check-latest: true - - name: build - run: | + go-version-file: 'go.mod' + - run: | make apko - ./apko version - - - name: build images - timeout-minutes: 15 - run: | for cfg in $(find ./examples/ -name '*.yaml'); do name=$(basename ${cfg} .yaml) ./apko build ${cfg} ${name}:build /tmp/${name}.tar --debug --arch amd64 @@ -66,26 +92,16 @@ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v2.1.5 with: - go-version: "1.21" - check-latest: true - - name: Setup QEMU - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - - - name: build - run: | - make apko - ./apko version - + go-version-file: 'go.mod' - uses: chainguard-dev/actions/setup-registry@main with: port: 5000 - name: build image (w/ source date epoch) - shell: bash - timeout-minutes: 15 env: SOURCE_DATE_EPOCH: "0" run: | + make apko FIRST=$(./apko publish ./examples/alpine-base.yaml localhost:5000/alpine 2> /dev/null) for idx in {2..10} @@ -108,24 +124,14 @@ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v2.1.5 with: - go-version: "1.21" - check-latest: true - - name: Setup QEMU - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - - - name: build - run: | - make apko - ./apko version - + go-version-file: 'go.mod' - uses: chainguard-dev/actions/setup-registry@main with: port: 5000 - name: build image (w/ build date epoch) - shell: bash - timeout-minutes: 15 run: | + make apko # Without SOURCE_DATE_EPOCH set, the timestamp of the image will be computed to be # the maximum build date of the resolved APKs. FIRST=$(./apko publish ./examples/alpine-base.yaml localhost:5000/alpine 2> /dev/null) @@ -155,10 +161,8 @@ - uses: chainguard-dev/actions/setup-registry@main with: port: 5000 - - name: build - run: | + - run: | make apko - ./apko version # Build image with annotations. ref=$(./apko publish ./examples/nginx.yaml localhost:5000/nginx) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/NEWS.md new/apko-0.12.0/NEWS.md --- old/apko-0.11.3/NEWS.md 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/NEWS.md 2023-11-29 20:49:11.000000000 +0100 @@ -1,3 +1,19 @@ +# Changes from 0.11.3 to 0.12.0 + +* Fix installing packages with multiple replaces. +* Fix files paths within SBOMs. + +# Changes from 0.11.2 to 0.11.3 + +* Build with go 1.21. +* Remove unused flags: + * `--use-docker-mediatypes` + * `--package-version-tag` + * `--package-version-tag-stem` + * `--package-version-tag-prefix` + * `--tag-suffix` + * `--stage-tags` + # Changes from 0.11.1 to 0.11.2 * Fix a bug in version selection. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/go.mod new/apko-0.12.0/go.mod --- old/apko-0.11.3/go.mod 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/go.mod 2023-11-29 20:49:11.000000000 +0100 @@ -3,13 +3,14 @@ go 1.21 require ( - github.com/chainguard-dev/go-apk v0.0.0-20231113174935-f86aaf233502 + github.com/chainguard-dev/go-apk v0.0.0-20231120201550-7b08e8f3b0fc github.com/dominodatalab/os-release v0.0.0-20190522011736-bcdb4a3e3c2f github.com/go-git/go-git/v5 v5.10.0 github.com/google/go-cmp v0.6.0 github.com/google/go-containerregistry v0.16.1 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hashicorp/go-multierror v1.1.1 + github.com/invopop/jsonschema v0.12.0 github.com/jinzhu/copier v0.4.0 github.com/klauspost/pgzip v1.2.6 github.com/package-url/packageurl-go v0.1.2 @@ -36,6 +37,8 @@ github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect github.com/acomagu/bufpipe v1.0.4 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/cloudflare/circl v1.3.5 // indirect github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect @@ -92,6 +95,7 @@ github.com/spf13/pflag v1.0.5 // indirect github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect github.com/vbatts/tar-split v0.11.5 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect go.lsp.dev/uri v0.3.0 // indirect go.mongodb.org/mongo-driver v1.12.1 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/go.sum new/apko-0.12.0/go.sum --- old/apko-0.11.3/go.sum 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/go.sum 2023-11-29 20:49:11.000000000 +0100 @@ -21,13 +21,17 @@ github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chainguard-dev/go-apk v0.0.0-20231113174935-f86aaf233502 h1:xYYl90jArqY6gFWTNA+6hRlrtKqHJ0lsWPluieS/xO8= -github.com/chainguard-dev/go-apk v0.0.0-20231113174935-f86aaf233502/go.mod h1:y0BbOQALsoi1T2Lt5KmFNn92G+fRFSUuogQI2171HS8= +github.com/chainguard-dev/go-apk v0.0.0-20231120201550-7b08e8f3b0fc h1:Car7PYrE9RD5qBN7ScGuTnDyzg6s6HFFDeUf8cFHlVI= +github.com/chainguard-dev/go-apk v0.0.0-20231120201550-7b08e8f3b0fc/go.mod h1:y0BbOQALsoi1T2Lt5KmFNn92G+fRFSUuogQI2171HS8= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.5 h1:g+wWynZqVALYAlpSQFAa7TscDnUK8mKYtrxMpw6AUKo= github.com/cloudflare/circl v1.3.5/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= @@ -175,6 +179,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= +github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= @@ -314,6 +320,8 @@ github.com/tmc/dot v0.0.0-20210901225022-f9bc17da75c0/go.mod h1:DV83s9TfD0rgoKcqvDmM+aYdz6BXmTkquwd+bI/8tlo= github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/internal/cli/build.go new/apko-0.12.0/internal/cli/build.go --- old/apko-0.11.3/internal/cli/build.go 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/internal/cli/build.go 2023-11-29 20:49:11.000000000 +0100 @@ -72,8 +72,11 @@ bill of materials) describing the image contents. `, Example: ` apko build <config.yaml> <tag> <output.tar|oci-layout-dir/>`, - Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { + if len(args) != 3 { + return fmt.Errorf("requires 3 arg: 1 config file, a tag for the image, and an output path") + } + if len(logPolicy) == 0 { if quietEnabled { logPolicy = []string{"builtin:discard"} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/internal/cli/publish_test.go new/apko-0.12.0/internal/cli/publish_test.go --- old/apko-0.11.3/internal/cli/publish_test.go 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/internal/cli/publish_test.go 2023-11-29 20:49:11.000000000 +0100 @@ -104,7 +104,7 @@ // 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:8dcaffc88372c0b3bf08a04d5c7bb70e59fe22c7ff781f868f3bb8ea3d093eda" + swant := "sha256:2cbdb42a7b4160cdcd44836a583fa23985532e1641f026365f653006545ad90c" require.Equal(t, swant, got) im, err := idx.IndexManifest() @@ -113,8 +113,8 @@ // 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:24a4f1a47dd353ca8e33b0c6bad00b7efc8cabeb27338e3288c2290fd8aaf389", - "sha256:db34ca4a2ac9a03f037edbe0e208fb546e9ccd602d918bf10191ab6056ef8413", + "sha256:a6acf3531effec2dd296834096fccff905d73f6838d9f680419c9bfbedad42f7", + "sha256:91097a5a791914cf2456e540671d47d369ae980c5376844ae978e56c15e8957c", } for i, m := range im.Manifests { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/internal/gen-jsonschema/generate.go new/apko-0.12.0/internal/gen-jsonschema/generate.go --- old/apko-0.11.3/internal/gen-jsonschema/generate.go 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-0.12.0/internal/gen-jsonschema/generate.go 2023-11-29 20:49:11.000000000 +0100 @@ -0,0 +1,16 @@ +// Copyright 2023 Chainguard, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:generate go run . -o ../../pkg/build/types/schema.json +package main diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/internal/gen-jsonschema/main.go new/apko-0.12.0/internal/gen-jsonschema/main.go --- old/apko-0.11.3/internal/gen-jsonschema/main.go 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-0.12.0/internal/gen-jsonschema/main.go 2023-11-29 20:49:11.000000000 +0100 @@ -0,0 +1,41 @@ +package main + +import ( + "bytes" + "encoding/json" + "flag" + "log" + "os" + + "github.com/invopop/jsonschema" + + "chainguard.dev/apko/pkg/build/types" +) + +var ( + outputFlag = flag.String("o", "", "output path") +) + +func main() { + flag.Parse() + + if *outputFlag == "" { + log.Fatal("output path is required") + } + + r := new(jsonschema.Reflector) + if err := r.AddGoComments("chainguard.dev/apko/pkg/build", "../../pkg/build/types"); err != nil { + log.Fatal(err) + } + schema := r.Reflect(types.ImageConfiguration{}) + b := new(bytes.Buffer) + enc := json.NewEncoder(b) + enc.SetIndent("", " ") + if err := enc.Encode(schema); err != nil { + log.Fatal(err) + } + //nolint:gosec // gosec wants us to use 0600, but making this globally readable is preferred. + if err := os.WriteFile(*outputFlag, b.Bytes(), 0644); err != nil { + log.Fatal(err) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/pkg/build/busybox_test.go new/apko-0.12.0/pkg/build/busybox_test.go --- old/apko-0.11.3/pkg/build/busybox_test.go 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/pkg/build/busybox_test.go 2023-11-29 20:49:11.000000000 +0100 @@ -41,7 +41,7 @@ require.NoError(t, err) err = fsys.MkdirAll("/lib/apk/db", 0755) require.NoError(t, err) - pkgLines := apk.PackageToIndex(pkg) + pkgLines := apk.PackageToInstalled(pkg) err = fsys.WriteFile("/lib/apk/db/installed", []byte(strings.Join(pkgLines, "\n")+"\n\n"), 0755) require.NoError(t, err) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/pkg/build/types/schema.json new/apko-0.12.0/pkg/build/types/schema.json --- old/apko-0.11.3/pkg/build/types/schema.json 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-0.12.0/pkg/build/types/schema.json 2023-11-29 20:49:11.000000000 +0100 @@ -0,0 +1,346 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://chainguard.dev/apko/pkg/build/types/image-configuration", + "$ref": "#/$defs/ImageConfiguration", + "$defs": { + "AccountsOption": { + "properties": { + "RunAs": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "RunAs" + ], + "description": "AccountsOption describes an optional deviation to an apko environment's run-as setting." + }, + "BuildOption": { + "properties": { + "Contents": { + "$ref": "#/$defs/ContentsOption" + }, + "Accounts": { + "$ref": "#/$defs/AccountsOption" + }, + "Environment": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "Entrypoint": { + "$ref": "#/$defs/ImageEntrypoint" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "Contents", + "Accounts", + "Environment", + "Entrypoint" + ], + "description": "BuildOption describes an optional deviation to an apko environment." + }, + "ContentsOption": { + "properties": { + "Packages": { + "$ref": "#/$defs/ListOption" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "Packages" + ], + "description": "ContentsOption describes an optional deviation to an apko environment's contents block." + }, + "Group": { + "properties": { + "groupname": { + "type": "string", + "description": "Required: The name of the group" + }, + "gid": { + "type": "integer", + "description": "Required: The group ID" + }, + "members": { + "items": { + "type": "string" + }, + "type": "array", + "description": "Required: The list of members of the group" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ImageAccounts": { + "properties": { + "run-as": { + "type": "string", + "description": "Required: The user to run the container as. This can be a username or UID." + }, + "users": { + "items": { + "$ref": "#/$defs/User" + }, + "type": "array", + "description": "Required: List of users to populate the image with" + }, + "groups": { + "items": { + "$ref": "#/$defs/Group" + }, + "type": "array", + "description": "Required: List of groups to populate the image with" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ImageConfiguration": { + "properties": { + "contents": { + "$ref": "#/$defs/ImageContents", + "description": "Required: The apk packages in the container image" + }, + "entrypoint": { + "$ref": "#/$defs/ImageEntrypoint", + "description": "Required: The entrypoint of the container image\n\nThis typically is the path to the executable to run. Since many of\nimages do not include a shell, this should be the full path\nto the executable." + }, + "cmd": { + "type": "string", + "description": "Optional: The command of the container image\n\nThese are the additional arguments to pass to the entrypoint." + }, + "stop-signal": { + "type": "string", + "description": "Optional: The stop signal used to suspend the execution of the containers process" + }, + "work-dir": { + "type": "string", + "description": "Optional: The working directory of the container" + }, + "accounts": { + "$ref": "#/$defs/ImageAccounts", + "description": "Optional: Account configuration for the container image" + }, + "archs": { + "items": { + "type": "string" + }, + "type": "array", + "description": "Optional: List of CPU architectures to build the container image for\n\nThe list of supported architectures is: 386, amd64, arm64, arm/v6, arm/v7, ppc64le, riscv64, s390x" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "Optional: Envionment variables to set in the container image" + }, + "paths": { + "items": { + "$ref": "#/$defs/PathMutation" + }, + "type": "array", + "description": "Optional: List of paths mutations" + }, + "os-release": { + "$ref": "#/$defs/OSRelease", + "description": "Optional: The /etc/os-release configuration for the container image" + }, + "vcs-url": { + "type": "string", + "description": "Optional: The link to version control system for this container's source code" + }, + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "Optional: Annotations to apply to the images manifests" + }, + "include": { + "type": "string", + "description": "Optional: Path to a local file containing additional image configuration\n\nThe included configuration is deep merged with the parent configuration" + }, + "options": { + "additionalProperties": { + "$ref": "#/$defs/BuildOption" + }, + "type": "object", + "description": "Optional: A map of named build option deviations\n\nDeprecated: Use WithExtraPackages." + }, + "volumes": { + "items": { + "type": "string" + }, + "type": "array", + "description": "Optional: A list of volumes to configure\n\nThis is _not_ the same as Paths, but refers to the OCI spec \"volumes\"\nfield used by some container runtimes (docker) to create volumes at\nruntime. For most use cases, this is not needed, but consider using this\nwhen the image requires special volume configuration at runtime for\nsupported container runtimes." + } + }, + "additionalProperties": false, + "type": "object" + }, + "ImageContents": { + "properties": { + "repositories": { + "items": { + "type": "string" + }, + "type": "array", + "description": "A list of apk repositories to use for pulling packages" + }, + "keyring": { + "items": { + "type": "string" + }, + "type": "array", + "description": "A list of public keys used to verify the desired repositories" + }, + "packages": { + "items": { + "type": "string" + }, + "type": "array", + "description": "A list of packages to include in the image" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ImageEntrypoint": { + "properties": { + "type": { + "type": "string", + "description": "Optional: The type of entrypoint. Only \"service-bundle\" is supported." + }, + "command": { + "type": "string", + "description": "Required: The command of the entrypoint" + }, + "shell-fragment": { + "type": "string", + "description": "Optional: The shell fragment of the entrypoint command" + }, + "services": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ListOption": { + "properties": { + "Add": { + "items": { + "type": "string" + }, + "type": "array" + }, + "Remove": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "Add", + "Remove" + ], + "description": "ListOption describes an optional deviation to a list, for example, a list of packages." + }, + "OSRelease": { + "properties": { + "name": { + "type": "string", + "description": "Optional: The name of the OS" + }, + "id": { + "type": "string", + "description": "Optional: The unique identifier for the OS" + }, + "version-id": { + "type": "string", + "description": "Optional: The unique identifier for the version of the OS" + }, + "pretty-name": { + "type": "string", + "description": "Optional: The human readable description of the OS" + }, + "home-url": { + "type": "string", + "description": "Optional: The URL of the homepage for the OS" + }, + "bug-report-url": { + "type": "string", + "description": "Optional: The URL of the bug reporting website for the OS" + } + }, + "additionalProperties": false, + "type": "object" + }, + "PathMutation": { + "properties": { + "path": { + "type": "string", + "description": "The target path to mutate" + }, + "type": { + "type": "string", + "description": "The type of mutation to perform\n\nThis can be one of: directory, empty-file, hardlink, symlink, permissions" + }, + "uid": { + "type": "integer", + "description": "The mutation's desired user ID" + }, + "gid": { + "type": "integer", + "description": "The mutation's desired group ID" + }, + "permissions": { + "type": "integer", + "description": "The permission bits for the path" + }, + "source": { + "type": "string", + "description": "The source path to mutate" + }, + "recursive": { + "type": "boolean", + "description": "Toggle whether to mutate recursively" + } + }, + "additionalProperties": false, + "type": "object" + }, + "User": { + "properties": { + "username": { + "type": "string", + "description": "Required: The name of the user" + }, + "uid": { + "type": "integer", + "description": "Required: The user ID" + }, + "gid": { + "type": "integer", + "description": "Required: The user's group ID" + } + }, + "additionalProperties": false, + "type": "object" + } + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/pkg/sbom/generator/spdx/spdx.go new/apko-0.12.0/pkg/sbom/generator/spdx/spdx.go --- old/apko-0.11.3/pkg/sbom/generator/spdx/spdx.go 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/pkg/sbom/generator/spdx/spdx.go 2023-11-29 20:49:11.000000000 +0100 @@ -115,9 +115,7 @@ if opts.ImageInfo.VCSUrl != "" { if opts.ImageInfo.ImageDigest != "" { - addSourcePackage(opts.ImageInfo.VCSUrl, doc, imagePackage) - } else { - addSourcePackage(opts.ImageInfo.VCSUrl, doc, layerPackage) + addSourcePackage(opts.ImageInfo.VCSUrl, doc, imagePackage, opts) } } @@ -221,8 +219,6 @@ return nil } - // TODO: Logf("composing packages from %s into image SBOM", path) - internalDoc, err := sx.ParseInternalSBOM(opts, path) if err != nil { // TODO: Log error parsing apk SBOM @@ -302,6 +298,8 @@ for _, f := range sourceDoc.Files { if _, ok := todo[f.ID]; ok { + f.Name = strings.TrimPrefix(f.Name, "/") // Strip leading slashes, which SPDX doesn't like. + targetDoc.Files = append(targetDoc.Files, f) done[f.ID] = struct{}{} } @@ -366,6 +364,8 @@ "SPDXRef-Package-%s", opts.ImageInfo.ImageDigest, )), Name: opts.ImageInfo.ImageDigest, + Version: opts.ImageInfo.ImageDigest, + Supplier: "Organization: " + opts.OS.Name, DownloadLocation: NOASSERTION, PrimaryPurpose: "CONTAINER", FilesAnalyzed: false, @@ -397,6 +397,7 @@ )), Name: pkg.Name, Version: pkg.Version, + Supplier: "Organization: " + opts.OS.Name, FilesAnalyzed: false, LicenseConcluded: pkg.License, Description: pkg.Description, @@ -436,6 +437,7 @@ Description: "apko operating system layer", DownloadLocation: NOASSERTION, Originator: "", + Supplier: "Organization: " + opts.OS.Name, Checksums: []Checksum{}, ExternalRefs: []ExternalRef{ { @@ -500,6 +502,7 @@ Description string `json:"description,omitempty"` DownloadLocation string `json:"downloadLocation,omitempty"` Originator string `json:"originator,omitempty"` + Supplier string `json:"supplier,omitempty"` SourceInfo string `json:"sourceInfo,omitempty"` CopyrightText string `json:"copyrightText,omitempty"` PrimaryPurpose string `json:"primaryPackagePurpose,omitempty"` @@ -560,6 +563,8 @@ indexPackage := Package{ ID: "SPDXRef-Package-" + stringToIdentifier(opts.ImageInfo.IndexDigest.DeepCopy().String()), Name: opts.ImageInfo.IndexDigest.DeepCopy().String(), + Version: opts.ImageInfo.IndexDigest.DeepCopy().String(), + Supplier: "Organization: " + opts.OS.Name, FilesAnalyzed: false, Description: "Multi-arch image index", SourceInfo: "Generated at image build time by apko", @@ -592,6 +597,8 @@ doc.Packages = append(doc.Packages, Package{ ID: imagePackageID, Name: fmt.Sprintf("sha256:%s", info.Digest.DeepCopy().Hex), + Version: fmt.Sprintf("sha256:%s", info.Digest.DeepCopy().Hex), + Supplier: "Organization: " + opts.OS.Name, FilesAnalyzed: false, DownloadLocation: NOASSERTION, PrimaryPurpose: "CONTAINER", @@ -620,7 +627,9 @@ }) } - addSourcePackage(opts.ImageInfo.VCSUrl, doc, &indexPackage) + if opts.ImageInfo.VCSUrl != "" { + addSourcePackage(opts.ImageInfo.VCSUrl, doc, &indexPackage, opts) + } if err := renderDoc(doc, path); err != nil { return fmt.Errorf("rendering document: %w", err) @@ -630,7 +639,7 @@ } // addSourcePackage creates a package describing the source code -func addSourcePackage(vcsURL string, doc *Document, parent *Package) { +func addSourcePackage(vcsURL string, doc *Document, parent *Package, opts *options.Options) { version := "" checksums := []Checksum{} packageName := vcsURL @@ -648,16 +657,22 @@ packageName = strings.TrimPrefix(packageName, "git://") packageName = strings.TrimPrefix(packageName, "https://") + downloadLocation := vcsURL + if vcsURL == "" { + downloadLocation = NOASSERTION + } + sourcePackage := Package{ ID: fmt.Sprintf("SPDXRef-Package-%s", stringToIdentifier(vcsURL)), Name: packageName, Version: version, + Supplier: "Organization: " + opts.OS.Name, FilesAnalyzed: false, HasFiles: []string{}, LicenseInfoFromFiles: []string{}, PrimaryPurpose: "SOURCE", Description: "Image configuration source", - DownloadLocation: vcsURL, + DownloadLocation: downloadLocation, Checksums: checksums, ExternalRefs: []ExternalRef{}, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/pkg/sbom/generator/spdx/spdx_test.go new/apko-0.12.0/pkg/sbom/generator/spdx/spdx_test.go --- old/apko-0.11.3/pkg/sbom/generator/spdx/spdx_test.go 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/pkg/sbom/generator/spdx/spdx_test.go 2023-11-29 20:49:11.000000000 +0100 @@ -131,7 +131,11 @@ } // Call the function - addSourcePackage(vcsURL, &doc, &imagePackage) + addSourcePackage(vcsURL, &doc, &imagePackage, &options.Options{ + OS: options.OSInfo{ + Name: "Testing", + }, + }) // Verify the purl require.Len(t, doc.Packages[0].ExternalRefs, 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/pkg/tarfs/fs.go new/apko-0.12.0/pkg/tarfs/fs.go --- old/apko-0.11.3/pkg/tarfs/fs.go 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/pkg/tarfs/fs.go 2023-11-29 20:49:11.000000000 +0100 @@ -490,8 +490,24 @@ return nil } + // If the existing file's package replaces the package we want to install, we don't need to write this file. + for _, replace := range got.pkg.Replaces { + if want.pkg.Name == replace { + return nil + } + } + + // Otherwise, determine if the package we are installing replaces the existing package. + replaces := false + for _, replace := range want.pkg.Replaces { + if got.pkg.Name == replace { + replaces = true + break + } + } + + // Or if they're from the same origin. sameOrigin := got.pkg.Origin == want.pkg.Origin - replaces := got.pkg.Name == want.pkg.Replaces // At this point we know the files conflict, but it's okay if this file replaces that one. if !sameOrigin && !replaces { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.11.3/pkg/tarfs/fs_test.go new/apko-0.12.0/pkg/tarfs/fs_test.go --- old/apko-0.11.3/pkg/tarfs/fs_test.go 2023-11-16 11:19:06.000000000 +0100 +++ new/apko-0.12.0/pkg/tarfs/fs_test.go 2023-11-29 20:49:11.000000000 +0100 @@ -99,7 +99,7 @@ t.Errorf("wanted conflicting checksum err, got nil") } - pkg.Replaces = pkg.Name + pkg.Replaces = []string{pkg.Name} if err := tfs.WriteHeader(*file, tfs, &pkg.Package); err != nil { t.Errorf("pkg replaces file, got %v", err) } ++++++ apko.obsinfo ++++++ --- /var/tmp/diff_new_pack.ply8hy/_old 2023-11-30 22:02:22.719398526 +0100 +++ /var/tmp/diff_new_pack.ply8hy/_new 2023-11-30 22:02:22.719398526 +0100 @@ -1,5 +1,5 @@ name: apko -version: 0.11.3 -mtime: 1700129946 -commit: 4f9a4c617d079adc838c47303154d90a5ee4455e +version: 0.12.0 +mtime: 1701287351 +commit: 691fe51dd1d536460f8a955d1357eaba974208b5 ++++++ vendor.tar.gz ++++++ ++++ 5822 lines of diff (skipped)
participants (1)
-
Source-Sync