github.com/pdmccormick/importable-docker-buildx@v0.0.0-20240426161518-e47091289030/util/buildflags/cache.go (about) 1 package buildflags 2 3 import ( 4 "context" 5 "encoding/csv" 6 "os" 7 "strings" 8 9 awsconfig "github.com/aws/aws-sdk-go-v2/config" 10 controllerapi "github.com/docker/buildx/controller/pb" 11 "github.com/pkg/errors" 12 ) 13 14 func ParseCacheEntry(in []string) ([]*controllerapi.CacheOptionsEntry, error) { 15 outs := make([]*controllerapi.CacheOptionsEntry, 0, len(in)) 16 for _, in := range in { 17 csvReader := csv.NewReader(strings.NewReader(in)) 18 fields, err := csvReader.Read() 19 if err != nil { 20 return nil, err 21 } 22 if isRefOnlyFormat(fields) { 23 for _, field := range fields { 24 outs = append(outs, &controllerapi.CacheOptionsEntry{ 25 Type: "registry", 26 Attrs: map[string]string{"ref": field}, 27 }) 28 } 29 continue 30 } 31 32 out := controllerapi.CacheOptionsEntry{ 33 Attrs: map[string]string{}, 34 } 35 for _, field := range fields { 36 parts := strings.SplitN(field, "=", 2) 37 if len(parts) != 2 { 38 return nil, errors.Errorf("invalid value %s", field) 39 } 40 key := strings.ToLower(parts[0]) 41 value := parts[1] 42 switch key { 43 case "type": 44 out.Type = value 45 default: 46 out.Attrs[key] = value 47 } 48 } 49 if out.Type == "" { 50 return nil, errors.Errorf("type required form> %q", in) 51 } 52 if !addGithubToken(&out) { 53 continue 54 } 55 addAwsCredentials(&out) 56 outs = append(outs, &out) 57 } 58 return outs, nil 59 } 60 61 func isRefOnlyFormat(in []string) bool { 62 for _, v := range in { 63 if strings.Contains(v, "=") { 64 return false 65 } 66 } 67 return true 68 } 69 70 func addGithubToken(ci *controllerapi.CacheOptionsEntry) bool { 71 if ci.Type != "gha" { 72 return true 73 } 74 if _, ok := ci.Attrs["token"]; !ok { 75 if v, ok := os.LookupEnv("ACTIONS_RUNTIME_TOKEN"); ok { 76 ci.Attrs["token"] = v 77 } 78 } 79 if _, ok := ci.Attrs["url"]; !ok { 80 if v, ok := os.LookupEnv("ACTIONS_CACHE_URL"); ok { 81 ci.Attrs["url"] = v 82 } 83 } 84 return ci.Attrs["token"] != "" && ci.Attrs["url"] != "" 85 } 86 87 func addAwsCredentials(ci *controllerapi.CacheOptionsEntry) { 88 if ci.Type != "s3" { 89 return 90 } 91 _, okAccessKeyID := ci.Attrs["access_key_id"] 92 _, okSecretAccessKey := ci.Attrs["secret_access_key"] 93 // If the user provides access_key_id, secret_access_key, do not override the session token. 94 if okAccessKeyID && okSecretAccessKey { 95 return 96 } 97 ctx := context.TODO() 98 awsConfig, err := awsconfig.LoadDefaultConfig(ctx) 99 if err != nil { 100 return 101 } 102 credentials, err := awsConfig.Credentials.Retrieve(ctx) 103 if err != nil { 104 return 105 } 106 if !okAccessKeyID && credentials.AccessKeyID != "" { 107 ci.Attrs["access_key_id"] = credentials.AccessKeyID 108 } 109 if !okSecretAccessKey && credentials.SecretAccessKey != "" { 110 ci.Attrs["secret_access_key"] = credentials.SecretAccessKey 111 } 112 if _, ok := ci.Attrs["session_token"]; !ok && credentials.SessionToken != "" { 113 ci.Attrs["session_token"] = credentials.SessionToken 114 } 115 }