Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package apko for openSUSE:Factory checked in at 2024-06-03 17:41:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/apko (Old) and /work/SRC/openSUSE:Factory/.apko.new.24587 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "apko" Mon Jun 3 17:41:57 2024 rev:11 rq:1178037 version:0.14.7 Changes: -------- --- /work/SRC/openSUSE:Factory/apko/apko.changes 2024-05-31 22:15:57.658150200 +0200 +++ /work/SRC/openSUSE:Factory/.apko.new.24587/apko.changes 2024-06-03 17:42:11.720237989 +0200 @@ -1,0 +2,19 @@ +Sat Jun 01 09:23:29 UTC 2024 - opensuse_buildservice@ojkastl.de + +- Update to version 0.14.7: + * ensure homedir respects non-defaults + * build(deps): bump github/codeql-action from 3.25.6 to 3.25.7 + +------------------------------------------------------------------- +Sat Jun 01 09:10:13 UTC 2024 - opensuse_buildservice@ojkastl.de + +- Update to version 0.14.6: + * plumb through HomeDir as optional build configuration + * Pull in the auth fix in go-apk (#1145) + * Update internal/cli/build.go + * Update internal/cli/publish.go + * This fixes the boolean logic to pass auth. + * go mod tidy + * support basic HTTP auth + +------------------------------------------------------------------- Old: ---- apko-0.14.5.obscpio New: ---- apko-0.14.7.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apko.spec ++++++ --- /var/tmp/diff_new_pack.aDIWcw/_old 2024-06-03 17:42:12.608270429 +0200 +++ /var/tmp/diff_new_pack.aDIWcw/_new 2024-06-03 17:42:12.608270429 +0200 @@ -19,7 +19,7 @@ %define __arch_install_post export NO_BRP_STRIP_DEBUG=true Name: apko -Version: 0.14.5 +Version: 0.14.7 Release: 0 Summary: Build OCI images from APK packages directly without Dockerfile License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.aDIWcw/_old 2024-06-03 17:42:12.644271744 +0200 +++ /var/tmp/diff_new_pack.aDIWcw/_new 2024-06-03 17:42:12.648271891 +0200 @@ -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.14.5</param> + <param name="revision">v0.14.7</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.aDIWcw/_old 2024-06-03 17:42:12.664272475 +0200 +++ /var/tmp/diff_new_pack.aDIWcw/_new 2024-06-03 17:42:12.668272621 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/chainguard-dev/apko</param> - <param name="changesrevision">b69d852e8fc29b2eb2f412e0fdee150aed03645c</param></service></servicedata> + <param name="changesrevision">f5aa053346e01a693dedca1e7d86a2df76dec6ab</param></service></servicedata> (No newline at EOF) ++++++ apko-0.14.5.obscpio -> apko-0.14.7.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/.github/workflows/codeql.yaml new/apko-0.14.7/.github/workflows/codeql.yaml --- old/apko-0.14.5/.github/workflows/codeql.yaml 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/.github/workflows/codeql.yaml 2024-05-31 18:54:55.000000000 +0200 @@ -29,7 +29,7 @@ check-latest: true - name: Initialize CodeQL - uses: github/codeql-action/init@9fdb3e49720b44c48891d036bb502feb25684276 + uses: github/codeql-action/init@f079b8493333aace61c81488f8bd40919487bd9f with: languages: go @@ -37,4 +37,4 @@ run: make apko - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9fdb3e49720b44c48891d036bb502feb25684276 + uses: github/codeql-action/analyze@f079b8493333aace61c81488f8bd40919487bd9f diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/go.mod new/apko-0.14.7/go.mod --- old/apko-0.14.5/go.mod 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/go.mod 2024-05-31 18:54:55.000000000 +0200 @@ -4,7 +4,7 @@ require ( github.com/chainguard-dev/clog v1.3.1 - github.com/chainguard-dev/go-apk v0.0.0-20240529154108-3de67a94ddad + github.com/chainguard-dev/go-apk v0.0.0-20240530214935-2ff9aee8385a github.com/charmbracelet/log v0.4.0 github.com/dominodatalab/os-release v0.0.0-20190522011736-bcdb4a3e3c2f github.com/go-git/go-git/v5 v5.12.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/go.sum new/apko-0.14.7/go.sum --- old/apko-0.14.5/go.sum 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/go.sum 2024-05-31 18:54:55.000000000 +0200 @@ -28,8 +28,8 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chainguard-dev/clog v1.3.1 h1:CDNCty5WKQhJzoOPubk0GdXt+bPQyargmfClqebrpaQ= github.com/chainguard-dev/clog v1.3.1/go.mod h1:cV516KZWqYc/phZsCNwF36u/KMGS+Gj5Uqeb8Hlp95Y= -github.com/chainguard-dev/go-apk v0.0.0-20240529154108-3de67a94ddad h1:MweFfBg9pmE4X+3SdlqJy3SVwbm3XEOze94IkXb3uwY= -github.com/chainguard-dev/go-apk v0.0.0-20240529154108-3de67a94ddad/go.mod h1:4UVB5GXk5yVOVwe3QPdmMLMVTpYbvzygjXlRrJxJPMc= +github.com/chainguard-dev/go-apk v0.0.0-20240530214935-2ff9aee8385a h1:E8EgiRgZsmq1Twz6H2gyyzDB0OxHfZ+h3g8R9BimdAU= +github.com/chainguard-dev/go-apk v0.0.0-20240530214935-2ff9aee8385a/go.mod h1:4UVB5GXk5yVOVwe3QPdmMLMVTpYbvzygjXlRrJxJPMc= github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/internal/cli/build.go new/apko-0.14.7/internal/cli/build.go --- old/apko-0.14.5/internal/cli/build.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/internal/cli/build.go 2024-05-31 18:54:55.000000000 +0200 @@ -22,6 +22,7 @@ "log/slog" "os" "path/filepath" + "strings" "sync" "github.com/chainguard-dev/clog" @@ -91,6 +92,18 @@ } defer os.RemoveAll(tmp) + var user, pass string + if auth, ok := os.LookupEnv("HTTP_AUTH"); !ok { + // Fine, no auth. + } else if parts := strings.SplitN(auth, ":", 4); len(parts) != 4 { + return fmt.Errorf("HTTP_AUTH must be in the form 'basic:REALM:USERNAME:PASSWORD' (got %d parts)", len(parts)) + } else if parts[0] != "basic" { + return fmt.Errorf("HTTP_AUTH must be in the form 'basic:REALM:USERNAME:PASSWORD' (got %q for first part)", parts[0]) + } else { + // NB: parts[1] is the realm, which we ignore. + user, pass = parts[2], parts[3] + } + return BuildCmd(cmd.Context(), args[1], args[2], archs, []string{args[1]}, writeSBOM, @@ -109,6 +122,7 @@ build.WithCacheDir(cacheDir, offline), build.WithLockFile(lockfile), build.WithTempDir(tmp), + build.WithAuth(user, pass), ) }, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/internal/cli/publish.go new/apko-0.14.7/internal/cli/publish.go --- old/apko-0.14.5/internal/cli/publish.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/internal/cli/publish.go 2024-05-31 18:54:55.000000000 +0200 @@ -99,6 +99,18 @@ } defer os.RemoveAll(tmp) + var user, pass string + if auth, ok := os.LookupEnv("HTTP_AUTH"); !ok { + // Fine, no auth. + } else if parts := strings.SplitN(auth, ":", 4); len(parts) != 4 { + return fmt.Errorf("HTTP_AUTH must be in the form 'basic:REALM:USERNAME:PASSWORD' (got %d parts)", len(parts)) + } else if parts[0] != "basic" { + return fmt.Errorf("HTTP_AUTH must be in the form 'basic:REALM:USERNAME:PASSWORD' (got %q for first part)", parts[0]) + } else { + // NB: parts[1] is the realm, which we ignore. + user, pass = parts[2], parts[3] + } + if err := PublishCmd(cmd.Context(), imageRefs, archs, remoteOpts, sbomPath, []build.Option{ @@ -115,6 +127,7 @@ build.WithAnnotations(annotations), build.WithCacheDir(cacheDir, offline), build.WithTempDir(tmp), + build.WithAuth(user, pass), }, []PublishOption{ // these are extra here just for publish; everything before is the same for BuildCmd as PublishCmd diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/internal/cli/testdata/packages/melange.rsa.pub new/apko-0.14.7/internal/cli/testdata/packages/melange.rsa.pub --- old/apko-0.14.5/internal/cli/testdata/packages/melange.rsa.pub 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-0.14.7/internal/cli/testdata/packages/melange.rsa.pub 2024-05-31 18:54:55.000000000 +0200 @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuE9aHvpBoe7HNnWxhp2p +x+HGjbPhzP0CyQYMNMcHjd76UcaPwWNTVqJI8JMT2u72mPsEXpC+J6KqjIggJoOa +QYg87oYEdthoJZjyDaKzezNZKndzVQkg4RfQPiCPQkm4r9v6So0MCDa4rwRYnqrf +s3Je9/wi8B/wG1sz7P4wOG23djxpORDsMI9CyZhnAKfNg/uqmF/sxEwOL4FaDZMg +0oo7Kx3FjtqqKTV8uFbCDsTxV3CR0pm3WJdX9TNfjXLXfp2a6QDYk1JoYl++UUHK ++7izMXro6xgY7OPT+F48/YNYxS/ciH90DmN7ysJnQ2otZHSqhOkJV4UrYCKBHY55 +XjpDe7+nmwXaqVyAlCS6pDqHeYUUpYTpnv4b9bbst9NtYPRY8W00Oc5Cs3KdHeV6 +LqvHAGwNTZziv91UTpi0hMf27I+MLaXx+jNWm5j40a+ZyswLAQSLI+u3LxfPlHda +lhpaQw+CoM3ucX9rcnJaBgowXclDAAvRNIj7EJNW5sk+3SbpmKKDkrD7Cl0rMSrd +1dixDZZPzA8UtwheNTmV+I+0r1kQMcNYcB8iUKsoWIpaur0CBCww02WTHpOMcMGw ++rVr/wzPP3Iqo1+EVrzVI5kSnZ7VLRtO5VdMLw0PlIK4ShJ+X5OtVtWnJ9jIiLaI +se0tr8lpqU40eV862X+jKz0CAwEAAQ== +-----END PUBLIC KEY----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/build/accounts.go new/apko-0.14.7/pkg/build/accounts.go --- old/apko-0.14.5/pkg/build/accounts.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/pkg/build/accounts.go 2024-05-31 18:54:55.000000000 +0200 @@ -44,11 +44,14 @@ if user.Shell == "" { user.Shell = "/bin/sh" } + if user.HomeDir == "" { + user.HomeDir = "/home/" + user.UserName + } return passwd.UserEntry{ UserName: user.UserName, UID: user.UID, GID: user.GID, - HomeDir: "/home/" + user.UserName, + HomeDir: user.HomeDir, Password: "x", Info: "Account created by apko", Shell: user.Shell, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/build/build.go new/apko-0.14.7/pkg/build/build.go --- old/apko-0.14.5/pkg/build/build.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/pkg/build/build.go 2024-05-31 18:54:55.000000000 +0200 @@ -267,6 +267,10 @@ log.Warnf("cache disabled because cache dir was not set, and cannot determine system default: %v", err) } + if bc.o.User != "" || bc.o.Pass != "" { + apkOpts = append(apkOpts, apk.WithAuth(bc.o.User, bc.o.Pass)) + } + if bc.ic.Contents.BaseImage != nil { baseImg, err := baseimg.New(bc.ic.Contents.BaseImage.Image, bc.ic.Contents.BaseImage.APKIndex, bc.Arch(), bc.o.TempDir()) if err != nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/build/build_test.go new/apko-0.14.7/pkg/build/build_test.go --- old/apko-0.14.5/pkg/build/build_test.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/pkg/build/build_test.go 2024-05-31 18:54:55.000000000 +0200 @@ -16,6 +16,8 @@ import ( "context" + "net/http" + "net/http/httptest" "path/filepath" "testing" @@ -23,6 +25,7 @@ "github.com/stretchr/testify/require" "chainguard.dev/apko/pkg/build" + "chainguard.dev/apko/pkg/build/types" ) func TestBuildLayer(t *testing.T) { @@ -102,3 +105,75 @@ "locked package pretend-baselayout has missing checksum (please regenerate the lock file with Apko >=0.13)", err.Error()) } + +func TestAuth_good(t *testing.T) { + called := false + testUser, testPass := "user", "pass" + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("ETag", "123") + if r.Method == http.MethodHead { + return + } + + called = true + if gotuser, gotpass, ok := r.BasicAuth(); !ok || gotuser != testUser || gotpass != testPass { + t.Logf("got user: %q, pass: %q", gotuser, gotpass) + w.WriteHeader(http.StatusForbidden) + return + } + http.FileServer(http.Dir("testdata/packages")).ServeHTTP(w, r) + })) + defer s.Close() + + ctx := context.Background() + bc, err := build.New(ctx, fs.NewMemFS(), + build.WithAuth(testUser, testPass), + build.WithImageConfiguration(types.ImageConfiguration{ + Contents: types.ImageContents{ + Repositories: []string{s.URL}, + Keyring: []string{s.URL + "/melange.rsa.pub"}, + Packages: []string{"pretend-baselayout"}, + }, + Archs: types.ParseArchitectures([]string{"amd64", "arm64"}), + }), + ) + if err != nil { + t.Fatal(err) + } + err = bc.BuildImage(ctx) + require.NoError(t, err, "build image failed") + require.True(t, called) +} + +func TestAuth_bad(t *testing.T) { + called := false + testUser, testPass := "user", "pass" + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("ETag", "123") + if r.Method == http.MethodHead { + return + } + + called = true + if gotuser, gotpass, ok := r.BasicAuth(); !ok || gotuser != testUser || gotpass != testPass { + w.WriteHeader(http.StatusForbidden) + return + } + http.FileServer(http.Dir("testdata/packages")).ServeHTTP(w, r) + })) + defer s.Close() + + ctx := context.Background() + _, err := build.New(ctx, fs.NewMemFS(), + build.WithAuth("baduser", "badpass"), + build.WithImageConfiguration(types.ImageConfiguration{ + Contents: types.ImageContents{ + Keyring: []string{s.URL + "/melange.rsa.pub"}, + // We don't even need to specify repository or packages, since keyring init will fail without auth. + }, + Archs: types.ParseArchitectures([]string{"amd64", "arm64"}), + }), + ) + require.Error(t, err, "build should have failed to init keyring") + require.True(t, called) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/build/options.go new/apko-0.14.7/pkg/build/options.go --- old/apko-0.14.5/pkg/build/options.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/pkg/build/options.go 2024-05-31 18:54:55.000000000 +0200 @@ -207,3 +207,11 @@ return nil } } + +func WithAuth(user, pass string) Option { + return func(bc *Context) error { + bc.o.User = user + bc.o.Pass = pass + return nil + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/build/types/image_configuration.go new/apko-0.14.7/pkg/build/types/image_configuration.go --- old/apko-0.14.5/pkg/build/types/image_configuration.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/pkg/build/types/image_configuration.go 2024-05-31 18:54:55.000000000 +0200 @@ -164,7 +164,7 @@ } } - for _, u := range ic.Accounts.Users { + for i, u := range ic.Accounts.Users { if u.UserName == "" { return fmt.Errorf("configured user %v has no configured user name", u) } @@ -172,6 +172,10 @@ if u.UID == 0 { return fmt.Errorf("configured user %v has UID 0 (to run as root, use `run-as: 0`)", u) } + + if u.HomeDir == "" { + ic.Accounts.Users[i].HomeDir = "/home/" + u.UserName + } } for _, g := range ic.Accounts.Groups { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/build/types/image_configuration_test.go new/apko-0.14.7/pkg/build/types/image_configuration_test.go --- old/apko-0.14.5/pkg/build/types/image_configuration_test.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/pkg/build/types/image_configuration_test.go 2024-05-31 18:54:55.000000000 +0200 @@ -36,3 +36,19 @@ require.ElementsMatch(t, ic.Contents.Keyring, []string{"key"}) require.ElementsMatch(t, ic.Contents.Packages, []string{"package", "other_package"}) } + +func TestUserContents(t *testing.T) { + ctx := context.Background() + + configPath := filepath.Join("testdata", "users.apko.yaml") + hasher := sha256.New() + ic := types.ImageConfiguration{} + + require.NoError(t, ic.Load(ctx, configPath, hasher)) + if err := ic.Validate(); err != nil { + t.Fatal(err) + } + + require.Equal(t, "/not/home", ic.Accounts.Users[0].HomeDir) + require.Equal(t, "/home/user", ic.Accounts.Users[1].HomeDir) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/build/types/schema.json new/apko-0.14.7/pkg/build/types/schema.json --- old/apko-0.14.5/pkg/build/types/schema.json 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/pkg/build/types/schema.json 2024-05-31 18:54:55.000000000 +0200 @@ -274,7 +274,11 @@ }, "shell": { "type": "string", - "description": "Required: The user's shell" + "description": "Optional: The user's shell" + }, + "homedir": { + "type": "string", + "description": "Optional: The user's home directory" } }, "additionalProperties": false, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/build/types/testdata/users.apko.yaml new/apko-0.14.7/pkg/build/types/testdata/users.apko.yaml --- old/apko-0.14.5/pkg/build/types/testdata/users.apko.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/apko-0.14.7/pkg/build/types/testdata/users.apko.yaml 2024-05-31 18:54:55.000000000 +0200 @@ -0,0 +1,17 @@ +contents: + repositories: + - "repository" + keyring: + - "key" + packages: + - "package" + +accounts: + users: + - gid: 1 + uid: 2 + homedir: "/not/home" + username: "something-else" + - gid: 2 + uid: 3 + username: "user" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/build/types/types.go new/apko-0.14.7/pkg/build/types/types.go --- old/apko-0.14.5/pkg/build/types/types.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/pkg/build/types/types.go 2024-05-31 18:54:55.000000000 +0200 @@ -30,8 +30,10 @@ UID uint32 `json:"uid,omitempty"` // Required: The user's group ID GID uint32 `json:"gid,omitempty"` - // Required: The user's shell + // Optional: The user's shell Shell string `json:"shell,omitempty"` + // Optional: The user's home directory + HomeDir string `json:"homedir,omitempty"` } type Group struct { @@ -138,9 +140,9 @@ // Required: The user to run the container as. This can be a username or UID. RunAs string `json:"run-as,omitempty" yaml:"run-as"` // Required: List of users to populate the image with - Users []User `json:"users,omitempty"` + Users []User `json:"users,omitempty" yaml:"users"` // Required: List of groups to populate the image with - Groups []Group `json:"groups,omitempty"` + Groups []Group `json:"groups,omitempty" yaml:"groups"` } type ImageConfiguration struct { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.14.5/pkg/options/options.go new/apko-0.14.7/pkg/options/options.go --- old/apko-0.14.5/pkg/options/options.go 2024-05-29 19:10:29.000000000 +0200 +++ new/apko-0.14.7/pkg/options/options.go 2024-05-31 18:54:55.000000000 +0200 @@ -48,6 +48,8 @@ CacheDir string `json:"cacheDir,omitempty"` Offline bool `json:"offline,omitempty"` Lockfile string `json:"lockfile,omitempty"` + User string `json:"user"` + Pass string `json:"-"` } var Default = Options{ ++++++ apko.obsinfo ++++++ --- /var/tmp/diff_new_pack.aDIWcw/_old 2024-06-03 17:42:12.868279928 +0200 +++ /var/tmp/diff_new_pack.aDIWcw/_new 2024-06-03 17:42:12.872280074 +0200 @@ -1,5 +1,5 @@ name: apko -version: 0.14.5 -mtime: 1717002629 -commit: b69d852e8fc29b2eb2f412e0fdee150aed03645c +version: 0.14.7 +mtime: 1717174495 +commit: f5aa053346e01a693dedca1e7d86a2df76dec6ab ++++++ vendor.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/cache.go new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/cache.go --- old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/cache.go 2024-05-30 10:59:08.000000000 +0200 +++ new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/cache.go 2024-06-01 11:23:30.000000000 +0200 @@ -54,7 +54,9 @@ // Do all the expensive things inside the once. once, _ := e.etags.LoadOrStore(url, &sync.Once{}) once.(*sync.Once).Do(func() { - resp, rerr := t.wrapped.Head(url) + req := request.Clone(request.Context()) + req.Method = http.MethodHead + resp, rerr := t.wrapped.Do(req) if resp != nil { // We don't expect any body from a HEAD so just always close it to appease the linter. resp.Body.Close() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/implementation.go new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/implementation.go --- old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/implementation.go 2024-05-30 10:59:08.000000000 +0200 +++ new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/implementation.go 2024-06-01 11:23:30.000000000 +0200 @@ -65,6 +65,7 @@ cache *cache ignoreSignatures bool noSignatureIndexes []string + user, pass string // filename to owning package, last write wins installedFiles map[string]*Package @@ -93,6 +94,8 @@ cache: opt.cache, noSignatureIndexes: opt.noSignatureIndexes, installedFiles: map[string]*Package{}, + user: opt.user, + pass: opt.pass, }, nil } @@ -377,7 +380,7 @@ var asURL *url.URL var err error - if strings.HasPrefix(element, "https://") { + if strings.HasPrefix(element, "https://") || strings.HasPrefix(element, "http://") { asURL, err = url.Parse(element) } else { // Attempt to parse non-https elements into URI's so they are translated into @@ -395,7 +398,7 @@ if err != nil { return fmt.Errorf("failed to read apk key: %w", err) } - case "https": //nolint:goconst + case "https", "http": //nolint:goconst client := a.client if a.cache != nil { client = a.cache.client(client, true) @@ -404,11 +407,15 @@ if err != nil { return err } + // if the URL contains HTTP Basic Auth credentials, add them to the request if asURL.User != nil { user := asURL.User.Username() pass, _ := asURL.User.Password() req.SetBasicAuth(user, pass) + req.URL.User = nil + } else if a.user != "" && a.pass != "" { + req.SetBasicAuth(a.user, a.pass) } resp, err := client.Do(req) @@ -714,6 +721,7 @@ if err != nil { return err } + // NB: Not setting basic auth, since we know Alpine doesn't support it. res, err := client.Do(req) if err != nil { return fmt.Errorf("failed to fetch alpine releases: %w", err) @@ -748,6 +756,7 @@ if err != nil { return err } + // NB: Not setting basic auth, since we know Alpine doesn't support it. res, err := client.Do(req) if err != nil { return fmt.Errorf("failed to fetch alpine key %s: %w", u, err) @@ -995,7 +1004,7 @@ func packageAsURI(pkg InstallablePackage) (uri.URI, error) { u := pkg.URL() - if strings.HasPrefix(u, "https://") { + if strings.HasPrefix(u, "https://") || strings.HasPrefix(u, "http://") { return uri.Parse(u) } @@ -1035,7 +1044,7 @@ return nil, fmt.Errorf("failed to read repository package apk %s: %w", u, err) } return f, nil - case "https": + case "https", "http": client := a.client if a.cache != nil { client = a.cache.client(client, false) @@ -1044,6 +1053,9 @@ if err != nil { return nil, err } + if a.user != "" && a.pass != "" { + req.SetBasicAuth(a.user, a.pass) + } // This will return a body that retries requests using Range requests if Read() hits an error. rrt := newRangeRetryTransport(ctx, client) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/index.go new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/index.go --- old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/index.go 2024-05-30 10:59:08.000000000 +0200 +++ new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/index.go 2024-06-01 11:23:30.000000000 +0200 @@ -64,7 +64,7 @@ } func (i *indexCache) get(ctx context.Context, u string, keys map[string][]byte, arch string, opts *indexOpts) (*APKIndex, error) { - if strings.HasPrefix(u, "https://") { + if strings.HasPrefix(u, "https://") || strings.HasPrefix(u, "http://") { // We don't want remote indexes to change while we're running. once, _ := i.onces.LoadOrStore(u, &sync.Once{}) once.(*sync.Once).Do(func() { @@ -173,7 +173,7 @@ return true } -func getRepositoryIndex(ctx context.Context, u string, keys map[string][]byte, arch string, opts *indexOpts) (*APKIndex, error) { +func getRepositoryIndex(ctx context.Context, u string, keys map[string][]byte, arch string, opts *indexOpts) (*APKIndex, error) { //nolint:gocyclo // Normalize the repo as a URI, so that local paths // are translated into file:// URLs, allowing them to be parsed // into a url.URL{}. @@ -182,7 +182,7 @@ asURL *url.URL err error ) - if strings.HasPrefix(u, "https://") { + if strings.HasPrefix(u, "https://") || strings.HasPrefix(u, "http://") { asURL, err = url.Parse(u) } else { // Attempt to parse non-https elements into URI's so they are translated into @@ -202,7 +202,7 @@ } return nil, nil } - case "https": + case "https", "http": client := opts.httpClient req, err := http.NewRequestWithContext(ctx, http.MethodGet, asURL.String(), nil) if err != nil { @@ -213,6 +213,8 @@ user := asURL.User.Username() pass, _ := asURL.User.Password() req.SetBasicAuth(user, pass) + } else if opts.user != "" || opts.pass != "" { + req.SetBasicAuth(opts.user, opts.pass) } // This will return a body that retries requests using Range requests if Read() hits an error. @@ -318,6 +320,7 @@ ignoreSignatures bool noSignatureIndexes []string httpClient *http.Client + user, pass string } type IndexOption func(*indexOpts) @@ -338,3 +341,10 @@ o.httpClient = c } } + +func WithIndexAuth(user, pass string) IndexOption { + return func(o *indexOpts) { + o.user = user + o.pass = pass + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/options.go new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/options.go --- old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/options.go 2024-05-30 10:59:08.000000000 +0200 +++ new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/options.go 2024-06-01 11:23:30.000000000 +0200 @@ -30,6 +30,7 @@ version string cache *cache noSignatureIndexes []string + user, pass string } type Option func(*opts) error @@ -104,6 +105,14 @@ return nil } } + +func WithAuth(user, pass string) Option { + return func(o *opts) error { + o.user = user + o.pass = pass + return nil + } +} func defaultOpts() *opts { return &opts{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/repo.go new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/repo.go --- old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/repo.go 2024-05-30 10:59:08.000000000 +0200 +++ new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/repo.go 2024-06-01 11:23:30.000000000 +0200 @@ -176,7 +176,11 @@ if a.cache != nil { httpClient = a.cache.client(httpClient, true) } - return GetRepositoryIndexes(ctx, repos, keys, arch, WithIgnoreSignatures(ignoreSignatures), WithHTTPClient(httpClient), WithIgnoreSignatureForIndexes(a.noSignatureIndexes...)) + return GetRepositoryIndexes(ctx, repos, keys, arch, + WithIgnoreSignatures(ignoreSignatures), + WithIgnoreSignatureForIndexes(a.noSignatureIndexes...), + WithHTTPClient(httpClient), + WithIndexAuth(a.user, a.pass)) } // PkgResolver resolves packages from a list of indexes. @@ -193,7 +197,7 @@ nameMap map[string][]*repositoryPackage installIfMap map[string][]*repositoryPackage // contains any package that should be installed if the named package is installed - parsedVersions map[string]packageVersion + parsedVersions map[string]Version depForVersion map[string]parsedConstraint } @@ -211,7 +215,7 @@ ) p := &PkgResolver{ indexes: indexes, - parsedVersions: map[string]packageVersion{}, + parsedVersions: map[string]Version{}, depForVersion: map[string]parsedConstraint{}, } @@ -695,7 +699,7 @@ if allowSelfFulfill && pkg.Name == name { var ( - actualVersion, requiredVersion packageVersion + actualVersion, requiredVersion Version err1, err2 error ) actualVersion, err1 = p.parseVersion(pkg.Version) @@ -787,13 +791,13 @@ return dependencies, conflicts, nil } -func (p *PkgResolver) parseVersion(version string) (packageVersion, error) { +func (p *PkgResolver) parseVersion(version string) (Version, error) { pkg, ok := p.parsedVersions[version] if ok { return pkg, nil } - parsed, err := parseVersion(version) + parsed, err := ParseVersion(version) if err != nil { return parsed, err } @@ -906,9 +910,9 @@ // If j fails to parse, prefer i. return -1 } - versions := compareVersions(iVersion, jVersion) + versions := CompareVersions(iVersion, jVersion) if versions != equal { - return -1 * int(versions) + return -1 * versions } // if versions are equal, they might not be the same as the package versions if iVersionStr != a.Version || jVersionStr != b.Version { @@ -921,9 +925,9 @@ // If j fails to parse, prefer i. return -1 } - versions := compareVersions(iVersion, jVersion) + versions := CompareVersions(iVersion, jVersion) if versions != equal { - return -1 * int(versions) + return -1 * versions } } // if versions are equal, compare names diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/version.go new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/version.go --- old/vendor/github.com/chainguard-dev/go-apk/pkg/apk/version.go 2024-05-30 10:59:08.000000000 +0200 +++ new/vendor/github.com/chainguard-dev/go-apk/pkg/apk/version.go 2024-06-01 11:23:30.000000000 +0200 @@ -67,7 +67,7 @@ packageVersionPostModifierMax packageVersionPostModifier = 1000 ) -type packageVersion struct { +type Version struct { numbers []int letter rune preSuffix packageVersionPreModifier @@ -77,21 +77,22 @@ revision int } -func parseVersion(version string) (packageVersion, error) { +// ParseVersion parses a version string into a Version struct. +func ParseVersion(version string) (Version, error) { parts := versionRegex.FindAllStringSubmatch(version, -1) if len(parts) == 0 { - return packageVersion{}, fmt.Errorf("invalid version %s, could not parse", version) + return Version{}, fmt.Errorf("invalid version %s, could not parse", version) } actuals := parts[0] numbers := make([]int, 0, 10) if len(actuals) != 14 { - return packageVersion{}, fmt.Errorf("invalid version %s, could not find enough components", version) + return Version{}, fmt.Errorf("invalid version %s, could not find enough components", version) } // get the first version number num, err := strconv.Atoi(actuals[1]) if err != nil { - return packageVersion{}, fmt.Errorf("invalid version %s, first part is not number: %w", version, err) + return Version{}, fmt.Errorf("invalid version %s, first part is not number: %w", version, err) } numbers = append(numbers, num) @@ -104,7 +105,7 @@ } num, err := strconv.Atoi(s) if err != nil { - return packageVersion{}, fmt.Errorf("invalid version %s, part %d is not number: %w", version, i, err) + return Version{}, fmt.Errorf("invalid version %s, part %d is not number: %w", version, i, err) } numbers = append(numbers, num) } @@ -126,13 +127,13 @@ case "": preSuffix = packageVersionPreModifierNone default: - return packageVersion{}, fmt.Errorf("invalid version %s, pre-suffix %s is not valid", version, actuals[6]) + return Version{}, fmt.Errorf("invalid version %s, pre-suffix %s is not valid", version, actuals[6]) } var preSuffixNumber int if actuals[7] != "" { num, err := strconv.Atoi(actuals[7]) if err != nil { - return packageVersion{}, fmt.Errorf("invalid version %s, suffix %s number %s is not number: %w", version, actuals[6], actuals[7], err) + return Version{}, fmt.Errorf("invalid version %s, suffix %s number %s is not number: %w", version, actuals[6], actuals[7], err) } preSuffixNumber = num } @@ -152,13 +153,13 @@ case "": postSuffix = packageVersionPostModifierNone default: - return packageVersion{}, fmt.Errorf("invalid version %s, suffix %s is not valid", version, actuals[9]) + return Version{}, fmt.Errorf("invalid version %s, suffix %s is not valid", version, actuals[9]) } var postSuffixNumber int if actuals[10] != "" { num, err := strconv.Atoi(actuals[10]) if err != nil { - return packageVersion{}, fmt.Errorf("invalid version %s, post-suffix %s number %s is not number: %w", version, actuals[9], actuals[10], err) + return Version{}, fmt.Errorf("invalid version %s, post-suffix %s number %s is not number: %w", version, actuals[9], actuals[10], err) } postSuffixNumber = num } @@ -167,11 +168,11 @@ if actuals[13] != "" { num, err := strconv.Atoi(actuals[13]) if err != nil { - return packageVersion{}, fmt.Errorf("invalid version %s, revision %s is not number: %w", version, actuals[13], err) + return Version{}, fmt.Errorf("invalid version %s, revision %s is not number: %w", version, actuals[13], err) } revision = num } - return packageVersion{ + return Version{ numbers: numbers, letter: letter, preSuffix: preSuffix, @@ -182,29 +183,14 @@ }, nil } -type versionCompare int - const ( - greater versionCompare = 1 - equal versionCompare = 0 - less versionCompare = -1 + greater = 1 + equal = 0 + less = -1 ) -func (vc versionCompare) String() string { - switch vc { - case greater: - return ">" - case equal: - return "=" - case less: - return "<" - default: - return "???" - } -} - -// compare versions based on https://dev.gentoo.org/~ulm/pms/head/pms.html#x1-250003.2 -func compareVersions(actual, required packageVersion) versionCompare { +// CompareVersions compares versions based on https://dev.gentoo.org/~ulm/pms/head/pms.html#x1-250003.2 +func CompareVersions(actual, required Version) int { for i := 0; i < len(actual.numbers) && i < len(required.numbers); i++ { if actual.numbers[i] > required.numbers[i] { return greater @@ -283,7 +269,7 @@ } // includesVersion returns true if the actual version is a strict subset of the required version -func includesVersion(actual, required packageVersion) bool { +func includesVersion(actual, required Version) bool { // if more required numbers than actual numbers, than require is more specific, // so no match if len(actual.numbers) < len(required.numbers) { @@ -340,11 +326,11 @@ versionTilde ) -func (v versionDependency) satisfies(actualVersion, requiredVersion packageVersion) bool { +func (v versionDependency) satisfies(actualVersion, requiredVersion Version) bool { if v == versionTilde { return includesVersion(actualVersion, requiredVersion) } - c := compareVersions(actualVersion, requiredVersion) + c := CompareVersions(actualVersion, requiredVersion) switch v { case versionAny: return true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt --- old/vendor/modules.txt 2024-05-30 10:59:09.000000000 +0200 +++ new/vendor/modules.txt 2024-06-01 11:23:31.000000000 +0200 @@ -46,7 +46,7 @@ # github.com/chainguard-dev/clog v1.3.1 ## explicit; go 1.21.2 github.com/chainguard-dev/clog -# github.com/chainguard-dev/go-apk v0.0.0-20240529154108-3de67a94ddad +# github.com/chainguard-dev/go-apk v0.0.0-20240530214935-2ff9aee8385a ## explicit; go 1.22.3 github.com/chainguard-dev/go-apk/internal/tarfs github.com/chainguard-dev/go-apk/pkg/apk