From c4dc4c2de1a09abd4263d8f8b9e7452d66bf2c06 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sun, 28 Feb 2016 02:45:41 -0600 Subject: [PATCH] Added support for resizing Droplets after creation. --- dospin.json | 1 + droplethandler.go | 86 ++++++++++++++++++++++++++++++++++++----------- servermanager.go | 2 +- settings.go | 7 ++-- 4 files changed, 72 insertions(+), 24 deletions(-) diff --git a/dospin.json b/dospin.json index 18333d6..6ae62ea 100644 --- a/dospin.json +++ b/dospin.json @@ -3,6 +3,7 @@ "Servers": { "minecraft": { "Ports": [25565], + "InitialSize": "512mb", "Size": "4gb", "Region": "nyc3" } diff --git a/droplethandler.go b/droplethandler.go index 365c097..9a5fbca 100644 --- a/droplethandler.go +++ b/droplethandler.go @@ -57,11 +57,21 @@ func (me *DropletHandler) Spinup(name string) (string, error) { if err != nil { return "", err } + vd := me.settings.Servers[name] + + // determine droplet size + var size string + if vd.InitialSize != "" { + size = vd.InitialSize + } else { + size = vd.Size + } + createRequest := &godo.DropletCreateRequest{ Name: DROPLET_NS + name, Region: vd.Region, - Size: vd.Size, + Size: size, PrivateNetworking: true, Image: godo.DropletCreateImage{ ID: image.ID, @@ -89,6 +99,28 @@ func (me *DropletHandler) Spinup(name string) (string, error) { } log.Println("Spinup: Created " + name) + // resize if necessary + if vd.InitialSize != "" && vd.InitialSize != vd.Size { + // power off + me.poweroff(name) + + // resize + log.Println("Spinup: Resizing " + name) + action, _, err := me.client.DropletActions.Resize(droplet.ID, vd.Size, false) + if err != nil || !me.actionWait(action.ID) { + return "", err + } + log.Println("Spinup: Resized " + name) + + // power back on + log.Println("Spinup: Powering on " + name) + action, _, err = me.client.DropletActions.PowerOn(droplet.ID) + if err != nil || !me.actionWait(action.ID) { + return "", err + } + log.Println("Spinup: Powered on " + name) + } + // delete the image log.Println("Spinup: Deleting image " + name) _, err = me.client.Images.Delete(image.ID) @@ -113,23 +145,9 @@ func (me *DropletHandler) Spindown(name string) error { } // power off - if droplet.Status != "off" { - log.Println("Spindown: Powering down " + name) - // wait until machine is off - for { - droplet, err = me.getDroplet(name) - if err != nil { - log.Println(err) - } else if droplet.Status == "off" { - break - } - time.Sleep(100 * time.Millisecond) - _, _, err = me.client.DropletActions.Shutdown(droplet.ID) - if err != nil { - log.Println("Spindown: Power down of ", name, " failed: ", err) - } - } - log.Println("Spindown: Powered down " + name) + err = me.poweroff(name) + if err != nil { + return err } // snapshot existing droplet @@ -151,6 +169,35 @@ func (me *DropletHandler) Spindown(name string) error { return err } +func (me *DropletHandler) poweroff(name string) error { + droplet, err := me.getDroplet(name) + if err != nil { + return err + } + if droplet.Status != "off" { + log.Println("Powering down " + name) + // wait until machine is off + for { + droplet, err = me.getDroplet(name) + if err != nil { + log.Println("Power down of", name, "failed:", err) + if droplet.ID < 1 { + return err + } + } else if droplet.Status == "off" { + break + } + time.Sleep(100 * time.Millisecond) + _, _, err = me.client.DropletActions.Shutdown(droplet.ID) + if err != nil { + log.Println("Power down of", name, "failed:", err) + } + } + log.Println("Powered down", name) + } + return err +} + func (me *DropletHandler) getDroplet(name string) (godo.Droplet, error) { name = DROPLET_NS + name page := 0 @@ -220,8 +267,7 @@ func (me *DropletHandler) actionWait(actionId int) bool { for { a, _, err := me.client.Actions.Get(actionId) if err != nil { - log.Println("Action failed: ", err) - return false + log.Println("Action retrieval failed: ", err) } else if a.Status == "completed" { return true } else if a.Status == "errored" { diff --git a/servermanager.go b/servermanager.go index 432e745..9fbfe2b 100644 --- a/servermanager.go +++ b/servermanager.go @@ -92,7 +92,7 @@ func (me *ServerManager) serveAction(action int) bool { case SERVERMANAGER_SPINUP: ip, err := me.server.Spinup(me.name) if err == nil { - log.Println("ServerManager: Got IP for", me.name, ":", ip) + log.Println("ServerManager: Got IP for", me.name+":", ip) me.addPortForwards(ip) } else { log.Println("ServerManager: Could not spin up "+me.name+":", err) diff --git a/settings.go b/settings.go index d61d6b1..0bad8be 100644 --- a/settings.go +++ b/settings.go @@ -18,9 +18,10 @@ type Settings struct { } type Server struct { - Ports []int - Size string - Region string + Ports []int + InitialSize string + Size string + Region string } func loadSettings(path string) (Settings, error) {