@@ -391,6 +391,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
391391 }
392392
393393 // Get the upstream revision from the artifact digest
394+ // TODO: getRevision resolves the digest, which may change before image is fetched, so it should probaly update ref
394395 revision , err := r .getRevision (ref , opts )
395396 if err != nil {
396397 e := serror .NewGeneric (
@@ -575,33 +576,30 @@ func (r *OCIRepositoryReconciler) selectLayer(obj *ociv1.OCIRepository, image gc
575576// getRevision fetches the upstream digest, returning the revision in the
576577// format '<tag>@<digest>'.
577578func (r * OCIRepositoryReconciler ) getRevision (ref name.Reference , options []remote.Option ) (string , error ) {
578- repoTag := "" // TODO: can it be obtained from name.Reference directly?
579- repoName := ref .Context ().RepositoryStr ()
580- if s := strings .Split (repoName , ":" ); len (s ) == 2 && ! strings .Contains (repoName , "@" ) {
581- repoTag = s [1 ]
582- }
583-
584- if repoTag == "" && ! strings .Contains (repoName , "@" ) {
585- repoTag = "latest"
586- }
587-
588- var digest v1.Hash
589- desc , err := remote .Head (ref , options ... )
590- if err == nil {
591- digest = desc .Digest
592- } else {
593- rdesc , err := remote .Get (ref , options ... )
579+ switch ref := ref .(type ) {
580+ case name.Digest :
581+ digest , err := v1 .NewHash (ref .DigestStr ())
594582 if err != nil {
595583 return "" , err
596584 }
597- digest = rdesc .Descriptor .Digest
598- }
585+ return digest .String (), nil
586+ case name.Tag :
587+ var digest v1.Hash
599588
600- revision := digest .String ()
601- if repoTag != "" {
602- revision = fmt .Sprintf ("%s@%s" , repoTag , revision )
589+ desc , err := remote .Head (ref , options ... )
590+ if err == nil {
591+ digest = desc .Digest
592+ } else {
593+ rdesc , err := remote .Get (ref , options ... )
594+ if err != nil {
595+ return "" , err
596+ }
597+ digest = rdesc .Descriptor .Digest
598+ }
599+ return fmt .Sprintf ("%s@%s" , ref .TagStr (), digest .String ()), nil
600+ default :
601+ return "" , fmt .Errorf ("unsupported reference type: %T" , ref )
603602 }
604- return revision , nil
605603}
606604
607605// digestFromRevision extracts the digest from the revision string.
@@ -696,53 +694,53 @@ func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *ociv
696694}
697695
698696// parseRepository validates and extracts the repository URL.
699- func (r * OCIRepositoryReconciler ) parseRepository (obj * ociv1. OCIRepository ) (name.Reference , error ) {
700- if ! strings .HasPrefix (obj . Spec . URL , ociv1 .OCIRepositoryPrefix ) {
701- return nil , fmt .Errorf ("URL must be in format 'oci://<domain>/<org>/<repo>'" )
697+ func (r * OCIRepositoryReconciler ) parseRepository (url string ) (name.Repository , error ) {
698+ if ! strings .HasPrefix (url , ociv1 .OCIRepositoryPrefix ) {
699+ return name. Repository {} , fmt .Errorf ("URL must be in format 'oci://<domain>/<org>/<repo>'" )
702700 }
703701
704- url : = strings .TrimPrefix (obj . Spec . URL , ociv1 .OCIRepositoryPrefix )
705- ref , err := name .ParseReference (url )
702+ url = strings .TrimPrefix (url , ociv1 .OCIRepositoryPrefix )
703+ repo , err := name .NewRepository (url )
706704 if err != nil {
707- return nil , err
705+ return name. Repository {} , err
708706 }
709707
710- imageName := strings .TrimPrefix (url , ref . Context () .RegistryStr ())
708+ imageName := strings .TrimPrefix (url , repo .RegistryStr ())
711709 if s := strings .Split (imageName , ":" ); len (s ) > 1 {
712- return nil , fmt .Errorf ("URL must not contain a tag; remove ':%s'" , s [1 ])
710+ return name. Repository {} , fmt .Errorf ("URL must not contain a tag; remove ':%s'" , s [1 ])
713711 }
714712
715- return ref , nil
713+ return repo , nil
716714}
717715
718716// getArtifactRef determines which tag or revision should be used and returns the OCI artifact FQN.
719717func (r * OCIRepositoryReconciler ) getArtifactRef (obj * ociv1.OCIRepository , options []remote.Option ) (name.Reference , error ) {
720- ref , err := r .parseRepository (obj )
718+ repo , err := r .parseRepository (obj . Spec . URL )
721719 if err != nil {
722720 return nil , invalidOCIURLError {err }
723721 }
724722
725723 if obj .Spec .Reference != nil {
726724 if obj .Spec .Reference .Digest != "" {
727- return ref . Context (). Digest (fmt . Sprintf ( "%s@%s" , ref , obj .Spec .Reference .Digest ) ), nil
725+ return repo . Digest (obj .Spec .Reference .Digest ), nil
728726 }
729727
730728 if obj .Spec .Reference .SemVer != "" {
731- return r .getTagBySemver (ref , obj .Spec .Reference .SemVer , options )
729+ return r .getTagBySemver (repo , obj .Spec .Reference .SemVer , options )
732730 }
733731
734732 if obj .Spec .Reference .Tag != "" {
735- return ref . Context () .Tag (obj .Spec .Reference .Tag ), nil
733+ return repo .Tag (obj .Spec .Reference .Tag ), nil
736734 }
737735 }
738736
739- return ref , nil
737+ return repo . Tag ( "latest" ) , nil
740738}
741739
742740// getTagBySemver call the remote container registry, fetches all the tags from the repository,
743741// and returns the latest tag according to the semver expression.
744- func (r * OCIRepositoryReconciler ) getTagBySemver (ref name.Reference , exp string , options []remote.Option ) (name.Reference , error ) {
745- tags , err := remote .List (ref . Context (). Repo () , options ... )
742+ func (r * OCIRepositoryReconciler ) getTagBySemver (repo name.Repository , exp string , options []remote.Option ) (name.Reference , error ) {
743+ tags , err := remote .List (repo , options ... )
746744 if err != nil {
747745 return nil , err
748746 }
@@ -769,7 +767,7 @@ func (r *OCIRepositoryReconciler) getTagBySemver(ref name.Reference, exp string,
769767 }
770768
771769 sort .Sort (sort .Reverse (semver .Collection (matchingVersions )))
772- return ref . Context () .Tag (matchingVersions [0 ].Original ()), nil
770+ return repo .Tag (matchingVersions [0 ].Original ()), nil
773771}
774772
775773// keychain generates the credential keychain based on the resource
0 commit comments