builder/openstack: simplify by passing csp instead of accessor and api

This commit is contained in:
Mark Peek 2013-08-27 22:08:18 -07:00
parent 62fbf8fef8
commit ca1388f7bc
6 changed files with 23 additions and 54 deletions

View File

@ -60,19 +60,21 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Setup the state bag and initial state for the steps
state := make(map[string]interface{})
state["config"] = b.config
state["accessor"] = auth
api := &gophercloud.ApiCriteria{ api := &gophercloud.ApiCriteria{
Name: "cloudServersOpenStack", Name: "cloudServersOpenStack",
Region: "DFW", Region: "DFW",
VersionId: "2", VersionId: "2",
UrlChoice: gophercloud.PublicURL, UrlChoice: gophercloud.PublicURL,
} }
state["api"] = api csp, err := gophercloud.ServersApi(auth, *api)
if err != nil {
return nil, err
}
// Setup the state bag and initial state for the steps
state := make(map[string]interface{})
state["config"] = b.config
state["csp"] = csp
state["hook"] = hook state["hook"] = hook
state["ui"] = ui state["ui"] = ui
@ -85,7 +87,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
SourceImage: b.config.SourceImage, SourceImage: b.config.SourceImage,
}, },
&common.StepConnectSSH{ &common.StepConnectSSH{
SSHAddress: SSHAddress(&auth, api, b.config.SSHPort), SSHAddress: SSHAddress(csp, b.config.SSHPort),
SSHConfig: SSHConfig(b.config.SSHUsername), SSHConfig: SSHConfig(b.config.SSHUsername),
SSHWaitTimeout: b.config.SSHTimeout(), SSHWaitTimeout: b.config.SSHTimeout(),
}, },

View File

@ -23,8 +23,6 @@ type StateRefreshFunc func() (result interface{}, state string, progress int, er
// StateChangeConf is the configuration struct used for `WaitForState`. // StateChangeConf is the configuration struct used for `WaitForState`.
type StateChangeConf struct { type StateChangeConf struct {
Accessor *gophercloud.Access
Api *gophercloud.ApiCriteria
Pending []string Pending []string
Refresh StateRefreshFunc Refresh StateRefreshFunc
StepState map[string]interface{} StepState map[string]interface{}
@ -33,9 +31,8 @@ type StateChangeConf struct {
// ServerStateRefreshFunc returns a StateRefreshFunc that is used to watch // ServerStateRefreshFunc returns a StateRefreshFunc that is used to watch
// an openstacn server. // an openstacn server.
func ServerStateRefreshFunc(accessor *gophercloud.Access, api *gophercloud.ApiCriteria, s *gophercloud.Server) StateRefreshFunc { func ServerStateRefreshFunc(csp gophercloud.CloudServersProvider, s *gophercloud.Server) StateRefreshFunc {
return func() (interface{}, string, int, error) { return func() (interface{}, string, int, error) {
csp, err := gophercloud.ServersApi(accessor, *api)
resp, err := csp.ServerById(s.Id) resp, err := csp.ServerById(s.Id)
if err != nil { if err != nil {
log.Printf("Error on ServerStateRefresh: %s", err) log.Printf("Error on ServerStateRefresh: %s", err)

View File

@ -11,14 +11,13 @@ import (
// SSHAddress returns a function that can be given to the SSH communicator // SSHAddress returns a function that can be given to the SSH communicator
// for determining the SSH address based on the server AccessIPv4 setting.. // for determining the SSH address based on the server AccessIPv4 setting..
func SSHAddress(accessor *gophercloud.AccessProvider, api *gophercloud.ApiCriteria, port int) func(map[string]interface{}) (string, error) { func SSHAddress(csp gophercloud.CloudServersProvider, port int) func(map[string]interface{}) (string, error) {
return func(state map[string]interface{}) (string, error) { return func(state map[string]interface{}) (string, error) {
for j := 0; j < 2; j++ { for j := 0; j < 2; j++ {
s := state["server"].(*gophercloud.Server) s := state["server"].(*gophercloud.Server)
if s.AccessIPv4 != "" { if s.AccessIPv4 != "" {
return fmt.Sprintf("%s:%d", s.AccessIPv4, port), nil return fmt.Sprintf("%s:%d", s.AccessIPv4, port), nil
} }
csp, err := gophercloud.ServersApi(*accessor, *api)
serverState, err := csp.ServerById(s.Id) serverState, err := csp.ServerById(s.Id)
if err != nil { if err != nil {

View File

@ -12,8 +12,7 @@ import (
type stepCreateImage struct{} type stepCreateImage struct{}
func (s *stepCreateImage) Run(state map[string]interface{}) multistep.StepAction { func (s *stepCreateImage) Run(state map[string]interface{}) multistep.StepAction {
accessor := state["accessor"].(*gophercloud.Access) csp := state["csp"].(gophercloud.CloudServersProvider)
api := state["api"].(*gophercloud.ApiCriteria)
config := state["config"].(config) config := state["config"].(config)
server := state["server"].(*gophercloud.Server) server := state["server"].(*gophercloud.Server)
ui := state["ui"].(packer.Ui) ui := state["ui"].(packer.Ui)
@ -23,7 +22,6 @@ func (s *stepCreateImage) Run(state map[string]interface{}) multistep.StepAction
createOpts := gophercloud.CreateImage{ createOpts := gophercloud.CreateImage{
Name: config.ImageName, Name: config.ImageName,
} }
csp, err := gophercloud.ServersApi(accessor, *api)
imageId, err := csp.CreateImage(server.Id, createOpts) imageId, err := csp.CreateImage(server.Id, createOpts)
if err != nil { if err != nil {
err := fmt.Errorf("Error creating image: %s", err) err := fmt.Errorf("Error creating image: %s", err)
@ -38,7 +36,7 @@ func (s *stepCreateImage) Run(state map[string]interface{}) multistep.StepAction
// Wait for the image to become ready // Wait for the image to become ready
ui.Say("Waiting for image to become ready...") ui.Say("Waiting for image to become ready...")
if err := WaitForImage(accessor, api, imageId); err != nil { if err := WaitForImage(csp, imageId); err != nil {
err := fmt.Errorf("Error waiting for image: %s", err) err := fmt.Errorf("Error waiting for image: %s", err)
state["error"] = err state["error"] = err
ui.Error(err.Error()) ui.Error(err.Error())
@ -53,9 +51,8 @@ func (s *stepCreateImage) Cleanup(map[string]interface{}) {
} }
// WaitForImage waits for the given Image ID to become ready. // WaitForImage waits for the given Image ID to become ready.
func WaitForImage(accessor *gophercloud.Access, api *gophercloud.ApiCriteria, imageId string) error { func WaitForImage(csp gophercloud.CloudServersProvider, imageId string) error {
for { for {
csp, err := gophercloud.ServersApi(accessor, *api)
image, err := csp.ImageById(imageId) image, err := csp.ImageById(imageId)
if err != nil { if err != nil {
return err return err

View File

@ -15,14 +15,12 @@ type StepKeyPair struct {
} }
func (s *StepKeyPair) Run(state map[string]interface{}) multistep.StepAction { func (s *StepKeyPair) Run(state map[string]interface{}) multistep.StepAction {
accessor := state["accessor"].(*gophercloud.Access) csp := state["csp"].(gophercloud.CloudServersProvider)
api := state["api"].(*gophercloud.ApiCriteria)
ui := state["ui"].(packer.Ui) ui := state["ui"].(packer.Ui)
ui.Say("Creating temporary keypair for this instance...") ui.Say("Creating temporary keypair for this instance...")
keyName := fmt.Sprintf("packer %s", hex.EncodeToString(identifier.NewUUID().Raw())) keyName := fmt.Sprintf("packer %s", hex.EncodeToString(identifier.NewUUID().Raw()))
log.Printf("temporary keypair name: %s", keyName) log.Printf("temporary keypair name: %s", keyName)
csp, err := gophercloud.ServersApi(accessor, *api)
keyResp, err := csp.CreateKeyPair(gophercloud.NewKeyPair{Name: keyName}) keyResp, err := csp.CreateKeyPair(gophercloud.NewKeyPair{Name: keyName})
if err != nil { if err != nil {
state["error"] = fmt.Errorf("Error creating temporary keypair: %s", err) state["error"] = fmt.Errorf("Error creating temporary keypair: %s", err)
@ -45,13 +43,11 @@ func (s *StepKeyPair) Cleanup(state map[string]interface{}) {
return return
} }
accessor := state["accessor"].(*gophercloud.Access) csp := state["csp"].(gophercloud.CloudServersProvider)
api := state["api"].(*gophercloud.ApiCriteria)
ui := state["ui"].(packer.Ui) ui := state["ui"].(packer.Ui)
ui.Say("Deleting temporary keypair...") ui.Say("Deleting temporary keypair...")
csp, err := gophercloud.ServersApi(accessor, *api) err := csp.DeleteKeyPair(s.keyName)
err = csp.DeleteKeyPair(s.keyName)
if err != nil { if err != nil {
ui.Error(fmt.Sprintf( ui.Error(fmt.Sprintf(
"Error cleaning up keypair. Please delete the key manually: %s", s.keyName)) "Error cleaning up keypair. Please delete the key manually: %s", s.keyName))

View File

@ -17,19 +17,10 @@ type StepRunSourceServer struct {
} }
func (s *StepRunSourceServer) Run(state map[string]interface{}) multistep.StepAction { func (s *StepRunSourceServer) Run(state map[string]interface{}) multistep.StepAction {
accessor := state["accessor"].(*gophercloud.Access) csp := state["csp"].(gophercloud.CloudServersProvider)
api := state["api"].(*gophercloud.ApiCriteria)
keyName := state["keyPair"].(string) keyName := state["keyPair"].(string)
ui := state["ui"].(packer.Ui) ui := state["ui"].(packer.Ui)
csp, err := gophercloud.ServersApi(accessor, *api)
if err != nil {
err := fmt.Errorf("Error connecting to api: %s", err)
state["error"] = err
ui.Error(err.Error())
return multistep.ActionHalt
}
// XXX - validate image and flavor is available // XXX - validate image and flavor is available
server := gophercloud.NewServer{ server := gophercloud.NewServer{
@ -52,11 +43,9 @@ func (s *StepRunSourceServer) Run(state map[string]interface{}) multistep.StepAc
ui.Say(fmt.Sprintf("Waiting for server (%s) to become ready...", s.server.Id)) ui.Say(fmt.Sprintf("Waiting for server (%s) to become ready...", s.server.Id))
stateChange := StateChangeConf{ stateChange := StateChangeConf{
Accessor: accessor,
Api: api,
Pending: []string{"BUILD"}, Pending: []string{"BUILD"},
Target: "ACTIVE", Target: "ACTIVE",
Refresh: ServerStateRefreshFunc(accessor, api, s.server), Refresh: ServerStateRefreshFunc(csp, s.server),
StepState: state, StepState: state,
} }
latestServer, err := WaitForState(&stateChange) latestServer, err := WaitForState(&stateChange)
@ -78,18 +67,9 @@ func (s *StepRunSourceServer) Cleanup(state map[string]interface{}) {
return return
} }
accessor := state["accessor"].(*gophercloud.Access) csp := state["csp"].(gophercloud.CloudServersProvider)
api := state["api"].(*gophercloud.ApiCriteria)
ui := state["ui"].(packer.Ui) ui := state["ui"].(packer.Ui)
csp, err := gophercloud.ServersApi(accessor, *api)
if err != nil {
err := fmt.Errorf("Error connecting to api: %s", err)
state["error"] = err
ui.Error(err.Error())
return
}
ui.Say("Terminating the source server...") ui.Say("Terminating the source server...")
if err := csp.DeleteServerById(s.server.Id); err != nil { if err := csp.DeleteServerById(s.server.Id); err != nil {
ui.Error(fmt.Sprintf("Error terminating server, may still be around: %s", err)) ui.Error(fmt.Sprintf("Error terminating server, may still be around: %s", err))
@ -97,11 +77,9 @@ func (s *StepRunSourceServer) Cleanup(state map[string]interface{}) {
} }
stateChange := StateChangeConf{ stateChange := StateChangeConf{
Accessor: accessor, Pending: []string{"ACTIVE", "BUILD", "REBUILD", "SUSPENDED"},
Api: api, Refresh: ServerStateRefreshFunc(csp, s.server),
Pending: []string{"ACTIVE", "BUILD", "REBUILD", "SUSPENDED"}, Target: "DELETED",
Refresh: ServerStateRefreshFunc(accessor, api, s.server),
Target: "DELETED",
} }
WaitForState(&stateChange) WaitForState(&stateChange)