zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/pkg/common/oci.go (about) 1 package common 2 3 import ( 4 "strings" 5 "time" 6 7 "github.com/opencontainers/go-digest" 8 ispec "github.com/opencontainers/image-spec/specs-go/v1" 9 10 zerr "zotregistry.io/zot/errors" 11 ) 12 13 func GetImageDirAndTag(imageName string) (string, string) { 14 var imageDir string 15 16 var imageTag string 17 18 if strings.Contains(imageName, ":") { 19 imageDir, imageTag, _ = strings.Cut(imageName, ":") 20 } else { 21 imageDir = imageName 22 } 23 24 return imageDir, imageTag 25 } 26 27 func GetImageDirAndDigest(imageName string) (string, string) { 28 var imageDir string 29 30 var imageDigest string 31 32 if strings.Contains(imageName, "@") { 33 imageDir, imageDigest, _ = strings.Cut(imageName, "@") 34 } else { 35 imageDir = imageName 36 } 37 38 return imageDir, imageDigest 39 } 40 41 // GetImageDirAndReference returns the repo, digest and isTag. 42 func GetImageDirAndReference(imageName string) (string, string, bool) { 43 if strings.Contains(imageName, "@") { 44 repo, digest := GetImageDirAndDigest(imageName) 45 46 return repo, digest, false 47 } 48 49 repo, tag := GetImageDirAndTag(imageName) 50 51 return repo, tag, true 52 } 53 54 func GetManifestArtifactType(manifestContent ispec.Manifest) string { 55 if manifestContent.ArtifactType != "" { 56 return manifestContent.ArtifactType 57 } 58 59 return manifestContent.Config.MediaType 60 } 61 62 func GetIndexArtifactType(indexContent ispec.Index) string { 63 return indexContent.ArtifactType 64 } 65 66 // GetImageLastUpdated This method will return last updated timestamp. 67 // The Created timestamp is used, but if it is missing, look at the 68 // history field and, if provided, return the timestamp of last entry in history. 69 func GetImageLastUpdated(imageInfo ispec.Image) time.Time { 70 timeStamp := imageInfo.Created 71 72 if timeStamp != nil && !timeStamp.IsZero() { 73 return *timeStamp 74 } 75 76 if len(imageInfo.History) > 0 { 77 timeStamp = imageInfo.History[len(imageInfo.History)-1].Created 78 } 79 80 if timeStamp == nil { 81 timeStamp = &time.Time{} 82 } 83 84 return *timeStamp 85 } 86 87 // GetRepoReference returns the components of a repoName:tag or repoName@digest string. If the format is wrong 88 // an error is returned. 89 // The returned values have the following meaning: 90 // 91 // - string: repo name 92 // 93 // - string: reference (tag or digest) 94 // 95 // - bool: value for the statement: "the reference is a tag" 96 // 97 // - error: error value. 98 func GetRepoReference(repo string) (string, string, bool, error) { 99 repoName, digest, found := strings.Cut(repo, "@") 100 101 if !found { 102 repoName, tag, found := strings.Cut(repo, ":") 103 104 if !found { 105 return "", "", false, zerr.ErrInvalidRepoRefFormat 106 } 107 108 return repoName, tag, true, nil 109 } 110 111 return repoName, digest, false, nil 112 } 113 114 // GetFullImageName returns the formatted string for the given repo/tag or repo/digest. 115 func GetFullImageName(repo, ref string) string { 116 if IsTag(ref) { 117 return repo + ":" + ref 118 } 119 120 return repo + "@" + ref 121 } 122 123 func IsDigest(ref string) bool { 124 _, err := digest.Parse(ref) 125 126 return err == nil 127 } 128 129 func IsTag(ref string) bool { 130 return !IsDigest(ref) 131 } 132 133 func CheckIsCorrectRepoNameFormat(repo string) bool { 134 return !strings.ContainsAny(repo, ":@") 135 }