From bffc9c8ff8fe5132465ab7f35d9bf63feeb7db56 Mon Sep 17 00:00:00 2001 From: Elias Date: Sat, 17 Feb 2024 08:30:06 -0300 Subject: [PATCH] fix: can't run multiple services on k8s (#3395) Fix Issue: https://github.com/woodpecker-ci/woodpecker/issues/3288 The way the pod service starts up makes it impossible to run two or more pipelines at the same time when we have a service section. The idea is to set the name of the service in the same way we did for the pod name. Pipeline: ```yaml services: mydb: image: mysql environment: - MYSQL_DATABASE=test - MYSQL_ROOT_PASSWORD=example ports: - 3306/tcp steps: get-version: image: ubuntu commands: - ( apt update && apt dist-upgrade -y && apt install -y mysql-client 2>&1 )> /dev/null - sleep 30s # need to wait for mysql-server init - echo 'SHOW VARIABLES LIKE "version"' | mysql -uroot -hmydb test -pexample ``` Running more than one pipeline result: ![image](https://github.com/woodpecker-ci/woodpecker/assets/22245125/e512309f-0d1e-4125-bab9-2357a710fedd) --------- Co-authored-by: elias.souza --- pipeline/backend/kubernetes/pod.go | 2 +- pipeline/backend/kubernetes/pod_test.go | 2 +- pipeline/backend/kubernetes/service.go | 5 +++-- pipeline/backend/kubernetes/service_test.go | 17 +++++++++-------- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/pipeline/backend/kubernetes/pod.go b/pipeline/backend/kubernetes/pod.go index 698cdba57..70413951f 100644 --- a/pipeline/backend/kubernetes/pod.go +++ b/pipeline/backend/kubernetes/pod.go @@ -90,7 +90,7 @@ func podMeta(step *types.Step, config *config, options BackendOptions, podName s } if step.Type == types.StepTypeService { - meta.Labels[ServiceLabel] = step.Name + meta.Labels[ServiceLabel], _ = serviceName(step) } meta.Annotations = config.PodAnnotations diff --git a/pipeline/backend/kubernetes/pod_test.go b/pipeline/backend/kubernetes/pod_test.go index 207b050a0..167ba849e 100644 --- a/pipeline/backend/kubernetes/pod_test.go +++ b/pipeline/backend/kubernetes/pod_test.go @@ -51,7 +51,7 @@ func TestStepToPodName(t *testing.T) { assert.EqualValues(t, "wp-01he8bebctabr3kg", name) name, err = stepToPodName(&types.Step{UUID: "01he8bebctabr3kg", Name: "postgres", Type: types.StepTypeService}) assert.NoError(t, err) - assert.EqualValues(t, "postgres", name) + assert.EqualValues(t, "wp-svc-01he8bebctabr3kg-postgres", name) } func TestStepLabel(t *testing.T) { diff --git a/pipeline/backend/kubernetes/service.go b/pipeline/backend/kubernetes/service.go index 6d3d54df0..48c8d3fdc 100644 --- a/pipeline/backend/kubernetes/service.go +++ b/pipeline/backend/kubernetes/service.go @@ -29,7 +29,8 @@ import ( ) const ( - ServiceLabel = "service" + ServiceLabel = "service" + servicePrefix = "wp-svc-" ) func mkService(step *types.Step, config *config) (*v1.Service, error) { @@ -62,7 +63,7 @@ func mkService(step *types.Step, config *config) (*v1.Service, error) { } func serviceName(step *types.Step) (string, error) { - return dnsName(step.Name) + return dnsName(servicePrefix + step.UUID + "-" + step.Name) } func servicePort(port types.Port) v1.ServicePort { diff --git a/pipeline/backend/kubernetes/service_test.go b/pipeline/backend/kubernetes/service_test.go index 0380f1101..91ce54c1b 100644 --- a/pipeline/backend/kubernetes/service_test.go +++ b/pipeline/backend/kubernetes/service_test.go @@ -24,24 +24,24 @@ import ( ) func TestServiceName(t *testing.T) { - name, err := serviceName(&types.Step{Name: "database"}) + name, err := serviceName(&types.Step{Name: "database", UUID: "01he8bebctabr3kgk0qj36d2me"}) assert.NoError(t, err) - assert.Equal(t, "database", name) + assert.Equal(t, "wp-svc-01he8bebctabr3kgk0qj36d2me-database", name) - name, err = serviceName(&types.Step{Name: "wp-01he8bebctabr3kgk0qj36d2me-0-services-0.woodpecker-runtime.svc.cluster.local"}) + name, err = serviceName(&types.Step{Name: "wp-01he8bebctabr3kgk0qj36d2me-0-services-0.woodpecker-runtime.svc.cluster.local", UUID: "01he8bebctabr3kgk0qj36d2me"}) assert.NoError(t, err) - assert.Equal(t, "wp-01he8bebctabr3kgk0qj36d2me-0-services-0.woodpecker-runtime.svc.cluster.local", name) + assert.Equal(t, "wp-svc-01he8bebctabr3kgk0qj36d2me-wp-01he8bebctabr3kgk0qj36d2me-0-services-0.woodpecker-runtime.svc.cluster.local", name) - name, err = serviceName(&types.Step{Name: "awesome_service"}) + name, err = serviceName(&types.Step{Name: "awesome_service", UUID: "01he8bebctabr3kgk0qj36d2me"}) assert.NoError(t, err) - assert.Equal(t, "awesome-service", name) + assert.Equal(t, "wp-svc-01he8bebctabr3kgk0qj36d2me-awesome-service", name) } func TestService(t *testing.T) { expected := ` { "metadata": { - "name": "bar", + "name": "wp-svc-01he8bebctabr3kgk0qj36d2me-0-bar", "namespace": "foo", "creationTimestamp": null }, @@ -66,7 +66,7 @@ func TestService(t *testing.T) { } ], "selector": { - "service": "bar" + "service": "wp-svc-01he8bebctabr3kgk0qj36d2me-0-bar" }, "type": "ClusterIP" }, @@ -81,6 +81,7 @@ func TestService(t *testing.T) { } s, err := mkService(&types.Step{ Name: "bar", + UUID: "01he8bebctabr3kgk0qj36d2me-0", Ports: ports, }, &config{Namespace: "foo"}) assert.NoError(t, err)