Compare commits
1 commit
main
...
feature/sa
Author | SHA1 | Date | |
---|---|---|---|
2f246bb05c |
1 changed files with 50 additions and 19 deletions
69
main.go
69
main.go
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
@ -21,11 +21,19 @@ import (
|
||||||
const PARALLELIZE = 16
|
const PARALLELIZE = 16
|
||||||
const instanceNotFound = Error("instance not found")
|
const instanceNotFound = Error("instance not found")
|
||||||
|
|
||||||
|
var msgOut chan string
|
||||||
|
var msgErr chan string
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if len(os.Args) < 2 {
|
if len(os.Args) < 2 {
|
||||||
usage()
|
usage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msgOut = make(chan string, PARALLELIZE)
|
||||||
|
msgErr = make(chan string, PARALLELIZE)
|
||||||
|
go logger(os.Stdout, msgOut)
|
||||||
|
go logger(os.Stderr, msgErr)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
switch os.Args[1] {
|
switch os.Args[1] {
|
||||||
case "spawn":
|
case "spawn":
|
||||||
|
@ -37,17 +45,23 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "cmd failed: %v\n", err)
|
msgErr <- fmt.Sprintf("cmd failed: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func logger(o *os.File, c chan string) {
|
||||||
|
for m := range c {
|
||||||
|
fmt.Fprint(o, m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func usage() {
|
func usage() {
|
||||||
var programName = "swtool"
|
var programName = "swtool"
|
||||||
if len(os.Args) > 0 {
|
if len(os.Args) > 0 {
|
||||||
programName = 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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +84,7 @@ type instanceReceiver interface {
|
||||||
|
|
||||||
func passInstanceTo(r io.Reader, d instanceReceiver) error {
|
func passInstanceTo(r io.Reader, d instanceReceiver) error {
|
||||||
com := make(chan error, PARALLELIZE)
|
com := make(chan error, PARALLELIZE)
|
||||||
|
|
||||||
count := 0
|
count := 0
|
||||||
failed := 0
|
failed := 0
|
||||||
|
|
||||||
|
@ -87,14 +102,15 @@ func passInstanceTo(r io.Reader, d instanceReceiver) error {
|
||||||
go func(zone, machine, image, name string) {
|
go func(zone, machine, image, name string) {
|
||||||
err := d.onInstance(zone, machine, image, name)
|
err := d.onInstance(zone, machine, image, name)
|
||||||
if err != nil {
|
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
|
com <- err
|
||||||
}(zone, machine, image, name)
|
}(zone, machine, image, name)
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(os.Stdout, "ℹ️ Waiting for %v servers\n", count)
|
msgOut <- fmt.Sprintf("ℹ️ Waiting for %v servers\n", count)
|
||||||
for count > 0 {
|
for count > 0 {
|
||||||
err := <- com
|
err := <- com
|
||||||
count -= 1
|
count -= 1
|
||||||
|
@ -170,7 +186,7 @@ func (sp *spawner) onInstance(zone, machine, image, name string) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ip := parseIP(targetServer)
|
ip := parseIP(targetServer)
|
||||||
if targetServer.State == instance.ServerStateRunning {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
} else if err == instanceNotFound {
|
} else if err == instanceNotFound {
|
||||||
|
@ -207,7 +223,7 @@ func (sp *spawner) onInstance(zone, machine, image, name string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
ip := parseIP(targetServer)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +240,7 @@ func (dt *destroyer) onInstance(zone, machine, image, name string) error {
|
||||||
|
|
||||||
targetServer, err := dt.getInstanceByName(z, name)
|
targetServer, err := dt.getInstanceByName(z, name)
|
||||||
if err == instanceNotFound {
|
if err == instanceNotFound {
|
||||||
fmt.Fprintf(os.Stdout, "🟣 %v is already destroyed\n", name)
|
msgOut <- fmt.Sprintf("🟣 %v is already destroyed\n", name)
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -248,7 +264,7 @@ func (dt *destroyer) onInstance(zone, machine, image, name string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
ip := parseIP(targetServer)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +312,7 @@ func (r *runner) connect(zone, name string) (*ssh.Client, error) {
|
||||||
func (r *runner) send(sshClient *ssh.Client) error {
|
func (r *runner) send(sshClient *ssh.Client) error {
|
||||||
// Source script
|
// Source script
|
||||||
if len(os.Args) < 3 {
|
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])
|
src, err := os.Open(os.Args[2])
|
||||||
|
@ -327,6 +343,16 @@ func (r *runner) send(sshClient *ssh.Client) error {
|
||||||
return err
|
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 {
|
func (r *runner) exec(sshClient *ssh.Client) error {
|
||||||
// Run the script
|
// Run the script
|
||||||
session, err := sshClient.NewSession()
|
session, err := sshClient.NewSession()
|
||||||
|
@ -335,16 +361,21 @@ func (r *runner) exec(sshClient *ssh.Client) error {
|
||||||
}
|
}
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
var sshStdout, sshStderr bytes.Buffer
|
if os.Getenv("VERBOSE") != "" {
|
||||||
session.Stdout = &sshStdout
|
readErr, err := session.StderrPipe()
|
||||||
session.Stderr = &sshStderr
|
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")
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -369,7 +400,7 @@ func (r *runner) onInstance(zone, machine, image, name string) error {
|
||||||
return err
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue