Skip to content

Instantly share code, notes, and snippets.

@iandelahorne
Created June 28, 2014 01:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iandelahorne/f8b13e486786fee6fa44 to your computer and use it in GitHub Desktop.
Save iandelahorne/f8b13e486786fee6fa44 to your computer and use it in GitHub Desktop.
gophercloud create and delete
package main
import (
"errors"
"fmt"
"github.com/rackspace/gophercloud"
"github.com/mitchellh/multistep"
"log"
"time"
)
func main() {
authoptions := gophercloud.AuthOptions{
AllowReauth: true,
ApiKey: "APIKEY",
Username: "USERNAME",
Password: "APIKEY",
}
auth, err := gophercloud.Authenticate("rackspace-us", authoptions)
if err != nil {
log.Printf("Authenticate err %+v", err)
return
}
api, err := gophercloud.PopulateApi("rackspace")
if err != nil {
log.Printf("PopulateApi err %+v", err)
return
}
api.Region = "DFW"
csp, err := gophercloud.ServersApi(auth, api)
if err != nil {
log.Printf("ServersApi err %+v\n", err)
return
}
networks := make([]gophercloud.NetworkConfig, 0)
serverConf := gophercloud.NewServer{
Name: "test-foo3",
ImageRef: "23b564c9-c3e6-49f9-bc68-86c7a9ab5018",
FlavorRef: "2",
KeyPairName: "laptop",
Networks: networks,
}
serverResp, err := csp.CreateServer(serverConf)
if err != nil {
log.Printf("CreateServer err %+v", err)
return
}
server, err := csp.ServerById(serverResp.Id)
log.Printf("server id: %s", server.Id)
state := new(multistep.BasicStateBag)
stateChange := StateChangeConf{
Pending: []string{"BUILD"},
Target: "ACTIVE",
Refresh: ServerStateRefreshFunc(csp, server),
StepState: state,
}
latestServer, err := WaitForState(&stateChange)
if err != nil {
log.Printf("Error waiting for server (%s) to become ready: %s", server.Id, err)
return
}
server = latestServer.(*gophercloud.Server)
log.Printf("Server %s built", server.Id)
log.Printf("Terminating server %s", server.Id)
if err := csp.DeleteServerById(server.Id); err != nil {
log.Printf("Error terminating server, may still be around: %s", err)
return
}
for {
resp, err := csp.ServerById(server.Id)
if err != nil {
log.Printf("ServerById error: %s", err)
return
}
if resp.Status == "DELETED" {
log.Printf("Sever %s deleted", server.Id)
return
}
log.Printf("Waiting for server %s to shut down, current is %s",
server.Id, resp.Status)
time.Sleep(1 * time.Second)
}
}
type StateRefreshFunc func() (result interface{}, state string, progress int, err error)
type StateChangeConf struct {
Pending []string
Refresh StateRefreshFunc
StepState multistep.StateBag
Target string
}
func ServerStateRefreshFunc(csp gophercloud.CloudServersProvider, s *gophercloud.Server) StateRefreshFunc {
return func() (interface{}, string, int, error) {
resp, err := csp.ServerById(s.Id)
if err != nil {
log.Printf("Error on ServerStateRefresh: %s", err)
return nil, "", 0, err
}
return resp, resp.Status, resp.Progress, nil
}
}
func WaitForState(conf *StateChangeConf) (i interface{}, err error) {
log.Printf("Waiting for state to become: %s", conf.Target)
for {
var currentProgress int
var currentState string
i, currentState, currentProgress, err = conf.Refresh()
if err != nil {
return
}
if currentState == conf.Target {
return
}
if conf.StepState != nil {
if _, ok := conf.StepState.GetOk(multistep.StateCancelled); ok {
return nil, errors.New("interrupted")
}
}
found := false
for _, allowed := range conf.Pending {
if currentState == allowed {
found = true
break
}
}
if !found {
return nil, fmt.Errorf("unexpected state '%s', wanted target '%s'", currentState, conf.Target)
}
log.Printf("Waiting for state to become: %s currently %s (%d%%)", conf.Target, currentState, currentProgress)
time.Sleep(2 * time.Second)
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment