avoided some weird scary jsonpb bug with this exact syntax

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2019-05-24 23:53:52 -07:00
parent df91e3b191
commit 817b424eee
7 changed files with 292 additions and 133 deletions

224
config.go
View File

@ -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
}
*/

95
main.go
View File

@ -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";
}

View File

@ -1,5 +1,4 @@
{
"USER": "jcarr",
"width": 700,
"height": 500,
"accounts": [

View File

@ -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"
}
]
}

View File

@ -0,0 +1 @@
{}

3
test2/Makefile Normal file
View File

@ -0,0 +1,3 @@
run:
go build
./test2

72
test2/config.go Normal file
View File

@ -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)
}