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 <zshotan@bloomberg.net>
This commit is contained in:
Zav Shotan 2022-02-10 11:05:19 -05:00 committed by GitHub
parent 51904c9ee1
commit 905350fa15
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 51 additions and 15 deletions

View file

@ -96,6 +96,12 @@ var flags = []cli.Flag{
Name: "authenticate-public-repos", 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.", 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{ &cli.StringFlag{
EnvVars: []string{"WOODPECKER_DOCS"}, EnvVars: []string{"WOODPECKER_DOCS"},
Name: "docs", Name: "docs",

View file

@ -274,6 +274,9 @@ func setupEvilGlobals(c *cli.Context, v store.Store, r remote.Remote) {
// authentication // authentication
server.Config.Pipeline.AuthenticatePublicRepos = c.Bool("authenticate-public-repos") server.Config.Pipeline.AuthenticatePublicRepos = c.Bool("authenticate-public-repos")
// Cloning
server.Config.Pipeline.DefaultCloneImage = c.String("default-clone-image")
// limits // limits
server.Config.Pipeline.Limits.MemSwapLimit = c.Int64("limit-mem-swap") server.Config.Pipeline.Limits.MemSwapLimit = c.Int64("limit-mem-swap")
server.Config.Pipeline.Limits.MemLimit = c.Int64("limit-mem") server.Config.Pipeline.Limits.MemLimit = c.Int64("limit-mem")

View file

@ -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. 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` ### `WOODPECKER_SESSION_EXPIRES`
> Default: `72h` > Default: `72h`

View file

@ -47,20 +47,21 @@ type ResourceLimit struct {
// Compiler compiles the yaml // Compiler compiles the yaml
type Compiler struct { type Compiler struct {
local bool local bool
escalated []string escalated []string
prefix string prefix string
volumes []string volumes []string
networks []string networks []string
env map[string]string env map[string]string
cloneEnv map[string]string cloneEnv map[string]string
base string base string
path string path string
metadata frontend.Metadata metadata frontend.Metadata
registries []Registry registries []Registry
secrets map[string]Secret secrets map[string]Secret
cacher Cacher cacher Cacher
reslimit ResourceLimit reslimit ResourceLimit
defaultCloneImage string
} }
// New creates a new Compiler with options. // New creates a new Compiler with options.
@ -120,9 +121,13 @@ func (c *Compiler) Compile(conf *yaml.Config) *backend.Config {
// add default clone step // add default clone step
if !c.local && len(conf.Clone.Containers) == 0 && !conf.SkipClone { if !c.local && len(conf.Clone.Containers) == 0 && !conf.SkipClone {
cloneImage := defaultCloneImage
if len(c.defaultCloneImage) > 0 {
cloneImage = c.defaultCloneImage
}
container := &yaml.Container{ container := &yaml.Container{
Name: defaultCloneName, Name: defaultCloneName,
Image: defaultCloneImage, Image: cloneImage,
Settings: map[string]interface{}{"depth": "0"}, Settings: map[string]interface{}{"depth": "0"},
Environment: c.cloneEnv, Environment: c.cloneEnv,
} }

View file

@ -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 // TODO(bradrydzewski) consider an alternate approach to
// WithProxy where the proxy strings are passed directly // WithProxy where the proxy strings are passed directly
// to the function as named parameters. // to the function as named parameters.

View file

@ -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) { func TestWithS3Cacher(t *testing.T) {
compiler := New( compiler := New(
WithS3Cacher("some-access-key", "some-secret-key", "some-region", "some-bucket"), WithS3Cacher("some-access-key", "some-secret-key", "some-region", "some-bucket"),

View file

@ -67,6 +67,7 @@ var Config = struct {
} }
Pipeline struct { Pipeline struct {
AuthenticatePublicRepos bool AuthenticatePublicRepos bool
DefaultCloneImage string
Limits model.ResourceLimit Limits model.ResourceLimit
Volumes []string Volumes []string
Networks []string Networks []string

View file

@ -246,6 +246,7 @@ func (b *ProcBuilder) toInternalRepresentation(parsed *yaml.Config, environ map[
), ),
b.Repo.IsSCMPrivate || server.Config.Pipeline.AuthenticatePublicRepos, b.Repo.IsSCMPrivate || server.Config.Pipeline.AuthenticatePublicRepos,
), ),
compiler.WithDefaultCloneImage(server.Config.Pipeline.DefaultCloneImage),
compiler.WithRegistry(registries...), compiler.WithRegistry(registries...),
compiler.WithSecret(secrets...), compiler.WithSecret(secrets...),
compiler.WithPrefix( compiler.WithPrefix(