package main /* All the information is defined by protobuf files The config files written out by default into ~/.config/virtigo/ protobuf definitions are by nature non-relational so each protobuf is written out as a seperate file. This seems like the simpilist way to handle this. */ import ( "errors" "fmt" "os" "path/filepath" "time" pb "go.wit.com/lib/protobuf/virtbuf" "go.wit.com/log" ) var ErrorNoFile error = errors.New("missing file") var ErrorParseJSON error = errors.New("invalid json") var ErrorParseXML error = errors.New("invalid xml") // something is wrong somewhere and sometimes the // protobuf json files get written out with garbage func cfgfile() { err := readConfigFile("virtigo.json") if err == nil { return } if err == ErrorParseJSON { os.Exit(-1) } err = readConfigFile("virtigo.json.last") if err == nil { log.Info("read json failed", err) os.Exit(-1) } if err == ErrorNoFile { log.Info("no config file created yet", err) os.Exit(-1) } } func readConfigFile(filename string) error { me.cluster = new(pb.Cluster) fullname := filepath.Join(os.Getenv("VIRTIGO_HOME"), filename) pfile, err := os.ReadFile(fullname) if err != nil { log.Info("open config file :", err) return err } err = me.cluster.UnmarshalJSON(pfile) if err != nil { log.Info("read json failed", err) os.Exit(-1) return err } // initialize each hypervisor for _, pbh := range me.cluster.Hypervisors { h := findHypervisor(pbh.Hostname) if h != nil { continue } // this is a new unknown droplet (not in the config file) h = new(HyperT) h.pb = pbh h.lastpoll = time.Now() me.hypers = append(me.hypers, h) log.Log(EVENT, "config new hypervisors", h.pb.Hostname) } // initialize values for each droplet for _, pbd := range me.cluster.Droplets { d := findDroplet(pbd.Hostname) if d != nil { continue } // this is a new unknown droplet (not in the config file) d = new(DropletT) d.pb = pbd me.droplets = append(me.droplets, d) log.Log(EVENT, "config new droplet", d.pb.Hostname, d.pb.StartState, d.pb.PreferredHypervisor) } return nil } func writeConfigFile() { // Get the current time now := time.Now() // Format the time to match your desired format: YYYY.MM.DD.HHMMSS timestamp := now.Format("2006.01.02.150405") filename := "virtigo.json.new." + timestamp if !writeConfigFileTmp(filename) { log.Println("config file write error") os.Exit(-1) } origname := filepath.Join(os.Getenv("VIRTIGO_HOME"), "virtigo.json") newname := filepath.Join(os.Getenv("VIRTIGO_HOME"), "virtigo.json.old") err := os.Rename(origname, newname) if err != nil { log.Printf("rename fail: %s", err) os.Exit(-1) } if !writeConfigFileTmp("virtigo.json") { log.Println("config file write error") os.Exit(-1) } if me.events.WriteConfigJSON() { os.Exit(-1) } if me.events.WriteConfigTEXT() { os.Exit(-1) } /* if me.cluster.Droplets.WriteConfigJSON() { os.Exit(-1) } if me.cluster.Droplets.WriteConfigTEXT() { os.Exit(-1) } */ } func writeConfigFileTmp(filename string) bool { fullname := filepath.Join(os.Getenv("VIRTIGO_HOME"), filename) cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666) defer cfgfile.Close() if err != nil { log.Info("open config file :", err) return false } json := me.cluster.FormatJSON() fmt.Fprintln(cfgfile, json) log.Info("Write:", fullname, "OK") return true } func writeConfigFileDroplets() { fullname := filepath.Join(os.Getenv("VIRTIGO_HOME"), "droplets.text") cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666) defer cfgfile.Close() if err != nil { log.Info("open config file :", err) return } // text := me.cluster.Droplets.FormatTEXT() text := me.cluster.FormatTEXT() fmt.Fprintln(cfgfile, text) log.Info("Write:", fullname, "OK") }