Skip to content

Commit

Permalink
Make cron string to crons []string, fix background and error output bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
marshyski committed Oct 19, 2024
1 parent c11a59a commit 6c0a3d7
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/pal-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion data/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
96 changes: 51 additions & 45 deletions routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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"
Expand All @@ -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")
}

Expand All @@ -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)
Expand All @@ -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())
Expand Down Expand Up @@ -688,7 +690,7 @@ func PostFilesUpload(c echo.Context) error {

}

return c.HTML(http.StatusOK, fmt.Sprintf("<!DOCTYPE html><html><head><meta http-equiv='refresh' content='5; url=/v1/pal/ui/files' /><title>Redirecting...</title></head><body><h2>Successfully uploaded %d files. You will be redirected to <a href='/v1/pal/ui/files'>/v1/pal/ui/files</a> in 5 seconds...</h2></body></html>", len(files)))
return c.HTML(http.StatusOK, fmt.Sprintf("<!DOCTYPE html><html><head><meta http-equiv='refresh' content='3; url=/v1/pal/ui/files' /><title>Redirecting...</title></head><body><h2>Successfully uploaded %d files. You will be redirected to <a href='/v1/pal/ui/files'>/v1/pal/ui/files</a> in 3 seconds...</h2></body></html>", len(files)))

}

Expand Down Expand Up @@ -972,24 +974,28 @@ func CronStart(r map[string][]data.ActionData) error {

for k, v := range r {
for _, e := range v {
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, e),
gocron.WithName(k+"/"+e.Action),
gocron.WithTags(cronDesc, e.Group+e.Action),
)
if err != nil {
return err
}
}
}
_, err = sched.NewJob(
gocron.CronJob(e.Cron, false),
gocron.NewTask(cronTask, e),
gocron.WithName(k+"/"+e.Action),
gocron.WithTags(cronDesc, e.Group+e.Action),
)
if err != nil {
return err
}
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions test/pal-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ test:
desc: Test No auth_header and cron
auth_header:
output: true
cron: "* * * * *"
crons:
- "* * * * *"
- "*/2 * * * *"
concurrent: true
cmd: echo "$PAL_INPUT no_auth"

Expand All @@ -24,7 +26,8 @@ test:
desc: Test cron at 5 on Sunday
auth_header:
output: true
cron: "0 5 * * 0"
crons:
- "0 5 * * 0"
concurrent: true
cmd: echo "$PAL_INPUT sunday_test"

Expand Down Expand Up @@ -118,6 +121,7 @@ build:
make
file ./pal
du -sh ./pal
sha256sum ./pal
./pal -h
json:
Expand Down
4 changes: 3 additions & 1 deletion ui/action.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@
{{ end }}
</td>
<td class="fs-5">
<a href="/v1/pal/ui/crons">{{ $action.Cron }}</a>
{{range $action.Crons}}
<p><a href="/v1/pal/ui/crons">{{ . }}</a></p>
{{ end }}
</td>
<td>
{{range $header := $action.ResponseHeaders}}
Expand Down
2 changes: 1 addition & 1 deletion ui/actions.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
<span class="material-symbols-outlined me-2 fs-2">circle</span>
{{ end }}</td>
<td class="text-center fs-5 text-secondary">
{{ if $action.Cron }}
{{ if $action.Crons }}
<span class="material-symbols-outlined me-2 text-success fs-2">circle</span>
{{ else }}
<span class="material-symbols-outlined me-2 fs-2">circle</span>
Expand Down
4 changes: 2 additions & 2 deletions ui/files.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@
<div class="card">
<div class="card-body">
<h5 class="card-title">Upload Files</h5>
<form enctype="multipart/form-data" method="post" action="/v1/pal/ui/files/upload">
<form enctype="multipart/form-data" method="POST" action="/v1/pal/ui/files/upload">
<div class="mb-3 d-flex align-items-center">
<input class="form-control flex-grow-1" type="file" id="fileInput" name="files" multiple />
<input class="form-control flex-grow-1" type="file" id="files" name="files" multiple>
<button type="submit" class="btn btn-sm btn-primary ms-4">
<span class="material-symbols-outlined align-bottom">cloud_upload</span>
<strong>Upload</strong>
Expand Down
4 changes: 2 additions & 2 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func CmdRun(action data.ActionData, prefix string) (string, int, error) {
}
}

errStr := fmt.Sprintf("command error after %d retries in %d seconds : %s", action.OnError.Retries, int(time.Since(startTime).Seconds()), err.Error())
errStr := fmt.Sprintf("error after %d retries in %d seconds : %s %s", action.OnError.Retries, int(time.Since(startTime).Seconds()), strings.TrimSpace(string(output)), err.Error())

// If it's a context timeout or the maximum retries are reached, return the error
return errStr, int(time.Since(startTime).Seconds()), errors.New(errStr)
Expand Down Expand Up @@ -157,7 +157,7 @@ func updateAction(oldAction, newAction data.ActionData) data.ActionData {
oldAction.Timeout = newAction.Timeout
oldAction.Cmd = newAction.Cmd
oldAction.ResponseHeaders = newAction.ResponseHeaders
oldAction.Cron = newAction.Cron
oldAction.Crons = newAction.Crons
oldAction.OnError = newAction.OnError
oldAction.InputValidate = newAction.InputValidate
oldAction.Tags = newAction.Tags
Expand Down

0 comments on commit 6c0a3d7

Please sign in to comment.