Add ports into pipeline backend step model (#2656)

Closes #2655.


[Pipeline](https://woodpecker-ci.org/docs/next/usage/services#complete-pipeline-example):
```yaml
services:
  database:
    image: mysql
    environment:
      - MYSQL_DATABASE=test
      - MYSQL_ROOT_PASSWORD=example
    ports:
      - 3306

steps:
  get-version:
    image: ubuntu
    commands:
      - ( apt update && apt dist-upgrade -y && apt install -y mysql-client 2>&1 )> /dev/null
      - sleep 60s # need to wait for mysql-server init
      - echo 'SHOW VARIABLES LIKE "version"' | mysql -uroot -hdatabase test -pexample
```

Service:
```yaml
apiVersion: v1
kind: Service
metadata:
  name: wp-01hdq6gbkw1mn6k1655fs3rntf-0-services-0
  namespace: woodpecker-runtime
  ...
  selfLink: >-
    /api/v1/namespaces/woodpecker-runtime/services/wp-01hdq6gbkw1mn6k1655fs3rntf-0-services-0
status:
  loadBalancer: {}
spec:
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
  selector:
    step: database
  clusterIP: 10.43.180.120
  clusterIPs:
    - 10.43.180.120
  type: ClusterIP
  sessionAffinity: None
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  internalTrafficPolicy: Cluster
```
This commit is contained in:
Thomas Anderson 2023-11-02 06:12:41 +03:00 committed by GitHub
parent 3620c84da4
commit de53b906e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 18 additions and 18 deletions

View file

@ -164,9 +164,7 @@ func (e *kube) SetupWorkflow(ctx context.Context, conf *types.Config, taskUUID s
return err
}
log.Trace().Str("pod-name", stepName).Msgf("Creating service: %s", step.Name)
// TODO: support ports setting
// svc, err := Service(e.config.Namespace, step.Name, stepName, step.Ports)
svc, err := Service(e.config.Namespace, step.Name, stepName, []string{})
svc, err := Service(e.config.Namespace, step.Name, step.Alias, step.Ports)
if err != nil {
return err
}
@ -393,9 +391,7 @@ func (e *kube) DestroyWorkflow(_ context.Context, conf *types.Config, taskUUID s
if stage.Alias == "services" {
for _, step := range stage.Steps {
log.Trace().Msgf("Deleting service: %s", step.Name)
// TODO: support ports setting
// svc, err := Service(e.config.Namespace, step.Name, step.Alias, step.Ports)
svc, err := Service(e.config.Namespace, step.Name, step.Alias, []string{})
svc, err := Service(e.config.Namespace, step.Name, step.Alias, step.Ports)
if err != nil {
return err
}

View file

@ -15,24 +15,17 @@
package kubernetes
import (
"fmt"
"strconv"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)
func Service(namespace, name, podName string, ports []string) (*v1.Service, error) {
func Service(namespace, name, podName string, ports []uint16) (*v1.Service, error) {
var svcPorts []v1.ServicePort
for _, p := range ports {
i, err := strconv.Atoi(p)
if err != nil {
return nil, fmt.Errorf("Could not parse service port %s as integer", p)
}
for _, port := range ports {
svcPorts = append(svcPorts, v1.ServicePort{
Port: int32(i),
TargetPort: intstr.IntOrString{IntVal: int32(i)},
Port: int32(port),
TargetPort: intstr.IntOrString{IntVal: int32(port)},
})
}

View file

@ -54,7 +54,7 @@ func TestService(t *testing.T) {
}
}`
s, _ := Service("foo", "bar", "baz", []string{"1", "2", "3"})
s, _ := Service("foo", "bar", "baz", []uint16{1, 2, 3})
j, err := json.Marshal(s)
assert.NoError(t, err)
assert.JSONEq(t, expected, string(j))

View file

@ -48,6 +48,7 @@ type Step struct {
NetworkMode string `json:"network_mode,omitempty"`
IpcMode string `json:"ipc_mode,omitempty"`
Sysctls map[string]string `json:"sysctls,omitempty"`
Ports []uint16 `json:"ports,omitempty"`
BackendOptions BackendOptions `json:"backend_options,omitempty"`
}

View file

@ -164,6 +164,11 @@ func (c *Compiler) createProcess(name string, container *yaml_types.Container, s
cpuSet = c.reslimit.CPUSet
}
var ports []uint16
for _, port := range container.Ports {
ports = append(ports, uint16(port))
}
// at least one constraint contain status success, or all constraints have no status set
onSuccess := container.When.IncludesStatusSuccess()
// at least one constraint must include the status failure.
@ -206,6 +211,7 @@ func (c *Compiler) createProcess(name string, container *yaml_types.Container, s
Failure: failure,
NetworkMode: networkMode,
IpcMode: ipcMode,
Ports: ports,
BackendOptions: backendOptions,
}
}

View file

@ -47,6 +47,7 @@ type (
Settings map[string]interface{} `yaml:"settings"`
Volumes Volumes `yaml:"volumes,omitempty"`
When constraint.When `yaml:"when,omitempty"`
Ports []base.StringOrInt `yaml:"ports,omitempty"`
// Docker Specific
Privileged bool `yaml:"privileged,omitempty"`

View file

@ -68,6 +68,8 @@ when:
settings:
foo: bar
baz: false
ports:
- 8080
`)
func TestUnmarshalContainer(t *testing.T) {
@ -126,6 +128,7 @@ func TestUnmarshalContainer(t *testing.T) {
"foo": "bar",
"baz": false,
},
Ports: []base.StringOrInt{8080},
}
got := Container{}
err := yaml.Unmarshal(containerYaml, &got)