Skip to content

Instantly share code, notes, and snippets.

@bradfitz
Created July 25, 2017 06:47
Show Gist options
  • Save bradfitz/4e32229f4d55f983be38177da7aa9755 to your computer and use it in GitHub Desktop.
Save bradfitz/4e32229f4d55f983be38177da7aa9755 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"flag"
"fmt"
"log"
"strings"
"time"
"golang.org/x/build/buildlet"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
compute "google.golang.org/api/compute/v1"
)
var (
serial = flag.Bool("serial", false, "watch serial")
pauseAfterUp = flag.Bool("pause-after-up", false, "pause for a few seconds (enough to SIGSTOP) after WorkDir returns")
)
func main() {
flag.Parse()
ts, err := google.DefaultTokenSource(context.Background())
if err != nil {
log.Fatal(err)
}
computeSvc, _ := compute.New(oauth2.NewClient(context.TODO(), ts))
name := fmt.Sprintf("debug-brad-windows-%d", time.Now().Unix())
log.Printf("Creating %s", name)
c, err := buildlet.StartNewVM(ts, name, "host-windows-amd64-2012", buildlet.VMOpts{
Zone: "us-central1-f",
ProjectID: "symbolic-datum-552",
DeleteIn: 30 * time.Minute,
OnInstanceRequested: func() { log.Printf("instance requested") },
OnInstanceCreated: func() {
log.Printf("instance created")
if *serial {
// This is roughly "gcloud compute
// connect-to-serial-port --zone=us-central1-f
// $NAME", but in Go and works. For some reason,
// gcloud doesn't work as a child process and
// has weird errors.
go watchSerial(name)
return
}
},
OnGotInstanceInfo: func() { log.Printf("got instance info") },
})
if err != nil {
log.Fatalf("StartNewVM: %v", err)
}
dir, err := c.WorkDir()
log.Printf("WorkDir: %v, %v", dir, err)
if *pauseAfterUp {
log.Printf("Shutting down in 5 seconds...")
time.Sleep(5 * time.Second)
}
if err := c.Close(); err != nil {
log.Fatalf("Close: %v", err)
}
log.Printf("done.")
}
func watchSerial(name string) {
start := int64(0)
for {
sout, err := computeSvc.Instances.GetSerialPortOutput("symbolic-datum-552", "us-central1-f", name).Start(start).Do()
if err != nil {
log.Printf("serial output error: %v", err)
return
}
moved := sout.Next != start
start = sout.Next
contents := strings.TrimSpace(sout.Contents)
if contents != "" {
log.Printf("SERIAL: %s", strings.TrimSpace(sout.Contents))
}
if !moved {
time.Sleep(1 * time.Second)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment