diff --git a/docs/appendices/0.23.0-migration-guide.md b/docs/appendices/0.23.0-migration-guide.md index b46cb8bc4..2853eafde 100644 --- a/docs/appendices/0.23.0-migration-guide.md +++ b/docs/appendices/0.23.0-migration-guide.md @@ -4,5 +4,5 @@ - The `plugin:list` command no longer outputs the version for the `plugn` binary. - Users building docker images that run Dokku will need to use a new sudoer wrapper for the `docker-image-labeler` binary to work correctly. A reference version has been placed in the `docker` skeleton directory. This should only impact platform developers, and users of our Docker image will already have the file available. -- The `dokku` user's cron is now in use by Dokku itself. Customizations will be overwritten. Users are encouraged to use a cron entry in `/etc/cron.d/dokku` to avoid this issue. +- The `dokku` user's cron is now in use by Dokku itself. Customizations will be overwritten. Users are encouraged to use a cron file at `/etc/cron.d/dokku` to avoid this issue. - As of 0.23.0, Dokku will now inject the `max-size` log driver option for applications. This is restricted to app-configured log driver values empty, `local` or `json-file` in 0.23.1 to increase setup compatibility. Users who configure alternative log drivers at the system level will need to either set the global `max-size` property to `unlimited` or switch to the built-in `vector` logging support. diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md index 43bbab731..1d202951c 100644 --- a/docs/development/plugin-triggers.md +++ b/docs/development/plugin-triggers.md @@ -582,7 +582,7 @@ APP="$1"; PROPERTY="$2" ### `cron-entries` -- Description: Allows injecting cron entries into the written out scheduled cron task list. Each entry is newline delimited, and individual entries come in the form `$SCHEDULE;$FULL_COMMAND;$ARBITRARY_DATA`. Individual implementations of cron writing can decide whether and how to include these cron entries. The `ARBITRARY_DATA` includes the log file path for the basic `docker-local` cron implementation. +- Description: Allows injecting cron tasks into the written out scheduled cron task list. Each entry is newline delimited, and individual tasks come in the form `$SCHEDULE;$FULL_COMMAND;$ARBITRARY_DATA`. Individual implementations of cron writing can decide whether and how to include these cron tasks. The `ARBITRARY_DATA` includes the log file path for the basic `docker-local` cron implementation. - Invoked by: - Arguments: `$DOKKU_SCHEDULER` - Example: @@ -2450,7 +2450,7 @@ DOKKU_SCHEDULER="$1"; APP="$2"; > The scheduler plugin trigger apis are under development and may change > between minor releases until the 1.0 release. -- Description: Force triggers writing out cron entries. Arguments are optional. +- Description: Force triggers writing out cron tasks. Arguments are optional. - Invoked by: `ps:start`, `ps:stop`, `cron:set` - Arguments: `$DOKKU_SCHEDULER $APP` - Example: diff --git a/docs/processes/scheduled-cron-tasks.md b/docs/processes/scheduled-cron-tasks.md index 76c3f2232..0fe1d3cbe 100644 --- a/docs/processes/scheduled-cron-tasks.md +++ b/docs/processes/scheduled-cron-tasks.md @@ -31,12 +31,12 @@ The `app.json` file for a given app can define a special `cron` key that contain } ``` -A cron entry takes the following properties: +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. - `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 commands can be specified per app. Cron entries 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. +Zero or more cron commands 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. See the [app.json location documentation](/docs/advanced-usage/deployment-tasks.md#changing-the-appjson-location) for more information on where to place your `app.json` file. @@ -218,7 +218,7 @@ For tasks that will properly resume, you _should_ use the above method, as runni Regularly scheduled tasks can be a bit of a pain with Dokku. The following are general recommendations to follow to help ensure successful task runs. -- Use the `dokku` user in your cron entry. +- Use the `dokku` user in your cron task. - If you do not, the `dokku` binary will attempt to execute with `sudo`, and your cron run with fail with `sudo: no tty present and no askpass program specified`. - Add a `MAILTO` environment variable to ship cron emails to yourself. - Add a `PATH` environment variable or specify the full path to binaries on the host. diff --git a/plugins/cron/cron.go b/plugins/cron/cron.go index 12754f846..f5a74e0bd 100644 --- a/plugins/cron/cron.go +++ b/plugins/cron/cron.go @@ -66,15 +66,15 @@ func (t TemplateCommand) CronCommand() string { return fmt.Sprintf("dokku run --cron-id %s %s %s", t.ID, t.App, t.Command) } -// FetchCronEntriesInput is the input for the FetchCronEntries function -type FetchCronEntriesInput struct { +// FetchCronTasksInput is the input for the FetchCronTasks function +type FetchCronTasksInput struct { AppName string AppJSON *appjson.AppJSON WarnToFailure bool } -// FetchCronEntries returns a list of cron commands for a given app -func FetchCronEntries(input FetchCronEntriesInput) ([]TemplateCommand, error) { +// FetchCronTasks returns a list of cron commands for a given app +func FetchCronTasks(input FetchCronTasksInput) ([]TemplateCommand, error) { appName := input.AppName commands := []TemplateCommand{} isMaintenance := reportComputedMaintenance(appName) == "true" @@ -129,10 +129,10 @@ func FetchCronEntries(input FetchCronEntriesInput) ([]TemplateCommand, error) { return commands, nil } -// FetchGlobalCronEntries returns a list of global cron commands +// FetchGlobalCronTasks returns a list of global cron commands // This function should only be used for the cron:list --global command // and not internally by the cron plugin -func FetchGlobalCronEntries() ([]TemplateCommand, error) { +func FetchGlobalCronTasks() ([]TemplateCommand, error) { commands := []TemplateCommand{} response, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{ Trigger: "cron-entries", diff --git a/plugins/cron/report.go b/plugins/cron/report.go index 3514b8f53..acf9760cb 100644 --- a/plugins/cron/report.go +++ b/plugins/cron/report.go @@ -41,7 +41,7 @@ func reportMailto(_ string) string { } func reportTasks(appName string) string { - c, _ := FetchCronEntries(FetchCronEntriesInput{AppName: appName}) + c, _ := FetchCronTasks(FetchCronTasksInput{AppName: appName}) return strconv.Itoa(len(c)) } diff --git a/plugins/cron/subcommands.go b/plugins/cron/subcommands.go index f8d0e941e..5b7057619 100644 --- a/plugins/cron/subcommands.go +++ b/plugins/cron/subcommands.go @@ -22,10 +22,10 @@ func CommandList(appName string, format string) error { return fmt.Errorf("Invalid format specified, supported formats: json, stdout") } - var entries []TemplateCommand + var tasks []TemplateCommand if appName == "--global" { var err error - entries, err = FetchGlobalCronEntries() + tasks, err = FetchGlobalCronTasks() if err != nil { return err } @@ -34,7 +34,7 @@ func CommandList(appName string, format string) error { if err := common.VerifyAppName(appName); err != nil { return err } - entries, err = FetchCronEntries(FetchCronEntriesInput{AppName: appName}) + tasks, err = FetchCronTasks(FetchCronTasksInput{AppName: appName}) if err != nil { return err } @@ -42,8 +42,8 @@ func CommandList(appName string, format string) error { if format == "stdout" { output := []string{"ID | Schedule | Maintenance | Command"} - for _, entry := range entries { - output = append(output, fmt.Sprintf("%s | %s | %t | %s", entry.ID, entry.Schedule, entry.Maintenance, entry.Command)) + for _, task := range tasks { + output = append(output, fmt.Sprintf("%s | %s | %t | %s", task.ID, task.Schedule, task.Maintenance, task.Command)) } result := columnize.SimpleFormat(output) @@ -51,7 +51,7 @@ func CommandList(appName string, format string) error { return nil } - out, err := json.Marshal(entries) + out, err := json.Marshal(tasks) if err != nil { return err } @@ -88,7 +88,7 @@ func CommandRun(appName string, cronID string, detached bool) error { return err } - entries, err := FetchCronEntries(FetchCronEntriesInput{AppName: appName}) + tasks, err := FetchCronTasks(FetchCronTasksInput{AppName: appName}) if err != nil { return err } @@ -98,9 +98,9 @@ func CommandRun(appName string, cronID string, detached bool) error { } command := "" - for _, entry := range entries { - if entry.ID == cronID { - command = entry.Command + for _, task := range tasks { + if task.ID == cronID { + command = task.Command } } diff --git a/plugins/cron/templates/cron.tmpl b/plugins/cron/templates/cron.tmpl index 5c510dcae..c38d40499 100644 --- a/plugins/cron/templates/cron.tmpl +++ b/plugins/cron/templates/cron.tmpl @@ -7,6 +7,6 @@ MAILTO={{ .Mailto }} PATH=/usr/local/bin:/usr/bin:/bin SHELL=/bin/bash -{{ range $entry := .Commands -}} -{{ $entry.Schedule }} {{ $entry.CronCommand }} +{{ range $task := .Commands -}} +{{ $task.Schedule }} {{ $task.CronCommand }} {{ end -}} diff --git a/plugins/cron/triggers.go b/plugins/cron/triggers.go index 499405913..e19097bbd 100644 --- a/plugins/cron/triggers.go +++ b/plugins/cron/triggers.go @@ -24,7 +24,7 @@ func TriggerCronGetProperty(appName string, key string) error { return nil } -// TriggerAppJSONIsValid validates the cron entries for a given app +// TriggerAppJSONIsValid validates the cron tasks for a given app func TriggerAppJSONIsValid(appName string, appJSONPath string) error { if !common.FileExists(appJSONPath) { return nil @@ -35,7 +35,7 @@ func TriggerAppJSONIsValid(appName string, appJSONPath string) error { return err } - _, err = FetchCronEntries(FetchCronEntriesInput{ + _, err = FetchCronTasks(FetchCronTasksInput{ AppName: appName, AppJSON: &appJSON, WarnToFailure: true, diff --git a/plugins/scheduler-docker-local/functions.go b/plugins/scheduler-docker-local/functions.go index e11d7c035..316192d31 100644 --- a/plugins/scheduler-docker-local/functions.go +++ b/plugins/scheduler-docker-local/functions.go @@ -38,7 +38,7 @@ func deleteCrontab() error { return nil } -func generateCronEntries() ([]cron.TemplateCommand, error) { +func generateCronTasks() ([]cron.TemplateCommand, error) { apps, _ := common.UnfilteredDokkuApps() g := new(errgroup.Group) @@ -52,7 +52,7 @@ func generateCronEntries() ([]cron.TemplateCommand, error) { return nil } - c, err := cron.FetchCronEntries(cron.FetchCronEntriesInput{AppName: appName}) + c, err := cron.FetchCronTasks(cron.FetchCronTasksInput{AppName: appName}) if err != nil { results <- []cron.TemplateCommand{} common.LogWarn(err.Error()) @@ -116,13 +116,13 @@ func generateCronEntries() ([]cron.TemplateCommand, error) { return commands, nil } -func writeCronEntries(scheduler string) error { +func writeCronTasks(scheduler string) error { // allow empty scheduler, which means all apps (used by letsencrypt) if scheduler != "docker-local" && scheduler != "" { return nil } - commands, err := generateCronEntries() + commands, err := generateCronTasks() if err != nil { return err } @@ -154,7 +154,7 @@ func writeCronEntries(scheduler string) error { return err } - tmpFile, err := os.CreateTemp(os.TempDir(), fmt.Sprintf("dokku-%s-%s", common.MustGetEnv("DOKKU_PID"), "WriteCronEntries")) + tmpFile, err := os.CreateTemp(os.TempDir(), fmt.Sprintf("dokku-%s-%s", common.MustGetEnv("DOKKU_PID"), "WriteCronTasks")) if err != nil { return fmt.Errorf("Cannot create temporary schedule file: %v", err) } diff --git a/plugins/scheduler-docker-local/triggers.go b/plugins/scheduler-docker-local/triggers.go index 4f9fded0d..3bd78229d 100644 --- a/plugins/scheduler-docker-local/triggers.go +++ b/plugins/scheduler-docker-local/triggers.go @@ -2,5 +2,5 @@ package schedulerdockerlocal // TriggerSchedulerCronWrite force updates the cron file for all apps func TriggerSchedulerCronWrite(scheduler string) error { - return writeCronEntries(scheduler) + return writeCronTasks(scheduler) } diff --git a/plugins/scheduler-k3s/triggers.go b/plugins/scheduler-k3s/triggers.go index b89aa017c..5be47ea33 100644 --- a/plugins/scheduler-k3s/triggers.go +++ b/plugins/scheduler-k3s/triggers.go @@ -312,15 +312,15 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e workingDir := common.GetWorkingDir(appName, image) - allCronEntries, err := cron.FetchCronEntries(cron.FetchCronEntriesInput{AppName: appName}) + allCronTasks, err := cron.FetchCronTasks(cron.FetchCronTasksInput{AppName: appName}) if err != nil { - return fmt.Errorf("Error fetching cron entries: %w", err) + return fmt.Errorf("Error fetching cron tasks: %w", err) } - // remove maintenance cron entries - cronEntries := []cron.TemplateCommand{} - for _, cronEntry := range allCronEntries { - if !cronEntry.Maintenance { - cronEntries = append(cronEntries, cronEntry) + // remove maintenance cron tasks + cronTasks := []cron.TemplateCommand{} + for _, cronTask := range allCronTasks { + if !cronTask.Maintenance { + cronTasks = append(cronTasks, cronTask) } } @@ -605,13 +605,13 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e if err != nil { return fmt.Errorf("Error listing cron jobs: %w", err) } - for _, cronEntry := range cronEntries { + for _, cronTask := range cronTasks { // todo: implement deployment annotations // todo: implement pod annotations // todo: implement volumes suffix := "" for _, cronJob := range cronJobs { - if cronJob.Labels["dokku.com/cron-id"] == cronEntry.ID { + if cronJob.Labels["dokku.com/cron-id"] == cronTask.ID { var ok bool suffix, ok = cronJob.Annotations["dokku.com/job-suffix"] if !ok { @@ -628,22 +628,22 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e suffix = strings.ToLower(fmt.Sprintf("%X", b)) } - words, err := shellquote.Split(cronEntry.Command) + words, err := shellquote.Split(cronTask.Command) if err != nil { return fmt.Errorf("Error parsing cron command: %w", err) } - processResources, err := getProcessResources(appName, cronEntry.ID) + processResources, err := getProcessResources(appName, cronTask.ID) if err != nil { return fmt.Errorf("Error getting process resources: %w", err) } - annotations, err := getAnnotations(appName, cronEntry.ID) + annotations, err := getAnnotations(appName, cronTask.ID) if err != nil { return fmt.Errorf("Error getting process annotations: %w", err) } - labels, err := getLabels(appName, cronEntry.ID) + labels, err := getLabels(appName, cronTask.ID) if err != nil { return fmt.Errorf("Error getting process labels: %w", err) } @@ -652,8 +652,8 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e Args: words, Annotations: annotations, Cron: ProcessCron{ - ID: cronEntry.ID, - Schedule: cronEntry.Schedule, + ID: cronTask.ID, + Schedule: cronTask.Schedule, Suffix: suffix, }, Labels: labels, @@ -662,10 +662,10 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e Resources: processResources, Volumes: processVolumes, } - values.Processes[cronEntry.ID] = processValues + values.Processes[cronTask.ID] = processValues } - if len(cronEntries) > 0 { + if len(cronTasks) > 0 { b, err := templates.ReadFile("templates/chart/cron-job.yaml") if err != nil { return fmt.Errorf("Error reading cron job template: %w", err) @@ -1443,14 +1443,14 @@ func TriggerSchedulerRunList(scheduler string, appName string, format string) er return fmt.Errorf("Error getting cron jobs: %w", err) } - type CronJobEntry struct { + type CronJobTask struct { ID string `json:"id"` AppName string `json:"app"` Command string `json:"command"` Schedule string `json:"schedule"` } - data := []CronJobEntry{} + data := []CronJobTask{} lines := []string{"ID | Schedule | Command"} for _, cronJob := range cronJobs { command := "" @@ -1467,7 +1467,7 @@ func TriggerSchedulerRunList(scheduler string, appName string, format string) er } lines = append(lines, fmt.Sprintf("%s | %s | %s", cronID, cronJob.Spec.Schedule, command)) - data = append(data, CronJobEntry{ + data = append(data, CronJobTask{ ID: cronID, AppName: appName, Command: command,