wip: feat(cron in new config): added parser
wip: fix: remove unreachable code wip: test cron
This commit is contained in:
parent
6dd0a8007c
commit
006f8278d7
@ -49,5 +49,4 @@ func convertSchedule(cfg config.CronTimeSpec) task.CronTimeSpec {
|
||||
}
|
||||
|
||||
panic("invalid conversion")
|
||||
return nil
|
||||
}
|
||||
|
||||
149
config/yaml.go
149
config/yaml.go
@ -1,16 +1,27 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gitea.suyono.dev/suyono/wingmate"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ServiceConfigGroup = "service"
|
||||
CronConfigGroup = "cron"
|
||||
ServiceKeyFormat = "service.%s"
|
||||
CronKeyFormat = "cron.%s"
|
||||
CrontabScheduleRegexPattern = `^\s*(?P<minute>\S+)\s+(?P<hour>\S+)\s+(?P<dom>\S+)\s+(?P<month>\S+)\s+(?P<dow>\S+)\s*$`
|
||||
CrontabScheduleSubMatchLen = 6
|
||||
ServiceConfigGroup = "service"
|
||||
CronConfigGroup = "cron"
|
||||
ServiceKeyFormat = "service.%s"
|
||||
CronKeyFormat = "cron.%s"
|
||||
)
|
||||
|
||||
var (
|
||||
crontabScheduleRegex = regexp.MustCompile(CrontabScheduleRegexPattern)
|
||||
)
|
||||
|
||||
func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, error) {
|
||||
@ -54,8 +65,138 @@ func readConfigYaml(path, name, format string) ([]ServiceTask, []CronTask, error
|
||||
continue
|
||||
}
|
||||
cronTask.Name = itemName
|
||||
if cronTask.CronSchedule, err = parseYamlSchedule(cronTask.Schedule); err != nil {
|
||||
wingmate.Log().Error().Msgf("parsing cron schedule: %+v", err)
|
||||
continue
|
||||
}
|
||||
crones = append(crones, cronTask)
|
||||
}
|
||||
|
||||
return services, crones, nil
|
||||
}
|
||||
|
||||
func parseYamlSchedule(input string) (schedule CronSchedule, err error) {
|
||||
var (
|
||||
parts []string
|
||||
pSched *CronSchedule
|
||||
)
|
||||
|
||||
parts = crontabScheduleRegex.FindStringSubmatch(input)
|
||||
if len(parts) != CrontabScheduleSubMatchLen {
|
||||
return schedule, fmt.Errorf("invalid schedule: %s", input)
|
||||
}
|
||||
|
||||
pSched = &schedule
|
||||
if err = pSched.setField(minute, parts[1]); err != nil {
|
||||
return schedule, fmt.Errorf("error parsing Minute field: %w", err)
|
||||
}
|
||||
|
||||
if err = pSched.setField(hour, parts[2]); err != nil {
|
||||
return schedule, fmt.Errorf("error parsing Hour field: %w", err)
|
||||
}
|
||||
|
||||
if err = pSched.setField(dom, parts[3]); err != nil {
|
||||
return schedule, fmt.Errorf("error parsing Day of Month field: %w", err)
|
||||
}
|
||||
|
||||
if err = pSched.setField(month, parts[4]); err != nil {
|
||||
return schedule, fmt.Errorf("error parsing Month field: %w", err)
|
||||
}
|
||||
|
||||
if err = pSched.setField(dow, parts[5]); err != nil {
|
||||
return schedule, fmt.Errorf("error parsing Day of Week field: %w", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *CronSchedule) setField(field cronField, input string) error {
|
||||
var (
|
||||
fr *fieldRange
|
||||
cField *CronTimeSpec
|
||||
err error
|
||||
parsed64 uint64
|
||||
parsed uint8
|
||||
multi []uint8
|
||||
current uint8
|
||||
multiStr []string
|
||||
)
|
||||
switch field {
|
||||
case minute:
|
||||
fr = newRange(0, 59)
|
||||
cField = &c.Minute
|
||||
case hour:
|
||||
fr = newRange(0, 23)
|
||||
cField = &c.Hour
|
||||
case dom:
|
||||
fr = newRange(1, 31)
|
||||
cField = &c.DoM
|
||||
case month:
|
||||
fr = newRange(1, 12)
|
||||
cField = &c.Month
|
||||
case dow:
|
||||
fr = newRange(0, 6)
|
||||
cField = &c.DoW
|
||||
default:
|
||||
return errors.New("invalid cron field descriptor")
|
||||
}
|
||||
|
||||
if input == "*" {
|
||||
*cField = &SpecAny{}
|
||||
} else if strings.HasPrefix(input, "*/") {
|
||||
if parsed64, err = strconv.ParseUint(input[2:], 10, 8); err != nil {
|
||||
return fmt.Errorf("error parse field %+v with input %s: %w", field, input, err)
|
||||
}
|
||||
|
||||
parsed = uint8(parsed64)
|
||||
if !fr.valid(parsed) {
|
||||
return fmt.Errorf("error parse field %+v with input %s parsed to %d: invalid value", field, input, parsed)
|
||||
}
|
||||
multi = make([]uint8, 0)
|
||||
current = parsed
|
||||
for fr.valid(current) {
|
||||
multi = append(multi, current)
|
||||
current += parsed
|
||||
}
|
||||
|
||||
*cField = &SpecMultiOccurrence{
|
||||
values: multi,
|
||||
}
|
||||
} else {
|
||||
multiStr = strings.Split(input, ",")
|
||||
if len(multiStr) > 1 {
|
||||
multi = make([]uint8, 0)
|
||||
for _, s := range multiStr {
|
||||
if parsed64, err = strconv.ParseUint(s, 10, 8); err != nil {
|
||||
return fmt.Errorf("error parse field %+v with input %s: %w", field, input, err)
|
||||
}
|
||||
|
||||
parsed = uint8(parsed64)
|
||||
if !fr.valid(parsed) {
|
||||
return fmt.Errorf("error parse field %+v with input %s: invalid value", field, input)
|
||||
}
|
||||
|
||||
multi = append(multi, parsed)
|
||||
}
|
||||
|
||||
*cField = &SpecMultiOccurrence{
|
||||
values: multi,
|
||||
}
|
||||
} else {
|
||||
if parsed64, err = strconv.ParseUint(input, 10, 8); err != nil {
|
||||
return fmt.Errorf("error parse field %+v with input %s: %w", field, input, err)
|
||||
}
|
||||
|
||||
parsed = uint8(parsed64)
|
||||
if !fr.valid(parsed) {
|
||||
return fmt.Errorf("error parse field %+v with input %s: invalid value", field, input)
|
||||
}
|
||||
|
||||
*cField = &SpecExact{
|
||||
value: parsed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"gitea.suyono.dev/suyono/wingmate"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"gitea.suyono.dev/suyono/wingmate"
|
||||
)
|
||||
|
||||
const configName = "wingmate.yaml"
|
||||
@ -65,4 +66,14 @@ service:
|
||||
environ: ["ENV1=value1", "ENV2=valueX"]
|
||||
user: "user1"
|
||||
group: "999"
|
||||
working_dir: "/path/to/working"`
|
||||
working_dir: "/path/to/working"
|
||||
cron:
|
||||
cron-one:
|
||||
command:
|
||||
- command-cron
|
||||
- arg0
|
||||
- arg1
|
||||
environ: ["ENV1=v1", "ENV2=var2"]
|
||||
user: "1001"
|
||||
group: "978"
|
||||
schedule: "*/5 * * * 2,3"`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user