Skip to content

Commit b5cde4f

Browse files
committed
local jobs
1 parent 567e99f commit b5cde4f

File tree

5 files changed

+108
-10
lines changed

5 files changed

+108
-10
lines changed

README.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ The main feature of **Ofelia** is the ability to execute commands directly on Do
1818

1919
## Configuration
2020

21-
It uses a INI-style config file and the [scheduling format](https://godoc.org/github.com/robfig/cron) is exactly the same from the original `cron`:
21+
It uses a INI-style config file and the [scheduling format](https://godoc.org/github.com/robfig/cron) is exactly the same from the original `cron`, you can configure three different kind of jobs:
22+
23+
- `job-exec`: this job is executed inside of a running container.
24+
- `job-run`: runs a command inside of a new container, using a specific image.
25+
- `job-local`: runs the command inside of the host running ofelia.
26+
2227

2328
```ini
2429
[job-exec "job-executed-on-running-container"]
@@ -30,6 +35,10 @@ command = touch /tmp/example
3035
schedule = @hourly
3136
image = ubuntu:latest
3237
command = touch /tmp/example
38+
39+
[job-local "job-executed-on-current-host"]
40+
schedule = @hourly
41+
command = touch /tmp/example
3342
```
3443

3544

cli/config.go

+27-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ type Config struct {
1919
middlewares.SaveConfig
2020
middlewares.MailConfig
2121
}
22-
ExecJobs map[string]*ExecJobConfig `gcfg:"job-exec"`
23-
RunJobs map[string]*RunJobConfig `gcfg:"job-run"`
22+
ExecJobs map[string]*ExecJobConfig `gcfg:"job-exec"`
23+
RunJobs map[string]*RunJobConfig `gcfg:"job-run"`
24+
LocalJobs map[string]*LocalJobConfig `gcfg:"job-local"`
2425
}
2526

2627
// BuildFromFile buils a scheduler using the config from a file
@@ -72,6 +73,14 @@ func (c *Config) build() (*core.Scheduler, error) {
7273
sh.AddJob(j)
7374
}
7475

76+
for name, j := range c.LocalJobs {
77+
defaults.SetDefaults(j)
78+
79+
j.Name = name
80+
j.buildMiddlewares()
81+
sh.AddJob(j)
82+
}
83+
7584
return sh, nil
7685
}
7786

@@ -127,3 +136,19 @@ func (c *RunJobConfig) buildMiddlewares() {
127136
c.RunJob.Use(middlewares.NewSave(&c.SaveConfig))
128137
c.RunJob.Use(middlewares.NewMail(&c.MailConfig))
129138
}
139+
140+
// LocalJobConfig contains all configuration params needed to build a RunJob
141+
type LocalJobConfig struct {
142+
core.LocalJob
143+
middlewares.OverlapConfig
144+
middlewares.SlackConfig
145+
middlewares.SaveConfig
146+
middlewares.MailConfig
147+
}
148+
149+
func (c *LocalJobConfig) buildMiddlewares() {
150+
c.LocalJob.Use(middlewares.NewOverlap(&c.OverlapConfig))
151+
c.LocalJob.Use(middlewares.NewSlack(&c.SlackConfig))
152+
c.LocalJob.Use(middlewares.NewSave(&c.SaveConfig))
153+
c.LocalJob.Use(middlewares.NewMail(&c.MailConfig))
154+
}

cli/config_test.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,19 @@ func (s *SuiteConfig) TestBuildFromString(c *C) {
1616
sh, err := BuildFromString(`
1717
[job-exec "foo"]
1818
schedule = @every 10s
19-
container = test
2019
2120
[job-exec "bar"]
2221
schedule = @every 10s
23-
container = test
2422
2523
[job-run "qux"]
2624
schedule = @every 10s
27-
image = test
25+
26+
[job-local "baz"]
27+
schedule = @every 10s
2828
`)
2929

3030
c.Assert(err, IsNil)
31-
c.Assert(sh.Jobs, HasLen, 3)
32-
c.Assert(sh.Jobs[0].GetName(), Equals, "foo")
33-
c.Assert(sh.Jobs[1].GetName(), Equals, "bar")
34-
c.Assert(sh.Jobs[2].GetName(), Equals, "qux")
31+
c.Assert(sh.Jobs, HasLen, 4)
3532
}
3633

3734
func (s *SuiteConfig) TestExecJobBuildEmpty(c *C) {

core/localjob.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package core
2+
3+
import (
4+
"os/exec"
5+
6+
"github.com/gobs/args"
7+
)
8+
9+
type LocalJob struct {
10+
BareJob
11+
Dir string
12+
Environment []string
13+
}
14+
15+
func NewLocalJob() *LocalJob {
16+
return &LocalJob{}
17+
}
18+
19+
func (j *LocalJob) Run(ctx *Context) error {
20+
cmd, err := j.buildCommand(ctx)
21+
if err != nil {
22+
return err
23+
}
24+
25+
return cmd.Run()
26+
}
27+
28+
func (j *LocalJob) buildCommand(ctx *Context) (*exec.Cmd, error) {
29+
args := args.GetArgs(j.Command)
30+
bin, err := exec.LookPath(args[0])
31+
if err != nil {
32+
return nil, err
33+
}
34+
35+
return &exec.Cmd{
36+
Path: bin,
37+
Args: args,
38+
Stdout: ctx.Execution.OutputStream,
39+
Stderr: ctx.Execution.ErrorStream,
40+
Env: j.Environment,
41+
Dir: j.Dir,
42+
}, nil
43+
}

core/localjob_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package core
2+
3+
import (
4+
"bytes"
5+
6+
. "gopkg.in/check.v1"
7+
)
8+
9+
type SuiteLocalJob struct{}
10+
11+
var _ = Suite(&SuiteLocalJob{})
12+
13+
func (s *SuiteLocalJob) TestRun(c *C) {
14+
job := &LocalJob{}
15+
job.Command = `echo "foo bar"`
16+
17+
b := bytes.NewBuffer(nil)
18+
e := NewExecution()
19+
e.OutputStream = b
20+
21+
err := job.Run(&Context{Execution: e})
22+
c.Assert(err, IsNil)
23+
c.Assert(b.String(), Equals, "foo bar\n")
24+
}

0 commit comments

Comments
 (0)