From 905350fa1573b39a41ba289b4d4e76b7f652df3b Mon Sep 17 00:00:00 2001 From: Zav Shotan <3694482+LamaAni@users.noreply.github.com> Date: Thu, 10 Feb 2022 11:05:19 -0500 Subject: [PATCH] Add support for default clone image environment variable (#769) This allows for custom clone images for deployment in air-gap systems. Co-authored-by: Zav Shotan --- cmd/server/flags.go | 6 ++++ cmd/server/server.go | 3 ++ .../30-administration/10-server-config.md | 5 +++ pipeline/frontend/yaml/compiler/compiler.go | 35 +++++++++++-------- pipeline/frontend/yaml/compiler/option.go | 6 ++++ .../frontend/yaml/compiler/option_test.go | 9 +++++ server/config.go | 1 + server/shared/procBuilder.go | 1 + 8 files changed, 51 insertions(+), 15 deletions(-) diff --git a/cmd/server/flags.go b/cmd/server/flags.go index d8485f40c..0a55d84bb 100644 --- a/cmd/server/flags.go +++ b/cmd/server/flags.go @@ -96,6 +96,12 @@ var flags = []cli.Flag{ Name: "authenticate-public-repos", Usage: "Always use authentication to clone repositories even if they are public. Needed if the SCM requires to always authenticate as used by many companies.", }, + &cli.StringFlag{ + EnvVars: []string{"WOODPECKER_DEFAULT_CLONE_IMAGE"}, + Name: "default-clone-image", + Usage: "The default docker image to be used when cloning the repo", + Value: "woodpeckerci/plugin-git:latest", + }, &cli.StringFlag{ EnvVars: []string{"WOODPECKER_DOCS"}, Name: "docs", diff --git a/cmd/server/server.go b/cmd/server/server.go index 2b4266820..2e7ac5d9d 100644 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -274,6 +274,9 @@ func setupEvilGlobals(c *cli.Context, v store.Store, r remote.Remote) { // authentication server.Config.Pipeline.AuthenticatePublicRepos = c.Bool("authenticate-public-repos") + // Cloning + server.Config.Pipeline.DefaultCloneImage = c.String("default-clone-image") + // limits server.Config.Pipeline.Limits.MemSwapLimit = c.Int64("limit-mem-swap") server.Config.Pipeline.Limits.MemLimit = c.Int64("limit-mem") diff --git a/docs/docs/30-administration/10-server-config.md b/docs/docs/30-administration/10-server-config.md index 80663029b..88ec50357 100644 --- a/docs/docs/30-administration/10-server-config.md +++ b/docs/docs/30-administration/10-server-config.md @@ -164,6 +164,11 @@ Link to documentation in the UI. Always use authentication to clone repositories even if they are public. Needed if the SCM requires to always authenticate as used by many companies. +### `WOODPECKER_DEFAULT_CLONE_IMAGE` +> Default: `woodpeckerci/plugin-git:latest` + +The default docker image to be used when cloning the repo + ### `WOODPECKER_SESSION_EXPIRES` > Default: `72h` diff --git a/pipeline/frontend/yaml/compiler/compiler.go b/pipeline/frontend/yaml/compiler/compiler.go index cbff32ec7..1a1a39c87 100644 --- a/pipeline/frontend/yaml/compiler/compiler.go +++ b/pipeline/frontend/yaml/compiler/compiler.go @@ -47,20 +47,21 @@ type ResourceLimit struct { // Compiler compiles the yaml type Compiler struct { - local bool - escalated []string - prefix string - volumes []string - networks []string - env map[string]string - cloneEnv map[string]string - base string - path string - metadata frontend.Metadata - registries []Registry - secrets map[string]Secret - cacher Cacher - reslimit ResourceLimit + local bool + escalated []string + prefix string + volumes []string + networks []string + env map[string]string + cloneEnv map[string]string + base string + path string + metadata frontend.Metadata + registries []Registry + secrets map[string]Secret + cacher Cacher + reslimit ResourceLimit + defaultCloneImage string } // New creates a new Compiler with options. @@ -120,9 +121,13 @@ func (c *Compiler) Compile(conf *yaml.Config) *backend.Config { // add default clone step if !c.local && len(conf.Clone.Containers) == 0 && !conf.SkipClone { + cloneImage := defaultCloneImage + if len(c.defaultCloneImage) > 0 { + cloneImage = c.defaultCloneImage + } container := &yaml.Container{ Name: defaultCloneName, - Image: defaultCloneImage, + Image: cloneImage, Settings: map[string]interface{}{"depth": "0"}, Environment: c.cloneEnv, } diff --git a/pipeline/frontend/yaml/compiler/option.go b/pipeline/frontend/yaml/compiler/option.go index 08cf0f927..4ec98e302 100644 --- a/pipeline/frontend/yaml/compiler/option.go +++ b/pipeline/frontend/yaml/compiler/option.go @@ -199,6 +199,12 @@ func WithResourceLimit(swap, mem, shmsize, cpuQuota, cpuShares int64, cpuSet str } } +func WithDefaultCloneImage(cloneImage string) Option { + return func(compiler *Compiler) { + compiler.defaultCloneImage = cloneImage + } +} + // TODO(bradrydzewski) consider an alternate approach to // WithProxy where the proxy strings are passed directly // to the function as named parameters. diff --git a/pipeline/frontend/yaml/compiler/option_test.go b/pipeline/frontend/yaml/compiler/option_test.go index e61a5f09c..52f0f0c9f 100644 --- a/pipeline/frontend/yaml/compiler/option_test.go +++ b/pipeline/frontend/yaml/compiler/option_test.go @@ -240,6 +240,15 @@ func TestWithVolumeCacher(t *testing.T) { } } +func TestWithDefaultCloneImage(t *testing.T) { + compiler := New( + WithDefaultCloneImage("not-an-image"), + ) + if compiler.defaultCloneImage != "not-an-image" { + t.Errorf("Expected default clone image 'not-an-image' not found") + } +} + func TestWithS3Cacher(t *testing.T) { compiler := New( WithS3Cacher("some-access-key", "some-secret-key", "some-region", "some-bucket"), diff --git a/server/config.go b/server/config.go index 6d4a2019f..3384cb184 100644 --- a/server/config.go +++ b/server/config.go @@ -67,6 +67,7 @@ var Config = struct { } Pipeline struct { AuthenticatePublicRepos bool + DefaultCloneImage string Limits model.ResourceLimit Volumes []string Networks []string diff --git a/server/shared/procBuilder.go b/server/shared/procBuilder.go index fd8710744..864268878 100644 --- a/server/shared/procBuilder.go +++ b/server/shared/procBuilder.go @@ -246,6 +246,7 @@ func (b *ProcBuilder) toInternalRepresentation(parsed *yaml.Config, environ map[ ), b.Repo.IsSCMPrivate || server.Config.Pipeline.AuthenticatePublicRepos, ), + compiler.WithDefaultCloneImage(server.Config.Pipeline.DefaultCloneImage), compiler.WithRegistry(registries...), compiler.WithSecret(secrets...), compiler.WithPrefix(