Skip to content

Commit

Permalink
feat: cronjob configureable timeouts
Browse files Browse the repository at this point in the history
  • Loading branch information
shreddedbacon committed Dec 19, 2024
1 parent e9f8dc4 commit 7b14a21
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 0 deletions.
16 changes: 16 additions & 0 deletions internal/generator/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"regexp"
"strconv"
"strings"
"time"

composetypes "github.com/compose-spec/compose-go/types"
"github.com/uselagoon/build-deploy-tool/internal/helpers"
Expand Down Expand Up @@ -490,6 +491,21 @@ func composeToServiceValues(
if err != nil {
return nil, fmt.Errorf("unable to convert crontab for cronjob %s: %v", cronjob.Name, err)
}
// handle setting the cronjob timeout here
// can't be greater than 24hrs and must match go time duration https://pkg.go.dev/time#ParseDuration
if cronjob.Timeout != "" {
cronjobTimeout, err := time.ParseDuration(cronjob.Timeout)
if err != nil {
return nil, fmt.Errorf("unable to convert timeout for cronjob %s: %v", cronjob.Name, err)
}
// max cronjob timeout is 24 hours
if cronjobTimeout > time.Duration(24*time.Hour) {
return nil, fmt.Errorf("timeout for cronjob %s cannot be longer than 24 hours", cronjob.Name)
}
} else {
// default cronjob timeout is 4h
cronjob.Timeout = "4h"
}
// if the cronjob is inpod, or the cronjob has an inpod flag override
if inpod || (cronjob.InPod != nil && *cronjob.InPod) {
inpodcronjobs = append(inpodcronjobs, cronjob)
Expand Down
85 changes: 85 additions & 0 deletions internal/generator/services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,7 @@ func Test_composeToServiceValues(t *testing.T) {
Service: "cli",
Schedule: "3,8,13,18,23,28,33,38,43,48,53,58 * * * *",
Command: "drush cron",
Timeout: "4h",
},
},
NativeCronjobs: []lagoon.Cronjob{
Expand All @@ -952,12 +953,14 @@ func Test_composeToServiceValues(t *testing.T) {
Service: "cli",
Schedule: "5 2 * * *",
Command: "env",
Timeout: "4h",
},
{
Name: "cronjob-cli-my-cronjob-that-has-a-very-very-v-znwv36",
Service: "cli",
Schedule: "5 2 * * *",
Command: "drush cron",
Timeout: "4h",
},
},
ImageBuild: &ImageBuild{
Expand Down Expand Up @@ -1278,6 +1281,88 @@ func Test_composeToServiceValues(t *testing.T) {
want: nil,
wantErr: true,
},
{
name: "test24 - failure on cronjob timeout longer than 24h",
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{
Cronjobs: []lagoon.Cronjob{
{
Name: "My Cronjob that has a very very very long timeout",
Command: "drush cron",
Service: "cli",
Schedule: "5 2 * * *",
Timeout: "48h",
},
},
},
},
},
},
composeService: "cli",
composeServiceValues: composetypes.ServiceConfig{
Labels: composetypes.Labels{
"lagoon.type": "cli",
},
Build: &composetypes.BuildConfig{
Context: ".",
Dockerfile: "../testdata/basic/docker/basic.dockerfile",
},
},
},
want: nil,
wantErr: true,
},
{
name: "test25 - failure on invalid cronjob timeout",
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{
Cronjobs: []lagoon.Cronjob{
{
Name: "My Cronjob that has an invalid timeout",
Command: "drush cron",
Service: "cli",
Schedule: "5 2 * * *",
Timeout: "2hrs",
},
},
},
},
},
},
composeService: "cli",
composeServiceValues: composetypes.ServiceConfig{
Labels: composetypes.Labels{
"lagoon.type": "cli",
},
Build: &composetypes.BuildConfig{
Context: ".",
Dockerfile: "../testdata/basic/docker/basic.dockerfile",
},
},
},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions internal/lagoon/lagoon.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type Cronjob struct {
Schedule string `json:"schedule"`
Command string `json:"command"`
InPod *bool `json:"inPod"`
Timeout string `json:"timeout"`
}

type Override struct {
Expand Down
6 changes: 6 additions & 0 deletions internal/templating/templates_cronjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package templating

import (
"fmt"
"time"

"github.com/uselagoon/build-deploy-tool/internal/generator"
"github.com/uselagoon/build-deploy-tool/internal/helpers"
Expand Down Expand Up @@ -104,6 +105,11 @@ func GenerateCronjobTemplate(
cronjob.Spec.StartingDeadlineSeconds = helpers.Int64Ptr(240)
cronjob.Spec.JobTemplate.Spec.Template.Spec.RestartPolicy = corev1.RestartPolicyNever

// time has already been parsed in generator/services to check for errors
// and the default timeout is added in generator/services
cronjobTimeout, _ := time.ParseDuration(nCronjob.Timeout)
cronjob.Spec.JobTemplate.Spec.ActiveDeadlineSeconds = (*int64)(&cronjobTimeout)

if serviceValues.CronjobUseSpotInstances {
// handle spot instance label and affinity/tolerations/selectors
additionalLabels["lagoon.sh/spot"] = "true"
Expand Down
50 changes: 50 additions & 0 deletions internal/templating/templates_cronjob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ func TestGenerateCronjobTemplate(t *testing.T) {
Service: "myservice",
Command: "sleep 300",
Schedule: "5 2 * * *",
Timeout: "4h",
},
{
Name: "cronjob-myservice-my-other-cronjobbb",
Service: "myservice",
Command: "env",
Schedule: "25 6 * * *",
Timeout: "4h",
},
},
},
Expand All @@ -72,6 +74,7 @@ func TestGenerateCronjobTemplate(t *testing.T) {
Service: "myservice",
Command: "sleep 300",
Schedule: "5 2 * * *",
Timeout: "4h",
},
},
},
Expand Down Expand Up @@ -116,12 +119,14 @@ func TestGenerateCronjobTemplate(t *testing.T) {
Service: "myservice",
Command: "sleep 300",
Schedule: "5 2 * * *",
Timeout: "4h",
},
{
Name: "cronjob-myservice-my-other-cronjobbb",
Service: "myservice",
Command: "env",
Schedule: "25 6 * * *",
Timeout: "4h",
},
},
},
Expand All @@ -138,6 +143,7 @@ func TestGenerateCronjobTemplate(t *testing.T) {
Service: "myservice",
Command: "sleep 300",
Schedule: "5 2 * * *",
Timeout: "4h",
},
},
},
Expand All @@ -146,6 +152,50 @@ func TestGenerateCronjobTemplate(t *testing.T) {
},
want: "test-resources/cronjob/result-cli-2.yaml",
},
{
name: "test3 - cli - security context - timeout",
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",
ImageReferences: map[string]string{
"myservice": "harbor.example.com/example-project/environment-name/myservice@latest",
},
GitSHA: "0",
ConfigMapSha: "32bf1359ac92178c8909f0ef938257b477708aa0d78a5a15ad7c2d7919adf273",
PodSecurityContext: generator.PodSecurityContext{
RunAsGroup: 0,
RunAsUser: 10000,
FsGroup: 10001,
OnRootMismatch: true,
},
Services: []generator.ServiceValues{
{
Name: "myservice",
OverrideName: "myservice",
Type: "cli",
DBaaSEnvironment: "production",
NativeCronjobs: []lagoon.Cronjob{
{
Name: "cronjob-myservice-my-cronjob",
Service: "myservice",
Command: "sleep 300",
Schedule: "5 2 * * *",
Timeout: "24h",
},
},
},
},
},
},
want: "test-resources/cronjob/result-cli-3.yaml",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
3 changes: 3 additions & 0 deletions internal/templating/test-resources/cronjob/result-cli-1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ spec:
metadata:
creationTimestamp: null
spec:
activeDeadlineSeconds: 14400000000000
template:
metadata:
annotations:
Expand Down Expand Up @@ -115,6 +116,7 @@ spec:
metadata:
creationTimestamp: null
spec:
activeDeadlineSeconds: 14400000000000
template:
metadata:
annotations:
Expand Down Expand Up @@ -205,6 +207,7 @@ spec:
metadata:
creationTimestamp: null
spec:
activeDeadlineSeconds: 14400000000000
template:
metadata:
annotations:
Expand Down
3 changes: 3 additions & 0 deletions internal/templating/test-resources/cronjob/result-cli-2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ spec:
metadata:
creationTimestamp: null
spec:
activeDeadlineSeconds: 14400000000000
template:
metadata:
annotations:
Expand Down Expand Up @@ -120,6 +121,7 @@ spec:
metadata:
creationTimestamp: null
spec:
activeDeadlineSeconds: 14400000000000
template:
metadata:
annotations:
Expand Down Expand Up @@ -215,6 +217,7 @@ spec:
metadata:
creationTimestamp: null
spec:
activeDeadlineSeconds: 14400000000000
template:
metadata:
annotations:
Expand Down
Loading

0 comments on commit 7b14a21

Please sign in to comment.