fixed -- correct execution order of scorsh commands

devel
KatolaZ 7 years ago
parent 200e2f0328
commit 9d60b3d95d
  1. 40
      commits.go
  2. 15
      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
}
func findCmdConfig(cmdName string, w *worker) (*commandCfg, bool) {
func findCmdConfig(cmdName string, w *worker) (commandCfg, bool) {
var cmdNull commandCfg
for _, c := range w.Commands {
if c.Name == cmdName {
return &c, true
return c, true
}
}
return nil, false
return cmdNull, false
}
func getAuthorEmail(c *git.Commit) string {
@ -124,6 +126,7 @@ func getCommitterEmail(c *git.Commit) string {
func walkCommits(msg spoolMsg, w *worker) error {
var cmdMsg *clientMsg
var cmdStack = make([]command, 0)
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
// that specific scorsh-command
// Check if the commit contains a scorsh command
// Check if the commit contains a scorsh message
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
// 1) get the list of all the keyrings which verify the message signature
validKeys := getValidKeys(commit, &(w.Keys))
debug.log("[worker: %s] validated keyrings on commit: %s\n", w.Name, validKeys)
// 2) then for each command in the message
for _, c := range cmdMsg.Commands {
if c.Cmd == "" {
// The command is empty -- ignore, log, and continue
log.Printf("[worker: %s] empty command\n", w.Name)
continue
}
// a) check that the command is among those accepted by the worker
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)
if !goodCmd {
@ -192,7 +198,7 @@ func walkCommits(msg spoolMsg, w *worker) error {
// b) check that at least one of the accepted command keyrings
// 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)
if !goodKeys {
@ -200,11 +206,11 @@ func walkCommits(msg spoolMsg, w *worker) error {
continue
}
// c) If everything is OK, execute the command
// c) If everything is OK, push the command to the stack
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)
cmd.setEnvironment(&msg, curCommit.Id().String(), getAuthorEmail(commit), getCommitterEmail(commit))
cmd.Args = c.Args
cmdStack = append(cmdStack, *cmd)
}
}
} else {
@ -216,6 +222,18 @@ func walkCommits(msg spoolMsg, w *worker) error {
fmt.Printf("Commit %x not found!\n", curCommit.Id())
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
}

@ -15,7 +15,7 @@ w_commands:
c_keyrings: ["allowed_users.asc"],
c_actions: [
{
a_url: "file:///home/katolaz/bin/scorsh_script.sh"
a_url: "file:///home/katolaz/bin/scorsh_script_log.sh"
## a_hash: "12da324fb76s924acbce"
}
]
@ -26,10 +26,19 @@ w_commands:
c_actions: [
{
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"
"log"
"net/url"
"os"
"os/exec"
)
@ -55,7 +54,7 @@ func execURL(cmdURL *url.URL, args, env []string) error {
return nil
}
func execCommand(cmd *commandCfg, args []string, env []string) []error {
func (cmd *command) exec() []error {
var ret []error
@ -78,29 +77,14 @@ func execCommand(cmd *commandCfg, args []string, env []string) []error {
continue
} else {
// 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" {
err = execURL(actionURL, args, env)
err = execURL(actionURL, cmd.Args, cmd.Env)
}
}
ret = append(ret, err)
}
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"
"fmt"
"golang.org/x/crypto/openpgp"
"os"
)
// error constants
@ -39,6 +40,16 @@ type commandCfg struct {
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
type workerCfg struct {
Name string `yaml:"w_name"`
@ -157,3 +168,30 @@ func (msg *clientMsg) String() 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