diff --git a/docs/appendices/file-formats/app-json.md b/docs/appendices/file-formats/app-json.md index 189a892b8..c7500e19f 100644 --- a/docs/appendices/file-formats/app-json.md +++ b/docs/appendices/file-formats/app-json.md @@ -21,6 +21,7 @@ (list, optional) A list of cron resources. Keys are the names of the process types. The values are an object containing one or more of the following properties: - `command`: (string, required) +- `maintenance`: (boolean, optional) - `schedule`: (string, required) ## Formation diff --git a/docs/processes/scheduled-cron-tasks.md b/docs/processes/scheduled-cron-tasks.md index f647b6edb..a8d39fdfc 100644 --- a/docs/processes/scheduled-cron-tasks.md +++ b/docs/processes/scheduled-cron-tasks.md @@ -34,6 +34,7 @@ The `app.json` file for a given app can define a special `cron` key that contain A cron task takes the following properties: - `command`: A command to be run within the built app image. Specified commands can also be `Procfile` entries. +- `maintenance`: A boolean value that decides whether the cron task is in maintenance and therefore executable or not. - `schedule`: A [cron-compatible](https://en.wikipedia.org/wiki/Cron#Overview) scheduling definition upon which to run the command. Seconds are generally not supported. Zero or more cron tasks can be specified per app. Cron tasks are validated after the build artifact is created but before the app is deployed, and the cron schedule is updated during the post-deploy phase. diff --git a/plugins/app-json/appjson.go b/plugins/app-json/appjson.go index d251da4ea..ab80fb21f 100644 --- a/plugins/app-json/appjson.go +++ b/plugins/app-json/appjson.go @@ -55,6 +55,9 @@ type CronTask struct { // Command is the command to execute Command string `json:"command"` + // Maintenance is whether or not the cron command is in maintenance mode + Maintenance bool `json:"maintenance"` + // Schedule is the cron schedule to execute the command on Schedule string `json:"schedule"` } diff --git a/plugins/cron/cron.go b/plugins/cron/cron.go index 9fb96860c..90cbdced7 100644 --- a/plugins/cron/cron.go +++ b/plugins/cron/cron.go @@ -77,7 +77,7 @@ type FetchCronTasksInput struct { func FetchCronTasks(input FetchCronTasksInput) ([]CronTask, error) { appName := input.AppName tasks := []CronTask{} - isMaintenance := reportComputedMaintenance(appName) == "true" + isAppCronInMaintenance := reportComputedMaintenance(appName) == "true" if input.AppJSON == nil && input.AppName == "" { return tasks, fmt.Errorf("Missing app name or app.json") @@ -121,12 +121,13 @@ func FetchCronTasks(input FetchCronTasksInput) ([]CronTask, error) { return tasks, fmt.Errorf("Invalid cron schedule for app %s (schedule %s): %s", appName, c.Schedule, err.Error()) } + maintenance := isAppCronInMaintenance || c.Maintenance tasks = append(tasks, CronTask{ App: appName, Command: c.Command, Schedule: c.Schedule, ID: GenerateCommandID(appName, c), - Maintenance: isMaintenance, + Maintenance: maintenance, }) } diff --git a/plugins/scheduler-k3s/triggers.go b/plugins/scheduler-k3s/triggers.go index 4ca07841f..7a2e0e030 100644 --- a/plugins/scheduler-k3s/triggers.go +++ b/plugins/scheduler-k3s/triggers.go @@ -169,7 +169,7 @@ func TriggerSchedulerCronWrite(scheduler string, appName string) error { return nil } - allCronEntries, err := cron.FetchCronEntries(cron.FetchCronEntriesInput{AppName: appName}) + cronTasks, err := cron.FetchCronTasks(cron.FetchCronTasksInput{AppName: appName}) if err != nil { return fmt.Errorf("Error fetching cron entries: %w", err) } @@ -193,13 +193,13 @@ func TriggerSchedulerCronWrite(scheduler string, appName string) error { return fmt.Errorf("Error creating kubernetes client: %w", err) } - for _, cronEntry := range allCronEntries { + for _, cronTask := range cronTasks { labelSelector := []string{ fmt.Sprintf("app.kubernetes.io/part-of=%s", appName), - fmt.Sprintf("dokku.com/cron-id=%s", cronEntry.ID), + fmt.Sprintf("dokku.com/cron-id=%s", cronTask.ID), } - if cronEntry.Maintenance { + if cronTask.Maintenance { err = clientset.SuspendCronJobs(ctx, SuspendCronJobsInput{ Namespace: namespace, LabelSelector: strings.Join(labelSelector, ","), @@ -706,7 +706,7 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e ID: cronTask.ID, Schedule: cronTask.Schedule, Suffix: suffix, - Suspend: cronEntry.Maintenance, + Suspend: cronTask.Maintenance, }, Labels: labels, ProcessType: ProcessType_Cron,