summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.go23
-rw-r--r--parse.go99
-rw-r--r--scorsh.go70
-rw-r--r--spooler.go22
-rw-r--r--types.go79
5 files changed, 149 insertions, 144 deletions
diff --git a/config.go b/config.go
index 452f187..15e234b 100644
--- a/config.go
+++ b/config.go
@@ -10,33 +10,18 @@ import (
"os"
)
-type SCORSHWorker_cfg 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"`
- Keyrings []string `yaml:"w_keyrings"`
-}
-
-type SCORSHcfg struct {
- Spooldir string `yaml:"s_spooldir"`
- Logfile string `yaml:"s_logfile"`
- LogPrefix string `yaml:"s_logprefix"`
- Workers []SCORSHWorker_cfg `yaml:"s_workers"`
-}
// Read a configuration from fname or die
-func ReadGlobalConfig(fname string) *SCORSHcfg {
+func ReadGlobalConfig(fname string) *SCORSHmaster {
data, err := ioutil.ReadFile(fname)
if err != nil {
log.Fatal("Error while reading file: ", err)
}
- var cfg *SCORSHcfg
- cfg = new(SCORSHcfg)
+ var cfg *SCORSHmaster
+ cfg = new(SCORSHmaster)
// Unmarshal the YAML configuration file into a SCORSHcfg structure
err = yaml.Unmarshal(data, cfg)
@@ -73,7 +58,7 @@ func ReadGlobalConfig(fname string) *SCORSHcfg {
}
-func (cfg *SCORSHcfg) String() string {
+func (cfg *SCORSHmaster_cfg) String() string {
var buff bytes.Buffer
diff --git a/parse.go b/parse.go
deleted file mode 100644
index c76395b..0000000
--- a/parse.go
+++ /dev/null
@@ -1,99 +0,0 @@
-package main
-
-import (
- "fmt"
- "github.com/KatolaZ/git2go"
- "golang.org/x/crypto/openpgp"
- "os"
- "strings"
- "log"
-)
-
-func CommitToString(commit *git.Commit) string {
-
- var ret string
-
- ret += fmt.Sprintf("type: %s\n", commit.Type())
- ret += fmt.Sprintf("Id: %s\n", commit.Id())
- ret += fmt.Sprintf("Author: %s\n", commit.Author())
- ret += fmt.Sprintf("Message: %s\n", commit.Message())
- ret += fmt.Sprintf("Parent-count: %d\n", commit.ParentCount())
-
- return ret
-}
-
-// FIXME: RETURN THE ENTITY PROVIDED BY THE CHECK, OR nil
-func check_signature(commit *git.Commit, keyring *openpgp.KeyRing) (signature, signed string, err error) {
-
- signature, signed, err = commit.ExtractSignature()
- if err == nil {
-
- _, err_sig :=
- openpgp.CheckArmoredDetachedSignature(*keyring, strings.NewReader(signed),
- strings.NewReader(signature))
-
- if err_sig == nil {
- fmt.Printf("Good signature \n")
- return signature, signed, nil
- }
- err = err_sig
- }
-
- return "", "", err
-}
-
-
-// traverse all the commits between two references, looking for
-func walk_commits(msg SCORSHmsg, keyring openpgp.KeyRing) int {
-
- fmt.Printf("Inside parse_commits\n")
-
- reponame := msg.repo
- old_rev := msg.old_rev
- new_rev := msg.new_rev
-
- repo, err := git.OpenRepository(reponame)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error while opening repository %s (%s)\n",
- reponame, err)
- return SCORSH_ERR_NO_REPO
- }
-
- old_rev_oid, err := git.NewOid(old_rev)
-
- oldrev_commit, err := repo.LookupCommit(old_rev_oid)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Commit: %s does not exist\n", old_rev)
- return SCORSH_ERR_NO_COMMIT
- }
-
- new_rev_oid, err := git.NewOid(new_rev)
-
- newrev_commit, err := repo.LookupCommit(new_rev_oid)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Commit: %s does not exist\n", new_rev)
- return SCORSH_ERR_NO_COMMIT
- }
-
- cur_commit := newrev_commit
-
- for cur_commit.Id().String() != oldrev_commit.Id().String() {
-
- commit, err := repo.LookupCommit(cur_commit.Id())
- if err == nil {
-
- fmt.Printf("%s", CommitToString(commit))
- //signature, signed, err := check_signature(commit, &keyring)
- _, _, err := check_signature(commit, &keyring)
- if err != nil {
- log.Printf("%s\n", SCORSHErr(SCORSH_ERR_SIGNATURE))
-
- }
- cur_commit = commit.Parent(0)
- } else {
- fmt.Printf("Commit %x not found!\n", cur_commit.Id())
- return SCORSH_ERR_NO_COMMIT
- }
- }
- return 0
-}
diff --git a/scorsh.go b/scorsh.go
index 07745b3..af9c367 100644
--- a/scorsh.go
+++ b/scorsh.go
@@ -2,30 +2,14 @@ package main
import (
"errors"
- "log"
"flag"
-)
-
-const (
- SCORSH_ERR_NO_FILE = -(1 << iota)
- SCORSH_ERR_KEYRING
- SCORSH_ERR_NO_REPO
- SCORSH_ERR_NO_COMMIT
- SCORSH_ERR_SIGNATURE
+ "log"
)
-type SCORSHmsg struct {
- repo string
- branch string
- old_rev string
- new_rev string
-}
var conf_file = flag.String("c", "./scorsh.cfg", "Configuration file for SCORSH")
-
-
func SCORSHErr(err int) error {
var err_str string
@@ -50,17 +34,55 @@ func SCORSHErr(err int) error {
}
+func FindMatchingWorkers(master *SCORSHmaster, msg *SCORSHmsg) []*SCORSHworker {
+
+ var ret []*SCORSHworker
+
+ for _,w := range master.Workers {
+ if w.Matches(msg.repo, msg.branch) {
+ ret = append(ret, &w)
+ }
+ }
+ return ret
+}
+
+
+func Master(master *SCORSHmaster) {
+
+ // master main loop:
+
+ var matching_workers []*SCORSHworker
+ var push_msg SCORSHmsg
+
+ matching_workers = make([]*SCORSHworker, len(master.Workers))
+
+ for {
+ select {
+ // - receive stuff from the spooler
+ case push_msg = <- master.Spooler:
+ // - lookup the repos map for matching workers
+ matching_workers = FindMatchingWorkers(master, &push_msg)
+ // - dispatch the message to all the matching workers
+ for _, w := range matching_workers {
+ w.Chan <- push_msg
+ }
+ }
+ }
+}
func main() {
flag.Parse()
- cfg := ReadGlobalConfig(*conf_file)
+ master := ReadGlobalConfig(*conf_file)
- msg, status := StartWorkers(cfg)
-
-
-
- log.Printf("%s\n", cfg)
-
+ err_workers := StartWorkers(master)
+ if err_workers != nil {
+ log.Fatal("Error starting workers: ", err_workers)
+ }
+ err_spooler := StartSpooler(master)
+ if err_spooler != nil {
+ log.Fatal("Error starting spooler: ", err_spooler)
+ }
+ go Master(master)
}
diff --git a/spooler.go b/spooler.go
index 05dcf1a..4f0f508 100644
--- a/spooler.go
+++ b/spooler.go
@@ -4,6 +4,7 @@ import (
"github.com/fsnotify/fsnotify"
"log"
"os"
+ "fmt"
)
// parse a request file and return a SCORSHmessage
@@ -22,7 +23,7 @@ func parse_request(fname string) (SCORSHmsg, error) {
func spooler(watcher *fsnotify.Watcher, worker chan SCORSHmsg) {
-
+
for {
select {
case event := <-watcher.Events:
@@ -36,8 +37,25 @@ func spooler(watcher *fsnotify.Watcher, worker chan SCORSHmsg) {
case err := <-watcher.Errors:
log.Println("error:", err)
}
-
}
}
+func StartSpooler(master *SCORSHmaster) error {
+
+ watcher, err := fsnotify.NewWatcher()
+
+ if err != nil {
+ return fmt.Errorf("Error creating watcher: %s\n", err)
+ }
+
+ err = watcher.Add(master.Spooldir)
+ if err != nil {
+ return fmt.Errorf("Error adding folder: %s\n", err)
+ }
+
+ go spooler(watcher, master.Spooler)
+
+ return nil
+
+}
diff --git a/types.go b/types.go
new file mode 100644
index 0000000..b14a103
--- /dev/null
+++ b/types.go
@@ -0,0 +1,79 @@
+package main
+
+import (
+ "golang.org/x/crypto/openpgp"
+)
+
+const (
+ SCORSH_ERR_NO_FILE = -(1 << iota)
+ SCORSH_ERR_KEYRING
+ SCORSH_ERR_NO_REPO
+ SCORSH_ERR_NO_COMMIT
+ SCORSH_ERR_SIGNATURE
+)
+
+// the SCORSHmsg type represents messages received from the spool and
+// sent to workers
+type SCORSHmsg struct {
+ repo string
+ branch string
+ old_rev string
+ new_rev string
+}
+
+
+type SCORSHcmd struct {
+ URL string
+ hash string
+}
+
+type SCORSHtag struct {
+ TagName string
+ Keyrings []string
+ Commands []SCORSHcmd
+}
+
+// Configuration of a worker
+type SCORSHworker_cfg 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"`
+ Keyrings []string `yaml:"w_keyrings"`
+}
+
+// State of a worker
+type SCORSHworker_state struct {
+ Tags map[string]SCORSHtag
+ Keys map[string]openpgp.KeyRing
+ Chan chan SCORSHmsg
+}
+
+// The type SCORSHworker represents the configuration and state of a
+// worker
+type SCORSHworker struct {
+ SCORSHworker_cfg
+ SCORSHworker_state
+}
+
+// Configuration of the master
+type SCORSHmaster_cfg struct {
+ Spooldir string `yaml:"s_spooldir"`
+ Logfile string `yaml:"s_logfile"`
+ LogPrefix string `yaml:"s_logprefix"`
+ Workers []SCORSHworker `yaml:"s_workers"`
+}
+
+// State of the master
+type SCORSHmaster_state struct {
+ Spooler chan SCORSHmsg
+ Repos map[string][]*SCORSHworker
+}
+
+// The type SCORSHmaster represents the configuration and state of the
+// master
+type SCORSHmaster struct {
+ SCORSHmaster_cfg
+ SCORSHmaster_state
+}