mirror of
https://github.com/thegeeklab/drone-docker-buildx.git
synced 2024-11-16 01:20:39 +00:00
308 lines
6.8 KiB
Go
308 lines
6.8 KiB
Go
package plugin
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/urfave/cli/v2"
|
|
"golang.org/x/sys/execabs"
|
|
)
|
|
|
|
// helper function to create the docker login command.
|
|
func commandLogin(login Login) *execabs.Cmd {
|
|
if login.Email != "" {
|
|
return commandLoginEmail(login)
|
|
}
|
|
|
|
args := []string{
|
|
"login",
|
|
"-u", login.Username,
|
|
"-p", login.Password,
|
|
login.Registry,
|
|
}
|
|
|
|
return execabs.Command(
|
|
dockerBin, args...,
|
|
)
|
|
}
|
|
|
|
func commandLoginEmail(login Login) *execabs.Cmd {
|
|
args := []string{
|
|
"login",
|
|
"-u", login.Username,
|
|
"-p", login.Password,
|
|
"-e", login.Email,
|
|
login.Registry,
|
|
}
|
|
|
|
return execabs.Command(
|
|
dockerBin, args...,
|
|
)
|
|
}
|
|
|
|
// helper function to create the docker info command.
|
|
func commandVersion() *execabs.Cmd {
|
|
return execabs.Command(dockerBin, "version")
|
|
}
|
|
|
|
// helper function to create the docker info command.
|
|
func commandInfo() *execabs.Cmd {
|
|
return execabs.Command(dockerBin, "info")
|
|
}
|
|
|
|
func commandBuilder(daemon Daemon) *execabs.Cmd {
|
|
args := []string{
|
|
"buildx",
|
|
"create",
|
|
"--use",
|
|
}
|
|
|
|
if daemon.BuildkitConfig != "" {
|
|
args = append(args, "--config", buildkitConfig)
|
|
}
|
|
|
|
return execabs.Command(dockerBin, args...)
|
|
}
|
|
|
|
func commandBuildx() *execabs.Cmd {
|
|
return execabs.Command(dockerBin, "buildx", "ls")
|
|
}
|
|
|
|
// helper function to create the docker build command.
|
|
func commandBuild(build Build, dryrun bool) *execabs.Cmd {
|
|
args := []string{
|
|
"buildx",
|
|
"build",
|
|
"--rm=true",
|
|
"-f", build.Dockerfile,
|
|
}
|
|
|
|
defaultBuildArgs := []string{
|
|
fmt.Sprintf("DOCKER_IMAGE_CREATED=%s", time.Now().Format(time.RFC3339)),
|
|
}
|
|
|
|
args = append(args, build.Context)
|
|
if !dryrun && build.Output == "" && len(build.Tags.Value()) > 0 {
|
|
args = append(args, "--push")
|
|
}
|
|
|
|
if build.Compress {
|
|
args = append(args, "--compress")
|
|
}
|
|
|
|
if build.Pull {
|
|
args = append(args, "--pull=true")
|
|
}
|
|
|
|
if build.NoCache {
|
|
args = append(args, "--no-cache")
|
|
}
|
|
|
|
for _, arg := range build.CacheFrom {
|
|
args = append(args, "--cache-from", arg)
|
|
}
|
|
|
|
if build.CacheTo != "" {
|
|
args = append(args, "--cache-to", build.CacheTo)
|
|
}
|
|
|
|
for _, arg := range build.ArgsEnv.Value() {
|
|
addProxyValue(&build, arg)
|
|
}
|
|
|
|
for _, arg := range append(defaultBuildArgs, build.Args.Value()...) {
|
|
args = append(args, "--build-arg", arg)
|
|
}
|
|
|
|
for _, host := range build.AddHost.Value() {
|
|
args = append(args, "--add-host", host)
|
|
}
|
|
|
|
if build.Target != "" {
|
|
args = append(args, "--target", build.Target)
|
|
}
|
|
|
|
if build.Quiet {
|
|
args = append(args, "--quiet")
|
|
}
|
|
|
|
if build.Output != "" {
|
|
args = append(args, "--output", build.Output)
|
|
}
|
|
|
|
for _, arg := range build.NamedContext.Value() {
|
|
args = append(args, "--build-context", arg)
|
|
}
|
|
|
|
if len(build.Platforms.Value()) > 0 {
|
|
args = append(args, "--platform", strings.Join(build.Platforms.Value(), ","))
|
|
}
|
|
|
|
for _, arg := range build.Tags.Value() {
|
|
args = append(args, "-t", fmt.Sprintf("%s:%s", build.Repo, arg))
|
|
}
|
|
|
|
for _, arg := range build.ExtraTags.Value() {
|
|
args = append(args, "-t", arg)
|
|
}
|
|
|
|
for _, arg := range build.Labels.Value() {
|
|
args = append(args, "--label", arg)
|
|
}
|
|
|
|
if build.Provenance != "" {
|
|
args = append(args, "--provenance", build.Provenance)
|
|
}
|
|
|
|
if build.SBOM != "" {
|
|
args = append(args, "--sbom", build.SBOM)
|
|
}
|
|
|
|
if build.Secret != "" {
|
|
args = append(args, "--secret", build.Secret)
|
|
}
|
|
|
|
for _, secret := range build.SecretEnvs.Value() {
|
|
if arg, err := getSecretStringCmdArg(secret); err == nil {
|
|
args = append(args, "--secret", arg)
|
|
}
|
|
}
|
|
|
|
for _, secret := range build.SecretFiles.Value() {
|
|
if arg, err := getSecretFileCmdArg(secret); err == nil {
|
|
args = append(args, "--secret", arg)
|
|
}
|
|
}
|
|
|
|
return execabs.Command(dockerBin, args...)
|
|
}
|
|
|
|
// helper function to parse string secret key-pair.
|
|
func getSecretStringCmdArg(kvp string) (string, error) {
|
|
return getSecretCmdArg(kvp, false)
|
|
}
|
|
|
|
// helper function to parse file secret key-pair.
|
|
func getSecretFileCmdArg(kvp string) (string, error) {
|
|
return getSecretCmdArg(kvp, true)
|
|
}
|
|
|
|
// helper function to parse secret key-pair.
|
|
func getSecretCmdArg(kvp string, file bool) (string, error) {
|
|
delimIndex := strings.IndexByte(kvp, '=')
|
|
if delimIndex == -1 {
|
|
return "", errors.New("invalid secret")
|
|
}
|
|
|
|
key := kvp[:delimIndex]
|
|
value := kvp[delimIndex+1:]
|
|
|
|
if key == "" || value == "" {
|
|
return "", errors.New("invalid secret")
|
|
}
|
|
|
|
if file {
|
|
return fmt.Sprintf("id=%s,src=%s", key, value), nil
|
|
}
|
|
|
|
return fmt.Sprintf("id=%s,env=%s", key, value), nil
|
|
}
|
|
|
|
// helper function to add proxy values from the environment.
|
|
func addProxyBuildArgs(build *Build) {
|
|
addProxyValue(build, "http_proxy")
|
|
addProxyValue(build, "https_proxy")
|
|
addProxyValue(build, "no_proxy")
|
|
}
|
|
|
|
// helper function to add the upper and lower case version of a proxy value.
|
|
func addProxyValue(build *Build, key string) {
|
|
value := getProxyValue(key)
|
|
|
|
if len(value) > 0 && !hasProxyBuildArg(build, key) {
|
|
build.Args = *cli.NewStringSlice(append(build.Args.Value(), fmt.Sprintf("%s=%s", key, value))...)
|
|
build.Args = *cli.NewStringSlice(append(build.Args.Value(), fmt.Sprintf("%s=%s", strings.ToUpper(key), value))...)
|
|
}
|
|
}
|
|
|
|
// helper function to get a proxy value from the environment.
|
|
//
|
|
// assumes that the upper and lower case versions of are the same.
|
|
func getProxyValue(key string) string {
|
|
value := os.Getenv(key)
|
|
|
|
if len(value) > 0 {
|
|
return value
|
|
}
|
|
|
|
return os.Getenv(strings.ToUpper(key))
|
|
}
|
|
|
|
// helper function that looks to see if a proxy value was set in the build args.
|
|
func hasProxyBuildArg(build *Build, key string) bool {
|
|
keyUpper := strings.ToUpper(key)
|
|
|
|
for _, s := range build.Args.Value() {
|
|
if strings.HasPrefix(s, key) || strings.HasPrefix(s, keyUpper) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// helper function to create the docker daemon command.
|
|
func commandDaemon(daemon Daemon) *execabs.Cmd {
|
|
args := []string{
|
|
"--data-root", daemon.StoragePath,
|
|
"--host=unix:///var/run/docker.sock",
|
|
}
|
|
|
|
if daemon.StorageDriver != "" {
|
|
args = append(args, "-s", daemon.StorageDriver)
|
|
}
|
|
|
|
if daemon.Insecure && daemon.Registry != "" {
|
|
args = append(args, "--insecure-registry", daemon.Registry)
|
|
}
|
|
|
|
if daemon.IPv6 {
|
|
args = append(args, "--ipv6")
|
|
}
|
|
|
|
if len(daemon.Mirror) != 0 {
|
|
args = append(args, "--registry-mirror", daemon.Mirror)
|
|
}
|
|
|
|
if len(daemon.Bip) != 0 {
|
|
args = append(args, "--bip", daemon.Bip)
|
|
}
|
|
|
|
for _, dns := range daemon.DNS.Value() {
|
|
args = append(args, "--dns", dns)
|
|
}
|
|
|
|
for _, dnsSearch := range daemon.DNSSearch.Value() {
|
|
args = append(args, "--dns-search", dnsSearch)
|
|
}
|
|
|
|
if len(daemon.MTU) != 0 {
|
|
args = append(args, "--mtu", daemon.MTU)
|
|
}
|
|
|
|
if daemon.Experimental {
|
|
args = append(args, "--experimental")
|
|
}
|
|
|
|
return execabs.Command(dockerdBin, args...)
|
|
}
|
|
|
|
// trace writes each command to stdout with the command wrapped in an xml
|
|
// tag so that it can be extracted and displayed in the logs.
|
|
func trace(cmd *execabs.Cmd) {
|
|
fmt.Fprintf(os.Stdout, "+ %s\n", strings.Join(cmd.Args, " "))
|
|
}
|