diff --git a/.github/workflows/pal-ci.yml b/.github/workflows/pal-ci.yml index 1b42980..527abf3 100644 --- a/.github/workflows/pal-ci.yml +++ b/.github/workflows/pal-ci.yml @@ -32,12 +32,17 @@ jobs: - name: Build pal Binary run: | make linux + file ./pal + du -sh ./pal + sha256sum ./pal + ./pal -h - name: Build pal Docker Container run: | make certs echo make docker + rm -f ./localhost.* - name: Run Tests Using pal Docker Container run: | diff --git a/README.md b/README.md index 57418d9..beb5f65 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,9 @@ deploy: background: false # Run concurrently (default: false) concurrent: true - # Set action to run to a cron style schedule - cron: "*****" + # Set action to run multiple cron style schedules + crons: + - "*****" # Set command timeout in seconds (default: 600 seconds/10 mins) timeout: 600 # Set custom HTTP Response Headers diff --git a/data/data.go b/data/data.go index 5dcf697..9bb5a73 100644 --- a/data/data.go +++ b/data/data.go @@ -26,7 +26,7 @@ type ActionData struct { Timeout int `yaml:"timeout" json:"timeout" validate:"number"` Cmd string `yaml:"cmd" json:"cmd" validate:"required"` ResponseHeaders []ResponseHeaders `yaml:"headers" json:"headers"` - Cron string `yaml:"cron" json:"cron"` + Crons []string `yaml:"crons" json:"crons"` OnError OnError `yaml:"on_error" json:"on_error"` InputValidate string `yaml:"input_validate" json:"input_validate"` LastRan string `json:"last_ran"` diff --git a/routes/routes.go b/routes/routes.go index a400009..c10fcae 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -84,27 +84,31 @@ func condDisable(group, action string, disabled bool) { if disabled { sched.RemoveByTags(group + action) } else { - if e.Cron != "" && validateInput(e.Cron, "cron") == nil { - var cronDesc string - exprDesc, err := cron.NewDescriptor() - if err == nil { - cronDesc, err = exprDesc.ToDescription(e.Cron, cron.Locale_en) - if err != nil { - cronDesc = "" + if len(e.Crons) > 0 { + for _, c := range e.Crons { + if validateInput(c, "cron") == nil { + var cronDesc string + exprDesc, err := cron.NewDescriptor() + if err == nil { + cronDesc, err = exprDesc.ToDescription(c, cron.Locale_en) + if err != nil { + cronDesc = "" + } + } + + _, err = sched.NewJob( + gocron.CronJob(c, false), + gocron.NewTask(cronTask, resData[group][i]), + gocron.WithName(group+"/"+action), + gocron.WithTags(cronDesc, group+action), + ) + + if err != nil { + // TODOD: log error + return + } } } - - _, err = sched.NewJob( - gocron.CronJob(e.Cron, false), - gocron.NewTask(cronTask, resData[group][i]), - gocron.WithName(group+"/"+action), - gocron.WithTags(cronDesc, group+action), - ) - - if err != nil { - // TODOD: log error - return - } } return } @@ -128,9 +132,9 @@ func getCond(group, action string) bool { } // logError time, error, id, uri fields -func logError(c echo.Context, e error) { +func logError(reqid, uri string, e error) { fmt.Printf("%s\n", fmt.Sprintf(`{"time":"%s","error":"%s","id":"%s","uri":"%s"}`, - utils.TimeNow(config.GetConfigStr("global_timezone")), e.Error(), c.Response().Header().Get(echo.HeaderXRequestID), c.Request().RequestURI)) + utils.TimeNow(config.GetConfigStr("global_timezone")), e.Error(), reqid, uri)) } // RunGroup is the main route for triggering a command @@ -257,7 +261,7 @@ func RunGroup(c echo.Context) error { actionData.LastOutput = err.Error() } mergeGroup(actionData) - logError(c, err) + logError("", "", err) if actionData.OnError.Notification != "" { notification := actionData.OnError.Notification notification = strings.ReplaceAll(notification, "$PAL_GROUP", actionData.Group) @@ -268,10 +272,10 @@ func RunGroup(c echo.Context) error { } err := putNotifications(data.Notification{Group: group, Notification: notification}) if err != nil { - logError(c, err) + logError("", "", err) } } - + return } actionData.Cmd = cmdOrig actionData.Status = "success" @@ -287,8 +291,6 @@ func RunGroup(c echo.Context) error { lock(group, action, false) } - time.Sleep(20 * time.Millisecond) - return c.String(http.StatusOK, "running in background") } @@ -305,7 +307,7 @@ func RunGroup(c echo.Context) error { actionData.LastOutput = err.Error() } mergeGroup(actionData) - logError(c, errors.New(errorScript+" "+err.Error())) + logError(c.Response().Header().Get(echo.HeaderXRequestID), c.Request().RequestURI, errors.New(errorScript+" "+err.Error())) if actionData.OnError.Notification != "" { notification := actionData.OnError.Notification notification = strings.ReplaceAll(notification, "$PAL_GROUP", actionData.Group) @@ -316,7 +318,7 @@ func RunGroup(c echo.Context) error { } err := putNotifications(data.Notification{Group: group, Notification: notification}) if err != nil { - logError(c, err) + logError(c.Response().Header().Get(echo.HeaderXRequestID), c.Request().RequestURI, err) } } return c.String(http.StatusInternalServerError, err.Error()) @@ -688,7 +690,7 @@ func PostFilesUpload(c echo.Context) error { } - return c.HTML(http.StatusOK, fmt.Sprintf("