Commit 92b6b5c3 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

builder/openstack: can ref flavor by name

parent ad374e82
...@@ -67,13 +67,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -67,13 +67,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
// Build the steps // Build the steps
steps := []multistep.Step{ steps := []multistep.Step{
&StepLoadFlavor{
Flavor: b.config.Flavor,
},
&StepKeyPair{ &StepKeyPair{
Debug: b.config.PackerDebug, Debug: b.config.PackerDebug,
DebugKeyPath: fmt.Sprintf("os_%s.pem", b.config.PackerBuildName), DebugKeyPath: fmt.Sprintf("os_%s.pem", b.config.PackerBuildName),
}, },
&StepRunSourceServer{ &StepRunSourceServer{
Name: b.config.ImageName, Name: b.config.ImageName,
Flavor: b.config.Flavor,
SourceImage: b.config.SourceImage, SourceImage: b.config.SourceImage,
SecurityGroups: b.config.SecurityGroups, SecurityGroups: b.config.SecurityGroups,
Networks: b.config.Networks, Networks: b.config.Networks,
......
package openstack
import (
"fmt"
"log"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/rackspace/gophercloud/openstack/compute/v2/flavors"
)
// StepLoadFlavor gets the FlavorRef from a Flavor. It first assumes
// that the Flavor is a ref and verifies it. Otherwise, it tries to find
// the flavor by name.
type StepLoadFlavor struct {
Flavor string
}
func (s *StepLoadFlavor) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(Config)
ui := state.Get("ui").(packer.Ui)
// We need the v2 compute client
client, err := config.computeV2Client()
if err != nil {
err = fmt.Errorf("Error initializing compute client: %s", err)
state.Put("error", err)
return multistep.ActionHalt
}
ui.Say(fmt.Sprintf("Loading flavor: %s", s.Flavor))
log.Printf("[INFO] Loading flavor by ID: %s", s.Flavor)
flavor, err := flavors.Get(client, s.Flavor).Extract()
if err != nil {
log.Printf("[ERROR] Failed to find flavor by ID: %s", err)
geterr := err
log.Printf("[INFO] Loading flavor by name: %s", s.Flavor)
id, err := flavors.IDFromName(client, s.Flavor)
if err != nil {
log.Printf("[ERROR] Failed to find flavor by name: %s", err)
err = fmt.Errorf(
"Unable to find specified flavor by ID or name!\n\n"+
"Error from ID lookup: %s\n\n"+
"Error from name lookup: %s",
geterr,
err)
state.Put("error", err)
return multistep.ActionHalt
}
flavor = &flavors.Flavor{ID: id}
}
ui.Message(fmt.Sprintf("Verified flavor. ID: %s", flavor.ID))
state.Put("flavor_id", flavor.ID)
return multistep.ActionContinue
}
func (s *StepLoadFlavor) Cleanup(state multistep.StateBag) {
}
...@@ -11,7 +11,6 @@ import ( ...@@ -11,7 +11,6 @@ import (
) )
type StepRunSourceServer struct { type StepRunSourceServer struct {
Flavor string
Name string Name string
SourceImage string SourceImage string
SecurityGroups []string SecurityGroups []string
...@@ -22,6 +21,7 @@ type StepRunSourceServer struct { ...@@ -22,6 +21,7 @@ type StepRunSourceServer struct {
func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction { func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(Config) config := state.Get("config").(Config)
flavor := state.Get("flavor_id").(string)
keyName := state.Get("keyPair").(string) keyName := state.Get("keyPair").(string)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
...@@ -38,11 +38,12 @@ func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction ...@@ -38,11 +38,12 @@ func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction
networks[i].UUID = networkUuid networks[i].UUID = networkUuid
} }
ui.Say("Launching server...")
s.server, err = servers.Create(computeClient, keypairs.CreateOptsExt{ s.server, err = servers.Create(computeClient, keypairs.CreateOptsExt{
CreateOptsBuilder: servers.CreateOpts{ CreateOptsBuilder: servers.CreateOpts{
Name: s.Name, Name: s.Name,
ImageRef: s.SourceImage, ImageRef: s.SourceImage,
FlavorName: s.Flavor, FlavorRef: flavor,
SecurityGroups: s.SecurityGroups, SecurityGroups: s.SecurityGroups,
Networks: networks, Networks: networks,
}, },
...@@ -56,9 +57,10 @@ func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction ...@@ -56,9 +57,10 @@ func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction
return multistep.ActionHalt return multistep.ActionHalt
} }
ui.Message(fmt.Sprintf("Server ID: %s", s.server.ID))
log.Printf("server id: %s", s.server.ID) log.Printf("server id: %s", s.server.ID)
ui.Say(fmt.Sprintf("Waiting for server (%s) to become ready...", s.server.ID)) ui.Say("Waiting for server to become ready...")
stateChange := StateChangeConf{ stateChange := StateChangeConf{
Pending: []string{"BUILD"}, Pending: []string{"BUILD"},
Target: "ACTIVE", Target: "ACTIVE",
......
...@@ -29,7 +29,7 @@ each category, the available configuration keys are alphabetized. ...@@ -29,7 +29,7 @@ each category, the available configuration keys are alphabetized.
### Required: ### Required:
* `flavor` (string) - The ID or full URL for the desired flavor for the * `flavor` (string) - The ID, name, or full URL for the desired flavor for the
server to be created. server to be created.
* `image_name` (string) - The name of the resulting image. * `image_name` (string) - The name of the resulting image.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment