Use docker.io configured creds in oci Puller (#1861)

Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
This commit is contained in:
Sergio C. Arteaga 2022-03-22 15:17:59 +01:00 committed by GitHub
parent 89b27ee65a
commit 57baef2e29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 13 deletions

View File

@ -72,7 +72,7 @@ func main() {
ImageStore: pg.NewImageStore(cfg, db, hc), ImageStore: pg.NewImageStore(cfg, db, hc),
Authorizer: az, Authorizer: az,
HTTPClient: hc, HTTPClient: hc,
OCIPuller: &oci.Puller{}, OCIPuller: oci.NewPuller(cfg),
ViewsTracker: vt, ViewsTracker: vt,
} }
h, err := handlers.Setup(ctx, cfg, hSvc) h, err := handlers.Setup(ctx, cfg, hSvc)

View File

@ -82,7 +82,7 @@ func main() {
Oe: &repo.OLMOCIExporter{}, Oe: &repo.OLMOCIExporter{},
Ec: ec, Ec: ec,
Hc: hc, Hc: hc,
Op: &oci.Puller{}, Op: oci.NewPuller(cfg),
Is: is, Is: is,
SetupTrackerSource: tracker.SetupSource, SetupTrackerSource: tracker.SetupSource,
} }

View File

@ -15,6 +15,7 @@ import (
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
csremote "github.com/sigstore/cosign/pkg/oci/remote" csremote "github.com/sigstore/cosign/pkg/oci/remote"
"github.com/sigstore/cosign/pkg/types" "github.com/sigstore/cosign/pkg/types"
"github.com/spf13/viper"
"oras.land/oras-go/pkg/content" "oras.land/oras-go/pkg/content"
ctxo "oras.land/oras-go/pkg/context" ctxo "oras.land/oras-go/pkg/context"
"oras.land/oras-go/pkg/oras" "oras.land/oras-go/pkg/oras"
@ -31,18 +32,31 @@ var (
) )
// Puller is a hub.OCIPuller implementation. // Puller is a hub.OCIPuller implementation.
type Puller struct{} type Puller struct {
cfg *viper.Viper
}
// NewPuller creates a new Puller instance.
func NewPuller(cfg *viper.Viper) *Puller {
return &Puller{
cfg: cfg,
}
}
// PullLayer pulls the first layer of the media type provided from the OCI // PullLayer pulls the first layer of the media type provided from the OCI
// artifact at the given reference. // artifact at the given reference.
func (p *Puller) PullLayer( func (p *Puller) PullLayer(
ctx context.Context, ctx context.Context,
ref, imageRef,
mediaType, mediaType,
username, username,
password string, password string,
) (ocispec.Descriptor, []byte, error) { ) (ocispec.Descriptor, []byte, error) {
// Pull layers available at the ref provided // Pull layers available at the ref provided
ref, err := name.ParseReference(imageRef)
if err != nil {
return ocispec.Descriptor{}, nil, err
}
resolverOptions := docker.ResolverOptions{} resolverOptions := docker.ResolverOptions{}
if username != "" || password != "" { if username != "" || password != "" {
resolverOptions.Authorizer = docker.NewDockerAuthorizer( resolverOptions.Authorizer = docker.NewDockerAuthorizer(
@ -50,14 +64,20 @@ func (p *Puller) PullLayer(
return username, password, nil return username, password, nil
}), }),
) )
} else if p.cfg != nil && strings.HasSuffix(ref.Context().Registry.Name(), "docker.io") {
resolverOptions.Authorizer = docker.NewDockerAuthorizer(
docker.WithAuthCreds(func(string) (string, string, error) {
return p.cfg.GetString("creds.dockerUsername"), p.cfg.GetString("creds.dockerPassword"), nil
}),
)
} }
registryStore := content.Registry{Resolver: docker.NewResolver(resolverOptions)} registryStore := content.Registry{Resolver: docker.NewResolver(resolverOptions)}
memoryStore := content.NewMemory() memoryStore := content.NewMemory()
var layers []ocispec.Descriptor var layers []ocispec.Descriptor
_, err := oras.Copy( _, err = oras.Copy(
ctxo.WithLoggerDiscarded(ctx), ctxo.WithLoggerDiscarded(ctx),
registryStore, registryStore,
ref, ref.String(),
memoryStore, memoryStore,
"", "",
oras.WithPullEmptyNameAllowed(), oras.WithPullEmptyNameAllowed(),
@ -84,7 +104,16 @@ func (p *Puller) PullLayer(
} }
// SignatureChecker is a hub.OCISignatureChecker implementation. // SignatureChecker is a hub.OCISignatureChecker implementation.
type SignatureChecker struct{} type SignatureChecker struct {
op hub.OCIPuller
}
// NewSignatureChecker creates a new Puller instance.
func NewSignatureChecker(op hub.OCIPuller) *SignatureChecker {
return &SignatureChecker{
op: op,
}
}
// HasCosignSignature checks if the OCI artifact identified by the reference // HasCosignSignature checks if the OCI artifact identified by the reference
// provided has a cosign (sigstore) signature. // provided has a cosign (sigstore) signature.
@ -105,8 +134,7 @@ func (c *SignatureChecker) HasCosignSignature(
} }
// Check if the OCI artifact exists and contains a signature layer // Check if the OCI artifact exists and contains a signature layer
p := &Puller{} _, _, err = c.op.PullLayer(ctx, signatureRef.String(), types.SimpleSigningMediaType, username, password)
_, _, err = p.PullLayer(ctx, signatureRef.String(), types.SimpleSigningMediaType, username, password)
if err != nil { if err != nil {
if errors.Is(err, ErrArtifactNotFound) || errors.Is(err, ErrLayerNotFound) { if errors.Is(err, ErrArtifactNotFound) || errors.Is(err, ErrLayerNotFound) {
return false, nil return false, nil

View File

@ -120,7 +120,7 @@ func NewManager(
db: db, db: db,
il: &HelmIndexLoader{}, il: &HelmIndexLoader{},
tg: &oci.TagsGetter{}, tg: &oci.TagsGetter{},
op: &oci.Puller{}, op: oci.NewPuller(cfg),
az: az, az: az,
hc: hc, hc: hc,
} }

View File

@ -8,6 +8,7 @@ import (
"testing" "testing"
"github.com/artifacthub/hub/internal/hub" "github.com/artifacthub/hub/internal/hub"
"github.com/artifacthub/hub/internal/oci"
"github.com/artifacthub/hub/internal/repo" "github.com/artifacthub/hub/internal/repo"
"github.com/artifacthub/hub/internal/tests" "github.com/artifacthub/hub/internal/tests"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -235,6 +236,9 @@ func TestSetupSource(t *testing.T) {
i := &hub.TrackerSourceInput{ i := &hub.TrackerSourceInput{
Repository: tc.r, Repository: tc.r,
Svc: &hub.TrackerSourceServices{
Op: &oci.PullerMock{},
},
} }
source := SetupSource(i) source := SetupSource(i)
assert.Equal(t, tc.expectedType, reflect.TypeOf(source).String()) assert.Equal(t, tc.expectedType, reflect.TypeOf(source).String())

View File

@ -91,7 +91,7 @@ func NewTrackerSource(i *hub.TrackerSourceInput, opts ...func(s *TrackerSource))
o(s) o(s)
} }
if s.sc == nil { if s.sc == nil {
s.sc = &oci.SignatureChecker{} s.sc = oci.NewSignatureChecker(i.Svc.Op)
} }
return s return s
} }

View File

@ -102,7 +102,7 @@ func NewTrackerSource(i *hub.TrackerSourceInput, opts ...func(s *TrackerSource))
s.il = &repo.HelmIndexLoader{} s.il = &repo.HelmIndexLoader{}
} }
if s.sc == nil { if s.sc == nil {
s.sc = &oci.SignatureChecker{} s.sc = oci.NewSignatureChecker(i.Svc.Op)
} }
if s.tg == nil { if s.tg == nil {
s.tg = &oci.TagsGetter{} s.tg = &oci.TagsGetter{}
@ -426,7 +426,7 @@ func LoadChartArchive(ctx context.Context, u *url.URL, o *LoadChartArchiveOption
case "oci": case "oci":
op := o.Op op := o.Op
if op == nil { if op == nil {
op = &oci.Puller{} op = oci.NewPuller(nil)
} }
ref := strings.TrimPrefix(u.String(), hub.RepositoryOCIPrefix) ref := strings.TrimPrefix(u.String(), hub.RepositoryOCIPrefix)
_, data, err := op.PullLayer(ctx, ref, ChartContentLayerMediaType, o.Username, o.Password) _, data, err := op.PullLayer(ctx, ref, ChartContentLayerMediaType, o.Username, o.Password)