diff --git a/Makefile b/Makefile index 63f9ae7..bfc4395 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,6 @@ GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(G XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest GOTESTSUM_PACKAGE ?= gotest.tools/gotestsum@latest -GENERATE ?= XGO_VERSION := go-1.22.x XGO_TARGETS ?= linux/amd64,linux/arm64 @@ -65,11 +64,7 @@ lint: golangci-lint .PHONY: generate generate: - $(GO) generate $(GENERATE) - -.PHONY: generate-docs -generate-docs: - $(GO) generate ./cmd/$(EXECUTABLE)/flags.go + $(GO) generate $(PACKAGES) .PHONY: test test: diff --git a/cmd/wp-docker-buildx/docs.go b/cmd/wp-docker-buildx/docs.go deleted file mode 100644 index 631e502..0000000 --- a/cmd/wp-docker-buildx/docs.go +++ /dev/null @@ -1,58 +0,0 @@ -//go:build generate -// +build generate - -package main - -import ( - "bytes" - "embed" - "fmt" - "os" - "text/template" - - "github.com/thegeeklab/wp-docker-buildx/plugin" - "github.com/thegeeklab/wp-plugin-go/docs" - wp "github.com/thegeeklab/wp-plugin-go/plugin" - wp_template "github.com/thegeeklab/wp-plugin-go/template" - "github.com/urfave/cli/v2" -) - -//go:embed templates/docs-data.yaml.tmpl -var yamlTemplate embed.FS - -func main() { - settings := &plugin.Settings{} - app := &cli.App{ - Flags: settingsFlags(settings, wp.FlagsPluginCategory), - } - - out, err := toYAML(app) - if err != nil { - panic(err) - } - - fi, err := os.Create("../../docs/data/data-raw.yaml") - if err != nil { - panic(err) - } - defer fi.Close() - if _, err := fi.WriteString(out); err != nil { - panic(err) - } -} - -func toYAML(app *cli.App) (string, error) { - var w bytes.Buffer - - yamlTmpl, err := template.New("docs").Funcs(wp_template.LoadFuncMap()).ParseFS(yamlTemplate, "templates/docs-data.yaml.tmpl") - if err != nil { - fmt.Println(yamlTmpl) - return "", err - } - - if err := yamlTmpl.ExecuteTemplate(&w, "docs-data.yaml.tmpl", docs.GetTemplateData(app)); err != nil { - return "", err - } - - return w.String(), nil -} diff --git a/cmd/wp-docker-buildx/flags.go b/cmd/wp-docker-buildx/flags.go deleted file mode 100644 index a07fc32..0000000 --- a/cmd/wp-docker-buildx/flags.go +++ /dev/null @@ -1,345 +0,0 @@ -package main - -import ( - "github.com/thegeeklab/wp-docker-buildx/plugin" - "github.com/thegeeklab/wp-plugin-go/types" - "github.com/urfave/cli/v2" -) - -// settingsFlags has the cli.Flags for the plugin.Settings. -// -//nolint:maintidx -//go:generate go run docs.go flags.go -func settingsFlags(settings *plugin.Settings, category string) []cli.Flag { - return []cli.Flag{ - &cli.BoolFlag{ - Name: "dry-run", - EnvVars: []string{"PLUGIN_DRY_RUN"}, - Usage: "disable docker push", - Destination: &settings.Dryrun, - Category: category, - }, - &cli.StringFlag{ - Name: "daemon.mirror", - EnvVars: []string{"PLUGIN_MIRROR", "DOCKER_PLUGIN_MIRROR"}, - Usage: "registry mirror to pull images", - Destination: &settings.Daemon.Mirror, - DefaultText: "$DOCKER_PLUGIN_MIRROR", - Category: category, - }, - &cli.StringFlag{ - Name: "daemon.storage-driver", - EnvVars: []string{"PLUGIN_STORAGE_DRIVER"}, - Usage: "docker daemon storage driver", - Destination: &settings.Daemon.StorageDriver, - Category: category, - }, - &cli.StringFlag{ - Name: "daemon.storage-path", - EnvVars: []string{"PLUGIN_STORAGE_PATH"}, - Usage: "docker daemon storage path", - Value: "/var/lib/docker", - Destination: &settings.Daemon.StoragePath, - Category: category, - }, - &cli.StringFlag{ - Name: "daemon.bip", - EnvVars: []string{"PLUGIN_BIP"}, - Usage: "allow the docker daemon to bride IP address", - Destination: &settings.Daemon.Bip, - Category: category, - }, - &cli.StringFlag{ - Name: "daemon.mtu", - EnvVars: []string{"PLUGIN_MTU"}, - Usage: "docker daemon custom MTU setting", - Destination: &settings.Daemon.MTU, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "daemon.dns", - EnvVars: []string{"PLUGIN_CUSTOM_DNS"}, - Usage: "custom docker daemon DNS server", - Destination: &settings.Daemon.DNS, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "daemon.dns-search", - EnvVars: []string{"PLUGIN_CUSTOM_DNS_SEARCH"}, - Usage: "custom docker daemon DNS search domain", - Destination: &settings.Daemon.DNSSearch, - Category: category, - }, - &cli.BoolFlag{ - Name: "daemon.insecure", - EnvVars: []string{"PLUGIN_INSECURE"}, - Usage: "allow the docker daemon to use insecure registries", - Value: false, - Destination: &settings.Daemon.Insecure, - Category: category, - }, - &cli.BoolFlag{ - Name: "daemon.ipv6", - EnvVars: []string{"PLUGIN_IPV6"}, - Usage: "enable docker daemon IPv6 support", - Value: false, - Destination: &settings.Daemon.IPv6, - Category: category, - }, - &cli.BoolFlag{ - Name: "daemon.experimental", - EnvVars: []string{"PLUGIN_EXPERIMENTAL"}, - Usage: "enable docker daemon experimental mode", - Value: false, - Destination: &settings.Daemon.Experimental, - Category: category, - }, - &cli.BoolFlag{ - Name: "daemon.debug", - EnvVars: []string{"PLUGIN_DEBUG"}, - Usage: "enable verbose debug mode for the docker daemon", - Value: false, - Destination: &settings.Daemon.Debug, - Category: category, - }, - &cli.BoolFlag{ - Name: "daemon.off", - EnvVars: []string{"PLUGIN_DAEMON_OFF"}, - Usage: "disable the startup of the docker daemon", - Value: false, - Destination: &settings.Daemon.Disabled, - Category: category, - }, - &cli.StringFlag{ - Name: "daemon.buildkit-config", - EnvVars: []string{"PLUGIN_BUILDKIT_CONFIG"}, - Usage: "content of the docker buildkit toml config", - Destination: &settings.Daemon.BuildkitConfig, - Category: category, - }, - &cli.StringFlag{ - Name: "daemon.max-concurrent-uploads", - EnvVars: []string{"PLUGIN_MAX_CONCURRENT_UPLOADS"}, - Usage: "max concurrent uploads for each push", - Destination: &settings.Daemon.MaxConcurrentUploads, - Category: category, - }, - &cli.StringFlag{ - Name: "containerfile", - EnvVars: []string{"PLUGIN_CONTAINERFILE"}, - Usage: "containerfile to use for the image build", - Value: "Containerfile", - Destination: &settings.Build.Containerfile, - Category: category, - }, - &cli.StringFlag{ - Name: "context", - EnvVars: []string{"PLUGIN_CONTEXT"}, - Usage: "path of the build context", - Value: ".", - Destination: &settings.Build.Context, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "named-context", - EnvVars: []string{"PLUGIN_NAMED_CONTEXT"}, - Usage: "additional named build context", - Destination: &settings.Build.NamedContext, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "tags", - EnvVars: []string{"PLUGIN_TAGS", "PLUGIN_TAG"}, - Usage: "repository tags to use for the image", - FilePath: ".tags", - Destination: &settings.Build.Tags, - Category: category, - }, - &cli.BoolFlag{ - Name: "tags.auto", - EnvVars: []string{"PLUGIN_AUTO_TAG", "PLUGIN_DEFAULT_TAGS"}, - Usage: "generate tag names automatically based on git branch and git tag", - Value: false, - Destination: &settings.Build.TagsAuto, - Category: category, - }, - &cli.StringFlag{ - Name: "tags.suffix", - EnvVars: []string{"PLUGIN_AUTO_TAG_SUFFIX", "PLUGIN_DEFAULT_SUFFIX"}, - Usage: "generate tag names with the given suffix", - Destination: &settings.Build.TagsSuffix, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "extra.tags", - EnvVars: []string{"PLUGIN_EXTRA_TAGS"}, - Usage: "additional tags to use for the image including registry", - FilePath: ".extratags", - Destination: &settings.Build.ExtraTags, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "args", - EnvVars: []string{"PLUGIN_BUILD_ARGS"}, - Usage: "custom build arguments for the build", - Destination: &settings.Build.Args, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "args-from-env", - EnvVars: []string{"PLUGIN_BUILD_ARGS_FROM_ENV"}, - Usage: "forward environment variables as custom arguments to the build", - Destination: &settings.Build.ArgsEnv, - Category: category, - }, - &cli.BoolFlag{ - Name: "quiet", - EnvVars: []string{"PLUGIN_QUIET"}, - Usage: "enable suppression of the build output", - Value: false, - Destination: &settings.Build.Quiet, - Category: category, - }, - &cli.StringFlag{ - Name: "output", - EnvVars: []string{"PLUGIN_OUTPUT"}, - Usage: "export action for the build result", - Destination: &settings.Build.Output, - Category: category, - }, - &cli.StringFlag{ - Name: "target", - EnvVars: []string{"PLUGIN_TARGET"}, - Usage: "build target to use", - Destination: &settings.Build.Target, - Category: category, - }, - &cli.GenericFlag{ - Name: "cache-from", - EnvVars: []string{"PLUGIN_CACHE_FROM"}, - Usage: "images to consider as cache sources", - Value: &types.StringSliceFlag{}, - Category: category, - }, - &cli.StringFlag{ - Name: "cache-to", - EnvVars: []string{"PLUGIN_CACHE_TO"}, - Usage: "cache destination for the build cache", - Destination: &settings.Build.CacheTo, - Category: category, - }, - &cli.BoolFlag{ - Name: "pull-image", - EnvVars: []string{"PLUGIN_PULL_IMAGE"}, - Usage: "enforce to pull base image at build time", - Value: true, - Destination: &settings.Build.Pull, - Category: category, - }, - &cli.BoolFlag{ - Name: "compress", - EnvVars: []string{"PLUGIN_COMPRESS"}, - Usage: "enable compression of the build context using gzip", - Value: false, - Destination: &settings.Build.Compress, - Category: category, - }, - &cli.StringFlag{ - Name: "repo", - EnvVars: []string{"PLUGIN_REPO"}, - Usage: "repository name for the image", - Destination: &settings.Build.Repo, - Category: category, - }, - &cli.StringFlag{ - Name: "docker.registry", - EnvVars: []string{"PLUGIN_REGISTRY", "DOCKER_REGISTRY"}, - Usage: "docker registry to authenticate with", - Value: "https://index.docker.io/v1/", - Destination: &settings.Login.Registry, - Category: category, - }, - &cli.StringFlag{ - Name: "docker.username", - EnvVars: []string{"PLUGIN_USERNAME", "DOCKER_USERNAME"}, - Usage: "username for registry authentication", - Destination: &settings.Login.Username, - DefaultText: "$DOCKER_USERNAME", - Category: category, - }, - &cli.StringFlag{ - Name: "docker.password", - EnvVars: []string{"PLUGIN_PASSWORD", "DOCKER_PASSWORD"}, - Usage: "password for registry authentication", - Destination: &settings.Login.Password, - DefaultText: "$DOCKER_PASSWORD", - Category: category, - }, - &cli.StringFlag{ - Name: "docker.email", - EnvVars: []string{"PLUGIN_EMAIL", "DOCKER_EMAIL"}, - Usage: "email address for registry authentication", - Destination: &settings.Login.Email, - DefaultText: "$DOCKER_EMAIL", - Category: category, - }, - &cli.StringFlag{ - Name: "docker.config", - EnvVars: []string{"PLUGIN_CONFIG", "DOCKER_PLUGIN_CONFIG"}, - Usage: "content of the docker daemon json config", - Destination: &settings.Login.Config, - DefaultText: "$DOCKER_PLUGIN_CONFIG", - Category: category, - }, - &cli.BoolFlag{ - Name: "no-cache", - EnvVars: []string{"PLUGIN_NO_CACHE"}, - Usage: "disable the usage of cached intermediate containers", - Value: false, - Destination: &settings.Build.NoCache, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "add-host", - EnvVars: []string{"PLUGIN_ADD_HOST"}, - Usage: "additional `host:ip` mapping", - Destination: &settings.Build.AddHost, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "platforms", - EnvVars: []string{"PLUGIN_PLATFORMS"}, - Usage: "target platform for build", - Destination: &settings.Build.Platforms, - Category: category, - }, - &cli.StringSliceFlag{ - Name: "labels", - EnvVars: []string{"PLUGIN_LABELS"}, - Usage: "labels to add to image", - Destination: &settings.Build.Labels, - Category: category, - }, - &cli.StringFlag{ - Name: "provenance", - EnvVars: []string{"PLUGIN_PROVENANCE"}, - Usage: "generates provenance attestation for the build", - Destination: &settings.Build.Provenance, - Category: category, - }, - &cli.StringFlag{ - Name: "sbom", - EnvVars: []string{"PLUGIN_SBOM"}, - Usage: "generates SBOM attestation for the build", - Destination: &settings.Build.SBOM, - Category: category, - }, - &cli.GenericFlag{ - Name: "secrets", - EnvVars: []string{"PLUGIN_SECRETS"}, - Usage: "exposes secrets to the build", - Value: &types.StringSliceFlag{}, - Category: category, - }, - } -} diff --git a/cmd/wp-docker-buildx/main.go b/cmd/wp-docker-buildx/main.go index 144372a..5b732a3 100644 --- a/cmd/wp-docker-buildx/main.go +++ b/cmd/wp-docker-buildx/main.go @@ -1,11 +1,7 @@ package main import ( - "fmt" - "github.com/thegeeklab/wp-docker-buildx/plugin" - - wp "github.com/thegeeklab/wp-plugin-go/plugin" ) //nolint:gochecknoglobals @@ -15,14 +11,5 @@ var ( ) func main() { - settings := &plugin.Settings{} - options := wp.Options{ - Name: "wp-docker-buildx", - Description: "Build multiarch OCI images with buildx", - Version: BuildVersion, - VersionMetadata: fmt.Sprintf("date=%s", BuildDate), - Flags: settingsFlags(settings, wp.FlagsPluginCategory), - } - - plugin.New(options, settings).Run() + plugin.New(nil, BuildVersion, BuildDate).Run() } diff --git a/cmd/wp-docker-buildx/templates/docs-data.yaml.tmpl b/cmd/wp-docker-buildx/templates/docs-data.yaml.tmpl deleted file mode 100644 index e453a95..0000000 --- a/cmd/wp-docker-buildx/templates/docs-data.yaml.tmpl +++ /dev/null @@ -1,18 +0,0 @@ ---- -{{- if .GlobalArgs }} -properties: -{{- range $v := .GlobalArgs }} - - name: {{ $v.Name }} - {{- with $v.Description }} - description: | - {{ . | ToSentence }} - {{- end }} - {{- with $v.Type }} - type: {{ . }} - {{- end }} - {{- with $v.Default }} - defaultValue: {{ . }} - {{- end }} - required: {{ default false $v.Required }} -{{ end -}} -{{ end -}} diff --git a/docs/content/_index.md b/docs/content/_index.md index 1e1172d..002afea 100644 --- a/docs/content/_index.md +++ b/docs/content/_index.md @@ -104,7 +104,7 @@ docker run --rm \ -e PLUGIN_TAG=latest \ -e PLUGIN_REPO=octocat/hello-world \ -e CI_COMMIT_SHA=00000000 \ - -v $(pwd):/build:z \ + -v $(pwd)/testdata:/build:z \ -w /build \ --privileged \ thegeeklab/wp-docker-buildx --dry-run diff --git a/docs/data/data.yaml b/docs/data/data.yaml index 09cbe3a..f8eaf2d 100644 --- a/docs/data/data.yaml +++ b/docs/data/data.yaml @@ -179,6 +179,13 @@ properties: defaultValue: false required: false + - name: insecure_skip_verify + description: | + Skip SSL verification. + type: bool + defaultValue: false + required: false + - name: ipv6 description: | Enable docker daemon IPv6 support. @@ -192,6 +199,13 @@ properties: type: list required: false + - name: log_level + description: | + Plugin log level. + type: string + defaultValue: "info" + required: false + - name: max_concurrent_uploads description: | Max concurrent uploads for each push. diff --git a/go.mod b/go.mod index b149fc0..a432b52 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 require ( github.com/cenkalti/backoff/v4 v4.3.0 github.com/rs/zerolog v1.32.0 - github.com/thegeeklab/wp-plugin-go v1.7.1 + github.com/thegeeklab/wp-plugin-go/v2 v2.0.1 github.com/urfave/cli/v2 v2.27.2 golang.org/x/sys v0.19.0 ) diff --git a/go.sum b/go.sum index 89f287a..89e892b 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/thegeeklab/wp-plugin-go v1.7.1 h1:zfR/rfNPuyVhXJu1fsLfp4+Mz2pTf6WwW/mIqw9750I= -github.com/thegeeklab/wp-plugin-go v1.7.1/go.mod h1:Ixi5plt9tpFGTu6yc/Inm5DcDpp3xPTeohfr86gf2EU= +github.com/thegeeklab/wp-plugin-go/v2 v2.0.1 h1:42kqe5U1x5Ysa9I8tDEhh+tyvfFkfXKvlb3UsigBmN4= +github.com/thegeeklab/wp-plugin-go/v2 v2.0.1/go.mod h1:KRfDolkPSpO7Zx54Y0ofTFA7Cvd+7bHTHzYnYAo9WYg= github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI= github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= diff --git a/internal/docs/main.go b/internal/docs/main.go new file mode 100644 index 0000000..ee9d322 --- /dev/null +++ b/internal/docs/main.go @@ -0,0 +1,42 @@ +//go:build generate +// +build generate + +package main + +import ( + "context" + "flag" + "net/http" + "os" + "time" + + "github.com/thegeeklab/wp-docker-buildx/plugin" + "github.com/thegeeklab/wp-plugin-go/v2/docs" + wp_template "github.com/thegeeklab/wp-plugin-go/v2/template" +) + +func main() { + tmpl := "https://raw.githubusercontent.com/thegeeklab/woodpecker-plugins/main/templates/docs-data.yaml.tmpl" + client := http.Client{ + Timeout: 30 * time.Second, + } + + p := plugin.New(nil) + + out, err := wp_template.Render(context.Background(), client, tmpl, docs.GetTemplateData(p.App)) + if err != nil { + panic(err) + } + + outputFile := flag.String("output", "", "Output file path") + flag.Parse() + + if *outputFile == "" { + panic("no output file specified") + } + + err = os.WriteFile(*outputFile, []byte(out), 0o644) + if err != nil { + panic(err) + } +} diff --git a/plugin/coredns.go b/plugin/coredns.go index 4c17585..678f469 100644 --- a/plugin/coredns.go +++ b/plugin/coredns.go @@ -6,7 +6,7 @@ import ( "os" "os/exec" - "github.com/thegeeklab/wp-plugin-go/trace" + "github.com/thegeeklab/wp-plugin-go/v2/trace" ) func (p Plugin) startCoredns() { diff --git a/plugin/daemon.go b/plugin/daemon.go index 97f69c4..1b229be 100644 --- a/plugin/daemon.go +++ b/plugin/daemon.go @@ -4,7 +4,7 @@ import ( "io" "os" - "github.com/thegeeklab/wp-plugin-go/trace" + "github.com/thegeeklab/wp-plugin-go/v2/trace" ) const ( @@ -25,7 +25,7 @@ func (p Plugin) startDaemon() { } go func() { - trace.Cmd(cmd) + trace.Cmd(cmd.Cmd) _ = cmd.Run() }() } diff --git a/plugin/docker.go b/plugin/docker.go index bc22617..a6a1ba7 100644 --- a/plugin/docker.go +++ b/plugin/docker.go @@ -11,7 +11,7 @@ import ( ) // helper function to create the docker login command. -func commandLogin(login Login) *execabs.Cmd { +func commandLogin(login Login) *Cmd { if login.Email != "" { return commandLoginEmail(login) } @@ -23,12 +23,12 @@ func commandLogin(login Login) *execabs.Cmd { login.Registry, } - return execabs.Command( - dockerBin, args..., - ) + return &Cmd{ + Cmd: execabs.Command(dockerBin, args...), + } } -func commandLoginEmail(login Login) *execabs.Cmd { +func commandLoginEmail(login Login) *Cmd { args := []string{ "login", "-u", login.Username, @@ -37,22 +37,26 @@ func commandLoginEmail(login Login) *execabs.Cmd { login.Registry, } - return execabs.Command( - dockerBin, args..., - ) + return &Cmd{ + Cmd: execabs.Command(dockerBin, args...), + } } // helper function to create the docker info command. -func commandVersion() *execabs.Cmd { - return execabs.Command(dockerBin, "version") +func commandVersion() *Cmd { + return &Cmd{ + Cmd: execabs.Command(dockerBin, "version"), + } } // helper function to create the docker info command. -func commandInfo() *execabs.Cmd { - return execabs.Command(dockerBin, "info") +func commandInfo() *Cmd { + return &Cmd{ + Cmd: execabs.Command(dockerBin, "info"), + } } -func commandBuilder(daemon Daemon) *execabs.Cmd { +func commandBuilder(daemon Daemon) *Cmd { args := []string{ "buildx", "create", @@ -63,15 +67,19 @@ func commandBuilder(daemon Daemon) *execabs.Cmd { args = append(args, "--config", buildkitConfig) } - return execabs.Command(dockerBin, args...) + return &Cmd{ + Cmd: execabs.Command(dockerBin, args...), + } } -func commandBuildx() *execabs.Cmd { - return execabs.Command(dockerBin, "buildx", "ls") +func commandBuildx() *Cmd { + return &Cmd{ + Cmd: execabs.Command(dockerBin, "buildx", "ls"), + } } // helper function to create the docker build command. -func commandBuild(build Build, dryrun bool) *execabs.Cmd { +func commandBuild(build Build, dryrun bool) *Cmd { args := []string{ "buildx", "build", @@ -164,7 +172,9 @@ func commandBuild(build Build, dryrun bool) *execabs.Cmd { args = append(args, "--secret", secret) } - return execabs.Command(dockerBin, args...) + return &Cmd{ + Cmd: execabs.Command(dockerBin, args...), + } } // helper function to add proxy values from the environment. @@ -211,7 +221,7 @@ func hasProxyBuildArg(build *Build, key string) bool { } // helper function to create the docker daemon command. -func commandDaemon(daemon Daemon) *execabs.Cmd { +func commandDaemon(daemon Daemon) *Cmd { args := []string{ "--data-root", daemon.StoragePath, "--host=unix:///var/run/docker.sock", @@ -257,5 +267,7 @@ func commandDaemon(daemon Daemon) *execabs.Cmd { args = append(args, "--max-concurrent-uploads", daemon.MaxConcurrentUploads) } - return execabs.Command(dockerdBin, args...) + return &Cmd{ + Cmd: execabs.Command(dockerdBin, args...), + } } diff --git a/plugin/impl.go b/plugin/impl.go index 6e85242..9c347fa 100644 --- a/plugin/impl.go +++ b/plugin/impl.go @@ -10,11 +10,10 @@ import ( "github.com/cenkalti/backoff/v4" "github.com/rs/zerolog/log" - "github.com/thegeeklab/wp-plugin-go/tag" - "github.com/thegeeklab/wp-plugin-go/trace" - "github.com/thegeeklab/wp-plugin-go/types" + "github.com/thegeeklab/wp-plugin-go/v2/tag" + "github.com/thegeeklab/wp-plugin-go/v2/trace" + "github.com/thegeeklab/wp-plugin-go/v2/types" "github.com/urfave/cli/v2" - "golang.org/x/sys/execabs" ) var ErrTypeAssertionFailed = errors.New("type assertion failed") @@ -79,6 +78,8 @@ func (p *Plugin) Validate() error { // //nolint:gocognit func (p *Plugin) Execute() error { + batchCmd := make([]*Cmd, 0) + // start the Docker daemon server //nolint: nestif if !p.Settings.Daemon.Disabled { @@ -163,7 +164,7 @@ func (p *Plugin) Execute() error { versionCmd.Stdout = os.Stdout versionCmd.Stderr = os.Stderr - trace.Cmd(versionCmd) + trace.Cmd(versionCmd.Cmd) return versionCmd.Run() } @@ -175,19 +176,18 @@ func (p *Plugin) Execute() error { return err } - var batchCmd []*execabs.Cmd batchCmd = append(batchCmd, commandInfo()) // docker info batchCmd = append(batchCmd, commandBuilder(p.Settings.Daemon)) batchCmd = append(batchCmd, commandBuildx()) batchCmd = append(batchCmd, commandBuild(p.Settings.Build, p.Settings.Dryrun)) // docker build // execute all commands in batch mode. - for _, cmd := range batchCmd { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - trace.Cmd(cmd) + for _, bc := range batchCmd { + bc.Stdout = os.Stdout + bc.Stderr = os.Stderr + trace.Cmd(bc.Cmd) - err := cmd.Run() + err := bc.Run() if err != nil { return err } diff --git a/plugin/plugin.go b/plugin/plugin.go index 9fd71ac..0d6ce7d 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -1,10 +1,16 @@ package plugin import ( - wp "github.com/thegeeklab/wp-plugin-go/plugin" + "fmt" + + wp "github.com/thegeeklab/wp-plugin-go/v2/plugin" + "github.com/thegeeklab/wp-plugin-go/v2/types" "github.com/urfave/cli/v2" + "golang.org/x/sys/execabs" ) +//go:generate go run ../internal/docs/main.go -output=../docs/data/data-raw.yaml + // Plugin implements provide the plugin. type Plugin struct { *wp.Plugin @@ -77,15 +83,374 @@ type Build struct { Secrets []string // Docker build secrets } -func New(options wp.Options, settings *Settings) *Plugin { - p := &Plugin{} +type Cmd struct { + *execabs.Cmd + Private bool +} - if options.Execute == nil { - options.Execute = p.run +func New(e wp.ExecuteFunc, build ...string) *Plugin { + p := &Plugin{ + Settings: &Settings{}, + } + + options := wp.Options{ + Name: "wp-docker-buildx", + Description: "Build multiarch OCI images with buildx", + Flags: Flags(p.Settings, wp.FlagsPluginCategory), + Execute: p.run, + HideWoodpeckerFlags: true, + } + + if len(build) > 0 { + options.Version = build[0] + } + + if len(build) > 1 { + options.VersionMetadata = fmt.Sprintf("date=%s", build[1]) + } + + if e != nil { + options.Execute = e } p.Plugin = wp.New(options) - p.Settings = settings return p } + +// Flags returns a slice of CLI flags for the plugin. +// +//nolint:maintidx +func Flags(settings *Settings, category string) []cli.Flag { + return []cli.Flag{ + &cli.BoolFlag{ + Name: "dry-run", + EnvVars: []string{"PLUGIN_DRY_RUN"}, + Usage: "disable docker push", + Destination: &settings.Dryrun, + Category: category, + }, + &cli.StringFlag{ + Name: "daemon.mirror", + EnvVars: []string{"PLUGIN_MIRROR", "DOCKER_PLUGIN_MIRROR"}, + Usage: "registry mirror to pull images", + Destination: &settings.Daemon.Mirror, + DefaultText: "$DOCKER_PLUGIN_MIRROR", + Category: category, + }, + &cli.StringFlag{ + Name: "daemon.storage-driver", + EnvVars: []string{"PLUGIN_STORAGE_DRIVER"}, + Usage: "docker daemon storage driver", + Destination: &settings.Daemon.StorageDriver, + Category: category, + }, + &cli.StringFlag{ + Name: "daemon.storage-path", + EnvVars: []string{"PLUGIN_STORAGE_PATH"}, + Usage: "docker daemon storage path", + Value: "/var/lib/docker", + Destination: &settings.Daemon.StoragePath, + Category: category, + }, + &cli.StringFlag{ + Name: "daemon.bip", + EnvVars: []string{"PLUGIN_BIP"}, + Usage: "allow the docker daemon to bride IP address", + Destination: &settings.Daemon.Bip, + Category: category, + }, + &cli.StringFlag{ + Name: "daemon.mtu", + EnvVars: []string{"PLUGIN_MTU"}, + Usage: "docker daemon custom MTU setting", + Destination: &settings.Daemon.MTU, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "daemon.dns", + EnvVars: []string{"PLUGIN_CUSTOM_DNS"}, + Usage: "custom docker daemon DNS server", + Destination: &settings.Daemon.DNS, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "daemon.dns-search", + EnvVars: []string{"PLUGIN_CUSTOM_DNS_SEARCH"}, + Usage: "custom docker daemon DNS search domain", + Destination: &settings.Daemon.DNSSearch, + Category: category, + }, + &cli.BoolFlag{ + Name: "daemon.insecure", + EnvVars: []string{"PLUGIN_INSECURE"}, + Usage: "allow the docker daemon to use insecure registries", + Value: false, + Destination: &settings.Daemon.Insecure, + Category: category, + }, + &cli.BoolFlag{ + Name: "daemon.ipv6", + EnvVars: []string{"PLUGIN_IPV6"}, + Usage: "enable docker daemon IPv6 support", + Value: false, + Destination: &settings.Daemon.IPv6, + Category: category, + }, + &cli.BoolFlag{ + Name: "daemon.experimental", + EnvVars: []string{"PLUGIN_EXPERIMENTAL"}, + Usage: "enable docker daemon experimental mode", + Value: false, + Destination: &settings.Daemon.Experimental, + Category: category, + }, + &cli.BoolFlag{ + Name: "daemon.debug", + EnvVars: []string{"PLUGIN_DEBUG"}, + Usage: "enable verbose debug mode for the docker daemon", + Value: false, + Destination: &settings.Daemon.Debug, + Category: category, + }, + &cli.BoolFlag{ + Name: "daemon.off", + EnvVars: []string{"PLUGIN_DAEMON_OFF"}, + Usage: "disable the startup of the docker daemon", + Value: false, + Destination: &settings.Daemon.Disabled, + Category: category, + }, + &cli.StringFlag{ + Name: "daemon.buildkit-config", + EnvVars: []string{"PLUGIN_BUILDKIT_CONFIG"}, + Usage: "content of the docker buildkit toml config", + Destination: &settings.Daemon.BuildkitConfig, + Category: category, + }, + &cli.StringFlag{ + Name: "daemon.max-concurrent-uploads", + EnvVars: []string{"PLUGIN_MAX_CONCURRENT_UPLOADS"}, + Usage: "max concurrent uploads for each push", + Destination: &settings.Daemon.MaxConcurrentUploads, + Category: category, + }, + &cli.StringFlag{ + Name: "containerfile", + EnvVars: []string{"PLUGIN_CONTAINERFILE"}, + Usage: "containerfile to use for the image build", + Value: "Containerfile", + Destination: &settings.Build.Containerfile, + Category: category, + }, + &cli.StringFlag{ + Name: "context", + EnvVars: []string{"PLUGIN_CONTEXT"}, + Usage: "path of the build context", + Value: ".", + Destination: &settings.Build.Context, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "named-context", + EnvVars: []string{"PLUGIN_NAMED_CONTEXT"}, + Usage: "additional named build context", + Destination: &settings.Build.NamedContext, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "tags", + EnvVars: []string{"PLUGIN_TAGS", "PLUGIN_TAG"}, + Usage: "repository tags to use for the image", + FilePath: ".tags", + Destination: &settings.Build.Tags, + Category: category, + }, + &cli.BoolFlag{ + Name: "tags.auto", + EnvVars: []string{"PLUGIN_AUTO_TAG", "PLUGIN_DEFAULT_TAGS"}, + Usage: "generate tag names automatically based on git branch and git tag", + Value: false, + Destination: &settings.Build.TagsAuto, + Category: category, + }, + &cli.StringFlag{ + Name: "tags.suffix", + EnvVars: []string{"PLUGIN_AUTO_TAG_SUFFIX", "PLUGIN_DEFAULT_SUFFIX"}, + Usage: "generate tag names with the given suffix", + Destination: &settings.Build.TagsSuffix, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "extra.tags", + EnvVars: []string{"PLUGIN_EXTRA_TAGS"}, + Usage: "additional tags to use for the image including registry", + FilePath: ".extratags", + Destination: &settings.Build.ExtraTags, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "args", + EnvVars: []string{"PLUGIN_BUILD_ARGS"}, + Usage: "custom build arguments for the build", + Destination: &settings.Build.Args, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "args-from-env", + EnvVars: []string{"PLUGIN_BUILD_ARGS_FROM_ENV"}, + Usage: "forward environment variables as custom arguments to the build", + Destination: &settings.Build.ArgsEnv, + Category: category, + }, + &cli.BoolFlag{ + Name: "quiet", + EnvVars: []string{"PLUGIN_QUIET"}, + Usage: "enable suppression of the build output", + Value: false, + Destination: &settings.Build.Quiet, + Category: category, + }, + &cli.StringFlag{ + Name: "output", + EnvVars: []string{"PLUGIN_OUTPUT"}, + Usage: "export action for the build result", + Destination: &settings.Build.Output, + Category: category, + }, + &cli.StringFlag{ + Name: "target", + EnvVars: []string{"PLUGIN_TARGET"}, + Usage: "build target to use", + Destination: &settings.Build.Target, + Category: category, + }, + &cli.GenericFlag{ + Name: "cache-from", + EnvVars: []string{"PLUGIN_CACHE_FROM"}, + Usage: "images to consider as cache sources", + Value: &types.StringSliceFlag{}, + Category: category, + }, + &cli.StringFlag{ + Name: "cache-to", + EnvVars: []string{"PLUGIN_CACHE_TO"}, + Usage: "cache destination for the build cache", + Destination: &settings.Build.CacheTo, + Category: category, + }, + &cli.BoolFlag{ + Name: "pull-image", + EnvVars: []string{"PLUGIN_PULL_IMAGE"}, + Usage: "enforce to pull base image at build time", + Value: true, + Destination: &settings.Build.Pull, + Category: category, + }, + &cli.BoolFlag{ + Name: "compress", + EnvVars: []string{"PLUGIN_COMPRESS"}, + Usage: "enable compression of the build context using gzip", + Value: false, + Destination: &settings.Build.Compress, + Category: category, + }, + &cli.StringFlag{ + Name: "repo", + EnvVars: []string{"PLUGIN_REPO"}, + Usage: "repository name for the image", + Destination: &settings.Build.Repo, + Category: category, + }, + &cli.StringFlag{ + Name: "docker.registry", + EnvVars: []string{"PLUGIN_REGISTRY", "DOCKER_REGISTRY"}, + Usage: "docker registry to authenticate with", + Value: "https://index.docker.io/v1/", + Destination: &settings.Login.Registry, + Category: category, + }, + &cli.StringFlag{ + Name: "docker.username", + EnvVars: []string{"PLUGIN_USERNAME", "DOCKER_USERNAME"}, + Usage: "username for registry authentication", + Destination: &settings.Login.Username, + DefaultText: "$DOCKER_USERNAME", + Category: category, + }, + &cli.StringFlag{ + Name: "docker.password", + EnvVars: []string{"PLUGIN_PASSWORD", "DOCKER_PASSWORD"}, + Usage: "password for registry authentication", + Destination: &settings.Login.Password, + DefaultText: "$DOCKER_PASSWORD", + Category: category, + }, + &cli.StringFlag{ + Name: "docker.email", + EnvVars: []string{"PLUGIN_EMAIL", "DOCKER_EMAIL"}, + Usage: "email address for registry authentication", + Destination: &settings.Login.Email, + DefaultText: "$DOCKER_EMAIL", + Category: category, + }, + &cli.StringFlag{ + Name: "docker.config", + EnvVars: []string{"PLUGIN_CONFIG", "DOCKER_PLUGIN_CONFIG"}, + Usage: "content of the docker daemon json config", + Destination: &settings.Login.Config, + DefaultText: "$DOCKER_PLUGIN_CONFIG", + Category: category, + }, + &cli.BoolFlag{ + Name: "no-cache", + EnvVars: []string{"PLUGIN_NO_CACHE"}, + Usage: "disable the usage of cached intermediate containers", + Value: false, + Destination: &settings.Build.NoCache, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "add-host", + EnvVars: []string{"PLUGIN_ADD_HOST"}, + Usage: "additional `host:ip` mapping", + Destination: &settings.Build.AddHost, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "platforms", + EnvVars: []string{"PLUGIN_PLATFORMS"}, + Usage: "target platform for build", + Destination: &settings.Build.Platforms, + Category: category, + }, + &cli.StringSliceFlag{ + Name: "labels", + EnvVars: []string{"PLUGIN_LABELS"}, + Usage: "labels to add to image", + Destination: &settings.Build.Labels, + Category: category, + }, + &cli.StringFlag{ + Name: "provenance", + EnvVars: []string{"PLUGIN_PROVENANCE"}, + Usage: "generates provenance attestation for the build", + Destination: &settings.Build.Provenance, + Category: category, + }, + &cli.StringFlag{ + Name: "sbom", + EnvVars: []string{"PLUGIN_SBOM"}, + Usage: "generates SBOM attestation for the build", + Destination: &settings.Build.SBOM, + Category: category, + }, + &cli.GenericFlag{ + Name: "secrets", + EnvVars: []string{"PLUGIN_SECRETS"}, + Usage: "exposes secrets to the build", + Value: &types.StringSliceFlag{}, + Category: category, + }, + } +} diff --git a/cmd/wp-docker-buildx/config_test.go b/plugin/plugin_test.go similarity index 63% rename from cmd/wp-docker-buildx/config_test.go rename to plugin/plugin_test.go index 65eb918..e49eb8e 100644 --- a/cmd/wp-docker-buildx/config_test.go +++ b/plugin/plugin_test.go @@ -1,15 +1,12 @@ -package main +package plugin import ( "context" "reflect" "testing" - - "github.com/thegeeklab/wp-docker-buildx/plugin" - wp "github.com/thegeeklab/wp-plugin-go/plugin" ) -func Test_pluginOptions(t *testing.T) { +func TestFlags(t *testing.T) { tests := []struct { name string envs map[string]string @@ -32,14 +29,7 @@ func Test_pluginOptions(t *testing.T) { t.Setenv(key, value) } - settings := &plugin.Settings{} - options := wp.Options{ - Name: "wp-docker-buildx", - Flags: settingsFlags(settings, wp.FlagsPluginCategory), - Execute: func(_ context.Context) error { return nil }, - } - - got := plugin.New(options, settings) + got := New(func(_ context.Context) error { return nil }) _ = got.App.Run([]string{"wp-docker-buildx"}) _ = got.FlagsFromContext() diff --git a/testdata/Containerfile b/testdata/Containerfile new file mode 100644 index 0000000..b09b037 --- /dev/null +++ b/testdata/Containerfile @@ -0,0 +1 @@ +FROM alpine:latest