package conf import ( "encoding/json" "errors" "fmt" "github.com/dballard/warren/lib/warren" "os" ) type MsgType int const ( AddDeployment MsgType = iota RmDeploymen ) type Msg struct { mType MsgType reply chan error Args map[string]string } func NewMsg(mType MsgType) *Msg { var m = &Msg{mType, make(chan error), make(map[string]string)} return m } func (m *Msg) Call() error { confChan <- *m err := <-m.reply return err } // Conf package - thread safe conf // All write ops are public API functions ( Msg.Call() ) // that internall use channels to thread safely queue writes // all write ops cause FS conf writes so that state is preserved // Reads return copies of data type Deployment struct { Path string Pool struct{Low int; High int} } type Conf struct { // name : path Deployments map[string]Deployment } var conf *Conf = nil var Init = make(chan bool) var confChan = make(chan Msg) func loadConf() { file, err := os.Open(warren.WarrendConf) if err != nil { fmt.Println("Error loading ", warren.WarrendConf, ": ", err) return } defer file.Close() decoder := json.NewDecoder(file) conf = new(Conf) err = decoder.Decode(conf) if err != nil { conf = nil fmt.Println("Error parsing ", warren.WarrendConf, ": ", err) } if conf.Deployments == nil { conf.Deployments = make(map[string]Deployment) } // populate reverse map for nick, dep := range conf.Deployments { dirToNick[dep.Path] = nick } } func saveConf() error { file, err := os.Create(warren.WarrendConf) if err != nil { // TODO: Um, more than noting we might want to do something more drastic return errors.New("Error: could not open conf file for saving: " + err.Error()) } defer file.Close() jdata, err := json.MarshalIndent(conf, "", "\t") if err != nil { return errors.New("Error: Could not enocde to json: " + err.Error()) } if _, err := file.Write(jdata); err != nil { return errors.New("Error: Could not write to file: " + err.Error()) } return nil } func GetConf() *Conf { var confCopy *Conf = new(Conf) confCopy.Deployments = make(map[string]Deployment) for key, deployment := range(conf.Deployments) { confCopy.Deployments[key] = deployment } return conf } func GetConfFor(depName string) *Deployment { deployment, ok := conf.Deployments[depName] if !ok { return nil } return &deployment } func Run() { loadConf() if conf == nil { fmt.Println("failed to load conf") Init <- false } // set up comm chans Init <- true // loop for Writes for { m := <- confChan var err error = nil switch (m.mType) { case AddDeployment: err = addDeployment(&m) break case RmDeploymen: err = rmDeployment(&m) break; default: err = errors.New("Unknown command") break } m.reply <- err } }