fixed -- correct execution order of scorsh commands

devel
KatolaZ 7 years ago
parent 200e2f0328
commit 9d60b3d95d
  1. 40
      commits.go
  2. 13
      examples/worker1/worker1.cfg
  3. 22
      exec.go
  4. 38
      types.go

@ -96,14 +96,16 @@ func intersectKeys(ref map[string]bool, keys []string) []string {
return ret return ret
} }
func findCmdConfig(cmdName string, w *worker) (*commandCfg, bool) { func findCmdConfig(cmdName string, w *worker) (commandCfg, bool) {
var cmdNull commandCfg
for _, c := range w.Commands { for _, c := range w.Commands {
if c.Name == cmdName { if c.Name == cmdName {
return &c, true return c, true
} }
} }
return nil, false return cmdNull, false
} }
func getAuthorEmail(c *git.Commit) string { func getAuthorEmail(c *git.Commit) string {
@ -124,6 +126,7 @@ func getCommitterEmail(c *git.Commit) string {
func walkCommits(msg spoolMsg, w *worker) error { func walkCommits(msg spoolMsg, w *worker) error {
var cmdMsg *clientMsg var cmdMsg *clientMsg
var cmdStack = make([]command, 0)
debug.log("[worker: %s] Inside walkCommits\n", w.Name) debug.log("[worker: %s] Inside walkCommits\n", w.Name)
@ -166,23 +169,26 @@ func walkCommits(msg spoolMsg, w *worker) error {
// if it can be verified by any of the keyrings associated with // if it can be verified by any of the keyrings associated with
// that specific scorsh-command // that specific scorsh-command
// Check if the commit contains a scorsh command // Check if the commit contains a scorsh message
cmdMsg, err = findScorshMessage(commit) cmdMsg, err = findScorshMessage(commit)
if err == nil { if err == nil {
// the commit contains a valid scorsh message // the commit contains a valid scorsh message
// 1) get the list of all the keyrings which verify the message // 1) get the list of all the keyrings which verify the message signature
validKeys := getValidKeys(commit, &(w.Keys)) validKeys := getValidKeys(commit, &(w.Keys))
debug.log("[worker: %s] validated keyrings on commit: %s\n", w.Name, validKeys) debug.log("[worker: %s] validated keyrings on commit: %s\n", w.Name, validKeys)
// 2) then for each command in the message // 2) then for each command in the message
for _, c := range cmdMsg.Commands { for _, c := range cmdMsg.Commands {
if c.Cmd == "" { if c.Cmd == "" {
// The command is empty -- ignore, log, and continue
log.Printf("[worker: %s] empty command\n", w.Name) log.Printf("[worker: %s] empty command\n", w.Name)
continue continue
} }
// a) check that the command is among those accepted by the worker // a) check that the command is among those accepted by the worker
debug.log("[worker: %s] validating command: %s\n", w.Name, c.Cmd) debug.log("[worker: %s] validating command: %s\n", w.Name, c.Cmd)
cmdCfg, goodCmd := findCmdConfig(c.Cmd, w) var cmd = new(command)
var goodCmd, goodKeys bool
cmd.commandCfg, goodCmd = findCmdConfig(c.Cmd, w)
debug.log("[worker: %s] goodCmd: %s\n", w.Name, goodCmd) debug.log("[worker: %s] goodCmd: %s\n", w.Name, goodCmd)
if !goodCmd { if !goodCmd {
@ -192,7 +198,7 @@ func walkCommits(msg spoolMsg, w *worker) error {
// b) check that at least one of the accepted command keyrings // b) check that at least one of the accepted command keyrings
// is in valid_keys // is in valid_keys
goodKeys := intersectKeys(w.CommandKeys[c.Cmd], validKeys) != nil goodKeys = intersectKeys(w.CommandKeys[c.Cmd], validKeys) != nil
debug.log("[worker: %s] goodKeys: %s\n", w.Name, goodKeys) debug.log("[worker: %s] goodKeys: %s\n", w.Name, goodKeys)
if !goodKeys { if !goodKeys {
@ -200,11 +206,11 @@ func walkCommits(msg spoolMsg, w *worker) error {
continue continue
} }
// c) If everything is OK, execute the command // c) If everything is OK, push the command to the stack
if goodCmd && goodKeys { if goodCmd && goodKeys {
env := setEnvironment(&msg, c.Cmd, getAuthorEmail(commit), getCommitterEmail(commit)) cmd.setEnvironment(&msg, curCommit.Id().String(), getAuthorEmail(commit), getCommitterEmail(commit))
errs := execCommand(cmdCfg, c.Args, env) cmd.Args = c.Args
debug.log("[worker: %s] errors in command %s: %s\n", w.Name, c.Cmd, errs) cmdStack = append(cmdStack, *cmd)
} }
} }
} else { } else {
@ -216,6 +222,18 @@ func walkCommits(msg spoolMsg, w *worker) error {
fmt.Printf("Commit %x not found!\n", curCommit.Id()) fmt.Printf("Commit %x not found!\n", curCommit.Id())
return SCORSHerr(errNoCommit) return SCORSHerr(errNoCommit)
} }
} }
stackHead := len(cmdStack) - 1
debug.log("[worker: %s] Executing command stack:\n", w.Name)
for i := range cmdStack {
//debug.log("[stack elem: %d] %s\n", i, cmdStack[stackHead-i].String())
// now we execute the command that emerges from the stack
cmd := cmdStack[stackHead-i]
errs := cmd.exec()
debug.log("[worker: %s] errors in command %s: %s\n", w.Name, cmd.Name, errs)
}
return nil return nil
} }

@ -15,7 +15,7 @@ w_commands:
c_keyrings: ["allowed_users.asc"], c_keyrings: ["allowed_users.asc"],
c_actions: [ c_actions: [
{ {
a_url: "file:///home/katolaz/bin/scorsh_script.sh" a_url: "file:///home/katolaz/bin/scorsh_script_log.sh"
## a_hash: "12da324fb76s924acbce" ## a_hash: "12da324fb76s924acbce"
} }
] ]
@ -26,7 +26,16 @@ w_commands:
c_actions: [ c_actions: [
{ {
a_url: "file:///home/katolaz/bin/scorsh_script.sh", a_url: "file:///home/katolaz/bin/scorsh_script.sh",
a_hash: "aa606bc152824c1b650d7e71e2e92bb69a9b7c861c69cd439d17902488e5f76e" a_hash: "c129d4a12998c44dfb9a9fd61ec3159bf29606e0f7280f28bbd98fc6f972fa27"
}
]
},
{
c_name: "preview",
c_keyrings: ["allowed_users.asc"],
c_actions: [
{
a_url: "file:///home/katolaz/bin/scorsh_preview.sh"
} }
] ]
} }

@ -7,7 +7,6 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"net/url" "net/url"
"os"
"os/exec" "os/exec"
) )
@ -55,7 +54,7 @@ func execURL(cmdURL *url.URL, args, env []string) error {
return nil return nil
} }
func execCommand(cmd *commandCfg, args []string, env []string) []error { func (cmd *command) exec() []error {
var ret []error var ret []error
@ -78,29 +77,14 @@ func execCommand(cmd *commandCfg, args []string, env []string) []error {
continue continue
} else { } else {
// finally, the command can be executed // finally, the command can be executed
err = execLocalFile(actionURL, args, env) err = execLocalFile(actionURL, cmd.Args, cmd.Env)
} }
} else if actionURL.Scheme == "http" || actionURL.Scheme == "https" { } else if actionURL.Scheme == "http" || actionURL.Scheme == "https" {
err = execURL(actionURL, args, env) err = execURL(actionURL, cmd.Args, cmd.Env)
} }
} }
ret = append(ret, err) ret = append(ret, err)
} }
return ret return ret
} }
func setEnvironment(msg *spoolMsg, cmd, author, committer string) []string {
env := os.Environ()
env = append(env, fmt.Sprintf("SCORSH_REPO=%s", msg.Repo))
env = append(env, fmt.Sprintf("SCORSH_BRANCH=%s", msg.Branch))
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_COMMAND=%s", cmd))
env = append(env, fmt.Sprintf("SCORSH_AUTHOR=%s", author))
env = append(env, fmt.Sprintf("SCORSH_COMMITTER=%s", committer))
return env
}

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"golang.org/x/crypto/openpgp" "golang.org/x/crypto/openpgp"
"os"
) )
// error constants // error constants
@ -39,6 +40,16 @@ type commandCfg struct {
Actions []action `yaml:"c_actions"` Actions []action `yaml:"c_actions"`
} }
type commandState struct {
Env []string
Args []string
}
type command struct {
commandCfg
commandState
}
// workerCfg represents the static configuration of a worker // workerCfg represents the static configuration of a worker
type workerCfg struct { type workerCfg struct {
Name string `yaml:"w_name"` Name string `yaml:"w_name"`
@ -157,3 +168,30 @@ func (msg *clientMsg) String() string {
return buff.String() return buff.String()
} }
func (cmd *command) setEnvironment(msg *spoolMsg, commitID, author, committer string) {
env := os.Environ()
env = append(env, fmt.Sprintf("SCORSH_REPO=%s", msg.Repo))
env = append(env, fmt.Sprintf("SCORSH_BRANCH=%s", msg.Branch))
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_COMMIT=%s", commitID))
env = append(env, fmt.Sprintf("SCORSH_COMMAND=%s", cmd.Name))
env = append(env, fmt.Sprintf("SCORSH_AUTHOR=%s", author))
env = append(env, fmt.Sprintf("SCORSH_COMMITTER=%s", committer))
cmd.Env = env
}
func (cmd *command) String() string {
var buff bytes.Buffer
fmt.Fprintf(&buff, "Name: %s\n", cmd.Name)
fmt.Fprintf(&buff, "Keyrings: %s\n", cmd.Keyrings)
fmt.Fprintf(&buff, "Actions: %s\n", cmd.Actions)
fmt.Fprintf(&buff, "Env: %s\n", cmd.Env)
fmt.Fprintf(&buff, "Args: %s\n", cmd.Args)
return buff.String()
}

Loading…
Cancel
Save