Renaming: "tags" -> "commands"; "commands" -> "actions"

devel
KatolaZ 7 years ago
parent 096b3fd286
commit b31fe15e0d
  1. 48
      commits.go
  2. 6
      config.go
  3. 4
      examples/scorsh_example.cfg
  4. 12
      examples/worker1/worker1.cfg
  5. 10
      examples/worker2/worker2.cfg
  6. 28
      exec.go
  7. 10
      scorshd.go
  8. 2
      spooler.go
  9. 42
      types.go
  10. 33
      workers.go

@ -96,10 +96,10 @@ func intersectKeys(ref map[string]bool, keys []string) []string {
return ret
}
func findTagConfig(tagName string, w *worker) (*commandCfg, bool) {
func findCmdConfig(cmdName string, w *worker) (*commandCfg, bool) {
for _, c := range w.Tags {
if c.Name == tagName {
for _, c := range w.Commands {
if c.Name == cmdName {
return &c, true
}
}
@ -123,7 +123,7 @@ func getCommitterEmail(c *git.Commit) string {
// looking for scorsh commands, and tries to execute those if found
func walkCommits(msg spoolMsg, w *worker) error {
var commands *clientMsg
var cmdMsg *clientMsg
debug.log("[worker: %s] Inside walkCommits\n", w.Name)
@ -135,7 +135,7 @@ func walkCommits(msg spoolMsg, w *worker) error {
if err != nil {
fmt.Fprintf(os.Stderr, "Error while opening repository %s (%s)\n",
reponame, err)
return SCORSHerr(SCORSH_ERR_NO_REPO)
return SCORSHerr(errNoRepo)
}
oldRevOid, _ := git.NewOid(oldRev)
@ -143,7 +143,7 @@ func walkCommits(msg spoolMsg, w *worker) error {
oldrevCommit, err := repo.LookupCommit(oldRevOid)
if err != nil {
fmt.Fprintf(os.Stderr, "Commit: %s does not exist\n", oldRev)
return SCORSHerr(SCORSH_ERR_NO_COMMIT)
return SCORSHerr(errNoCommit)
}
newRevOid, _ := git.NewOid(newRev)
@ -151,7 +151,7 @@ func walkCommits(msg spoolMsg, w *worker) error {
newrevCommit, err := repo.LookupCommit(newRevOid)
if err != nil {
fmt.Fprintf(os.Stderr, "Commit: %s does not exist\n", newRev)
return SCORSHerr(SCORSH_ERR_NO_COMMIT)
return SCORSHerr(errNoCommit)
}
curCommit := newrevCommit
@ -167,39 +167,39 @@ func walkCommits(msg spoolMsg, w *worker) error {
// that specific scorsh-command
// Check if the commit contains a scorsh command
commands, err = findScorshMessage(commit)
cmdMsg, err = findScorshMessage(commit)
if err == nil {
// the commit contains a valid scorsh message
// 1) get the list of all the keyrings which verify the message
validKeys := getValidKeys(commit, &(w.Keys))
debug.log("[worker: %s] validated keyrings on commit: %s\n", w.Name, validKeys)
// 2) then for each tag in the message
for _, t := range commands.Tags {
// a) check that the tag is among those accepted by the worker
tagCfg, goodTag := findTagConfig(t.Tag, w)
debug.log("[worker: %s] goodTag: %s\n", w.Name, goodTag)
// 2) then for each command in the message
for _, c := range cmdMsg.Commands {
// a) check that the command is among those accepted by the worker
cmdCfg, goodCmd := findCmdConfig(c.Cmd, w)
debug.log("[worker: %s] goodCmd: %s\n", w.Name, goodCmd)
if !goodTag {
debug.log("[worker: %s] unsupported tag: %s\n", w.Name, t.Tag)
if !goodCmd {
debug.log("[worker: %s] unsupported command: %s\n", w.Name, c.Cmd)
continue
}
// b) check that at least one of the accepted tag keyrings
// b) check that at least one of the accepted command keyrings
// is in valid_keys
goodKeys := intersectKeys(w.TagKeys[t.Tag], validKeys) != nil
goodKeys := intersectKeys(w.CommandKeys[c.Cmd], validKeys) != nil
debug.log("[worker: %s] goodKeys: %s\n", w.Name, goodKeys)
if !goodKeys {
debug.log("[worker: %s] no matching keys for tag: %s\n", w.Name, t.Tag)
debug.log("[worker: %s] no matching keys for command: %s\n", w.Name, c.Cmd)
continue
}
// c) If everything is OK, execute the tag
if goodTag && goodKeys {
env := setEnvironment(&msg, t.Tag, getAuthorEmail(commit), getCommitterEmail(commit))
errs := execTag(tagCfg, t.Args, env)
debug.log("[worker: %s] errors in tag %s: %s\n", w.Name, t.Tag, errs)
// c) If everything is OK, execute the command
if goodCmd && goodKeys {
env := setEnvironment(&msg, c.Cmd, getAuthorEmail(commit), getCommitterEmail(commit))
errs := execCommand(cmdCfg, c.Args, env)
debug.log("[worker: %s] errors in command %s: %s\n", w.Name, c.Cmd, errs)
}
}
} else {
@ -209,7 +209,7 @@ func walkCommits(msg spoolMsg, w *worker) error {
curCommit = commit.Parent(0)
} else {
fmt.Printf("Commit %x not found!\n", curCommit.Id())
return SCORSHerr(SCORSH_ERR_NO_COMMIT)
return SCORSHerr(errNoCommit)
}
}
return nil

@ -27,10 +27,10 @@ func readGlobalConfig(fname string) *master {
//fmt.Printf("%s", cfg)
if cfg.Logfile != "" {
f, err := os.OpenFile(cfg.Logfile, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0600)
if cfg.LogFile != "" {
f, err := os.OpenFile(cfg.LogFile, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
log.Fatal("Error opening logfile: ", cfg.Logfile, err)
log.Fatal("Error opening logfile: ", cfg.LogFile, err)
} else {
log.SetOutput(io.Writer(f))
}

@ -10,14 +10,14 @@ s_workers:
w_repos: [".*:.*"], # All branches in all repos
w_folder: ./worker1,
w_logfile: ./worker1/worker1.log,
w_tagfile: "./worker1/worker1.cfg",
w_cfgfile: "./worker1/worker1.cfg",
},
{
w_name: worker2,
w_repos: [".*:master"], # Branch master in all repos
w_folder: ./worker2,
w_logfile: ./worker2/worker2.log,
w_tagfile: "./worker2/worker2.cfg",
w_cfgfile: "./worker2/worker2.cfg",
}
]
...

@ -8,24 +8,24 @@
---
w_tags:
w_commands:
[
{
t_name: "LOG",
t_keyrings: ["allowed_users.asc"],
t_commands: [
t_actions: [
{
c_url: "file:///home/katolaz/bin/scorsh_script.sh"
## c_hash: "12da324fb76s924acbce"
a_url: "file:///home/katolaz/bin/scorsh_script.sh"
## a_hash: "12da324fb76s924acbce"
}
]
},
{
t_name: "build",
t_keyrings: ["allowed_users.asc"],
t_commands: [
t_actions: [
{
c_url: "file:///home/katolaz/bin/scorsh_script.sh"
a_url: "file:///home/katolaz/bin/scorsh_script.sh"
}
]
}

@ -1,21 +1,21 @@
---
w_tags:
w_commands:
[
{
t_name: "DEPLOY",
t_keyrings: ["allowed_users.asc"],
t_commands: [
t_actions: [
{
c_url: "file:///home/katolaz/bin/deploy.sh"
a_url: "file:///home/katolaz/bin/deploy.sh"
}
]
},
{
t_name: "build",
t_keyrings: ["allowed_users.asc"],
t_commands: [
t_actions: [
{
c_url: "file:///home/katolaz/bin/scorsh_build.sh"
a_url: "file:///home/katolaz/bin/scorsh_build.sh"
}
]
}

@ -55,34 +55,34 @@ func execURL(cmdURL *url.URL, args, env []string) error {
return nil
}
func execTag(tag *commandCfg, args []string, env []string) []error {
func execCommand(cmd *commandCfg, args []string, env []string) []error {
var ret []error
for _, c := range tag.Commands {
debug.log("[tag: %s] attempting command: %s\n", tag.Name, c.URL)
cmdURL, err := url.Parse(c.URL)
for _, a := range cmd.Actions {
debug.log("[command: %s] attempting action: %s\n", cmd.Name, a.URL)
actionURL, err := url.Parse(a.URL)
if err != nil {
log.Printf("[tag: %s] error parsing URL: %s", tag.Name, err)
log.Printf("[command: %s] error parsing URL: %s", cmd.Name, err)
} else {
if cmdURL.Scheme == "file" {
if actionURL.Scheme == "file" {
err = nil
// if a hash is specified, check that it matches
if c.Hash != "" {
err = checkHash(cmdURL.Path, c.Hash)
if a.Hash != "" {
err = checkHash(actionURL.Path, a.Hash)
}
// if the hash does not match, abort the command
if err != nil {
log.Printf("[tag: %s] %s -- aborting command\n", tag.Name, err)
log.Printf("[command: %s] %s -- aborting action\n", cmd.Name, err)
ret = append(ret, err)
continue
} else {
// finally, the command can be executed
err = execLocalFile(cmdURL, args, env)
err = execLocalFile(actionURL, args, env)
}
} else if cmdURL.Scheme == "http" || cmdURL.Scheme == "https" {
err = execURL(cmdURL, args, env)
} else if actionURL.Scheme == "http" || actionURL.Scheme == "https" {
err = execURL(actionURL, args, env)
}
}
ret = append(ret, err)
@ -90,7 +90,7 @@ func execTag(tag *commandCfg, args []string, env []string) []error {
return ret
}
func setEnvironment(msg *spoolMsg, tag, author, committer string) []string {
func setEnvironment(msg *spoolMsg, cmd, author, committer string) []string {
env := os.Environ()
env = append(env, fmt.Sprintf("SCORSH_REPO=%s", msg.Repo))
@ -98,7 +98,7 @@ func setEnvironment(msg *spoolMsg, tag, author, committer string) []string {
env = append(env, fmt.Sprintf("SCORSH_OLDREV=%s", msg.OldRev))
env = append(env, fmt.Sprintf("SCORSH_NEWREV=%s", msg.NewRev))
env = append(env, fmt.Sprintf("SCORSH_ID=%s", msg.ID))
env = append(env, fmt.Sprintf("SCORSH_TAG=%s", tag))
env = append(env, fmt.Sprintf("SCORSH_COMMAND=%s", cmd))
env = append(env, fmt.Sprintf("SCORSH_AUTHOR=%s", author))
env = append(env, fmt.Sprintf("SCORSH_COMMITTER=%s", committer))

@ -29,15 +29,15 @@ func SCORSHerr(err int) error {
var errStr string
switch err {
case SCORSH_ERR_NO_FILE:
case errNoFile:
errStr = "Invalid file name"
case SCORSH_ERR_KEYRING:
case errKeyring:
errStr = "Invalid keyring"
case SCORSH_ERR_NO_REPO:
case errNoRepo:
errStr = "Invalid repository"
case SCORSH_ERR_NO_COMMIT:
case errNoCommit:
errStr = "Invalid commit ID"
case SCORSH_ERR_SIGNATURE:
case errSignature:
errStr = "Invalid signature"
default:
errStr = "Generic Error"

@ -18,7 +18,7 @@ func parseRequest(fname string, msg *spoolMsg) error {
data, err := ioutil.ReadFile(fname)
if err != nil {
log.Printf("Unable to open file: %s\n", fname)
return SCORSHerr(SCORSH_ERR_NO_FILE)
return SCORSHerr(errNoFile)
}
debug.log("[parseRequest] file contains: \n%s\n", data)

@ -8,11 +8,11 @@ import (
// error constants
const (
SCORSH_ERR_NO_FILE = -(1 << iota)
SCORSH_ERR_KEYRING
SCORSH_ERR_NO_REPO
SCORSH_ERR_NO_COMMIT
SCORSH_ERR_SIGNATURE
errNoFile = -(1 << iota)
errKeyring
errNoRepo
errNoCommit
errSignature
)
// spoolMsg type represents messages received from the spool and
@ -28,15 +28,15 @@ type spoolMsg struct {
// An action represents a script of a command configured on the server side
type action struct {
URL string `yaml:"c_url"`
Hash string `yaml:"c_hash"`
URL string `yaml:"a_url"`
Hash string `yaml:"a_hash"`
}
// commandCfg represents a command configured on the server side
type commandCfg struct {
Name string `yaml:"t_name"`
Keyrings []string `yaml:"t_keyrings"`
Commands []action `yaml:"t_commands"`
Actions []action `yaml:"t_actions"`
}
// workerCfg represents the static configuration of a worker
@ -44,11 +44,11 @@ type workerCfg struct {
Name string `yaml:"w_name"`
Repos []string `yaml:"w_repos"`
Folder string `yaml:"w_folder"`
Logfile string `yaml:"w_logfile"`
Tagfile string `yaml:"w_tagfile"`
LogFile string `yaml:"w_logfile"`
CfgFile string `yaml:"w_cfgfile"`
// Keyrings []string `yaml:"w_keyrings"`
Tags []commandCfg `yaml:"w_tags"`
TagKeys map[string]map[string]bool
Commands []commandCfg `yaml:"w_commands"`
CommandKeys map[string]map[string]bool
}
// workerState represents the runtime state of a worker
@ -67,7 +67,7 @@ type worker struct {
// masterCfg represents the static configuration of the master
type masterCfg struct {
Spooldir string `yaml:"s_spooldir"`
Logfile string `yaml:"s_logfile"`
LogFile string `yaml:"s_logfile"`
LogPrefix string `yaml:"s_logprefix"`
Workers []worker `yaml:"s_workers"`
}
@ -88,13 +88,13 @@ type master struct {
// clientCmd is the type of commands sent by clients
type clientCmd struct {
Tag string `yaml:"s_tag"`
Cmd string `yaml:"s_cmd"`
Args []string `yaml:"s_args"`
}
// clientMsg is the list of commands sent by a client
type clientMsg struct {
Tags []clientCmd `yaml:"scorsh"`
Commands []clientCmd `yaml:"scorsh"`
}
////////////////////////
@ -104,7 +104,7 @@ func (cfg *master) String() string {
var buff bytes.Buffer
fmt.Fprintf(&buff, "spooldir: %s\n", cfg.Spooldir)
fmt.Fprintf(&buff, "logfile: %s\n", cfg.Logfile)
fmt.Fprintf(&buff, "logfile: %s\n", cfg.LogFile)
fmt.Fprintf(&buff, "logprefix: %s\n", cfg.LogPrefix)
fmt.Fprintf(&buff, "Workers: \n")
@ -135,8 +135,8 @@ func (w *worker) String() string {
fmt.Fprintf(&buff, "Name: %s\n", w.Name)
fmt.Fprintf(&buff, "Repos: %s\n", w.Repos)
fmt.Fprintf(&buff, "Folder: %s\n", w.Folder)
fmt.Fprintf(&buff, "Logfile: %s\n", w.Logfile)
fmt.Fprintf(&buff, "Tagfile: %s\n", w.Tagfile)
fmt.Fprintf(&buff, "LogFile: %s\n", w.LogFile)
fmt.Fprintf(&buff, "CfgFile: %s\n", w.CfgFile)
// fmt.Fprintf(&buff, "Keyrings: %s\n", w.Keyrings)
return buff.String()
@ -146,10 +146,10 @@ func (msg *clientMsg) String() string {
var buff bytes.Buffer
for _, t := range msg.Tags {
for _, c := range msg.Commands {
fmt.Fprintf(&buff, "s_tag: %s\n", t.Tag)
for _, a := range t.Args {
fmt.Fprintf(&buff, "s_cmd: %s\n", c.Cmd)
for _, a := range c.Args {
fmt.Fprintf(&buff, " s_args: %s\n", a)
}
}

@ -35,16 +35,16 @@ func (w *worker) Matches(repo, branch string) bool {
func (w *worker) LoadKeyrings() error {
w.Keys = make(map[string]openpgp.KeyRing)
w.TagKeys = make(map[string]map[string]bool)
w.CommandKeys = make(map[string]map[string]bool)
for _, t := range w.Tags {
w.TagKeys[t.Name] = make(map[string]bool)
for _, c := range w.Commands {
w.CommandKeys[c.Name] = make(map[string]bool)
// Open the keyring files
for _, keyring := range t.Keyrings {
for _, keyring := range c.Keyrings {
if _, ok := w.Keys[keyring]; ok {
// keyring has been loaded: just add it to the TagKeys map
w.TagKeys[t.Name][keyring] = true
// keyring has been loaded: just add it to the CommandKeys map
w.CommandKeys[c.Name][keyring] = true
continue
}
kfile := fmt.Sprintf("%s/%s", w.Folder, keyring)
@ -64,26 +64,25 @@ func (w *worker) LoadKeyrings() error {
//return fmt.Errorf("Unable to load keyring: ", err_key)
}
w.Keys[keyring] = kr
w.TagKeys[t.Name][keyring] = true
w.CommandKeys[c.Name][keyring] = true
_ = f.Close()
}
}
return nil
}
// LoadTags loads all the configured commands for the worker
func (w *worker) LoadTags() error {
// LoadCommands loads all the configured commands for the worker
func (w *worker) LoadCommands() error {
wTags, err := ioutil.ReadFile(w.Tagfile)
wCmds, err := ioutil.ReadFile(w.CfgFile)
if err != nil {
return fmt.Errorf("Cannot read worker config: %s", err)
}
err = yaml.Unmarshal(wTags, w)
//err = yaml.Unmarshal(w_tags, tags)
err = yaml.Unmarshal(wCmds, w)
if err != nil {
return fmt.Errorf("Error while reading tags: %s", err)
return fmt.Errorf("Error while reading commands: %s", err)
}
return nil
@ -132,14 +131,14 @@ func startWorkers(master *master) error {
worker.StatusChan = master.StatusChan
worker.MsgChan = make(chan spoolMsg, 10)
// Load worker tags from worker.Tagfile
err := worker.LoadTags()
// Load worker commands from worker.CfgFile
err := worker.LoadCommands()
if err != nil {
close(worker.MsgChan)
return fmt.Errorf("[Starting worker: %s] Unable to load tags: %s", worker.Name, err)
return fmt.Errorf("[Starting worker: %s] Unable to load commands: %s", worker.Name, err)
}
// Load worker keyrings -- this must be called *after* LoadTags!!!!
// Load worker keyrings -- this must be called *after* LoadCommands!!!!
err = worker.LoadKeyrings()
if err != nil {
close(worker.MsgChan)

Loading…
Cancel
Save