diff --git a/cmd/template_lagoonservices_test.go b/cmd/template_lagoonservices_test.go index 786d3eb0..2d3a0110 100644 --- a/cmd/template_lagoonservices_test.go +++ b/cmd/template_lagoonservices_test.go @@ -480,6 +480,24 @@ func TestTemplateLagoonServices(t *testing.T) { templatePath: "testoutput", want: "internal/testdata/basic/service-templates/test-basic-spot-affinity", }, + { + name: "test16-nginx-php-resource-requests-from-env", + description: "tests an nginx-php deployment with service label resource requests set from env var", + args: testdata.GetSeedData( + testdata.TestData{ + ProjectName: "example-project", + EnvironmentName: "main", + Branch: "main", + LagoonYAML: "internal/testdata/complex/lagoon.resources.yml", + ImageReferences: map[string]string{ + "nginx": "harbor.example/example-project/main/nginx@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8", + "php": "harbor.example/example-project/main/php@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8", + "cli": "harbor.example/example-project/main/cli@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8", + }, + }, true), + templatePath: "testoutput", + want: "internal/testdata/complex/service-templates/test16-nginx-php-resources", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/generator/buildvalues.go b/internal/generator/buildvalues.go index ed1be72b..3a812d55 100644 --- a/internal/generator/buildvalues.go +++ b/internal/generator/buildvalues.go @@ -91,11 +91,14 @@ type Resources struct { } type ResourceLimits struct { + Cpu string `json:"cpu"` Memory string `json:"memory"` EphemeralStorage string `json:"ephemeral-storage"` } type ResourceRequests struct { + Cpu string `json:"cpu"` + Memory string `json:"memory"` EphemeralStorage string `json:"ephemeral-storage"` } @@ -200,6 +203,7 @@ type ServiceValues struct { IsDBaaS bool `json:"isDBaaS"` IsSingle bool `json:"isSingle"` AdditionalVolumes []ServiceVolume `json:"additonalVolumes,omitempty"` + Resources Resources `json:"resources,omitempty"` } type ImageBuild struct { diff --git a/internal/generator/services.go b/internal/generator/services.go index f3e8908e..6bd81836 100644 --- a/internal/generator/services.go +++ b/internal/generator/services.go @@ -511,6 +511,53 @@ func composeToServiceValues( } + // Helper lambda to look for resource requirement label, validate it, and update value + updateResourceRequirement := func(dest *string, resource_suffix string) (err error) { + // First check for branch override labels (example: lagoon.resources.override-branch.dev.requests.cpu) + { + branchOverrideLabel := fmt.Sprintf("lagoon.resources.override-branch.%s.%s", buildValues.Branch, resource_suffix) + + overrideResourceValue := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, branchOverrideLabel) + if overrideResourceValue != "" { + err := ValidateResourceQuantity(overrideResourceValue) + if err != nil { + return fmt.Errorf("Value of resource requirement label %s for %s is not valid resource quantity: %v", branchOverrideLabel, servicePersistentName, err) + } + *dest = overrideResourceValue + return nil + } + } + + // If no branch override, check for base service label (example: lagoon.resources.requests.cpu) + { + baseLabel := fmt.Sprintf("lagoon.resources.%s", resource_suffix) + resourceValue := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, baseLabel) + if resourceValue != "" { + err := ValidateResourceQuantity(resourceValue) + if err != nil { + return fmt.Errorf("Value of resource requirement label %s for %s is not valid resource quantity: %v", baseLabel, servicePersistentName, err) + } + *dest = resourceValue + } + } + return nil + } + + // Build container resource requirements from service labels, either base label or branch specific override. + resources := Resources{} + if err := updateResourceRequirement(&resources.Requests.Cpu, "requests.cpu"); err != nil { + return nil, err + } + if err := updateResourceRequirement(&resources.Requests.Memory, "requests.memory"); err != nil { + return nil, err + } + if err := updateResourceRequirement(&resources.Limits.Cpu, "limits.cpu"); err != nil { + return nil, err + } + if err := updateResourceRequirement(&resources.Limits.Memory, "limits.memory"); err != nil { + return nil, err + } + // create the service values cService := &ServiceValues{ Name: composeService, @@ -535,6 +582,7 @@ func composeToServiceValues( IsSingle: svcIsSingle, BackupsEnabled: backupsEnabled, AdditionalVolumes: serviceVolumes, + Resources: resources, } // work out the images here and the associated dockerfile and contexts diff --git a/internal/generator/services_test.go b/internal/generator/services_test.go index 94d84323..4a753be2 100644 --- a/internal/generator/services_test.go +++ b/internal/generator/services_test.go @@ -1236,6 +1236,65 @@ func Test_composeToServiceValues(t *testing.T) { want: nil, wantErr: true, }, + { + name: "test24 - service label resource requirements into ServiceValues", + args: args{ + buildValues: &BuildValues{ + Namespace: "example-project-main", + Project: "example-project", + ImageRegistry: "harbor.example", + Environment: "main", + Branch: "main", + BuildType: "branch", + ServiceTypeOverrides: &lagoon.EnvironmentVariable{}, + LagoonYAML: lagoon.YAML{ + Environments: lagoon.Environments{ + "main": lagoon.Environment{}, + }, + }, + }, + composeService: "nginx", + composeServiceValues: composetypes.ServiceConfig{ + Labels: composetypes.Labels{ + "lagoon.type": "nginx", + "lagoon.name": "nginx-php", + "lagoon.resources.requests.cpu": "200m", + "lagoon.resources.requests.memory": "200Mi", + "lagoon.resources.limits.cpu": "400m", + "lagoon.resources.limits.memory": "1Gi", + }, + Build: &composetypes.BuildConfig{ + Context: ".", + Dockerfile: "../testdata/basic/docker/basic.dockerfile", + }, + }, + }, + want: &ServiceValues{ + Name: "nginx", + OverrideName: "nginx-php", + Type: "nginx", + AutogeneratedRoutesEnabled: true, + AutogeneratedRoutesTLSAcme: true, + InPodCronjobs: []lagoon.Cronjob{}, + NativeCronjobs: []lagoon.Cronjob{}, + ImageBuild: &ImageBuild{ + TemporaryImage: "example-project-main-nginx", + Context: ".", + DockerFile: "../testdata/basic/docker/basic.dockerfile", + BuildImage: "harbor.example/example-project/main/nginx:latest", + }, + Resources: Resources{ + Requests: ResourceRequests{ + Cpu: "200m", + Memory: "200Mi", + }, + Limits: ResourceLimits{ + Cpu: "400m", + Memory: "1Gi", + }, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/templating/services/templates_deployment.go b/internal/templating/services/templates_deployment.go index 880b6c8e..0b388131 100644 --- a/internal/templating/services/templates_deployment.go +++ b/internal/templating/services/templates_deployment.go @@ -10,6 +10,7 @@ import ( "github.com/uselagoon/build-deploy-tool/internal/servicetypes" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" apivalidation "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -595,6 +596,8 @@ func GenerateDeploymentTemplate( } // set the resource limit overrides if htey are provided + // + // TODO: cpu limit, and cpu/mem requests have been added, should consider wiring up BuildValues resource override if buildValues.Resources.Limits.Memory != "" { if container.Container.Resources.Limits == nil { container.Container.Resources.Limits = corev1.ResourceList{} @@ -614,6 +617,35 @@ func GenerateDeploymentTemplate( container.Container.Resources.Requests[corev1.ResourceEphemeralStorage] = resource.MustParse(buildValues.Resources.Requests.EphemeralStorage) } + // If service resource overrides are present, use those + if serviceValues.Resources.Requests.Cpu != "" { + if container.Container.Resources.Requests == nil { + container.Container.Resources.Requests = corev1.ResourceList{} + } + container.Container.Resources.Requests[v1.ResourceCPU] = resource.MustParse(serviceValues.Resources.Requests.Cpu) + } + + if serviceValues.Resources.Requests.Memory != "" { + if container.Container.Resources.Requests == nil { + container.Container.Resources.Requests = corev1.ResourceList{} + } + container.Container.Resources.Requests[v1.ResourceMemory] = resource.MustParse(serviceValues.Resources.Requests.Memory) + } + + if serviceValues.Resources.Limits.Cpu != "" { + if container.Container.Resources.Limits == nil { + container.Container.Resources.Limits = corev1.ResourceList{} + } + container.Container.Resources.Limits[v1.ResourceCPU] = resource.MustParse(serviceValues.Resources.Limits.Cpu) + } + + if serviceValues.Resources.Limits.Memory != "" { + if container.Container.Resources.Limits == nil { + container.Container.Resources.Limits = corev1.ResourceList{} + } + container.Container.Resources.Limits[v1.ResourceMemory] = resource.MustParse(serviceValues.Resources.Limits.Memory) + } + // append the final defined container to the spec deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, container.Container) @@ -693,6 +725,36 @@ func GenerateDeploymentTemplate( helpers.TemplateThings(tpld, svm, &volumeMount) linkedContainer.Container.VolumeMounts = append(linkedContainer.Container.VolumeMounts, volumeMount) } + + // If service resource overrides are present, use those + if serviceValues.LinkedService.Resources.Requests.Cpu != "" { + if linkedContainer.Container.Resources.Requests == nil { + linkedContainer.Container.Resources.Requests = corev1.ResourceList{} + } + linkedContainer.Container.Resources.Requests[v1.ResourceCPU] = resource.MustParse(serviceValues.LinkedService.Resources.Requests.Cpu) + } + + if serviceValues.LinkedService.Resources.Requests.Memory != "" { + if linkedContainer.Container.Resources.Requests == nil { + linkedContainer.Container.Resources.Requests = corev1.ResourceList{} + } + linkedContainer.Container.Resources.Requests[v1.ResourceMemory] = resource.MustParse(serviceValues.LinkedService.Resources.Requests.Memory) + } + + if serviceValues.LinkedService.Resources.Limits.Cpu != "" { + if linkedContainer.Container.Resources.Limits == nil { + linkedContainer.Container.Resources.Limits = corev1.ResourceList{} + } + linkedContainer.Container.Resources.Limits[v1.ResourceCPU] = resource.MustParse(serviceValues.LinkedService.Resources.Limits.Cpu) + } + + if serviceValues.LinkedService.Resources.Limits.Memory != "" { + if linkedContainer.Container.Resources.Limits == nil { + linkedContainer.Container.Resources.Limits = corev1.ResourceList{} + } + linkedContainer.Container.Resources.Limits[v1.ResourceMemory] = resource.MustParse(serviceValues.LinkedService.Resources.Limits.Memory) + } + deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, linkedContainer.Container) } diff --git a/internal/templating/services/templates_deployment_test.go b/internal/templating/services/templates_deployment_test.go index ed41989c..bd4c0ca8 100644 --- a/internal/templating/services/templates_deployment_test.go +++ b/internal/templating/services/templates_deployment_test.go @@ -912,6 +912,71 @@ func TestGenerateDeploymentTemplate(t *testing.T) { }, want: "test-resources/deployment/result-basic-4.yaml", }, + { + name: "test20 - nginx-php ServiceValues Resource Override", + args: args{ + buildValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment-name", + EnvironmentType: "production", + Namespace: "myexample-project-environment-name", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment-name", + FeatureFlags: map[string]bool{ + "rootlessworkloads": true, + }, + PodSecurityContext: generator.PodSecurityContext{ + RunAsGroup: 0, + RunAsUser: 10000, + FsGroup: 10001, + }, + GitSHA: "0", + ConfigMapSha: "32bf1359ac92178c8909f0ef938257b477708aa0d78a5a15ad7c2d7919adf273", + ImageReferences: map[string]string{ + "nginx": "harbor.example.com/example-project/environment-name/nginx@latest", + "php": "harbor.example.com/example-project/environment-name/php@latest", + }, + // BuildValues.Resouces not expected to be used as is overriden by ServiceValues resource + // (Included to verify ServiceValues is final word) + Resources: generator.Resources{Limits: generator.ResourceLimits{Memory: "2Gi"}}, + Services: []generator.ServiceValues{ + { + Name: "nginx", + OverrideName: "nginx", + Type: "nginx-php", + DBaaSEnvironment: "production", + // Leave primary mem request as default, ensure that default from ServiceType is still templated + Resources: generator.Resources{ + Requests: generator.ResourceRequests{Cpu: "500m"}, + Limits: generator.ResourceLimits{ + Cpu: "2", + Memory: "1Gi", + }, + }, + }, + { + Name: "php", + OverrideName: "nginx", + Type: "nginx-php", + DBaaSEnvironment: "production", + Resources: generator.Resources{ + Requests: generator.ResourceRequests{ + Cpu: "500m", + Memory: "200Mi", + }, + Limits: generator.ResourceLimits{ + Cpu: "500m", + Memory: "1Gi", + }, + }, + }, + }, + }, + }, + want: "test-resources/deployment/result-nginx-php-resources-1.yaml", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/templating/services/test-resources/deployment/result-nginx-php-resources-1.yaml b/internal/templating/services/test-resources/deployment/result-nginx-php-resources-1.yaml new file mode 100644 index 00000000..037c228d --- /dev/null +++ b/internal/templating/services/test-resources/deployment/result-nginx-php-resources-1.yaml @@ -0,0 +1,130 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + lagoon.sh/branch: environment-name + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: nginx + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: nginx-php + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-name + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: nginx + lagoon.sh/service-type: nginx-php + lagoon.sh/template: nginx-php-0.1.0 + name: nginx +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: nginx + app.kubernetes.io/name: nginx-php + strategy: {} + template: + metadata: + annotations: + lagoon.sh/branch: environment-name + lagoon.sh/configMapSha: 32bf1359ac92178c8909f0ef938257b477708aa0d78a5a15ad7c2d7919adf273 + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: nginx + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: nginx-php + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-name + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: nginx + lagoon.sh/service-type: nginx-php + lagoon.sh/template: nginx-php-0.1.0 + spec: + containers: + - env: + - name: NGINX_FASTCGI_PASS + value: 127.0.0.1 + - name: LAGOON_GIT_SHA + value: "0" + - name: CRONJOBS + - name: SERVICE_NAME + value: nginx + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example.com/example-project/environment-name/nginx@latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 5 + httpGet: + path: /nginx_status + port: 50000 + initialDelaySeconds: 900 + timeoutSeconds: 3 + name: nginx + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /nginx_status + port: 50000 + initialDelaySeconds: 1 + timeoutSeconds: 3 + resources: + limits: + cpu: "2" + memory: 1Gi + requests: + cpu: 500m + memory: 10Mi + securityContext: {} + - env: + - name: NGINX_FASTCGI_PASS + value: 127.0.0.1 + - name: LAGOON_GIT_SHA + value: "0" + - name: SERVICE_NAME + value: nginx + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example.com/example-project/environment-name/php@latest + imagePullPolicy: Always + livenessProbe: + initialDelaySeconds: 60 + periodSeconds: 10 + tcpSocket: + port: 9000 + name: php + ports: + - containerPort: 9000 + name: php + protocol: TCP + readinessProbe: + initialDelaySeconds: 2 + periodSeconds: 10 + tcpSocket: + port: 9000 + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 500m + memory: 200Mi + securityContext: {} + enableServiceLinks: false + imagePullSecrets: + - name: lagoon-internal-registry-secret + priorityClassName: lagoon-priority-production + securityContext: + fsGroup: 10001 + runAsGroup: 0 + runAsUser: 10000 +status: {} diff --git a/internal/testdata/complex/docker-compose.resources.yml b/internal/testdata/complex/docker-compose.resources.yml new file mode 100644 index 00000000..2fe535f9 --- /dev/null +++ b/internal/testdata/complex/docker-compose.resources.yml @@ -0,0 +1,105 @@ +version: '2.3' + +x-example-image-version: + &example-image-version ${EXAMPLE_IMAGE_VERSION:-4.x} + +x-project: + &project ${PROJECT_NAME:-mysite} + +x-volumes: + &default-volumes + volumes: + - .:/app:${VOLUME_FLAGS:-delegated} ### Local overrides to mount host filesystem. Automatically removed in CI and PROD. + - ./docroot/sites/default/files:/app/docroot/sites/default/files:${VOLUME_FLAGS:-delegated} ### Local overrides to mount host filesystem. Automatically removed in CI and PROD. + +x-environment: + &default-environment + LAGOON_PROJECT: *project + DRUPAL_HASH_SALT: fakehashsaltfakehashsaltfakehashsalt + LAGOON_LOCALDEV_URL: ${LOCALDEV_URL:-http://mysite.docker.amazee.io} + LAGOON_ROUTE: ${LOCALDEV_URL:-http://mysite.docker.amazee.io} + GITHUB_TOKEN: ${GITHUB_TOKEN:-} + EXAMPLE_KEY: ${EXAMPLE_KEY:-} + EXAMPLE_IMAGE_VERSION: ${EXAMPLE_IMAGE_VERSION:-latest} + LAGOON_ENVIRONMENT_TYPE: ${LAGOON_ENVIRONMENT_TYPE:-local} + DRUPAL_REFRESH_SEARCHAPI: ${DRUPAL_REFRESH_SEARCHAPI:-} + EXAMPLE_INGRESS_PSK: ${EXAMPLE_INGRESS_PSK:-} + EXAMPLE_INGRESS_HEADER: ${EXAMPLE_INGRESS_HEADER:-} + EXAMPLE_INGRESS_ENABLED: ${EXAMPLE_INGRESS_ENABLED:-} + DB_ALIAS: ${DB_ALIAS:-bay.production} + + +services: + + cli: + build: + context: internal/testdata/complex/docker + dockerfile: .docker/Dockerfile.cli + args: + COMPOSER: ${COMPOSER:-composer.json} + EXAMPLE_IMAGE_VERSION: *example-image-version + image: *project + environment: + << : *default-environment + << : *default-volumes + volumes_from: ### Local overrides to mount host SSH keys. Automatically removed in CI. + - container:amazeeio-ssh-agent ### Local overrides to mount host SSH keys. Automatically removed in CI. + labels: + lagoon.type: cli-persistent + lagoon.persistent: /app/docroot/sites/default/files/ + lagoon.persistent.name: nginx-php + lagoon.persistent.size: 5Gi + + nginx: + build: + context: internal/testdata/complex/docker + dockerfile: .docker/Dockerfile.nginx-drupal + args: + CLI_IMAGE: *project + EXAMPLE_IMAGE_VERSION: *example-image-version + << : *default-volumes + environment: + << : *default-environment + depends_on: + - cli + networks: + - amazeeio-network + - default + labels: + lagoon.type: nginx-php-persistent + lagoon.persistent: /app/docroot/sites/default/files/ + lagoon.persistent.size: 5Gi + lagoon.name: nginx-php + lagoon.resources.requests.cpu: 10m + lagoon.resources.limits.cpu: 100m + lagoon.resources.override-branch.main.requests.cpu: 50m + expose: + - "8080" + php: + build: + context: internal/testdata/complex/docker + dockerfile: .docker/Dockerfile.php + args: + CLI_IMAGE: *project + EXAMPLE_IMAGE_VERSION: *example-image-version + environment: + << : *default-environment + << : *default-volumes + depends_on: + - cli + labels: + lagoon.type: nginx-php-persistent + lagoon.persistent: /app/docroot/sites/default/files/ + lagoon.persistent.size: 5Gi + lagoon.name: nginx-php + lagoon.resources.requests.cpu: 20m + lagoon.resources.limits.cpu: 200m + + +networks: + amazeeio-network: + external: true + +volumes: + app: {} + files: {} diff --git a/internal/testdata/complex/lagoon.resources.yml b/internal/testdata/complex/lagoon.resources.yml new file mode 100644 index 00000000..cc84e9be --- /dev/null +++ b/internal/testdata/complex/lagoon.resources.yml @@ -0,0 +1,10 @@ +--- +docker-compose-yaml: internal/testdata/complex/docker-compose.resources.yml + +project: example-com + +environments: + main: + routes: + - nginx: + - example.com diff --git a/internal/testdata/complex/service-templates/test16-nginx-php-resources/deployment-cli.yaml b/internal/testdata/complex/service-templates/test16-nginx-php-resources/deployment-cli.yaml new file mode 100644 index 00000000..86ecae22 --- /dev/null +++ b/internal/testdata/complex/service-templates/test16-nginx-php-resources/deployment-cli.yaml @@ -0,0 +1,97 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: cli + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: cli-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: cli + lagoon.sh/service-type: cli-persistent + lagoon.sh/template: cli-persistent-0.1.0 + name: cli +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: cli + app.kubernetes.io/name: cli-persistent + strategy: {} + template: + metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/configMapSha: abcdefg1234567890 + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: cli + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: cli-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: cli + lagoon.sh/service-type: cli-persistent + lagoon.sh/template: cli-persistent-0.1.0 + spec: + containers: + - env: + - name: LAGOON_GIT_SHA + value: "0000000000000000000000000000000000000000" + - name: CRONJOBS + - name: SERVICE_NAME + value: cli + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example/example-project/main/cli@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8 + imagePullPolicy: Always + name: cli + readinessProbe: + exec: + command: + - /bin/sh + - -c + - if [ -x /bin/entrypoint-readiness ]; then /bin/entrypoint-readiness; + fi + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 2 + resources: + requests: + cpu: 10m + memory: 10Mi + securityContext: {} + volumeMounts: + - mountPath: /var/run/secrets/lagoon/sshkey/ + name: lagoon-sshkey + readOnly: true + - mountPath: /app/docroot/sites/default/files//php + name: nginx-php-twig + - mountPath: /app/docroot/sites/default/files/ + name: nginx-php + enableServiceLinks: false + imagePullSecrets: + - name: lagoon-internal-registry-secret + priorityClassName: lagoon-priority-production + volumes: + - name: lagoon-sshkey + secret: + defaultMode: 420 + secretName: lagoon-sshkey + - emptyDir: {} + name: nginx-php-twig + - name: nginx-php + persistentVolumeClaim: + claimName: nginx-php +status: {} diff --git a/internal/testdata/complex/service-templates/test16-nginx-php-resources/deployment-nginx-php.yaml b/internal/testdata/complex/service-templates/test16-nginx-php-resources/deployment-nginx-php.yaml new file mode 100644 index 00000000..c82eaeda --- /dev/null +++ b/internal/testdata/complex/service-templates/test16-nginx-php-resources/deployment-nginx-php.yaml @@ -0,0 +1,138 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: nginx-php + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: nginx-php-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: nginx-php + lagoon.sh/service-type: nginx-php-persistent + lagoon.sh/template: nginx-php-persistent-0.1.0 + name: nginx-php +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: nginx-php + app.kubernetes.io/name: nginx-php-persistent + strategy: {} + template: + metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/configMapSha: abcdefg1234567890 + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: nginx-php + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: nginx-php-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: nginx-php + lagoon.sh/service-type: nginx-php-persistent + lagoon.sh/template: nginx-php-persistent-0.1.0 + spec: + containers: + - env: + - name: NGINX_FASTCGI_PASS + value: 127.0.0.1 + - name: LAGOON_GIT_SHA + value: "0000000000000000000000000000000000000000" + - name: CRONJOBS + - name: SERVICE_NAME + value: nginx-php + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example/example-project/main/nginx@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8 + imagePullPolicy: Always + livenessProbe: + failureThreshold: 5 + httpGet: + path: /nginx_status + port: 50000 + initialDelaySeconds: 900 + timeoutSeconds: 3 + name: nginx + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /nginx_status + port: 50000 + initialDelaySeconds: 1 + timeoutSeconds: 3 + resources: + limits: + cpu: 100m + requests: + cpu: 50m + memory: 10Mi + securityContext: {} + volumeMounts: + - mountPath: /app/docroot/sites/default/files/ + name: nginx-php + - env: + - name: NGINX_FASTCGI_PASS + value: 127.0.0.1 + - name: LAGOON_GIT_SHA + value: "0000000000000000000000000000000000000000" + - name: SERVICE_NAME + value: nginx-php + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example/example-project/main/php@sha256:b2001babafaa8128fe89aa8fd11832cade59931d14c3de5b3ca32e2a010fbaa8 + imagePullPolicy: Always + livenessProbe: + initialDelaySeconds: 60 + periodSeconds: 10 + tcpSocket: + port: 9000 + name: php + ports: + - containerPort: 9000 + name: php + protocol: TCP + readinessProbe: + initialDelaySeconds: 2 + periodSeconds: 10 + tcpSocket: + port: 9000 + resources: + limits: + cpu: 200m + requests: + cpu: 20m + memory: 100Mi + securityContext: {} + volumeMounts: + - mountPath: /app/docroot/sites/default/files/ + name: nginx-php + - mountPath: /app/docroot/sites/default/files//php + name: nginx-php-twig + enableServiceLinks: false + imagePullSecrets: + - name: lagoon-internal-registry-secret + priorityClassName: lagoon-priority-production + volumes: + - name: nginx-php + persistentVolumeClaim: + claimName: nginx-php + - emptyDir: {} + name: nginx-php-twig +status: {} diff --git a/internal/testdata/complex/service-templates/test16-nginx-php-resources/pvc-nginx-php.yaml b/internal/testdata/complex/service-templates/test16-nginx-php-resources/pvc-nginx-php.yaml new file mode 100644 index 00000000..9705d159 --- /dev/null +++ b/internal/testdata/complex/service-templates/test16-nginx-php-resources/pvc-nginx-php.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + k8up.io/backup: "true" + k8up.syn.tools/backup: "true" + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: nginx-php + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: nginx-php-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: nginx-php + lagoon.sh/service-type: nginx-php-persistent + lagoon.sh/template: nginx-php-persistent-0.1.0 + name: nginx-php +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + storageClassName: bulk +status: {} diff --git a/internal/testdata/complex/service-templates/test16-nginx-php-resources/service-nginx-php.yaml b/internal/testdata/complex/service-templates/test16-nginx-php-resources/service-nginx-php.yaml new file mode 100644 index 00000000..0e8aba6e --- /dev/null +++ b/internal/testdata/complex/service-templates/test16-nginx-php-resources/service-nginx-php.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: nginx-php + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: nginx-php-persistent + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: nginx-php + lagoon.sh/service-type: nginx-php-persistent + lagoon.sh/template: nginx-php-persistent-0.1.0 + name: nginx-php +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: http + selector: + app.kubernetes.io/instance: nginx-php + app.kubernetes.io/name: nginx-php-persistent +status: + loadBalancer: {}