Skip to content

Commit

Permalink
support imagetagmirrorset
Browse files Browse the repository at this point in the history
Signed-off-by: Qi Wang <qiwan@redhat.com>
  • Loading branch information
QiWang19 committed Feb 7, 2023
1 parent ca125d4 commit c89fc03
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 22 deletions.
4 changes: 4 additions & 0 deletions pkg/dockerregistry/server/client/client.go
Expand Up @@ -72,6 +72,10 @@ func (c *apiClient) ImageDigestMirrorSet() cfgv1.ImageDigestMirrorSetInterface {
return c.config.ImageDigestMirrorSets()
}

func (c *apiClient) ImageTagMirrorSet() cfgv1.ImageTagMirrorSetInterface {
return c.config.ImageTagMirrorSets()
}

func (c *apiClient) Users() UserInterface {
return c.user.Users()
}
Expand Down
1 change: 1 addition & 0 deletions pkg/dockerregistry/server/client/interfaces.go
Expand Up @@ -26,6 +26,7 @@ type UsersInterfacer interface {
type ImageContentSourcePolicyInterfacer interface {
ImageContentSourcePolicy() operatorclientv1alpha1.ImageContentSourcePolicyInterface
ImageDigestMirrorSet() cfgv1.ImageDigestMirrorSetInterface
ImageTagMirrorSet() cfgv1.ImageTagMirrorSetInterface
}

type ImagesInterfacer interface {
Expand Down
4 changes: 2 additions & 2 deletions pkg/dockerregistry/server/client/test.go
Expand Up @@ -23,8 +23,8 @@ func NewFakeRegistryClient(imageclient imageclientv1.ImageV1Interface) RegistryC

func (c *fakeRegistryClient) Client() (Interface, error) {
icsp := operatorfake.NewSimpleClientset().OperatorV1alpha1()
idms := cfgfake.NewSimpleClientset().ConfigV1()
return newAPIClient(nil, nil, c.images, nil, icsp, idms), nil
cfgclient := cfgfake.NewSimpleClientset().ConfigV1()
return newAPIClient(nil, nil, c.images, nil, icsp, cfgclient), nil
}

func NewFakeRegistryAPIClient(kc coreclientv1.CoreV1Interface, imageclient imageclientv1.ImageV1Interface) Interface {
Expand Down
6 changes: 6 additions & 0 deletions pkg/dockerregistry/server/pullthroughblobstore_test.go
Expand Up @@ -37,6 +37,7 @@ import (
func TestPullthroughServeBlob(t *testing.T) {
icsp := operatorfake.NewSimpleClientset().OperatorV1alpha1().ImageContentSourcePolicies()
idms := cfgfake.NewSimpleClientset().ConfigV1().ImageDigestMirrorSets()
itms := cfgfake.NewSimpleClientset().ConfigV1().ImageTagMirrorSets()
ctx := context.Background()
ctx = testutil.WithTestLogger(ctx, t)

Expand Down Expand Up @@ -174,6 +175,7 @@ func TestPullthroughServeBlob(t *testing.T) {
metrics.NewNoopMetrics(),
icsp,
idms,
itms,
)

ptbs := &pullthroughBlobStore{
Expand Down Expand Up @@ -335,6 +337,7 @@ func TestPullthroughServeNotSeekableBlob(t *testing.T) {
func TestPullthroughServeBlobInsecure(t *testing.T) {
icsp := operatorfake.NewSimpleClientset().OperatorV1alpha1().ImageContentSourcePolicies()
idms := cfgfake.NewSimpleClientset().ConfigV1().ImageDigestMirrorSets()
itms := cfgfake.NewSimpleClientset().ConfigV1().ImageTagMirrorSets()
namespace := "user"
repo1 := "app1"
repo2 := "app2"
Expand Down Expand Up @@ -613,6 +616,7 @@ func TestPullthroughServeBlobInsecure(t *testing.T) {
metrics.NewNoopMetrics(),
icsp,
idms,
itms,
)

ptbs := &pullthroughBlobStore{
Expand Down Expand Up @@ -681,6 +685,7 @@ func TestPullthroughServeBlobInsecure(t *testing.T) {
func TestPullthroughMetrics(t *testing.T) {
icsp := operatorfake.NewSimpleClientset().OperatorV1alpha1().ImageContentSourcePolicies()
idms := cfgfake.NewSimpleClientset().ConfigV1().ImageDigestMirrorSets()
itms := cfgfake.NewSimpleClientset().ConfigV1().ImageTagMirrorSets()
ctx := context.Background()
ctx = testutil.WithTestLogger(ctx, t)

Expand Down Expand Up @@ -742,6 +747,7 @@ func TestPullthroughMetrics(t *testing.T) {
metrics.NewMetrics(sink),
icsp,
idms,
itms,
)

ptbs := &pullthroughBlobStore{
Expand Down
3 changes: 2 additions & 1 deletion pkg/dockerregistry/server/pullthroughmanifestservice.go
Expand Up @@ -34,6 +34,7 @@ type pullthroughManifestService struct {
registryAddr string
metrics metrics.Pullthrough
idms cfgv1.ImageDigestMirrorSetInterface
itms cfgv1.ImageTagMirrorSetInterface
icsp operatorv1alpha1.ImageContentSourcePolicyInterface
}

Expand Down Expand Up @@ -131,7 +132,7 @@ func (m *pullthroughManifestService) getRemoteRepositoryClient(ctx context.Conte
dcontext.GetLogger(ctx).Errorf("error getting secrets: %v", err)
}

retriever, impErr := getImportContext(ctx, ref, secrets, m.metrics, m.icsp, m.idms)
retriever, impErr := getImportContext(ctx, ref, secrets, m.metrics, m.icsp, m.idms, m.itms)
if impErr != nil {
return nil, impErr
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/dockerregistry/server/pullthroughmanifestservice_test.go
Expand Up @@ -57,6 +57,7 @@ func createTestRegistryServer(t *testing.T, ctx context.Context) *httptest.Serve
func TestPullthroughManifests(t *testing.T) {
icsp := operatorfake.NewSimpleClientset().OperatorV1alpha1().ImageContentSourcePolicies()
idms := cfgfake.NewSimpleClientset().ConfigV1().ImageDigestMirrorSets()
itms := cfgfake.NewSimpleClientset().ConfigV1().ImageTagMirrorSets()
namespace := "fuser"
repo := "zapp"
repoName := fmt.Sprintf("%s/%s", namespace, repo)
Expand Down Expand Up @@ -191,6 +192,7 @@ func TestPullthroughManifests(t *testing.T) {
registryAddr: "localhost:5000",
metrics: metrics.NewNoopMetrics(),
idms: idms,
itms: itms,
icsp: icsp,
}

Expand Down Expand Up @@ -232,6 +234,7 @@ func TestPullthroughManifests(t *testing.T) {
func TestPullthroughManifestInsecure(t *testing.T) {
icsp := operatorfake.NewSimpleClientset().OperatorV1alpha1().ImageContentSourcePolicies()
idms := cfgfake.NewSimpleClientset().ConfigV1().ImageDigestMirrorSets()
itms := cfgfake.NewSimpleClientset().ConfigV1().ImageTagMirrorSets()
namespace := "fuser"
repo := "zapp"
repoName := fmt.Sprintf("%s/%s", namespace, repo)
Expand Down Expand Up @@ -436,6 +439,7 @@ func TestPullthroughManifestInsecure(t *testing.T) {
cache: cache,
metrics: metrics.NewNoopMetrics(),
idms: idms,
itms: itms,
icsp: icsp,
}

Expand Down Expand Up @@ -479,6 +483,7 @@ func TestPullthroughManifestInsecure(t *testing.T) {
func TestPullthroughManifestDockerReference(t *testing.T) {
icsp := operatorfake.NewSimpleClientset().OperatorV1alpha1().ImageContentSourcePolicies()
idms := cfgfake.NewSimpleClientset().ConfigV1().ImageDigestMirrorSets()
itms := cfgfake.NewSimpleClientset().ConfigV1().ImageTagMirrorSets()
namespace := "user"
repo1 := "repo1"
repo2 := "repo2"
Expand Down Expand Up @@ -579,6 +584,7 @@ func TestPullthroughManifestDockerReference(t *testing.T) {
imageStream: imageStream,
metrics: metrics.NewNoopMetrics(),
idms: idms,
itms: itms,
icsp: icsp,
}

Expand Down Expand Up @@ -676,6 +682,7 @@ func (ms *putWaiterManifestService) Put(ctx context.Context, manifest distributi
func TestPullthroughManifestMirroring(t *testing.T) {
icsp := operatorfake.NewSimpleClientset().OperatorV1alpha1().ImageContentSourcePolicies()
idms := cfgfake.NewSimpleClientset().ConfigV1().ImageDigestMirrorSets()
itms := cfgfake.NewSimpleClientset().ConfigV1().ImageTagMirrorSets()
const timeout = 5 * time.Second

namespace := "myproject"
Expand Down Expand Up @@ -741,6 +748,7 @@ func TestPullthroughManifestMirroring(t *testing.T) {
mirror: true,
metrics: metrics.NewNoopMetrics(),
idms: idms,
itms: itms,
icsp: icsp,
}

Expand All @@ -759,6 +767,7 @@ func TestPullthroughManifestMirroring(t *testing.T) {
func TestPullthroughManifestMetrics(t *testing.T) {
icsp := operatorfake.NewSimpleClientset().OperatorV1alpha1().ImageContentSourcePolicies()
idms := cfgfake.NewSimpleClientset().ConfigV1().ImageDigestMirrorSets()
itms := cfgfake.NewSimpleClientset().ConfigV1().ImageTagMirrorSets()
namespace := "myproject"
repo := "myapp"
repoName := fmt.Sprintf("%s/%s", namespace, repo)
Expand Down Expand Up @@ -821,6 +830,7 @@ func TestPullthroughManifestMetrics(t *testing.T) {
imageStream: imageStream,
metrics: metrics.NewMetrics(sink),
idms: idms,
itms: itms,
icsp: icsp,
}

Expand Down
7 changes: 5 additions & 2 deletions pkg/dockerregistry/server/remoteblobgetter.go
Expand Up @@ -74,6 +74,7 @@ type remoteBlobGetterService struct {
metrics metrics.Pullthrough
icsp operatorv1alpha1.ImageContentSourcePolicyInterface
idms cfgv1.ImageDigestMirrorSetInterface
itms cfgv1.ImageTagMirrorSetInterface
}

var _ BlobGetterService = &remoteBlobGetterService{}
Expand All @@ -87,6 +88,7 @@ func NewBlobGetterService(
m metrics.Pullthrough,
icsp operatorv1alpha1.ImageContentSourcePolicyInterface,
idms cfgv1.ImageDigestMirrorSetInterface,
itms cfgv1.ImageTagMirrorSetInterface,
) BlobGetterService {
return &remoteBlobGetterService{
imageStream: imageStream,
Expand All @@ -96,6 +98,7 @@ func NewBlobGetterService(
metrics: m,
icsp: icsp,
idms: idms,
itms: itms,
}
}

Expand Down Expand Up @@ -299,7 +302,7 @@ func (rbgs *remoteBlobGetterService) findCandidateRepository(
continue
}

retriever, impErr := getImportContext(ctx, spec.DockerImageReference, secrets, rbgs.metrics, rbgs.icsp, rbgs.idms)
retriever, impErr := getImportContext(ctx, spec.DockerImageReference, secrets, rbgs.metrics, rbgs.icsp, rbgs.idms, rbgs.itms)
if impErr != nil {
return distribution.Descriptor{}, nil, impErr
}
Expand All @@ -321,7 +324,7 @@ func (rbgs *remoteBlobGetterService) findCandidateRepository(
continue
}

retriever, impErr := getImportContext(ctx, spec.DockerImageReference, secrets, rbgs.metrics, rbgs.icsp, rbgs.idms)
retriever, impErr := getImportContext(ctx, spec.DockerImageReference, secrets, rbgs.metrics, rbgs.icsp, rbgs.idms, rbgs.itms)
if impErr != nil {
return distribution.Descriptor{}, nil, impErr
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/dockerregistry/server/repository.go
Expand Up @@ -49,6 +49,7 @@ type repository struct {
imageStream imagestream.ImageStream
icsp operatorv1alpha1.ImageContentSourcePolicyInterface
idms cfgv1.ImageDigestMirrorSetInterface
itms cfgv1.ImageTagMirrorSetInterface

// remoteBlobGetter is used to fetch blobs from remote registries if pullthrough is enabled.
remoteBlobGetter BlobGetterService
Expand Down Expand Up @@ -78,6 +79,7 @@ func (app *App) Repository(ctx context.Context, repo distribution.Repository, cr
cache: cache.NewRepositoryDigest(app.cache),
icsp: registryOSClient.ImageContentSourcePolicy(),
idms: registryOSClient.ImageDigestMirrorSet(),
itms: registryOSClient.ImageTagMirrorSet(),
}

r.remoteBlobGetter = NewBlobGetterService(
Expand All @@ -87,6 +89,7 @@ func (app *App) Repository(ctx context.Context, repo distribution.Repository, cr
r.app.metrics,
r.icsp,
r.idms,
r.itms,
)

repo = distribution.Repository(r)
Expand Down Expand Up @@ -128,6 +131,7 @@ func (r *repository) Manifests(ctx context.Context, options ...distribution.Mani
metrics: r.app.metrics,
idms: r.idms,
icsp: r.icsp,
itms: r.itms,
}

ms = newPendingErrorsManifestService(ms, r)
Expand Down
49 changes: 37 additions & 12 deletions pkg/dockerregistry/server/simplelookupicsp.go
Expand Up @@ -17,28 +17,31 @@ import (
"github.com/openshift/library-go/pkg/image/registryclient"
)

// simpleLookupICSP holds ImageContentSourcePolicy variables to look up image sources. Satisfies
// simpleLookupImageMirrorSets holds ImageContentSourcePolicy, ImageDigestMirrorSet, and ImageTagMirrorSet variables to look up image sources. Satisfies
// *Context AlternativeBlobSourceStrategy interface.
type simpleLookupICSP struct {
type simpleLookupImageMirrorSets struct {
icspClient operatorv1alpha1client.ImageContentSourcePolicyInterface
idmsClient cfgv1client.ImageDigestMirrorSetInterface
itmsClient cfgv1client.ImageTagMirrorSetInterface
}

// NewSimpleLookupICSPStrategy returns a new entity of simpleLookupICSP using provided client
// to obtain cluster wide ICSP or IDMS configuration.
func NewSimpleLookupICSPStrategy(
// NewSimpleLookupImageMirrorSetsStrategy returns a new entity of simpleLookupImageMirrorSets using provided client
// to obtain cluster wide ICSP or IDMS and ITMS configuration.
func NewSimpleLookupImageMirrorSetsStrategy(
icspcli operatorv1alpha1client.ImageContentSourcePolicyInterface,
idmscli cfgv1client.ImageDigestMirrorSetInterface,
itmscli cfgv1client.ImageTagMirrorSetInterface,
) registryclient.AlternateBlobSourceStrategy {
return &simpleLookupICSP{
return &simpleLookupImageMirrorSets{
icspClient: icspcli,
idmsClient: idmscli,
itmsClient: itmscli,
}
}

// FirstRequest returns a list of sources to use when searching for a given repository. Returns
// the whole list of mirrors followed by the original image reference.
func (s *simpleLookupICSP) FirstRequest(
func (s *simpleLookupImageMirrorSets) FirstRequest(
ctx context.Context, ref reference.DockerImageReference,
) ([]reference.DockerImageReference, error) {
klog.V(5).Infof("reading ICSP from cluster")
Expand All @@ -54,12 +57,23 @@ func (s *simpleLookupICSP) FirstRequest(
return []reference.DockerImageReference{ref.AsRepository()}, nil
}

itmsList, err := s.itmsClient.List(ctx, metav1.ListOptions{})
if err != nil {
klog.Errorf("unable to list ITMS config: %s", err)
return []reference.DockerImageReference{ref.AsRepository()}, nil
}

if len(icspList.Items) > 0 && len(idmsList.Items) > 0 {
err := fmt.Errorf("found both ICSP and IDMS resources, but only one or the other is supported")
return []reference.DockerImageReference{ref.AsRepository()}, err
}

imageRefList, err := s.alternativeImageSources(ref, icspList.Items, idmsList.Items)
if len(icspList.Items) > 0 && len(itmsList.Items) > 0 {
err := fmt.Errorf("found both ICSP and ITMS resources, but only one or the other is supported")
return []reference.DockerImageReference{ref.AsRepository()}, err
}

imageRefList, err := s.alternativeImageSources(ref, icspList.Items, idmsList.Items, itmsList.Items)
if err != nil {
klog.Errorf("error looking for alternate repositories: %s", err)
return []reference.DockerImageReference{ref.AsRepository()}, nil
Expand All @@ -69,7 +83,7 @@ func (s *simpleLookupICSP) FirstRequest(
return imageRefList, nil
}

func (s *simpleLookupICSP) OnFailure(
func (s *simpleLookupImageMirrorSets) OnFailure(
ctx context.Context, ref reference.DockerImageReference,
) ([]reference.DockerImageReference, error) {
return nil, nil
Expand All @@ -91,10 +105,10 @@ type mirrorSource struct {
}

// alternativeImageSources returns unique list of DockerImageReference objects from list of
// ImageContentSourcePolicy or ImageDigestMirrorSet objects
func (s *simpleLookupICSP) alternativeImageSources(
// ImageContentSourcePolicy or ImageDigestMirrorSet, ImageTagMirrorSet objects
func (s *simpleLookupImageMirrorSets) alternativeImageSources(
ref reference.DockerImageReference, icspList []operatorv1alpha1.ImageContentSourcePolicy,
idmsList []cfgv1.ImageDigestMirrorSet,
idmsList []cfgv1.ImageDigestMirrorSet, itmsList []cfgv1.ImageTagMirrorSet,
) ([]reference.DockerImageReference, error) {
repo := ref.AsRepository().Exact()

Expand All @@ -118,6 +132,17 @@ func (s *simpleLookupICSP) alternativeImageSources(
}
}

for _, itms := range itmsList {
s := mirrorSource{}
for _, itm := range itms.Spec.ImageTagMirrors {
s.source = itm.Source
for _, m := range itm.Mirrors {
s.mirrors = append(s.mirrors, string(m))
}
mirrorSources = append(mirrorSources, s)
}
}

imageSources := []reference.DockerImageReference{}
uniqueMirrors := map[reference.DockerImageReference]bool{}

Expand Down

0 comments on commit c89fc03

Please sign in to comment.