Skip to content

Commit

Permalink
Merge pull request crossplane#6257 from cychiang/6235-support-pull-im…
Browse files Browse the repository at this point in the history
…age-from-private-registry-with-podman

feat(render): Add support to read config file for Podman
  • Loading branch information
jbw976 authored Feb 3, 2025
2 parents d8be746 + 0bbed02 commit 8a75274
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 83 deletions.
42 changes: 16 additions & 26 deletions cmd/crank/render/runtime_docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,19 @@ package render

import (
"context"
"encoding/base64"
"fmt"
"io"
"net"
"os"

"github.com/distribution/reference"
"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
typesimage "github.com/docker/docker/api/types/image"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/client"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/registry"
"github.com/docker/go-connections/nat"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"

"github.com/crossplane/crossplane-runtime/pkg/errors"
"github.com/crossplane/crossplane-runtime/pkg/logging"
Expand Down Expand Up @@ -112,12 +109,12 @@ type RuntimeDocker struct {
// Cleanup controls how the containers are handled after rendering.
Cleanup DockerCleanup

// ConfigFile contains information like credentials for each registry, default to ~/.docker/config.json
ConfigFile *configfile.ConfigFile

// PullPolicy controls how the runtime image is pulled.
PullPolicy DockerPullPolicy

// Keychain to use for pulling images from private registry.
Keychain authn.Keychain

// log is the logger for this runtime.
log logging.Logger
}
Expand Down Expand Up @@ -162,15 +159,12 @@ func GetRuntimeDocker(fn pkgv1.Function, log logging.Logger) (*RuntimeDocker, er
return nil, errors.Wrapf(err, "cannot get pull policy for Function %q", fn.GetName())
}

// Initial ConfigFile
configFile := config.LoadDefaultConfigFile(os.Stderr)

r := &RuntimeDocker{
Image: fn.Spec.Package,
Name: "",
Cleanup: cleanup,
ConfigFile: configFile,
PullPolicy: pullPolicy,
Keychain: authn.DefaultKeychain,
log: log,
}

Expand Down Expand Up @@ -301,33 +295,29 @@ func (r *RuntimeDocker) createContainer(ctx context.Context, cli *client.Client)
}

func (r *RuntimeDocker) getPullOptions() (typesimage.PullOptions, error) {
// Resolve auth token by looking into config file
named, err := reference.ParseNormalizedNamed(r.Image)
// Resolve auth token by looking into keychain
ref, err := name.ParseReference(r.Image)
if err != nil {
return typesimage.PullOptions{}, errors.Wrapf(err, "Image is not a valid reference %s", r.Image)
}

repoInfo, err := registry.ParseRepositoryInfo(named)
auth, err := r.Keychain.Resolve(ref.Context().Registry)
if err != nil {
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot parse repository info: %s", named.String())
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot resolve auth for %s", ref.Context().RegistryStr())
}

configKey := repoInfo.Index.Name
if repoInfo.Index.Official {
configKey = registry.IndexServer
}
authConfig, err := r.ConfigFile.GetAuthConfig(configKey)
authConfig, err := auth.Authorization()
if err != nil {
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot get auth config info with configKey: %s", configKey)
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot get auth config for %s", ref.Context().RegistryStr())
}

encodedAuth, err := registrytypes.EncodeAuthConfig(registrytypes.AuthConfig(authConfig))
token, err := authConfig.MarshalJSON()
if err != nil {
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot encode auth config with configKey: %s", configKey)
return typesimage.PullOptions{}, errors.Wrapf(err, "Cannot marshal auth config for %s", ref.Context().RegistryStr())
}

return typesimage.PullOptions{
RegistryAuth: encodedAuth,
RegistryAuth: base64.URLEncoding.EncodeToString(token),
}, nil
}

Expand Down
8 changes: 1 addition & 7 deletions cmd/crank/render/runtime_docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ package render
import (
"context"
"io"
"os"
"testing"

"github.com/docker/cli/cli/config"
"github.com/docker/docker/api/types/image"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
Expand Down Expand Up @@ -78,7 +76,6 @@ func TestGetRuntimeDocker(t *testing.T) {
want: want{
rd: &RuntimeDocker{
Image: "test-image-from-annotation",
ConfigFile: config.LoadDefaultConfigFile(os.Stderr),
Cleanup: AnnotationValueRuntimeDockerCleanupOrphan,
PullPolicy: AnnotationValueRuntimeDockerPullPolicyAlways,
},
Expand All @@ -105,7 +102,6 @@ func TestGetRuntimeDocker(t *testing.T) {
want: want{
rd: &RuntimeDocker{
Image: "test-image-from-annotation",
ConfigFile: config.LoadDefaultConfigFile(os.Stderr),
Cleanup: AnnotationValueRuntimeDockerCleanupOrphan,
Name: "test-container-name-function",
PullPolicy: AnnotationValueRuntimeDockerPullPolicyIfNotPresent,
Expand All @@ -129,7 +125,6 @@ func TestGetRuntimeDocker(t *testing.T) {
want: want{
rd: &RuntimeDocker{
Image: "test-package",
ConfigFile: config.LoadDefaultConfigFile(os.Stderr),
Cleanup: AnnotationValueRuntimeDockerCleanupRemove,
PullPolicy: AnnotationValueRuntimeDockerPullPolicyIfNotPresent,
},
Expand Down Expand Up @@ -194,7 +189,6 @@ func TestGetRuntimeDocker(t *testing.T) {
want: want{
rd: &RuntimeDocker{
Image: "test-package",
ConfigFile: config.LoadDefaultConfigFile(os.Stderr),
Cleanup: AnnotationValueRuntimeDockerCleanupStop,
PullPolicy: AnnotationValueRuntimeDockerPullPolicyIfNotPresent,
},
Expand All @@ -204,7 +198,7 @@ func TestGetRuntimeDocker(t *testing.T) {
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
rd, err := GetRuntimeDocker(tc.args.fn, logging.NewNopLogger())
if diff := cmp.Diff(tc.want.rd, rd, cmpopts.IgnoreUnexported(RuntimeDocker{})); diff != "" {
if diff := cmp.Diff(tc.want.rd, rd, cmpopts.IgnoreUnexported(RuntimeDocker{}), cmpopts.IgnoreFields(RuntimeDocker{}, "Keychain")); diff != "" {
t.Errorf("\n%s\nGetRuntimeDocker(...): -want, +got:\n%s", tc.reason, diff)
}
if diff := cmp.Diff(tc.want.err, err, cmpopts.EquateErrors()); diff != "" {
Expand Down
7 changes: 2 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ require (
github.com/Masterminds/semver v1.5.0
github.com/alecthomas/kong v0.9.0
github.com/crossplane/crossplane-runtime v1.19.0-rc.0.0.20241105071456-19d95a69cc03
github.com/distribution/reference v0.5.0
github.com/docker/docker v27.1.1+incompatible
github.com/docker/go-connections v0.5.0
github.com/emicklei/dot v1.6.2
Expand Down Expand Up @@ -64,8 +63,7 @@ require (
github.com/cyphar/filepath-securejoin v0.2.5 // indirect
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect
github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
Expand All @@ -89,7 +87,6 @@ require (
github.com/google/certificate-transparency-go v1.2.1 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
Expand Down Expand Up @@ -192,7 +189,7 @@ require (
github.com/dave/jennifer v1.6.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/docker/cli v27.4.1+incompatible
github.com/docker/cli v27.4.1+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2
github.com/docker/go-units v0.5.0 // indirect
Expand Down
Loading

0 comments on commit 8a75274

Please sign in to comment.