zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/pkg/common/common.go (about) 1 package common 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "io/fs" 9 "os" 10 "regexp" 11 "strings" 12 "syscall" 13 "time" 14 "unicode/utf8" 15 ) 16 17 const ( 18 httpTimeout = 5 * time.Minute 19 certsPath = "/etc/containers/certs.d" 20 homeCertsDir = ".config/containers/certs.d" 21 clientCertFilename = "client.cert" 22 clientKeyFilename = "client.key" 23 caCertFilename = "ca.crt" 24 25 CosignSignature = "cosign" 26 CosignSigKey = "dev.cosignproject.cosign/signature" 27 NotationSignature = "notation" 28 // same value as github.com/notaryproject/notation-go/registry.ArtifactTypeNotation (assert by internal test). 29 // reason used: to reduce zot minimal binary size (otherwise adds oras.land/oras-go/v2 deps). 30 ArtifactTypeNotation = "application/vnd.cncf.notary.signature" 31 ArtifactTypeCosign = "application/vnd.dev.cosign.artifact.sig.v1+json" 32 ) 33 34 var cosignTagRule = regexp.MustCompile(`sha256\-.+\.sig`) 35 36 func IsCosignTag(tag string) bool { 37 return cosignTagRule.MatchString(tag) 38 } 39 40 func Contains[T comparable](elems []T, v T) bool { 41 for _, s := range elems { 42 if v == s { 43 return true 44 } 45 } 46 47 return false 48 } 49 50 // first match of item in []. 51 func Index(slice []string, item string) int { 52 for k, v := range slice { 53 if item == v { 54 return k 55 } 56 } 57 58 return -1 59 } 60 61 // remove matches of item in []. 62 func RemoveFrom(inputSlice []string, item string) []string { 63 var newSlice []string 64 65 for _, v := range inputSlice { 66 if item != v { 67 newSlice = append(newSlice, v) 68 } 69 } 70 71 return newSlice 72 } 73 74 func TypeOf(v interface{}) string { 75 return fmt.Sprintf("%T", v) 76 } 77 78 func DirExists(d string) bool { 79 if !utf8.ValidString(d) { 80 return false 81 } 82 83 fileInfo, err := os.Stat(d) 84 if err != nil { 85 if e, ok := err.(*fs.PathError); ok && errors.Is(e.Err, syscall.ENAMETOOLONG) || //nolint: errorlint 86 errors.Is(e.Err, syscall.EINVAL) { 87 return false 88 } 89 } 90 91 if err != nil && os.IsNotExist(err) { 92 return false 93 } 94 95 if !fileInfo.IsDir() { 96 return false 97 } 98 99 return true 100 } 101 102 // Used to filter a json fields by using an intermediate struct. 103 func MarshalThroughStruct(obj interface{}, throughStruct interface{}) ([]byte, error) { 104 toJSON, err := json.Marshal(obj) 105 if err != nil { 106 return []byte{}, err 107 } 108 109 err = json.Unmarshal(toJSON, throughStruct) 110 if err != nil { 111 return []byte{}, err 112 } 113 114 toJSON, err = json.Marshal(throughStruct) 115 if err != nil { 116 return []byte{}, err 117 } 118 119 return toJSON, nil 120 } 121 122 func ContainsStringIgnoreCase(strSlice []string, str string) bool { 123 for _, val := range strSlice { 124 if strings.EqualFold(val, str) { 125 return true 126 } 127 } 128 129 return false 130 } 131 132 // this function will check if tag is a referrers tag 133 // (https://github.com/opencontainers/distribution-spec/blob/main/spec.md#referrers-tag-schema). 134 func IsReferrersTag(tag string) bool { 135 referrersTagRule := regexp.MustCompile(`sha256\-[A-Za-z0-9]*$`) 136 137 return referrersTagRule.MatchString(tag) 138 } 139 140 func IsContextDone(ctx context.Context) bool { 141 select { 142 case <-ctx.Done(): 143 return true 144 default: 145 return false 146 } 147 }