mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 11:51:02 +00:00
Allow adding additional labels/annotations to kubernetes worker pods (#1510)
Example agent environment configuration using the new value: ```yaml - env: - name: WOODPECKER_BACKEND value: kubernetes - name: WOODPECKER_BACKEND_K8S_NAMESPACE value: default - name: WOODPECKER_BACKEND_K8S_POD_LABELS value: '{"sidecar.istio.io/inject":"false"}' ```
This commit is contained in:
parent
0923aa2624
commit
1816f6c715
5 changed files with 57 additions and 14 deletions
|
@ -14,6 +14,8 @@ env:
|
||||||
WOODPECKER_BACKEND_K8S_STORAGE_CLASS: ""
|
WOODPECKER_BACKEND_K8S_STORAGE_CLASS: ""
|
||||||
WOODPECKER_BACKEND_K8S_VOLUME_SIZE: 10G
|
WOODPECKER_BACKEND_K8S_VOLUME_SIZE: 10G
|
||||||
WOODPECKER_BACKEND_K8S_STORAGE_RWX: true
|
WOODPECKER_BACKEND_K8S_STORAGE_RWX: true
|
||||||
|
WOODPECKER_BACKEND_K8S_POD_LABELS: ""
|
||||||
|
WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS: ""
|
||||||
|
|
||||||
# Docker-in-Docker is normally not needed as Woodpecker natively supports Kubernetes
|
# Docker-in-Docker is normally not needed as Woodpecker natively supports Kubernetes
|
||||||
dind:
|
dind:
|
||||||
|
|
|
@ -295,4 +295,16 @@ var flags = []cli.Flag{
|
||||||
Usage: "backend k8s storage access mode, should ReadWriteMany (RWX) instead of ReadWriteOnce (RWO) be used? (default: true)",
|
Usage: "backend k8s storage access mode, should ReadWriteMany (RWX) instead of ReadWriteOnce (RWO) be used? (default: true)",
|
||||||
Value: true,
|
Value: true,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
EnvVars: []string{"WOODPECKER_BACKEND_K8S_POD_LABELS"},
|
||||||
|
Name: "backend-k8s-pod-labels",
|
||||||
|
Usage: "backend k8s additional worker pod labels",
|
||||||
|
Value: "",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
EnvVars: []string{"WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS"},
|
||||||
|
Name: "backend-k8s-pod-annotations",
|
||||||
|
Usage: "backend k8s additional worker pod annotations",
|
||||||
|
Value: "",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,4 +141,16 @@ var flags = []cli.Flag{
|
||||||
Usage: "backend k8s storage access mode, should ReadWriteMany (RWX) instead of ReadWriteOnce (RWO) be used? (default: true)",
|
Usage: "backend k8s storage access mode, should ReadWriteMany (RWX) instead of ReadWriteOnce (RWO) be used? (default: true)",
|
||||||
Value: true,
|
Value: true,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
EnvVars: []string{"WOODPECKER_BACKEND_K8S_POD_LABELS"},
|
||||||
|
Name: "backend-k8s-pod-labels",
|
||||||
|
Usage: "backend k8s additional worker pod labels",
|
||||||
|
Value: "",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
EnvVars: []string{"WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS"},
|
||||||
|
Name: "backend-k8s-pod-annotations",
|
||||||
|
Usage: "backend k8s additional worker pod annotations",
|
||||||
|
Value: "",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/woodpecker-ci/woodpecker/pipeline/backend/types"
|
"github.com/woodpecker-ci/woodpecker/pipeline/backend/types"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
@ -39,21 +40,35 @@ type kube struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Namespace string
|
Namespace string
|
||||||
StorageClass string
|
StorageClass string
|
||||||
VolumeSize string
|
VolumeSize string
|
||||||
StorageRwx bool
|
PodLabels map[string]string
|
||||||
|
PodAnnotations map[string]string
|
||||||
|
StorageRwx bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func configFromCliContext(ctx context.Context) (*Config, error) {
|
func configFromCliContext(ctx context.Context) (*Config, error) {
|
||||||
if ctx != nil {
|
if ctx != nil {
|
||||||
if c, ok := ctx.Value(types.CliContext).(*cli.Context); ok {
|
if c, ok := ctx.Value(types.CliContext).(*cli.Context); ok {
|
||||||
return &Config{
|
config := Config{
|
||||||
Namespace: c.String("backend-k8s-namespace"),
|
Namespace: c.String("backend-k8s-namespace"),
|
||||||
StorageClass: c.String("backend-k8s-storage-class"),
|
StorageClass: c.String("backend-k8s-storage-class"),
|
||||||
VolumeSize: c.String("backend-k8s-volume-size"),
|
VolumeSize: c.String("backend-k8s-volume-size"),
|
||||||
StorageRwx: c.Bool("backend-k8s-storage-rwx"),
|
StorageRwx: c.Bool("backend-k8s-storage-rwx"),
|
||||||
}, nil
|
}
|
||||||
|
// Unmarshal label and annotation settings here to ensure they're valid on startup
|
||||||
|
err := yaml.Unmarshal([]byte(c.String("backend-k8s-pod-labels")), &config.PodLabels)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("could not unmarshal pod labels '%s': %s", c.String("backend-k8s-pod-labels"), err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = yaml.Unmarshal([]byte(c.String("backend-k8s-pod-annotations")), &config.PodAnnotations)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("could not unmarshal pod annotations '%s': %s", c.String("backend-k8s-pod-annotations"), err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &config, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +162,7 @@ func (e *kube) Setup(ctx context.Context, conf *types.Config) error {
|
||||||
|
|
||||||
// Start the pipeline step.
|
// Start the pipeline step.
|
||||||
func (e *kube) Exec(ctx context.Context, step *types.Step) error {
|
func (e *kube) Exec(ctx context.Context, step *types.Step) error {
|
||||||
pod := Pod(e.config.Namespace, step)
|
pod := Pod(e.config.Namespace, step, e.config.PodLabels, e.config.PodAnnotations)
|
||||||
log.Trace().Msgf("Creating pod: %s", pod.Name)
|
log.Trace().Msgf("Creating pod: %s", pod.Name)
|
||||||
_, err := e.client.CoreV1().Pods(e.config.Namespace).Create(ctx, pod, metav1.CreateOptions{})
|
_, err := e.client.CoreV1().Pods(e.config.Namespace).Create(ctx, pod, metav1.CreateOptions{})
|
||||||
return err
|
return err
|
||||||
|
@ -232,7 +247,8 @@ func (e *kube) Tail(ctx context.Context, step *types.Step) (io.ReadCloser, error
|
||||||
<-up
|
<-up
|
||||||
|
|
||||||
opts := &v1.PodLogOptions{
|
opts := &v1.PodLogOptions{
|
||||||
Follow: true,
|
Follow: true,
|
||||||
|
Container: podName,
|
||||||
}
|
}
|
||||||
|
|
||||||
logs, err := e.client.CoreV1().RESTClient().Get().
|
logs, err := e.client.CoreV1().RESTClient().Get().
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Pod(namespace string, step *types.Step) *v1.Pod {
|
func Pod(namespace string, step *types.Step, labels, annotations map[string]string) *v1.Pod {
|
||||||
var (
|
var (
|
||||||
vols []v1.Volume
|
vols []v1.Volume
|
||||||
volMounts []v1.VolumeMount
|
volMounts []v1.VolumeMount
|
||||||
|
@ -88,13 +88,14 @@ func Pod(namespace string, step *types.Step) *v1.Pod {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
labels["step"] = podName(step)
|
||||||
|
|
||||||
return &v1.Pod{
|
return &v1.Pod{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: podName(step),
|
Name: podName(step),
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Labels: map[string]string{
|
Labels: labels,
|
||||||
"step": podName(step),
|
Annotations: annotations,
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Spec: v1.PodSpec{
|
Spec: v1.PodSpec{
|
||||||
RestartPolicy: v1.RestartPolicyNever,
|
RestartPolicy: v1.RestartPolicyNever,
|
||||||
|
|
Loading…
Reference in a new issue