cloud-control-panel/main.go

304 lines
8.6 KiB
Go
Raw Normal View History

package main
import "log"
import "os"
import "time"
import "os/user"
import "runtime"
import "runtime/debug"
import "github.com/gookit/config"
import "github.com/gobuffalo/packr"
// import "github.com/golang/protobuf/proto"
import pb "git.wit.com/wit/witProtobuf"
import "git.wit.com/wit/gui"
var GITCOMMIT string // this is passed in as an ldflag
var GOVERSION string // this is passed in as an ldflag
// import "github.com/davecgh/go-spew/spew"
// reminder to use this for JSON
// https://github.com/tidwall/gjson
// value := gjson.Get(json, "name.last")
// println(value.String())
// value := gjson.Get(json, friends.#[last=="Murphy"].first)
// use mergo to merge structs
// import "github.com/imdario/mergo"
// mergo.Merge(&dest, src)
// always sorted slice (new project)
// https://github.com/yaa110/sslice
// several smart slice functions (new project. April 2019)
// https://github.com/elliotchance/pie
// Exit and write out the config
// (in yaml and json I guess.)
// switch to json once it can be made human readable
func onExit(err error) {
log.Println("Sleep for 1 second")
time.Sleep(1 * 1000 * 1000 * 1000)
filename := config.String("configfile")
if (filename == "") {
log.Println("NOT SAVING CONFIG FILE")
} else {
log.Println("SAVING CONFIG FILE AS:", filename)
f, err := os.Create(filename + ".yaml")
if err == nil {
config.DumpTo(f, "yaml")
}
f, err = os.Create(filename)
if err == nil {
config.DumpTo(f, "json")
}
}
if (err != nil) {
panic(err)
}
os.Exit(0)
}
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
box := packr.NewBox("./resources")
defaultConfig, _ := box.FindString("cloud.json")
// This will parse the command line and config file
parseConfig(defaultConfig)
// only test the socket code if no GUI
if (config.String("nogui") == "true") {
log.Println("Need to re-implement this")
onExit(nil)
}
initChannel()
go processEvents()
go gorillaDial("v000185.testing.com.customers.wprod.wit.com:9000")
go watchGUI()
user, err := user.Current()
if err != nil {
onExit(err)
}
gui.Data.Width = config.Int("width")
gui.Data.Height = config.Int("height")
// TODO: figure out the hostname the right way
gui.Data.Hostname = "librem15.lab.wit.com"
gui.Data.IPv6 = "2604:bbc0:3:3:0:10:0:1004"
gui.Data.Version = "v0.5"
gui.Data.GitCommit = GITCOMMIT
gui.Data.GoVersion = GOVERSION
gui.Data.ButtonClick = buttonClick
gui.Data.HomeDir = user.HomeDir
gui.Data.Debug = config.Bool("debugging")
log.Println("config Bool debugging = ", config.Bool("debugging"))
log.Println("gui.Data.Debug = ", gui.Data.Debug)
// Current User
log.Println("Hi " + user.Name + " (id: " + user.Uid + ")")
log.Println("Username: " + user.Username)
log.Println("Home Dir: " + user.HomeDir)
// Get "Real" User under sudo.
// More Info: https://stackoverflow.com/q/29733575/402585
log.Println("Real User: " + os.Getenv("SUDO_USER"))
// make this the main loop in an attempt to figure out the crashes
// do not change this until the GUI is stable
gui.GoMainWindow()
}
func buttonClick(b *gui.ButtonMap) {
log.Println("buttonClick() b =", b)
if (b == nil) {
log.Println("THIS MOUSE EVENT WAS NOT FROM A BUTTON")
} else {
log.Println("\tb.Name", b.Name)
log.Println("\tb.Note", b.Note)
log.Println("\tb.AccNick", b.AccNick)
if (b.Note == "BACK") {
gui.Data.State = "splash"
}
if (b.Note == "QUIT") {
onExit(nil)
}
if (b.Note == "DEBUG") {
log.Println("debug.PrintStack() (SHOULD BE JUST THIS goroutine)")
debug.PrintStack()
log.Println("ATTEMPT FULL STACK DUMP")
buf := make([]byte, 1<<16)
runtime.Stack(buf, true)
log.Printf("%s", buf)
log.Println("FINISHED FULL STACK DUMP")
}
if (b.Note == "ADD") {
log.Println("\tSHOULD ADD ACCOUNT HERE")
if (gui.Data.AccNick != "") {
log.Println("\tADDING ACCOUNT HERE")
log.Println("\tADDING ACCOUNT HERE")
log.Println("\tADDING ACCOUNT HERE")
log.Println("\tData.AccNick = ", gui.Data.AccNick)
log.Println("\tData.AccUser = ", gui.Data.AccUser)
log.Println("\tData.AccPass = ", gui.Data.AccPass)
config.Set("accounts." + gui.Data.AccNick + ".username", gui.Data.AccUser)
config.Set("accounts." + gui.Data.AccNick + ".password", gui.Data.AccPass)
config.Set("accounts." + gui.Data.AccNick + ".hostname", "v000185.testing.com.customers.wprod.wit.com")
}
}
if (b.Note == "LOGIN") {
log.Println("\tTRIGGER LOGIN ACCOUNT")
gui.Data.State = "SEND LOGIN"
gui.Data.AccNick = b.AccNick
count := 0
for {
log.Println("Sleep() in buttonClick() gui.Data.State =", gui.Data.State)
time.Sleep(200 * time.Millisecond)
if (gui.Data.State == "NEW PROTOBUF") {
if (currentMessage == nil) {
gui.SocketError()
gui.Data.State = "done"
} else {
count := countVMS(currentMessage)
log.Println("LOGIN VMS currentMessage =", currentMessage)
log.Println("LOGIN VMS count =", count)
if (count != 0) {
name := "Virtual Machines (" + b.AccNick + ")"
mh := gui.AddVmsTab(name, count)
ReadReceivedData(currentMessage, mh)
}
currentMessage = nil
gui.Data.State = "done"
}
return
}
count += 1
if (count > 10) {
log.Println("ERROR: waited too long for a resposne")
currentMessage = nil
gui.Data.State = "done"
return
}
}
}
if (b.Note == "SHOW") {
log.Println("\tTRIGGER DISPLAY ACCOUNT")
gui.Data.State = "SEND WEBSOCKET"
gui.Data.AccNick = b.AccNick
count := 0
for {
log.Println("Sleep() in buttonClick() gui.Data.State =", gui.Data.State)
time.Sleep(200 * time.Millisecond)
if (gui.Data.State == "NEW PROTOBUF") {
if (currentMessage == nil) {
gui.SocketError()
gui.Data.State = "done"
} else {
count := countVMS(currentMessage)
log.Println("SHOW VMS currentMessage =", currentMessage)
log.Println("SHOW VMS count =", count)
if (count != 0) {
name := "Virtual Machines (" + b.AccNick + ")"
mh := gui.AddVmsTab(name, count)
ReadReceivedData(currentMessage, mh)
}
currentMessage = nil
gui.Data.State = "done"
}
return
}
count += 1
if (count > 10) {
log.Println("ERROR: waited too long for a resposne")
currentMessage = nil
gui.Data.State = "done"
return
}
}
}
}
if (gui.Data.State == "splash") {
gui.ShowAccountQuestionTab()
gui.Data.State = "account1"
return
} else if (gui.Data.State == "account1") {
gui.ShowAccountTab()
gui.Data.State = "main"
} else if (gui.Data.State == "main") {
gui.ShowMainTab()
gui.Data.State = "done"
} else if (gui.Data.State == "QUIT") {
onExit(nil)
}
}
// this watches the GUI primarily to process protobuf's
func watchGUI() {
count := 0
for {
if (count > 10) {
log.Println("Sleep() in watchGUI() gui.Data.State =", gui.Data.State)
count = 0
}
count += 1
time.Sleep(200 * time.Millisecond)
if (gui.Data.State == "SEND WEBSOCKET") {
log.Println("\tTRIGGERING WEBSOCKET HERE on AccNick =", gui.Data.AccNick)
log.Println("\tTRIGGERING WEBSOCKET HERE on AccNick =", gui.Data.AccNick)
log.Println("\tTRIGGERING WEBSOCKET HERE on AccNick =", gui.Data.AccNick)
event := pb.MakeGetEvent()
event.Token = config.String("accounts." + gui.Data.AccNick + ".token")
log.Println("\tTRIGGERING WEBSOCKET HERE with event.Token =", event.Token)
gorillaSendProtobuf(event)
gui.Data.State = "READ PROTOBUF"
}
if (gui.Data.State == "SEND LOGIN") {
log.Println("\tTRIGGERING LOGIN HERE on AccNick =", gui.Data.AccNick)
log.Println("\tTRIGGERING LOGIN HERE on AccNick =", gui.Data.AccNick)
log.Println("\tTRIGGERING LOGIN HERE on AccNick =", gui.Data.AccNick)
event := pb.MakeLoginEvent()
event.Username = config.String("accounts." + gui.Data.AccNick + ".username")
event.Password = config.String("accounts." + gui.Data.AccNick + ".password")
event.Token = config.String("accounts." + gui.Data.AccNick + ".token")
log.Println("\tTRIGGERING LOGIN HERE with event.Token =", event.Token)
gorillaSendProtobuf(event)
gui.Data.State = "READ PROTOBUF"
}
if (gui.Data.State == "kill") {
log.Println("gui.State = kill")
log.Println("gui.State = kill")
log.Println("gui.State = kill")
os.Exit(0)
}
if (gui.Data.State == "splash") {
for account, _ := range config.StringMap("accounts") {
log.Println("gui.State = splash BUT THERE IS AN ACCOUNT = ", account)
log.Println("gui.State = splash BUT THERE IS AN ACCOUNT = ", account)
log.Println("SETTING gui.State = main")
gui.Data.State = "main";
}
}
}
}