diff --git a/cmd/build.go b/cmd/build.go index a909b92..6271a15 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -3,6 +3,7 @@ package cmd import ( "fmt" "github.com/chainguard-dev/go-apk/pkg/fs" + "github.com/djcass44/all-your-base/pkg/airutil" aybv1 "github.com/djcass44/all-your-base/pkg/api/v1" "github.com/djcass44/all-your-base/pkg/containerutil" "github.com/djcass44/all-your-base/pkg/downloader" @@ -157,7 +158,7 @@ func build(cmd *cobra.Command, _ []string) error { return err } - baseImage := os.ExpandEnv(cfg.Spec.From) + baseImage := airutil.ExpandEnv(cfg.Spec.From) switch baseImage { case containerutil.MagicImageScratch: case "": @@ -193,7 +194,7 @@ func build(cmd *cobra.Command, _ []string) error { log.Error(err, "failed to prepare download directory") return err } - srcUri, err := url.Parse(os.ExpandEnv(file.URI)) + srcUri, err := url.Parse(airutil.ExpandEnv(file.URI)) if err != nil { return err } @@ -319,7 +320,7 @@ func getCacheDir(d string) string { func repoURLs(p []aybv1.Repository) []string { s := make([]string, len(p)) for i := range p { - s[i] = p[i].URL + s[i] = airutil.ExpandEnv(p[i].URL) } return s } diff --git a/cmd/lock.go b/cmd/lock.go index fa315d9..d5761c6 100644 --- a/cmd/lock.go +++ b/cmd/lock.go @@ -3,6 +3,7 @@ package cmd import ( "encoding/json" "fmt" + "github.com/djcass44/all-your-base/pkg/airutil" aybv1 "github.com/djcass44/all-your-base/pkg/api/v1" "github.com/djcass44/all-your-base/pkg/containerutil" "github.com/djcass44/all-your-base/pkg/lockfile" @@ -68,7 +69,7 @@ func lock(cmd *cobra.Command, _ []string) error { // get the digest of the base image if cfg.Spec.From != containerutil.MagicImageScratch { - baseDigest, err := crane.Digest(os.ExpandEnv(cfg.Spec.From), crane.WithAuthFromKeychain(ociutil.KeyChain(ociutil.Auth{}))) + baseDigest, err := crane.Digest(airutil.ExpandEnv(cfg.Spec.From), crane.WithAuthFromKeychain(ociutil.KeyChain(ociutil.Auth{}))) if err != nil { return err } @@ -119,7 +120,7 @@ func lock(cmd *cobra.Command, _ []string) error { return err } _ = dst.Close() - srcUri, err := url.Parse(os.ExpandEnv(file.URI)) + srcUri, err := url.Parse(airutil.ExpandEnv(file.URI)) if err != nil { return err } diff --git a/go.mod b/go.mod index 2176a54..4022288 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/chainguard-dev/go-apk v0.0.0-20230916230430-4fe65c7320b6 github.com/djcass44/ci-tools v1.6.2 github.com/djcass44/go-utils/logging v0.2.3 + github.com/drone/envsubst v1.0.3 github.com/go-logr/logr v1.2.4 github.com/google/go-containerregistry v0.16.1 github.com/hashicorp/go-getter v1.7.2 diff --git a/go.sum b/go.sum index c6bd994..5f4d5bb 100644 --- a/go.sum +++ b/go.sum @@ -316,6 +316,8 @@ github.com/docker/docker v24.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bc github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g= +github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= diff --git a/pkg/airutil/os.go b/pkg/airutil/os.go new file mode 100644 index 0000000..cadec25 --- /dev/null +++ b/pkg/airutil/os.go @@ -0,0 +1,8 @@ +package airutil + +import "github.com/drone/envsubst" + +func ExpandEnv(s string) string { + val, _ := envsubst.EvalEnv(s) + return val +} diff --git a/tests/fixtures/scratch_airgap_test-lock.json b/tests/fixtures/scratch_airgap_test-lock.json new file mode 100644 index 0000000..0b2decf --- /dev/null +++ b/tests/fixtures/scratch_airgap_test-lock.json @@ -0,0 +1,306 @@ +{ + "name": "scratch-airgap-test", + "lockfileVersion": 1, + "packages": { + "${GITHUB_MIRROR:-https://raw.githubusercontent.com}/djcass44/all-your-base/main/README.md": { + "type": "File", + "version": "", + "resolved": "https://raw.githubusercontent.com/djcass44/all-your-base/main/README.md?archive=false", + "integrity": "sha256:eb328cc0cfa6a90b212f35b36a0d4b302908df4d4b2949dbd655c797b5758f7f" + }, + "alpine-base": { + "type": "Alpine", + "version": "3.18.3-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/alpine-base-3.18.3-r0.apk", + "integrity": "Q10cGs1h9J5440p6BRXhZC8FO7pVg=" + }, + "alpine-baselayout": { + "type": "Alpine", + "version": "3.4.3-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/alpine-baselayout-3.4.3-r1.apk", + "integrity": "Q1zwvKMnYs1b6ZdPTBJ0Z7D5P3jyA=" + }, + "alpine-baselayout-data": { + "type": "Alpine", + "version": "3.4.3-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/alpine-baselayout-data-3.4.3-r1.apk", + "integrity": "Q1YCAH7jdO2W816b85sUh9Z8av4Cc=" + }, + "alpine-conf": { + "type": "Alpine", + "version": "3.16.2-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/alpine-conf-3.16.2-r0.apk", + "integrity": "Q16hoL3MjP2iziMtJfgrGrGkhY1Zw=" + }, + "alpine-keys": { + "type": "Alpine", + "version": "2.4-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/alpine-keys-2.4-r1.apk", + "integrity": "Q17Do9XvTHoWjQlRYJe7MhnKd8FTQ=" + }, + "alpine-release": { + "type": "Alpine", + "version": "3.18.3-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/alpine-release-3.18.3-r0.apk", + "integrity": "Q1u774lD/SabOBKjrk6dKblNnKVdU=" + }, + "apk-tools": { + "type": "Alpine", + "version": "2.14.0-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/apk-tools-2.14.0-r2.apk", + "integrity": "Q1jN4l8jnr9pHNE1o5VOUZPBrCrhM=" + }, + "binutils": { + "type": "Alpine", + "version": "2.40-r7", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/binutils-2.40-r7.apk", + "integrity": "Q1YayAMxFpsnglKTXz5kUMuFx5ZlE=" + }, + "busybox": { + "type": "Alpine", + "version": "1.36.1-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/busybox-1.36.1-r2.apk", + "integrity": "Q1gQ/L3UBnSjgkFWEHQaUkUDubqdI=" + }, + "busybox-binsh": { + "type": "Alpine", + "version": "1.36.1-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/busybox-binsh-1.36.1-r2.apk", + "integrity": "Q1ng9K4zeuARW5It8leWhwxor0cRQ=" + }, + "busybox-ifupdown": { + "type": "Alpine", + "version": "1.36.1-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/busybox-ifupdown-1.36.1-r2.apk", + "integrity": "Q1SdTAlDCzpbTM7tyi+yDD5Y5bM1I=" + }, + "busybox-mdev-openrc": { + "type": "Alpine", + "version": "1.36.1-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/busybox-mdev-openrc-1.36.1-r2.apk", + "integrity": "Q1l1zKfiXCTrXV0ByR4WSgpyYDRGQ=" + }, + "busybox-openrc": { + "type": "Alpine", + "version": "1.36.1-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/busybox-openrc-1.36.1-r2.apk", + "integrity": "Q1g4rNpK1QgIFeVljCoUfYX3ANMH4=" + }, + "busybox-suid": { + "type": "Alpine", + "version": "1.36.1-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/busybox-suid-1.36.1-r2.apk", + "integrity": "Q1RuyvI6dpYDjM9vDCDLJH+U5FXLs=" + }, + "ca-certificates-bundle": { + "type": "Alpine", + "version": "20230506-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/ca-certificates-bundle-20230506-r0.apk", + "integrity": "Q1R/SF0IZwqesh6/EOcK5l3EOrbD0=" + }, + "coreutils": { + "type": "Alpine", + "version": "9.3-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/coreutils-9.3-r1.apk", + "integrity": "Q1f60fZgsiTgS1arM7yXQeyqHk5y0=" + }, + "findutils": { + "type": "Alpine", + "version": "4.9.0-r5", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/findutils-4.9.0-r5.apk", + "integrity": "Q11xYFzlmryexiQp9QXhrLQ6C3Gxo=" + }, + "grep": { + "type": "Alpine", + "version": "3.10-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/grep-3.10-r1.apk", + "integrity": "Q1Fv02dFAdFUjKrD015RkP2D/Cd+E=" + }, + "iproute2": { + "type": "Alpine", + "version": "6.3.0-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/iproute2-6.3.0-r0.apk", + "integrity": "Q1is5t9X9/zihKAT385sfAdcnc1KY=" + }, + "iproute2-minimal": { + "type": "Alpine", + "version": "6.3.0-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/iproute2-minimal-6.3.0-r0.apk", + "integrity": "Q1LnifnASXBpuDEnYsXk40KpHsL4g=" + }, + "iproute2-ss": { + "type": "Alpine", + "version": "6.3.0-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/iproute2-ss-6.3.0-r0.apk", + "integrity": "Q1+etLo1zZk4DDWIE4jo1X7sn7ob0=" + }, + "iproute2-tc": { + "type": "Alpine", + "version": "6.3.0-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/iproute2-tc-6.3.0-r0.apk", + "integrity": "Q11WtAYqfKXpLC80WdgEMOvJOJRq4=" + }, + "iptables": { + "type": "Alpine", + "version": "1.8.9-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/iptables-1.8.9-r2.apk", + "integrity": "Q1FWqmPPDxQJS3fhQlLfXgzRlC6Fg=" + }, + "libacl": { + "type": "Alpine", + "version": "2.3.1-r3", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libacl-2.3.1-r3.apk", + "integrity": "Q1dT3NgXwAGQkUX/tOwTpxQMOyEGk=" + }, + "libattr": { + "type": "Alpine", + "version": "2.5.1-r4", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libattr-2.5.1-r4.apk", + "integrity": "Q1pBCBHCW9JyLiQrMUlyp7tWVJiwk=" + }, + "libbz2": { + "type": "Alpine", + "version": "1.0.8-r5", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libbz2-1.0.8-r5.apk", + "integrity": "Q1v13gWmLEhB4wJ6i0S77ZTIkSSDU=" + }, + "libc-utils": { + "type": "Alpine", + "version": "0.7.2-r5", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libc-utils-0.7.2-r5.apk", + "integrity": "Q1Llna/ri8oHhlQIRsaG8SGug0ikI=" + }, + "libcap2": { + "type": "Alpine", + "version": "2.69-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libcap2-2.69-r0.apk", + "integrity": "Q1x2rIM8+ePWI5y9o1VKMEaJR0M7E=" + }, + "libcrypto3": { + "type": "Alpine", + "version": "3.1.3-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libcrypto3-3.1.3-r0.apk", + "integrity": "Q1+hLHhXUQEYytDHHiaVNhV0493Ts=" + }, + "libelf": { + "type": "Alpine", + "version": "0.189-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libelf-0.189-r2.apk", + "integrity": "Q1fSyWjVNDJiJLJjHqgfNRi77A/bA=" + }, + "libgcc": { + "type": "Alpine", + "version": "12.2.1_git20220924-r10", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libgcc-12.2.1_git20220924-r10.apk", + "integrity": "Q1vaf5owBu4zZv4k9JHE5inhNZaGQ=" + }, + "libmnl": { + "type": "Alpine", + "version": "1.0.5-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libmnl-1.0.5-r1.apk", + "integrity": "Q1i06QucxuCP7iMSS2xUWUg5pl380=" + }, + "libnftnl": { + "type": "Alpine", + "version": "1.2.5-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libnftnl-1.2.5-r1.apk", + "integrity": "Q1uqInEpSBm/yAWppw/n0gcYQZVMA=" + }, + "libssl3": { + "type": "Alpine", + "version": "3.1.3-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libssl3-3.1.3-r0.apk", + "integrity": "Q1zrNyIdDwInJ5HULlg7lSAxvLeVc=" + }, + "libstdc++": { + "type": "Alpine", + "version": "12.2.1_git20220924-r10", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/libstdc++-12.2.1_git20220924-r10.apk", + "integrity": "Q1R8OXClfEGAan000NGiz07ag9AIU=" + }, + "mdev-conf": { + "type": "Alpine", + "version": "4.5-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/mdev-conf-4.5-r0.apk", + "integrity": "Q1KvlFL2qWRoICq2oCHqEWqHEhjDk=" + }, + "musl": { + "type": "Alpine", + "version": "1.2.4-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/musl-1.2.4-r1.apk", + "integrity": "Q12qHLEadu7QpBuz8kHB5EDF3mKB4=" + }, + "musl-fts": { + "type": "Alpine", + "version": "1.2.7-r5", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/musl-fts-1.2.7-r5.apk", + "integrity": "Q1sFhXJJRMV+7nuvoZciXfW6JJEhQ=" + }, + "musl-utils": { + "type": "Alpine", + "version": "1.2.4-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/musl-utils-1.2.4-r1.apk", + "integrity": "Q1x4sUHXjWjUzYP5FPvJL1HWBjL1M=" + }, + "openrc": { + "type": "Alpine", + "version": "0.48-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/openrc-0.48-r0.apk", + "integrity": "Q1PZgyHSNtQRx3Zi9Azv7WWcCVWUA=" + }, + "pcre2": { + "type": "Alpine", + "version": "10.42-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/pcre2-10.42-r1.apk", + "integrity": "Q1GVvOXp8moLoU9GDN9SGWx+OH8oI=" + }, + "scanelf": { + "type": "Alpine", + "version": "1.3.7-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/scanelf-1.3.7-r1.apk", + "integrity": "Q14nq9o4+uo2NaLbTVDQB3UeooC0M=" + }, + "skalibs": { + "type": "Alpine", + "version": "2.13.1.1-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/skalibs-2.13.1.1-r1.apk", + "integrity": "Q1glnmuqMZfoGd5sOZKfEJnYV7vfQ=" + }, + "ssl_client": { + "type": "Alpine", + "version": "1.36.1-r2", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/ssl_client-1.36.1-r2.apk", + "integrity": "Q1j6LHWpavmnFtpYjzQkH7apSIVOc=" + }, + "util-linux": { + "type": "Alpine", + "version": "2.38.1-r8", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/util-linux-2.38.1-r8.apk", + "integrity": "Q1SlxAHbTBQX92L3f0Rtf061q4jeE=" + }, + "utmps-libs": { + "type": "Alpine", + "version": "0.1.2.1-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/utmps-libs-0.1.2.1-r1.apk", + "integrity": "Q1bA7o9NfM0+FHYiB1/oK72Bl1b7k=" + }, + "xz-libs": { + "type": "Alpine", + "version": "5.4.3-r0", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/xz-libs-5.4.3-r0.apk", + "integrity": "Q1mtV1/ZRayPbsAAEYrhTsWQTMuho=" + }, + "zlib": { + "type": "Alpine", + "version": "1.2.13-r1", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/zlib-1.2.13-r1.apk", + "integrity": "Q1JlboSJkrN4qkDcokr4zenpcWEXQ=" + }, + "zstd-libs": { + "type": "Alpine", + "version": "1.5.5-r4", + "resolved": "https://mirror.aarnet.edu.au/pub/alpine/v3.18/main/x86_64/zstd-libs-1.5.5-r4.apk", + "integrity": "Q1g9irJ/T9RyWhRyRfidB2qpa1ImI=" + } + } +} diff --git a/tests/fixtures/scratch_airgap_test.yaml b/tests/fixtures/scratch_airgap_test.yaml new file mode 100644 index 0000000..23aa0e3 --- /dev/null +++ b/tests/fixtures/scratch_airgap_test.yaml @@ -0,0 +1,22 @@ +apiVersion: ayb.dcas.dev/v1 +kind: Build +metadata: + name: scratch-airgap-test +spec: + from: scratch + repositories: + alpine: + - url: "${ALPINE_MIRROR:-https://mirror.aarnet.edu.au/pub/alpine}/v3.18/main" + packages: + - type: Alpine + names: + - alpine-base + - util-linux + - coreutils + - binutils + - findutils + - grep + - iproute2 + files: + - uri: "${GITHUB_MIRROR:-https://raw.githubusercontent.com}/djcass44/all-your-base/main/README.md" + path: /README.md \ No newline at end of file