WIP safer logs
This commit is contained in:
parent
e03b09b68f
commit
2f246bb05c
1 changed files with 50 additions and 19 deletions
69
main.go
69
main.go
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"bufio"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
|
@ -21,11 +21,19 @@ import (
|
|||
const PARALLELIZE = 16
|
||||
const instanceNotFound = Error("instance not found")
|
||||
|
||||
var msgOut chan string
|
||||
var msgErr chan string
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
usage()
|
||||
}
|
||||
|
||||
msgOut = make(chan string, PARALLELIZE)
|
||||
msgErr = make(chan string, PARALLELIZE)
|
||||
go logger(os.Stdout, msgOut)
|
||||
go logger(os.Stderr, msgErr)
|
||||
|
||||
var err error
|
||||
switch os.Args[1] {
|
||||
case "spawn":
|
||||
|
@ -37,17 +45,23 @@ func main() {
|
|||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "cmd failed: %v\n", err)
|
||||
msgErr <- fmt.Sprintf("cmd failed: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func logger(o *os.File, c chan string) {
|
||||
for m := range c {
|
||||
fmt.Fprint(o, m)
|
||||
}
|
||||
}
|
||||
|
||||
func usage() {
|
||||
var programName = "swtool"
|
||||
if len(os.Args) > 0 {
|
||||
programName = os.Args[0]
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "Usage: %v (spawn|run|destroy)\n", programName)
|
||||
msgErr <- fmt.Sprintf("Usage: %v (spawn|run|destroy)\n", programName)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
@ -70,6 +84,7 @@ type instanceReceiver interface {
|
|||
|
||||
func passInstanceTo(r io.Reader, d instanceReceiver) error {
|
||||
com := make(chan error, PARALLELIZE)
|
||||
|
||||
count := 0
|
||||
failed := 0
|
||||
|
||||
|
@ -87,14 +102,15 @@ func passInstanceTo(r io.Reader, d instanceReceiver) error {
|
|||
go func(zone, machine, image, name string) {
|
||||
err := d.onInstance(zone, machine, image, name)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ Operation failed for %v (%v, %v, %v): %v\n", name, zone, machine, image, err)
|
||||
msgErr <- fmt.Sprintf("❌ Operation failed for %v (%v, %v, %v): %v\n", name, zone, machine, image, err)
|
||||
}
|
||||
com <- err
|
||||
}(zone, machine, image, name)
|
||||
|
||||
count += 1
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stdout, "ℹ️ Waiting for %v servers\n", count)
|
||||
msgOut <- fmt.Sprintf("ℹ️ Waiting for %v servers\n", count)
|
||||
for count > 0 {
|
||||
err := <- com
|
||||
count -= 1
|
||||
|
@ -170,7 +186,7 @@ func (sp *spawner) onInstance(zone, machine, image, name string) error {
|
|||
if err == nil {
|
||||
ip := parseIP(targetServer)
|
||||
if targetServer.State == instance.ServerStateRunning {
|
||||
fmt.Fprintf(os.Stdout, "🟣 Found %v on zone %v with ip %v\n", targetServer.Name, targetServer.Zone, ip)
|
||||
msgOut <- fmt.Sprintf("🟣 Found %v on zone %v with ip %v\n", targetServer.Name, targetServer.Zone, ip)
|
||||
return nil
|
||||
}
|
||||
} else if err == instanceNotFound {
|
||||
|
@ -207,7 +223,7 @@ func (sp *spawner) onInstance(zone, machine, image, name string) error {
|
|||
}
|
||||
|
||||
ip := parseIP(targetServer)
|
||||
fmt.Fprintf(os.Stdout, "✅ Started %v on zone %v with ip %v\n", targetServer.Name, targetServer.Zone, ip)
|
||||
msgOut <- fmt.Sprintf("✅ Started %v on zone %v with ip %v\n", targetServer.Name, targetServer.Zone, ip)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -224,7 +240,7 @@ func (dt *destroyer) onInstance(zone, machine, image, name string) error {
|
|||
|
||||
targetServer, err := dt.getInstanceByName(z, name)
|
||||
if err == instanceNotFound {
|
||||
fmt.Fprintf(os.Stdout, "🟣 %v is already destroyed\n", name)
|
||||
msgOut <- fmt.Sprintf("🟣 %v is already destroyed\n", name)
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
|
@ -248,7 +264,7 @@ func (dt *destroyer) onInstance(zone, machine, image, name string) error {
|
|||
}
|
||||
|
||||
ip := parseIP(targetServer)
|
||||
fmt.Fprintf(os.Stdout, "✅ Destroyed %v on zone %v with ip %v\n", targetServer.Name, targetServer.Zone, ip)
|
||||
msgOut <- fmt.Sprintf("✅ Destroyed %v on zone %v with ip %v\n", targetServer.Name, targetServer.Zone, ip)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -296,7 +312,7 @@ func (r *runner) connect(zone, name string) (*ssh.Client, error) {
|
|||
func (r *runner) send(sshClient *ssh.Client) error {
|
||||
// Source script
|
||||
if len(os.Args) < 3 {
|
||||
return errors.New("Missing script to run on the command line")
|
||||
return errors.New("missing script to run on the command line")
|
||||
}
|
||||
|
||||
src, err := os.Open(os.Args[2])
|
||||
|
@ -327,6 +343,16 @@ func (r *runner) send(sshClient *ssh.Client) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func readerToChan(r io.Reader, c chan string) {
|
||||
br := bufio.NewReader(r)
|
||||
for {
|
||||
s, err := br.ReadString('\n')
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
c <- s
|
||||
}
|
||||
}
|
||||
func (r *runner) exec(sshClient *ssh.Client) error {
|
||||
// Run the script
|
||||
session, err := sshClient.NewSession()
|
||||
|
@ -335,16 +361,21 @@ func (r *runner) exec(sshClient *ssh.Client) error {
|
|||
}
|
||||
defer session.Close()
|
||||
|
||||
var sshStdout, sshStderr bytes.Buffer
|
||||
session.Stdout = &sshStdout
|
||||
session.Stderr = &sshStderr
|
||||
if os.Getenv("VERBOSE") != "" {
|
||||
readErr, err := session.StderrPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readerToChan(readErr, msgErr)
|
||||
|
||||
readOut, err := session.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readerToChan(readOut, msgOut)
|
||||
}
|
||||
|
||||
err = session.Run("/tmp/nuage")
|
||||
if os.Getenv("VERBOSE") != "" {
|
||||
fmt.Fprintf(os.Stdout, "logs\n")
|
||||
io.Copy(os.Stdout, &sshStdout)
|
||||
io.Copy(os.Stderr, &sshStderr)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -369,7 +400,7 @@ func (r *runner) onInstance(zone, machine, image, name string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stdout, "✅ Successfully ran the script on %v (zone %v)\n", name, zone)
|
||||
msgOut <- fmt.Sprintf("✅ Successfully ran the script on %v (zone %v)\n", name, zone)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue