Skip to content

Instantly share code, notes, and snippets.

@dstpierre
Last active June 7, 2017 12:09
Show Gist options
  • Select an option

  • Save dstpierre/467651d7218475cf6523e2d445059783 to your computer and use it in GitHub Desktop.

Select an option

Save dstpierre/467651d7218475cf6523e2d445059783 to your computer and use it in GitHub Desktop.
Spinning a new DigitalOcean droplet, running a bash file that copy a Go binary and execute this binary on the new droplet and destroy the droplet via Go code
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/digitalocean/godo"
"golang.org/x/oauth2"
)
// TokenSource passes the personal access token from DO
type TokenSource struct {
AccessToken string
}
// Token returns the DO pat token
func (t *TokenSource) Token() (*oauth2.Token, error) {
token := &oauth2.Token{
AccessToken: t.AccessToken,
}
return token, nil
}
// start starts the engagement calculation process of:
// 1. Creating a new droplet
// 2. Deploying the app to the new machine
// 3. Starts the process
// 4. Destroy the machine
func start() error {
pat := os.Getenv("DO_KEY")
tokenSource := &TokenSource{
AccessToken: pat,
}
oauthClient := oauth2.NewClient(context.Background(), tokenSource)
client := godo.NewClient(oauthClient)
dropletName := "ops1.roadmap.space"
createRequest := &godo.DropletCreateRequest{
Name: dropletName,
Region: "tor1",
Size: "16gb",
Image: godo.DropletCreateImage{
Slug: "ubuntu-16-04-x64",
},
PrivateNetworking: true,
SSHKeys: []godo.DropletCreateSSHKey{godo.DropletCreateSSHKey{Fingerprint: os.Getenv("DO_FP")}},
}
ctx := context.TODO()
// 1. Create the new droplet
log.Println("1.", "creating new droplet")
newDroplet, _, err := client.Droplets.Create(ctx, createRequest)
if err != nil {
return err
}
id := fmt.Sprintf("%d", newDroplet.ID)
log.Println(" -> creating id file", id)
err = ioutil.WriteFile(fmt.Sprintf("%s.todelete", id), []byte(id), 0666)
if err != nil {
return err
}
// let's wait for the droplet to get created
time.Sleep((1 * time.Minute) + (30 * time.Second))
log.Println(" -> getting created droplet")
ip := ""
for c := 0; c < 3; c++ {
dl, _, err := client.Droplets.Get(ctx, newDroplet.ID)
if err != nil {
return err
} else if dl == nil {
return err
}
tmp, err := dl.PrivateIPv4()
if err != nil {
return err
} else if len(tmp) != 0 {
log.Println(" -> private ip address is", tmp)
ip = tmp
break
}
time.Sleep(35 * time.Second)
}
// 2. deploy to new droplet and running the task
log.Println("2.", "deploying app")
out, err := exec.Command("/bin/bash", "./process.sh", ip).Output()
if err != nil {
return err
}
log.Println(" -> writing output of process exec")
if err := ioutil.WriteFile(fmt.Sprintf("prc-%s.log", time.Now().Format("02")), out, 0666); err != nil {
return err
}
log.Println("4.", "cleaning up")
if err := end(); err != nil {
return err
}
return nil
}
func end() error {
log.Println(" -> opening current directory")
d, err := os.Open("./")
if err != nil {
return err
}
defer d.Close()
log.Println(" -> reading files")
files, err := d.Readdir(-1)
if err != nil {
return err
}
for _, file := range files {
if file.Mode().IsRegular() {
if filepath.Ext(file.Name()) == ".todelete" {
log.Println(" -> extracting droplet id")
id, err := extractID(file.Name())
if err != nil {
return err
}
log.Println(" -> destroying id", id)
if err := destroy(id); err != nil {
return err
}
log.Println(" -> removing todelete file", file.Name())
if err := os.Remove(file.Name()); err != nil {
return err
}
}
}
}
return nil
}
func extractID(s string) (int, error) {
return strconv.Atoi(strings.Replace(s, ".todelete", "", -1))
}
func destroy(id int) error {
pat := os.Getenv("DO_KEY")
tokenSource := &TokenSource{
AccessToken: pat,
}
oauthClient := oauth2.NewClient(context.Background(), tokenSource)
client := godo.NewClient(oauthClient)
if _, err := client.Droplets.Delete(context.TODO(), id); err != nil {
return err
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment