From a0371f88506298d49788deec3c6f1cddaea55fa0 Mon Sep 17 00:00:00 2001 From: OCram85 Date: Wed, 25 Oct 2023 09:58:02 +0000 Subject: [PATCH] adds driver-opt arg as plugin parameter (#93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### :book: Summary Adds `--driver-opt` buildx arg as plugin parameter. This should make it possible to pass through proxy settings. #### :bookmark_tabs: Test Plan > :bulb: Select your test plan for the code changes. - [x] CI pipeline tests - Custom test - No test plan ##### Details / Justification Manually tested on own instance behind corporate proxy: ![image](/attachments/b65d981d-c9b8-4228-8e9c-61fa517d98b6) Unfortunately the `--build-arg` passthru seems not working #### :books: Additional Notes - fixes #82 - still to do: - [x] update docs - [x] add usage example > 💡NOTE: This is my first contribution in this codebase. Feedback and help is probably needed 😸 Reviewed-on: https://codeberg.org/woodpecker-plugins/docker-buildx/pulls/93 Reviewed-by: Patrick Schratz Co-authored-by: OCram85 Co-committed-by: OCram85 --- cmd/docker-buildx/config.go | 6 ++++ docs.md | 53 +++++++++++++++++++++++++++ plugin/docker.go | 4 +++ plugin/docker_test.go | 72 +++++++++++++++++++++++++++++++++++++ plugin/impl.go | 29 +++++++-------- 5 files changed, 150 insertions(+), 14 deletions(-) create mode 100644 plugin/docker_test.go diff --git a/cmd/docker-buildx/config.go b/cmd/docker-buildx/config.go index 3b42772..a99cccf 100644 --- a/cmd/docker-buildx/config.go +++ b/cmd/docker-buildx/config.go @@ -99,6 +99,12 @@ func settingsFlags(settings *plugin.Settings) []cli.Flag { Usage: "sets content of the docker buildkit json config", Destination: &settings.Daemon.BuildkitConfig, }, + &cli.StringSliceFlag{ + Name: "daemon.buildkit-driveropt", + EnvVars: []string{"PLUGIN_BUILDKIT_DRIVEROPT"}, + Usage: "adds optional driver-ops args like 'env.http_proxy'", + Destination: &settings.Daemon.BuildkitDriverOpt, + }, &cli.StringFlag{ Name: "dockerfile", EnvVars: []string{"PLUGIN_DOCKERFILE"}, diff --git a/docs.md b/docs.md index 14898d8..f323410 100644 --- a/docs.md +++ b/docs.md @@ -102,6 +102,7 @@ If it's not a tag event, and no default branch, automated tags are skipped. | `debug` | `false` | enables verbose debug mode for the docker daemon | `daemon_off` | `false` | disables the startup of the docker daemon | `buildkit_config` | *none* | sets content of the docker [buildkit TOML config](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) +| `buildkit_driveropt` | *none* | adds one or multiple `--driver-opt` buildx arguments for the default buildkit builder instance | `tags_file` | *none* | overrides the `tags` option with values in a file named `.tags`; multiple tags can be specified separated by a comma | `context` | `.` | sets the path of the build context to use | `auto_tag` | `false` | generates tag names automatically based on git branch and git tag, tags supplied via `tags` are additionally added to the auto_tags without suffix @@ -142,3 +143,55 @@ settings: password: from_secret: cb_token ``` + + +## Using `plugin-docker-buildx` behind a proxy + +When performing a docker build behind a corporate proxy one needs to pass through the proxy settings to the plugin. + +```yaml +variables: + # proxy config + - proxy_conf: &proxy_conf + - http_proxy: 'http://X.Y.Z.Z:3128' + - https_proxy: 'http://X.Y.Z.Z:3128' + - no_proxy: '.my-subdomain.com' + # deployment targets + - &publish_repos 'codeberg.org/test' + # logins for deployment targets + - publish_logins: &publish_logins + - registry: https://codeberg.org + username: + from_secret: CODEBERG_USER + password: + from_secret: CODEBERG_TOKEN + +steps: + test: + image: woodpeckerci/plugin-docker-buildx:2 + environment: + # adding proxy in env for the plugin runtime itself. + - <<: *proxy_conf + privileged: true + settings: + dry_run: true + repo: *publish_repos + dockerfile: Dockerfile.multi + platforms: linux/amd64 + auto_tag: true + logins: *publish_logins + # Adding custom dns server to lookup internal Docker Hub mirror. + # custom_dns: + # - 192.168.55.31 + # - 192.168.55.32 + # Adding an optional Docker Hub mirror for the nested dockerd. + # mirror: https://my-mirror.example.com + build_args: + # passthrough proxy config to the build process and Dockerfile CMDs itself. + - <<: *proxy_conf + # add driver-opt http config to tell buildkit + buildx to resolve external checksums through a proxy. + buildkit_driveropt: + - 'env.http_proxy=http://X.Y.Z.Z:3128' + - 'env.https_proxy=http://X.Y.Z.Z:3128' + - 'env.no_proxy=.my-subdomain.com' +``` \ No newline at end of file diff --git a/plugin/docker.go b/plugin/docker.go index d914692..395a4c6 100644 --- a/plugin/docker.go +++ b/plugin/docker.go @@ -41,6 +41,10 @@ func commandBuilder(daemon Daemon) *exec.Cmd { args = append(args, "--config", buildkitConfig) } + for _, driveropt := range daemon.BuildkitDriverOpt.Value() { + args = append(args, "--driver-opt", driveropt) + } + return exec.Command(dockerExe, args...) } diff --git a/plugin/docker_test.go b/plugin/docker_test.go new file mode 100644 index 0000000..8be3298 --- /dev/null +++ b/plugin/docker_test.go @@ -0,0 +1,72 @@ +package plugin + +import ( + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/urfave/cli/v2" +) + +func TestCommandBuilder(t *testing.T) { + + tests := []struct { + Name string + Daemon Daemon + Input string + WantedLen int + Skip bool + Excuse string + }{ + { + Name: "Single driver-opt value", + Daemon: Daemon{}, + Input: "no_proxy=*.mydomain", + WantedLen: 1, + }, + { + Name: "Single driver-opt value with comma", + Input: "no_proxy=.mydomain,.sub.domain.com", + WantedLen: 1, + Skip: true, + Excuse: "Can be enabled whenever #94 is fixed.", + + }, + } + + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + if (test.Skip) { + t.Skip(fmt.Printf("%v skipped. %v", test.Name, test.Excuse)) + } + // prepare test values to mock plugin call with settings + os.Setenv("PLUGIN_BUILDKIT_DRIVEROPT", test.Input) + + // create dummy cli app to reproduce the issue + app := &cli.App{ + Name: "dummy App", + Usage: "testing inputs", + Version: "0.0.1", + Flags: []cli.Flag{ + &cli.StringSliceFlag{ + Name: "daemon.buildkit-driveropt", + EnvVars: []string{"PLUGIN_BUILDKIT_DRIVEROPT"}, + Usage: "adds optional driver-ops args like 'env.http_proxy'", + Destination: &test.Daemon.BuildkitDriverOpt, + }, + }, + Action: nil, + } + + // need to run the app to resolve the flags + _ = app.Run(nil) + + // call the commandBuilder to prepare the cmd with its args + _ = commandBuilder(test.Daemon) + + assert.Len(t, test.Daemon.BuildkitDriverOpt.Value(), test.WantedLen) + }) + } + +} diff --git a/plugin/impl.go b/plugin/impl.go index d6e16c8..720fbeb 100644 --- a/plugin/impl.go +++ b/plugin/impl.go @@ -18,20 +18,21 @@ import ( // Daemon defines Docker daemon parameters. type Daemon struct { - Registry string // Docker registry - Mirror string // Docker registry mirror - Insecure bool // Docker daemon enable insecure registries - StorageDriver string // Docker daemon storage driver - StoragePath string // Docker daemon storage path - Disabled bool // DOcker daemon is disabled (already running) - Debug bool // Docker daemon started in debug mode - Bip string // Docker daemon network bridge IP address - DNS cli.StringSlice // Docker daemon dns server - DNSSearch cli.StringSlice // Docker daemon dns search domain - MTU string // Docker daemon mtu setting - IPv6 bool // Docker daemon IPv6 networking - Experimental bool // Docker daemon enable experimental mode - BuildkitConfig string // Docker buildkit config + Registry string // Docker registry + Mirror string // Docker registry mirror + Insecure bool // Docker daemon enable insecure registries + StorageDriver string // Docker daemon storage driver + StoragePath string // Docker daemon storage path + Disabled bool // DOcker daemon is disabled (already running) + Debug bool // Docker daemon started in debug mode + Bip string // Docker daemon network bridge IP address + DNS cli.StringSlice // Docker daemon dns server + DNSSearch cli.StringSlice // Docker daemon dns search domain + MTU string // Docker daemon mtu setting + IPv6 bool // Docker daemon IPv6 networking + Experimental bool // Docker daemon enable experimental mode + BuildkitConfig string // Docker buildkit config + BuildkitDriverOpt cli.StringSlice // Docker buildkit driveropt args } // Login defines Docker login parameters.