Skip to content

Commit

Permalink
Parsing config file and scheduling jobs
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthieu Martin committed Nov 18, 2016
1 parent b18c2a8 commit eb7455d
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# Folders
_obj
_test
vendor

# Architecture specific extensions/prefixes
*.[568vq]
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# cronr
# cronr

cronr is a daemon utility intended to be an alternative to classic cron. The crontab is replaced by a custom config file, containing the jobs list. When cronr is started, each job is scheduled according to the config.
15 changes: 15 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

// ConfigFile represents a YAML config file
type ConfigFile struct {
Jobs []Job
}

// Job represents a unit to schedule
type Job struct {
Cron string `yaml:"cron"`
Command []string `yaml:"command"`
// User uint32 `yaml:"user"`
// Group uint32 `yaml:"group"`
WorkingDir string `yaml:"working_dir"`
}
105 changes: 105 additions & 0 deletions cron.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package main

import (
"io/ioutil"
"log"
"os"
"os/exec"
"os/signal"

"github.com/robfig/cron"
yaml "gopkg.in/yaml.v2"
)

type command struct {
name string
args []string
}

// CronAction parses and schedules jobs, waiting for SIGINT signal to stop
func CronAction(configFilepath string, verbose bool) error {

// get config file content
fileContent, err := ioutil.ReadFile(configFilepath)
if err != nil {
return err
}

// parse config file
config := ConfigFile{}
err = yaml.Unmarshal(fileContent, &config)
if err != nil {
return err
}

// prepare cron
c := cron.New()

// creating jobs
for i := range config.Jobs {
job := config.Jobs[i]

c.AddFunc(job.Cron, func() {

if verbose {
log.Println(job)
}

cmdArgs := newCommand(job.Command)
cmd := exec.Command(cmdArgs.name, cmdArgs.args...)

if job.WorkingDir != "" {
cmd.Dir = job.WorkingDir
}

// if job.User != 0 && job.Group != 0 {
// fmt.Println(job.User, ":", job.Group)
// cmd.SysProcAttr = &syscall.SysProcAttr{}
// cmd.SysProcAttr.Credential = &syscall.Credential{Uid: job.User, Gid: job.Group}
// }

cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

err := cmd.Run()
if err != nil {
log.Printf("[ERROR] cmd: %v: %v\n", job.Command, err)
}

})
}

log.Printf("%v job(s) scheduled\n", len(c.Entries()))

// start cron
c.Start()

// prepare chan for catching signals
done := make(chan os.Signal, 1)
signal.Notify(done, os.Interrupt, os.Kill)

// waiting for signal to stop
<-done

c.Stop()

return nil
}

func newCommand(rawCommand []string) command {

var (
name string
args []string
)

if len(rawCommand) > 1 {
name = rawCommand[0]
args = rawCommand[1:]
} else {
name = rawCommand[0]
args = []string{}
}

return command{name: name, args: args}
}
12 changes: 12 additions & 0 deletions cronr.example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

jobs:
- cron: "0/5 * * * * *" # e.g: 0 30 * * * * WARNING: first one is seconds (instead of minutes for classic cron, https://godoc.org/github.com/robfig/cron)
command:
- sh
- -c
- /bin/echo foo >> output_1
working_dir: tests # optional, cronr working dir by default
- cron: "0/2 * * * * *"
command:
- /bin/echo
- bar
10 changes: 10 additions & 0 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package: webup/cronr
import:
- package: github.com/robfig/cron
- package: github.com/jawher/mow.cli
- package: gopkg.in/yaml.v2
32 changes: 32 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"fmt"
"os"

cli "github.com/jawher/mow.cli"
)

func main() {

app := cli.App("cronr", "Executes scheduled jobs defined in a config file")

// version
app.Version("v version", "cronr 1 (build 1)")

// options & args
app.Spec = "-c [--verbose]"
configFile := app.StringOpt("c config-file", "", "Path of the cronr config file")
verbose := app.BoolOpt("verbose", false, "Display more informations on scheduled jobs")

// action
app.Action = func() {
err := CronAction(*configFile, *verbose)
if err != nil {
fmt.Println(err)
cli.Exit(1)
}
}

app.Run(os.Args)
}

0 comments on commit eb7455d

Please sign in to comment.