mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-01 00:23:56 +08:00 
			
		
		
		
	build: split buildflags package
Planned to be imported by nerdctl in future. Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
		
							
								
								
									
										81
									
								
								util/buildflags/cache.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								util/buildflags/cache.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| package buildflags | ||||
|  | ||||
| import ( | ||||
| 	"encoding/csv" | ||||
| 	"os" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/moby/buildkit/client" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func ParseCacheEntry(in []string) ([]client.CacheOptionsEntry, error) { | ||||
| 	imports := make([]client.CacheOptionsEntry, 0, len(in)) | ||||
| 	for _, in := range in { | ||||
| 		csvReader := csv.NewReader(strings.NewReader(in)) | ||||
| 		fields, err := csvReader.Read() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if isRefOnlyFormat(fields) { | ||||
| 			for _, field := range fields { | ||||
| 				imports = append(imports, client.CacheOptionsEntry{ | ||||
| 					Type:  "registry", | ||||
| 					Attrs: map[string]string{"ref": field}, | ||||
| 				}) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
| 		im := client.CacheOptionsEntry{ | ||||
| 			Attrs: map[string]string{}, | ||||
| 		} | ||||
| 		for _, field := range fields { | ||||
| 			parts := strings.SplitN(field, "=", 2) | ||||
| 			if len(parts) != 2 { | ||||
| 				return nil, errors.Errorf("invalid value %s", field) | ||||
| 			} | ||||
| 			key := strings.ToLower(parts[0]) | ||||
| 			value := parts[1] | ||||
| 			switch key { | ||||
| 			case "type": | ||||
| 				im.Type = value | ||||
| 			default: | ||||
| 				im.Attrs[key] = value | ||||
| 			} | ||||
| 		} | ||||
| 		if im.Type == "" { | ||||
| 			return nil, errors.Errorf("type required form> %q", in) | ||||
| 		} | ||||
| 		if !addGithubToken(&im) { | ||||
| 			continue | ||||
| 		} | ||||
| 		imports = append(imports, im) | ||||
| 	} | ||||
| 	return imports, nil | ||||
| } | ||||
|  | ||||
| func isRefOnlyFormat(in []string) bool { | ||||
| 	for _, v := range in { | ||||
| 		if strings.Contains(v, "=") { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func addGithubToken(ci *client.CacheOptionsEntry) bool { | ||||
| 	if ci.Type != "gha" { | ||||
| 		return true | ||||
| 	} | ||||
| 	if _, ok := ci.Attrs["token"]; !ok { | ||||
| 		if v, ok := os.LookupEnv("ACTIONS_RUNTIME_TOKEN"); ok { | ||||
| 			ci.Attrs["token"] = v | ||||
| 		} | ||||
| 	} | ||||
| 	if _, ok := ci.Attrs["url"]; !ok { | ||||
| 		if v, ok := os.LookupEnv("ACTIONS_CACHE_URL"); ok { | ||||
| 			ci.Attrs["url"] = v | ||||
| 		} | ||||
| 	} | ||||
| 	return ci.Attrs["token"] != "" && ci.Attrs["url"] != "" | ||||
| } | ||||
							
								
								
									
										21
									
								
								util/buildflags/entitlements.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								util/buildflags/entitlements.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| package buildflags | ||||
|  | ||||
| import ( | ||||
| 	"github.com/moby/buildkit/util/entitlements" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func ParseEntitlements(in []string) ([]entitlements.Entitlement, error) { | ||||
| 	out := make([]entitlements.Entitlement, 0, len(in)) | ||||
| 	for _, v := range in { | ||||
| 		switch v { | ||||
| 		case "security.insecure": | ||||
| 			out = append(out, entitlements.EntitlementSecurityInsecure) | ||||
| 		case "network.host": | ||||
| 			out = append(out, entitlements.EntitlementNetworkHost) | ||||
| 		default: | ||||
| 			return nil, errors.Errorf("invalid entitlement: %v", v) | ||||
| 		} | ||||
| 	} | ||||
| 	return out, nil | ||||
| } | ||||
							
								
								
									
										115
									
								
								util/buildflags/output.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								util/buildflags/output.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| package buildflags | ||||
|  | ||||
| import ( | ||||
| 	"encoding/csv" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/containerd/console" | ||||
| 	"github.com/moby/buildkit/client" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func ParseOutputs(inp []string) ([]client.ExportEntry, error) { | ||||
| 	var outs []client.ExportEntry | ||||
| 	if len(inp) == 0 { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 	for _, s := range inp { | ||||
| 		csvReader := csv.NewReader(strings.NewReader(s)) | ||||
| 		fields, err := csvReader.Read() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		out := client.ExportEntry{ | ||||
| 			Attrs: map[string]string{}, | ||||
| 		} | ||||
| 		if len(fields) == 1 && fields[0] == s && !strings.HasPrefix(s, "type=") { | ||||
| 			if s != "-" { | ||||
| 				outs = append(outs, client.ExportEntry{ | ||||
| 					Type:      client.ExporterLocal, | ||||
| 					OutputDir: s, | ||||
| 				}) | ||||
| 				continue | ||||
| 			} | ||||
| 			out = client.ExportEntry{ | ||||
| 				Type: client.ExporterTar, | ||||
| 				Attrs: map[string]string{ | ||||
| 					"dest": s, | ||||
| 				}, | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if out.Type == "" { | ||||
| 			for _, field := range fields { | ||||
| 				parts := strings.SplitN(field, "=", 2) | ||||
| 				if len(parts) != 2 { | ||||
| 					return nil, errors.Errorf("invalid value %s", field) | ||||
| 				} | ||||
| 				key := strings.TrimSpace(strings.ToLower(parts[0])) | ||||
| 				value := parts[1] | ||||
| 				switch key { | ||||
| 				case "type": | ||||
| 					out.Type = value | ||||
| 				default: | ||||
| 					out.Attrs[key] = value | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if out.Type == "" { | ||||
| 			return nil, errors.Errorf("type is required for output") | ||||
| 		} | ||||
|  | ||||
| 		// handle client side | ||||
| 		switch out.Type { | ||||
| 		case client.ExporterLocal: | ||||
| 			dest, ok := out.Attrs["dest"] | ||||
| 			if !ok { | ||||
| 				return nil, errors.Errorf("dest is required for local output") | ||||
| 			} | ||||
| 			out.OutputDir = dest | ||||
| 			delete(out.Attrs, "dest") | ||||
| 		case client.ExporterOCI, client.ExporterDocker, client.ExporterTar: | ||||
| 			dest, ok := out.Attrs["dest"] | ||||
| 			if !ok { | ||||
| 				if out.Type != client.ExporterDocker { | ||||
| 					dest = "-" | ||||
| 				} | ||||
| 			} | ||||
| 			if dest == "-" { | ||||
| 				if _, err := console.ConsoleFromFile(os.Stdout); err == nil { | ||||
| 					return nil, errors.Errorf("output file is required for %s exporter. refusing to write to console", out.Type) | ||||
| 				} | ||||
| 				out.Output = wrapWriteCloser(os.Stdout) | ||||
| 			} else if dest != "" { | ||||
| 				fi, err := os.Stat(dest) | ||||
| 				if err != nil && !os.IsNotExist(err) { | ||||
| 					return nil, errors.Wrapf(err, "invalid destination file: %s", dest) | ||||
| 				} | ||||
| 				if err == nil && fi.IsDir() { | ||||
| 					return nil, errors.Errorf("destination file %s is a directory", dest) | ||||
| 				} | ||||
| 				f, err := os.Create(dest) | ||||
| 				if err != nil { | ||||
| 					return nil, errors.Errorf("failed to open %s", err) | ||||
| 				} | ||||
| 				out.Output = wrapWriteCloser(f) | ||||
| 			} | ||||
| 			delete(out.Attrs, "dest") | ||||
| 		case "registry": | ||||
| 			out.Type = client.ExporterImage | ||||
| 			out.Attrs["push"] = "true" | ||||
| 		} | ||||
|  | ||||
| 		outs = append(outs, out) | ||||
| 	} | ||||
| 	return outs, nil | ||||
| } | ||||
|  | ||||
| func wrapWriteCloser(wc io.WriteCloser) func(map[string]string) (io.WriteCloser, error) { | ||||
| 	return func(map[string]string) (io.WriteCloser, error) { | ||||
| 		return wc, nil | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										68
									
								
								util/buildflags/secrets.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								util/buildflags/secrets.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| package buildflags | ||||
|  | ||||
| import ( | ||||
| 	"encoding/csv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/moby/buildkit/session" | ||||
| 	"github.com/moby/buildkit/session/secrets/secretsprovider" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func ParseSecretSpecs(sl []string) (session.Attachable, error) { | ||||
| 	fs := make([]secretsprovider.Source, 0, len(sl)) | ||||
| 	for _, v := range sl { | ||||
| 		s, err := parseSecret(v) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		fs = append(fs, *s) | ||||
| 	} | ||||
| 	store, err := secretsprovider.NewStore(fs) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return secretsprovider.NewSecretProvider(store), nil | ||||
| } | ||||
|  | ||||
| func parseSecret(value string) (*secretsprovider.Source, error) { | ||||
| 	csvReader := csv.NewReader(strings.NewReader(value)) | ||||
| 	fields, err := csvReader.Read() | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrap(err, "failed to parse csv secret") | ||||
| 	} | ||||
|  | ||||
| 	fs := secretsprovider.Source{} | ||||
|  | ||||
| 	var typ string | ||||
| 	for _, field := range fields { | ||||
| 		parts := strings.SplitN(field, "=", 2) | ||||
| 		key := strings.ToLower(parts[0]) | ||||
|  | ||||
| 		if len(parts) != 2 { | ||||
| 			return nil, errors.Errorf("invalid field '%s' must be a key=value pair", field) | ||||
| 		} | ||||
|  | ||||
| 		value := parts[1] | ||||
| 		switch key { | ||||
| 		case "type": | ||||
| 			if value != "file" && value != "env" { | ||||
| 				return nil, errors.Errorf("unsupported secret type %q", value) | ||||
| 			} | ||||
| 			typ = value | ||||
| 		case "id": | ||||
| 			fs.ID = value | ||||
| 		case "source", "src": | ||||
| 			fs.FilePath = value | ||||
| 		case "env": | ||||
| 			fs.Env = value | ||||
| 		default: | ||||
| 			return nil, errors.Errorf("unexpected key '%s' in '%s'", key, field) | ||||
| 		} | ||||
| 	} | ||||
| 	if typ == "env" && fs.Env == "" { | ||||
| 		fs.Env = fs.FilePath | ||||
| 		fs.FilePath = "" | ||||
| 	} | ||||
| 	return &fs, nil | ||||
| } | ||||
							
								
								
									
										38
									
								
								util/buildflags/ssh.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								util/buildflags/ssh.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| package buildflags | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/moby/buildkit/session" | ||||
| 	"github.com/moby/buildkit/session/sshforward/sshprovider" | ||||
| 	"github.com/moby/buildkit/util/gitutil" | ||||
| ) | ||||
|  | ||||
| func ParseSSHSpecs(sl []string) (session.Attachable, error) { | ||||
| 	configs := make([]sshprovider.AgentConfig, 0, len(sl)) | ||||
| 	for _, v := range sl { | ||||
| 		c, err := parseSSH(v) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		configs = append(configs, *c) | ||||
| 	} | ||||
| 	return sshprovider.NewSSHAgentProvider(configs) | ||||
| } | ||||
|  | ||||
| func parseSSH(value string) (*sshprovider.AgentConfig, error) { | ||||
| 	parts := strings.SplitN(value, "=", 2) | ||||
| 	cfg := sshprovider.AgentConfig{ | ||||
| 		ID: parts[0], | ||||
| 	} | ||||
| 	if len(parts) > 1 { | ||||
| 		cfg.Paths = strings.Split(parts[1], ",") | ||||
| 	} | ||||
| 	return &cfg, nil | ||||
| } | ||||
|  | ||||
| // IsGitSSH returns true if the given repo URL is accessed over ssh | ||||
| func IsGitSSH(url string) bool { | ||||
| 	_, gitProtocol := gitutil.ParseProtocol(url) | ||||
| 	return gitProtocol == gitutil.SSHProtocol | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Akihiro Suda
					Akihiro Suda