Unify ENV handling with Vixie cron's

This commit is contained in:
Thomas Orozco
2017-07-10 18:56:00 +02:00
parent 3522b1ec95
commit 8ae7f372c7
4 changed files with 74 additions and 14 deletions

View File

@@ -54,14 +54,11 @@ func parseJobLine(line string) (*CrontabLine, error) {
func ParseCrontab(reader io.Reader) (*Crontab, error) {
scanner := bufio.NewScanner(reader)
// TODO: Don't return an array of Job, return an object representing the crontab
// TODO: Understand environment variables, too.
// TODO: Increment position
position := 0
jobs := make([]*Job, 0)
// TODO: CRON_TZ
// TODO: CRON_TZ?
environ := make(map[string]string)
shell := "/bin/sh"
@@ -78,14 +75,27 @@ func ParseCrontab(reader io.Reader) (*Crontab, error) {
r := envLineMatcher.FindAllStringSubmatch(line, -1)
if len(r) == 1 && len(r[0]) == 3 {
// TODO: Should error on setting USER?
envKey := r[0][1]
envVal := r[0][2]
if envKey == "SHELL" {
shell = envVal
} else {
environ[envKey] = envVal
// Remove quotes (this emulates what Vixie cron does)
if envVal[0] == '"' || envVal[0] == '\'' {
if len(envVal) > 1 && envVal[0] == envVal[len(envVal)-1] {
envVal = envVal[1 : len(envVal)-1]
}
}
if envKey == "SHELL" {
logrus.Infof("processes will be spawned using shell: %s", envVal)
shell = envVal
}
if envKey == "USER" {
logrus.Warnf("processes will NOT be spawned as USER=%s", envVal)
}
environ[envKey] = envVal
continue
}

View File

@@ -34,6 +34,50 @@ var parseCrontabTestCases = []struct {
},
},
{
"FOO=\"bar\"",
&Crontab{
Context: &Context{
Shell: "/bin/sh",
Environ: map[string]string{"FOO": "bar"},
},
Jobs: []*Job{},
},
},
{
"FOO='bar'",
&Crontab{
Context: &Context{
Shell: "/bin/sh",
Environ: map[string]string{"FOO": "bar"},
},
Jobs: []*Job{},
},
},
{
"FOO='",
&Crontab{
Context: &Context{
Shell: "/bin/sh",
Environ: map[string]string{"FOO": "'"},
},
Jobs: []*Job{},
},
},
{
"FOO=''",
&Crontab{
Context: &Context{
Shell: "/bin/sh",
Environ: map[string]string{"FOO": ""},
},
Jobs: []*Job{},
},
},
{
"* * * * * foo some # qux",
&Crontab{
@@ -58,7 +102,8 @@ var parseCrontabTestCases = []struct {
Context: &Context{
Shell: "some",
Environ: map[string]string{
"KEY": "VAL",
"SHELL": "some",
"KEY": "VAL",
},
},
Jobs: []*Job{

View File

@@ -5,17 +5,21 @@ function run_supercronic() {
}
@test "it runs a cron job" {
run_supercronic "${BATS_TEST_DIRNAME}/hello.crontab" | grep -E "hello from crontab.*channel=stdout"
run_supercronic "${BATS_TEST_DIRNAME}/hello.crontab" | grep -iE "hello from crontab.*channel=stdout"
}
@test "it passes the environment through" {
VAR="hello from foo" run_supercronic "${BATS_TEST_DIRNAME}/env.crontab" | grep -E "hello from foo.*channel=stdout"
VAR="hello from foo" run_supercronic "${BATS_TEST_DIRNAME}/env.crontab" | grep -iE "hello from foo.*channel=stdout"
}
@test "it overrides the environment with the crontab" {
VAR="hello from foo" run_supercronic "${BATS_TEST_DIRNAME}/override.crontab" | grep -E "hello from bar.*channel=stdout"
VAR="hello from foo" run_supercronic "${BATS_TEST_DIRNAME}/override.crontab" | grep -iE "hello from bar.*channel=stdout"
}
@test "it warns when USER is set" {
run_supercronic "${BATS_TEST_DIRNAME}/user.crontab" 5s | grep -iE "processes will not.*USER="
}
@test "it warns when a job is falling behind" {
run_supercronic "${BATS_TEST_DIRNAME}/timeout.crontab" 5s | grep -E "job took too long to run"
run_supercronic "${BATS_TEST_DIRNAME}/timeout.crontab" 5s | grep -iE "job took too long to run"
}

1
integration/user.crontab Normal file
View File

@@ -0,0 +1 @@
USER=foo