mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-04-26 21:44:44 +00:00
Remove all default 3rd party privileged plugins (#3918)
This commit is contained in:
parent
1f74c8378f
commit
e4f954ef94
10 changed files with 53 additions and 12 deletions
|
@ -161,7 +161,7 @@ var flags = append([]cli.Flag{
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Sources: cli.EnvVars("WOODPECKER_ESCALATE"),
|
Sources: cli.EnvVars("WOODPECKER_ESCALATE"),
|
||||||
Name: "escalate",
|
Name: "escalate",
|
||||||
Usage: "images to run in privileged mode",
|
Usage: "Allow plugins to run in privileged mode, if environment variable is defined but empty there will be none",
|
||||||
Value: constant.PrivilegedPlugins,
|
Value: constant.PrivilegedPlugins,
|
||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
|
|
|
@ -222,10 +222,15 @@ func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) error
|
||||||
server.Config.Server.CustomJsFile = strings.TrimSpace(c.String("custom-js-file"))
|
server.Config.Server.CustomJsFile = strings.TrimSpace(c.String("custom-js-file"))
|
||||||
server.Config.Pipeline.Networks = c.StringSlice("network")
|
server.Config.Pipeline.Networks = c.StringSlice("network")
|
||||||
server.Config.Pipeline.Volumes = c.StringSlice("volume")
|
server.Config.Pipeline.Volumes = c.StringSlice("volume")
|
||||||
server.Config.Pipeline.Privileged = c.StringSlice("escalate")
|
|
||||||
server.Config.WebUI.EnableSwagger = c.Bool("enable-swagger")
|
server.Config.WebUI.EnableSwagger = c.Bool("enable-swagger")
|
||||||
server.Config.WebUI.SkipVersionCheck = c.Bool("skip-version-check")
|
server.Config.WebUI.SkipVersionCheck = c.Bool("skip-version-check")
|
||||||
|
|
||||||
|
// list has default value but should be able to be set to zero
|
||||||
|
server.Config.Pipeline.PrivilegedPlugins = c.StringSlice("escalate")
|
||||||
|
if val, set := os.LookupEnv("WOODPECKER_ESCALATE"); set && val == "" {
|
||||||
|
server.Config.Pipeline.PrivilegedPlugins = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
// prometheus
|
// prometheus
|
||||||
server.Config.Prometheus.AuthToken = c.String("prometheus-auth-token")
|
server.Config.Prometheus.AuthToken = c.String("prometheus-auth-token")
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ Some versions need some changes to the server configuration or the pipeline conf
|
||||||
|
|
||||||
## `next`
|
## `next`
|
||||||
|
|
||||||
|
- Remove `plugins/docker`, `plugins/gcr` and `plugins/ecr` from the default list of privileged plugins ([modify the list via config if needed](./30-administration/10-server-config.md#woodpecker_escalate)).
|
||||||
- Secret filters for plugins now check against tag if specified
|
- Secret filters for plugins now check against tag if specified
|
||||||
- Removed `WOODPECKER_DEV_OAUTH_HOST` and `WOODPECKER_DEV_GITEA_OAUTH_URL` use `WOODPECKER_EXPERT_FORGE_OAUTH_HOST`
|
- Removed `WOODPECKER_DEV_OAUTH_HOST` and `WOODPECKER_DEV_GITEA_OAUTH_URL` use `WOODPECKER_EXPERT_FORGE_OAUTH_HOST`
|
||||||
- Compatibility mode of deprecated `pipeline:`, `platform:` and `branches:` pipeline config options are now removed and pipeline will now fail if still in use.
|
- Compatibility mode of deprecated `pipeline:`, `platform:` and `branches:` pipeline config options are now removed and pipeline will now fail if still in use.
|
||||||
|
|
|
@ -24,11 +24,13 @@ import (
|
||||||
errorTypes "go.woodpecker-ci.org/woodpecker/v2/pipeline/errors/types"
|
errorTypes "go.woodpecker-ci.org/woodpecker/v2/pipeline/errors/types"
|
||||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/linter/schema"
|
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/linter/schema"
|
||||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/types"
|
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/types"
|
||||||
|
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Linter lints a pipeline configuration.
|
// A Linter lints a pipeline configuration.
|
||||||
type Linter struct {
|
type Linter struct {
|
||||||
trusted bool
|
trusted bool
|
||||||
|
privilegedPlugins *[]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Linter with options.
|
// New creates a new Linter with options.
|
||||||
|
@ -120,6 +122,9 @@ func (l *Linter) lintContainers(config *WorkflowConfig, area string) error {
|
||||||
if err := l.lintSettings(config, container, area); err != nil {
|
if err := l.lintSettings(config, container, area); err != nil {
|
||||||
linterErr = multierr.Append(linterErr, err)
|
linterErr = multierr.Append(linterErr, err)
|
||||||
}
|
}
|
||||||
|
if err := l.lintPrivilegedPlugins(config, container, area); err != nil {
|
||||||
|
linterErr = multierr.Append(linterErr, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return linterErr
|
return linterErr
|
||||||
|
@ -132,6 +137,22 @@ func (l *Linter) lintImage(config *WorkflowConfig, c *types.Container, area stri
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Linter) lintPrivilegedPlugins(config *WorkflowConfig, c *types.Container, area string) error {
|
||||||
|
// lint for conflicts of https://github.com/woodpecker-ci/woodpecker/pull/3918
|
||||||
|
if utils.MatchImage(c.Image, "plugins/docker", "plugins/gcr", "plugins/ecr") {
|
||||||
|
msg := "Cannot use once privileged plugins removed from WOODPECKER_ESCALATE, use 'woodpeckerci/plugin-docker-buildx' instead"
|
||||||
|
// check first if user did not add them back
|
||||||
|
if l.privilegedPlugins != nil && !utils.MatchImage(c.Image, *l.privilegedPlugins...) {
|
||||||
|
return newLinterError(msg, config.File, fmt.Sprintf("%s.%s", area, c.Name), false)
|
||||||
|
} else if l.privilegedPlugins == nil {
|
||||||
|
// if linter has no info of current privileged plugins, it's just a warning
|
||||||
|
return newLinterError(msg, config.File, fmt.Sprintf("%s.%s", area, c.Name), true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Linter) lintSettings(config *WorkflowConfig, c *types.Container, field string) error {
|
func (l *Linter) lintSettings(config *WorkflowConfig, c *types.Container, field string) error {
|
||||||
if len(c.Settings) == 0 {
|
if len(c.Settings) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -218,7 +239,7 @@ func (l *Linter) lintDeprecations(config *WorkflowConfig) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Linter) lintBadHabits(config *WorkflowConfig) (err error) {
|
func (l *Linter) lintBadHabits(config *WorkflowConfig) (err error) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ steps:
|
||||||
- go build
|
- go build
|
||||||
- go test
|
- go test
|
||||||
publish:
|
publish:
|
||||||
image: plugins/docker
|
image: woodpeckerci/plugin-docker-buildx
|
||||||
settings:
|
settings:
|
||||||
repo: foo/bar
|
repo: foo/bar
|
||||||
foo: bar
|
foo: bar
|
||||||
|
@ -61,7 +61,7 @@ steps:
|
||||||
- go build
|
- go build
|
||||||
- go test
|
- go test
|
||||||
- name: publish
|
- name: publish
|
||||||
image: plugins/docker
|
image: woodpeckerci/plugin-docker-buildx
|
||||||
settings:
|
settings:
|
||||||
repo: foo/bar
|
repo: foo/bar
|
||||||
foo: bar
|
foo: bar
|
||||||
|
@ -169,6 +169,10 @@ func TestLintErrors(t *testing.T) {
|
||||||
from: "{pipeline: { build: { image: golang, settings: { test: 'true' } } }, when: { branch: main, event: push } }",
|
from: "{pipeline: { build: { image: golang, settings: { test: 'true' } } }, when: { branch: main, event: push } }",
|
||||||
want: "Additional property pipeline is not allowed",
|
want: "Additional property pipeline is not allowed",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
from: "{steps: { build: { image: plugins/docker, settings: { test: 'true' } } }, when: { branch: main, event: push } } }",
|
||||||
|
want: "Cannot use once privileged plugins removed from WOODPECKER_ESCALATE, use 'woodpeckerci/plugin-docker-buildx' instead",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testdata {
|
for _, test := range testdata {
|
||||||
|
|
|
@ -23,3 +23,10 @@ func WithTrusted(trusted bool) Option {
|
||||||
linter.trusted = trusted
|
linter.trusted = trusted
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrivilegedPlugins adds the list of privileged plugins.
|
||||||
|
func PrivilegedPlugins(plugins []string) Option {
|
||||||
|
return func(linter *Linter) {
|
||||||
|
linter.privilegedPlugins = &plugins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -254,6 +254,11 @@ func Test_matchImage(t *testing.T) {
|
||||||
to: "gcr.io/golang",
|
to: "gcr.io/golang",
|
||||||
want: false,
|
want: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
from: "woodpeckerci/plugin-docker-buildx",
|
||||||
|
to: "docker.io/woodpeckerci/plugin-docker-buildx",
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testdata {
|
for _, test := range testdata {
|
||||||
assert.Equal(t, test.want, MatchImage(test.from, test.to))
|
assert.Equal(t, test.want, MatchImage(test.from, test.to))
|
||||||
|
|
|
@ -68,7 +68,7 @@ var Config = struct {
|
||||||
Limits model.ResourceLimit
|
Limits model.ResourceLimit
|
||||||
Volumes []string
|
Volumes []string
|
||||||
Networks []string
|
Networks []string
|
||||||
Privileged []string
|
PrivilegedPlugins []string
|
||||||
DefaultTimeout int64
|
DefaultTimeout int64
|
||||||
MaxTimeout int64
|
MaxTimeout int64
|
||||||
Proxy struct {
|
Proxy struct {
|
||||||
|
|
|
@ -142,6 +142,7 @@ func (b *StepBuilder) genItemForWorkflow(workflow *model.Workflow, axis matrix.A
|
||||||
// lint pipeline
|
// lint pipeline
|
||||||
errorsAndWarnings = multierr.Append(errorsAndWarnings, linter.New(
|
errorsAndWarnings = multierr.Append(errorsAndWarnings, linter.New(
|
||||||
linter.WithTrusted(b.Repo.IsTrusted),
|
linter.WithTrusted(b.Repo.IsTrusted),
|
||||||
|
linter.PrivilegedPlugins(server.Config.Pipeline.PrivilegedPlugins),
|
||||||
).Lint([]*linter.WorkflowConfig{{
|
).Lint([]*linter.WorkflowConfig{{
|
||||||
Workflow: parsed,
|
Workflow: parsed,
|
||||||
File: workflow.Name,
|
File: workflow.Name,
|
||||||
|
@ -267,7 +268,7 @@ func (b *StepBuilder) toInternalRepresentation(parsed *yaml_types.Workflow, envi
|
||||||
compiler.WithEnviron(environ),
|
compiler.WithEnviron(environ),
|
||||||
compiler.WithEnviron(b.Envs),
|
compiler.WithEnviron(b.Envs),
|
||||||
// TODO: server deps should be moved into StepBuilder fields and set on StepBuilder creation
|
// TODO: server deps should be moved into StepBuilder fields and set on StepBuilder creation
|
||||||
compiler.WithEscalated(server.Config.Pipeline.Privileged...),
|
compiler.WithEscalated(server.Config.Pipeline.PrivilegedPlugins...),
|
||||||
compiler.WithResourceLimit(server.Config.Pipeline.Limits.MemSwapLimit, server.Config.Pipeline.Limits.MemLimit, server.Config.Pipeline.Limits.ShmSize, server.Config.Pipeline.Limits.CPUQuota, server.Config.Pipeline.Limits.CPUShares, server.Config.Pipeline.Limits.CPUSet),
|
compiler.WithResourceLimit(server.Config.Pipeline.Limits.MemSwapLimit, server.Config.Pipeline.Limits.MemLimit, server.Config.Pipeline.Limits.ShmSize, server.Config.Pipeline.Limits.CPUQuota, server.Config.Pipeline.Limits.CPUShares, server.Config.Pipeline.Limits.CPUSet),
|
||||||
compiler.WithVolumes(server.Config.Pipeline.Volumes...),
|
compiler.WithVolumes(server.Config.Pipeline.Volumes...),
|
||||||
compiler.WithNetworks(server.Config.Pipeline.Networks...),
|
compiler.WithNetworks(server.Config.Pipeline.Networks...),
|
||||||
|
|
|
@ -16,10 +16,7 @@ package constant
|
||||||
|
|
||||||
// PrivilegedPlugins can be changed by 'WOODPECKER_ESCALATE' at runtime.
|
// PrivilegedPlugins can be changed by 'WOODPECKER_ESCALATE' at runtime.
|
||||||
var PrivilegedPlugins = []string{
|
var PrivilegedPlugins = []string{
|
||||||
"plugins/docker",
|
"docker.io/woodpeckerci/plugin-docker-buildx",
|
||||||
"plugins/gcr",
|
|
||||||
"plugins/ecr",
|
|
||||||
"woodpeckerci/plugin-docker-buildx",
|
|
||||||
"codeberg.org/woodpecker-plugins/docker-buildx",
|
"codeberg.org/woodpecker-plugins/docker-buildx",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue