diff --git a/config.go b/config.go index 180a6ef..4ecc4f8 100644 --- a/config.go +++ b/config.go @@ -16,11 +16,69 @@ import "os/user" import "flag" import "fmt" import "runtime" +import "io/ioutil" +import "strings" + +import "github.com/golang/protobuf/jsonpb" +import pb "git.wit.com/wit/witProtobuf" + +import "github.com/davecgh/go-spew/spew" // always override the debugging flag from the command line var debugging *bool var debugtable *bool +var config *pb.Config + +// This loads the config file and marshals it into the +// config protocol buffer definition. +// Then it is very easy to pass all the config options +// around and the re-write that JSON file when the GUI +// exits +func loadConfigFile() { + // look up the user information + user, err := user.Current() + if err != nil { + onExit(err) + } + spew.Dump(user) + + filename := "" + // TODO: figure out how to look for this file in the right + // place under Linux, MacOS and Windows + if runtime.GOOS == "linux" { + log.Println("OS: Linux") + filename = user.HomeDir + "/.config/cloud-control-panel.json" + } else if runtime.GOOS == "windows" { + log.Println("OS: Windows") + filename = user.HomeDir + "/.config/cloud-control-panel.json" + } else { + log.Println("OS: " + runtime.GOOS) + filename = user.HomeDir + "/cloud-control-panel.json" + } + + tmp := loadDefaultConfig() + config = &tmp +// os.Exit(1) + +// junk := marshalEvent() +// spew.Dump(junk) +// config = unmarshalConfig(junk) + + // config = unmarshalConfig(string(b)) + + config.Filename = filename +} + +func unmarshalConfig(a string) *pb.Config { + var newpb *pb.Config + log.Println("ATTEMTED TO UNMARSHAL string =", a) + err := jsonpb.UnmarshalString(a, newpb) + log.Println("ATTEMTED TO UNMARSHAL err =", err) + spew.Dump(newpb) + return newpb +} + var customUsage = func() { fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s:\n", os.Args[0]) flag.PrintDefaults() @@ -58,86 +116,134 @@ func parseFlags() { if (*width > 100) { log.Println("ENABLE width =", int32(*width)) - pbC.Width = int32(*width) + config.Width = int32(*width) } if (*height > 100) { log.Println("ENABLE height =", int32(*height)) - pbC.Height = int32(*height) + config.Height = int32(*height) } log.Println("ENABLE nogui =", *nogui) log.Println("ENABLE debugging =", *debugging) - // if (debugging == true) { if (*debugging) { log.Println("ENABLE width =", *width) log.Println("ENABLE debugging =", *debugging) } else { log.Println("DISABLE DEBUG debugging =", *debugging) } - // os.Exit(0) if (hostname == "") { - pbC.Hostname = hostname + config.Hostname = hostname } - pbC.Debugging = *debugging - pbC.Debugtable = *debugtable + config.Debugging = *debugging + config.Debugtable = *debugtable - log.Println("pbC.Width", pbC.Width) - log.Println("pbC.Debugging", pbC.Debugging) + log.Println("config.Width", config.Width) + log.Println("config.Debugging", config.Debugging) } -func parseConfig(defaultConfig string) { +func parseConfig() { + // first load the config file + loadConfigFile() + + // override the config file from the command line parseFlags() - log.Println("pbC.width", pbC.Width) - log.Println("pbC.height", pbC.Height) - log.Println("pbC.debugging", pbC.Debugging) + log.Println("config.width", config.Width) + log.Println("config.height", config.Height) + log.Println("config.debugging", config.Debugging) -// config.LoadOSEnv([]string{"MAIL"}) -// config.LoadOSEnv([]string{"USER"}) -// config.LoadOSEnv([]string{"BUILDDEBUG"}) + // use this to restore the default config +// defaultConfig, _ := packrBox.FindString("cloud.json") +// config = pb.MakeDefaultConfig() +// spew.Dump(config) - // look up the user information to try to figure out where the config file is stored - user, err := user.Current() - if err != nil { - onExit(err) - } - - // TODO: figure out how to look for this file in the right - // place under Linux, MacOS and Windows - if runtime.GOOS == "linux" { - log.Println("OS: Linux") - pbC.Filename = user.HomeDir + "/.config/cloud-control-panel.json" - } else if runtime.GOOS == "windows" { - log.Println("OS: Windows") - pbC.Filename = user.HomeDir + "/.config/cloud-control-panel.json" - // config.Set("configfile", user.HomeDir + "\\cloud-control-panel.json") - } else { - log.Println("OS: " + runtime.GOOS) - pbC.Filename = user.HomeDir + "/cloud-control-panel.json" - // config.Set("configfile", user.HomeDir + "/cloud-control-panel.json") - } - - // TODO: load the default config file from the resources dir if the config file doesn't exist yet - // config.LoadFiles("config.json") - -/* - filename := config.String("configfile") - config.LoadFiles(filename) - - // always override the JSON config file debugging flags from the command line - config.Set("debugging", *debugging) - config.Set("debugtable", *debugtable) - - for account, _ := range config.StringMap("cloud") { - port := config.String("accounts." + account + ".port") - proto := config.String("accounts." + account + ".proto") - hostname := config.String("accounts." + account + ".hostname") - log.Println(account, hostname, port, proto) - } - - if (config.String("nogui") == "true") { - log.Println("DO NOT DISPLAY THE GUI") - } -*/ } + +func marshalEvent() string { + // This is how you marshal into JSON from a Protobuf + c := pb.MakeDefaultConfig() + + marshaler := &jsonpb.Marshaler{} + stuff, _ := marshaler.MarshalToString(c) + log.Println(stuff) + + // also: + // var j *bytes.Buffer + // marshaler.Marshal(j, event) + // w.Write(j.Bytes()) + + return stuff +} + +func writeToFile(filename string, a string) { + f, _ := os.Create(filename) + f.WriteString(a) + f.Close() +} + +func saveConfig() { + filename := config.Filename + if (filename == "") { + log.Println("NOT SAVING CONFIG FILE") + } else { + marshaler := &jsonpb.Marshaler{} + stuff, _ := marshaler.MarshalToString(config) + log.Println(stuff) + + // TODO: Fix this + log.Println("FIXME: NOT SAVING CONFIG FILE AS:", filename) + writeToFile(filename, stuff) +/* + f, err := os.Create(filename + ".yaml") + if err == nil { + // DumpTo(f, "yaml") + } + + f, err = os.Create(filename) + if err == nil { + // DumpTo(f, "json") + } +*/ + } +} + +// will load the default config from within the go binary +func loadDefaultConfig() pb.Config { + log.Println("TRY TO LOAD DEFAULT CONFIG") + // defaultConfig, _ := packrBox.FindString("protobuf-config.json") + defaultConfig, err := packrBox.FindString("protobuf-small.json") + log.Println("defaultConfig =", defaultConfig) + log.Println("err =", err) + log.Println("NEED TO UNMARSHAL THIS HERE") + log.Println("NEED TO UNMARSHAL THIS HERE") + log.Println("NEED TO UNMARSHAL THIS HERE") + // var newpb *pb.Config + sets := pb.Config{} + b, err := ioutil.ReadFile("resources/protobuf-config.json") + if err != nil { + log.Println("ioutil.ReadFile() ERROR =", err) + } + log.Println("ioutil.ReadFile() b =", b) + + err = jsonpb.Unmarshal(strings.NewReader(string(b)), &sets) + if err != nil { + log.Println("jsonpb.Unmarshal() ERROR =", err) + } + spew.Dump(sets) + // os.Exit(0) + return sets +} + + /* + log.Println("ATTEMTED TO UNMARSHAL err =", err) + spew.Dump(newpb) + if (err == nil) { + log.Println("SETTING config to the default config", err) + // TODO: save the protobuf somewhere as the user could loose the tokens + log.Println("THIS IS PROBABLY REALLY BAD", err) + log.Println("THIS IS PROBABLY REALLY BAD", err) + log.Println("THIS IS PROBABLY REALLY BAD", err) + // config = newpb + } + */ diff --git a/main.go b/main.go index 8c0c497..6154d82 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,6 @@ import "time" import "os/user" import "runtime" import "runtime/debug" -import "github.com/golang/protobuf/jsonpb" -// import "github.com/golang/protobuf/proto" // this is the king of dns libraries import "github.com/miekg/dns" @@ -27,8 +25,6 @@ var GITCOMMIT string // this is passed in as an ldflag var GOVERSION string // this is passed in as an ldflag var BUILDTIME string // this is passed in as an ldflag -var pbC *pb.Config - // reminder to use this for JSON // https://github.com/tidwall/gjson // value := gjson.Get(json, "name.last") @@ -49,28 +45,8 @@ func onExit(err error) { log.Println("Sleep for 1 second") time.Sleep(1 * 1000 * 1000 * 1000) - filename := pbC.Filename - if (filename == "") { - log.Println("NOT SAVING CONFIG FILE") - } else { - marshaler := &jsonpb.Marshaler{} - stuff, _ := marshaler.MarshalToString(pbC) - log.Println(stuff) - - // TODO: Fix this - log.Println("FIXME: NOT SAVING CONFIG FILE AS:", filename) -/* - f, err := os.Create(filename + ".yaml") - if err == nil { - // DumpTo(f, "yaml") - } - - f, err = os.Create(filename) - if err == nil { - // DumpTo(f, "json") - } -*/ - } + // save the protobuf.Config as a JSON config file + saveConfig() if (err != nil) { panic(err) @@ -97,19 +73,20 @@ func main() { // This puts all the files in that directory in the binary // This directory includes the default config file if there is not already one packrBox = packr.NewBox("./resources") - defaultConfig, _ := packrBox.FindString("cloud.json") - - pbC = pb.MakeDefaultConfig() - spew.Dump(pbC) // This will parse the command line and config file - parseConfig(defaultConfig) + // This uses a protobuf definition and then Marshal's + // and unmarshal's that into a JSON config file + // that is human readable and editable. This is the easy way + // to pass around a configuration structure throughout a + // golang application IMHO + parseConfig() - for key, foo := range pbC.Accounts { - log.Println("account = ", key, foo) + for key, foo := range config.Accounts { + log.Println("FOUND ACCOUNT = ", key, foo) } - gui.Data.Config = pbC - // onExit(nil) + // pass a pointer to the config so the gui can access it + gui.Data.Config = config initChannel() go processEvents() @@ -122,8 +99,8 @@ func main() { onExit(err) } - gui.Data.Width = int(pbC.Width) - gui.Data.Height = int(pbC.Height) + gui.Data.Width = int(config.Width) + gui.Data.Height = int(config.Height) // use this to discover what the OS thinks it's hostname is // seems to be cross platform (?) @@ -144,8 +121,8 @@ func main() { gui.Data.HomeDir = user.HomeDir // Set output debugging level - gui.Data.Debug = pbC.Debugging - gui.Data.DebugTable = pbC.Debugtable + gui.Data.Debug = config.Debugging + gui.Data.DebugTable = config.Debugtable log.Println("gui.Data.Debug = ", gui.Data.Debug) log.Println("gui.Data.DebugTable = ", gui.Data.DebugTable) @@ -185,21 +162,12 @@ func mainMouseClick(b *gui.ButtonMap) { log.Println("\tTRIGGER CREATE VM") gui.Data.State = "CREATE" } else if (b.Action == "CONFIG") { - log.Println("TRY TO LOAD DEFAULT CONFIG") - defaultConfig, _ := packrBox.FindString("protobuf-config.json") - log.Println("defaultConfig =", defaultConfig) - log.Println("NEED TO UNMARSHAL THIS HERE") - log.Println("NEED TO UNMARSHAL THIS HERE") - log.Println("NEED TO UNMARSHAL THIS HERE") - var newpb *pb.Config - err := jsonpb.UnmarshalString(defaultConfig, newpb) - log.Println("ATTEMTED TO UNMARSHAL err =", err) - spew.Dump(newpb) + loadDefaultConfig() gui.Data.State = "done" } else if (b.Action == "DEBUG") { log.Println("debug.PrintStack() (SHOULD BE JUST THIS goroutine)") debug.PrintStack() - + } else if (b.Action == "DEBUG FULL") { log.Println("ATTEMPT FULL STACK DUMP") buf := make([]byte, 1<<16) runtime.Stack(buf, true) @@ -232,7 +200,7 @@ func mainMouseClick(b *gui.ButtonMap) { log.Println("LOGIN WAS OK!") log.Println("LOGIN WAS OK!") msg := "On account " + b.Account.Nick + "\n" - gui.ErrorWindow("Login OK", msg) + gui.MessageWindow("Login OK", msg) } if (currentMessage.Type == pb.Event_FAIL) { log.Println("LOGIN FAILED") @@ -321,25 +289,6 @@ func getToken() string { func watchGUI() { count := 0 -/* - // This is how you marshal into JSON from a Protobuf - event := pb.MakeGetEvent() - if (gui.Data.Current == nil) { - log.Println("gui.Data.Current == nil") - } else { - event.Token = gui.Data.Current.Token - } - - marshaler := &jsonpb.Marshaler{} - stuff, _ := marshaler.MarshalToString(event) - log.Println(stuff) -*/ - - // also: - // var j *bytes.Buffer - // marshaler.Marshal(j, event) - // w.Write(j.Bytes()) - for { if (count > 10) { log.Println("Sleep() in watchGUI() gui.Data.State =", gui.Data.State) @@ -392,9 +341,9 @@ func watchGUI() { os.Exit(0) } if (gui.Data.State == "splash") { - for key, _ := range pbC.Accounts { - log.Println("gui.State = splash BUT THERE IS AN ACCOUNT Nick = ", pbC.Accounts[key].Nick) - log.Println("gui.State = splash BUT THERE IS AN ACCOUNT Username = ", pbC.Accounts[key].Username) + for key, _ := range config.Accounts { + log.Println("gui.State = splash BUT THERE IS AN ACCOUNT Nick = ", config.Accounts[key].Nick) + log.Println("gui.State = splash BUT THERE IS AN ACCOUNT Username = ", config.Accounts[key].Username) log.Println("SETTING gui.State = main") gui.Data.State = "main"; } diff --git a/resources/protobuf-config.json b/resources/protobuf-config.json index e7568f5..49ec4eb 100644 --- a/resources/protobuf-config.json +++ b/resources/protobuf-config.json @@ -1,5 +1,4 @@ { - "USER": "jcarr", "width": 700, "height": 500, "accounts": [ diff --git a/resources/protobuf-config2.json b/resources/protobuf-config2.json new file mode 100644 index 0000000..5688f3c --- /dev/null +++ b/resources/protobuf-config2.json @@ -0,0 +1,29 @@ +{ + "USER": "jcarr", + "width": 700, + "height": 600, + "filename": "/home/jcarr/.config/cloud-control-panel.json", + "accounts": [ + { + "nick": "jcarr", + "username": "jcarr@wit.com", + "token": "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJ4IjozLCJyIjoiIiwiY3NyZiI6InRBY1p2eXVJbk1YdWUxV0RSbDFIeDI5YSIsImV4cCI6MTU1OTI3MDQwMCwiaXNzIjoid2l0Iiwic3ViIjoiamNhcnJAd2l0LmNvbSJ9.bqXX_6yrUHQGYh3SEmW8ydSa9Xfqx-HIKutTN_GirwhC_VrVX1xJBcgYfjdKGegvwY7Td1vO3rs40Iz7ifcptrtdzJnDX62d_1JJPKBHUQUfnTLr2qoTgaljElFM0Q_e", + "hostname": "hosttest.wit.com", + "domainname": "test.wit.com" + }, + { + "nick": "jcarr2", + "username": "jcarr@wit.com", + "token": "brokenToken", + "hostname": "hosttest.wit.com", + "domainname": "test.wit.com" + }, + { + "nick": "bmath", + "username": "bmath@wit.com", + "token": "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJ4IjoyLCJyIjoiIiwiY3NyZiI6Ik9rR0JWenphV2cxQjVlN0R5YjRXSzIyWCIsImV4cCI6MTU1OTE4NTc1MiwiaXNzIjoid2l0Iiwic3ViIjoiYm1hdGhAd2l0LmNvbSJ9.vdOAXyt3VIovqEIbivgt6upqR8glZv2UdzFcyudzCmGV-msdZWi_9TZaATyQMxEaVD3K6gRunakyOWK0jw4xxeDUbQym86IKMU2UOjp0tN0z72OmH822NmQ8_AgWiKNI", + "hostname": "hosttest.wit.com", + "domainname": "test.wit.com" + } + ] +} diff --git a/resources/protobuf-small.json b/resources/protobuf-small.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/resources/protobuf-small.json @@ -0,0 +1 @@ +{} diff --git a/test2/Makefile b/test2/Makefile new file mode 100644 index 0000000..2359f6e --- /dev/null +++ b/test2/Makefile @@ -0,0 +1,3 @@ +run: + go build + ./test2 diff --git a/test2/config.go b/test2/config.go new file mode 100644 index 0000000..6718bea --- /dev/null +++ b/test2/config.go @@ -0,0 +1,72 @@ +package main + +/* + This simply parses the command line arguments using the default golang + package called 'flag'. This can be used as a simple template to parse + command line arguments in other programs. + + It puts everything in the 'config' package which I think is a good + wrapper around the 'flags' package and doesn't need a whole mess of + global variables +*/ + +import "log" +import "strings" +import "io/ioutil" + +import "github.com/golang/protobuf/jsonpb" +import pb "git.wit.com/wit/witProtobuf" + +import "github.com/davecgh/go-spew/spew" + +// will load the default config from within the go binary +func loadDefaultConfig(a string) pb.Config { + log.Println("TRY TO LOAD DEFAULT CONFIG") + log.Println("a =", a) + log.Println("NEED TO UNMARSHAL THIS HERE") + log.Println("NEED TO UNMARSHAL THIS HERE") + log.Println("NEED TO UNMARSHAL THIS HERE") + var newpb *pb.Config + // var newpb *pb.Config + sets := pb.Config{} + + b, err := ioutil.ReadFile("../resources/protobuf-config.json") + if err != nil { + log.Println("ioutil.ReadFile() ERROR =", err) + } + log.Println("ioutil.ReadFile() b =", b) + + err = jsonpb.Unmarshal(strings.NewReader(string(b)), &sets) + if err != nil { + log.Println("jsonpb.Unmarshal() ERROR =", err) + } + spew.Dump(sets) + return sets +// +// err := jsonpb.UnmarshalString(defaultConfig, newpb) + log.Println("ATTEMTED TO UNMARSHAL err =", err) + spew.Dump(newpb) + if (err == nil) { + log.Println("SETTING config to the default config", err) + // TODO: save the protobuf somewhere as the user could loose the tokens + log.Println("THIS IS PROBABLY REALLY BAD", err) + log.Println("THIS IS PROBABLY REALLY BAD", err) + log.Println("THIS IS PROBABLY REALLY BAD", err) + // config = newpb + } + return sets +} + +func unmarshalConfig(a string) *pb.Event { + var newpb *pb.Event + log.Println("ATTEMTED TO UNMARSHAL string =", a) + err := jsonpb.UnmarshalString(a, newpb) + log.Println("ATTEMTED TO UNMARSHAL err =", err) + spew.Dump(newpb) + return newpb +} + +func main() { + blah := "{}" + loadDefaultConfig(blah) +}