diff options
-rw-r--r-- | config.go | 23 | ||||
-rw-r--r-- | parse.go | 99 | ||||
-rw-r--r-- | scorsh.go | 70 | ||||
-rw-r--r-- | spooler.go | 22 | ||||
-rw-r--r-- | types.go | 79 |
5 files changed, 149 insertions, 144 deletions
@@ -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 -} @@ -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) } @@ -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 +} |