Merge pull request #5173 from rickard-von-essen/cloudstack-fixes

cloudstack: Move ipaddress, host port, and source to statebag
This commit is contained in:
Rickard von Essen 2017-09-05 06:29:22 +02:00 committed by GitHub
commit 516bf52115
6 changed files with 54 additions and 49 deletions

View File

@ -80,10 +80,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&communicator.StepConnect{ &communicator.StepConnect{
Config: &b.config.Comm, Config: &b.config.Comm,
Host: commHost, Host: commHost,
SSHConfig: SSHConfig( SSHConfig: sshConfig(
b.config.Comm.SSHAgentAuth, b.config.Comm.SSHAgentAuth,
b.config.Comm.SSHUsername, b.config.Comm.SSHUsername,
b.config.Comm.SSHPassword), b.config.Comm.SSHPassword),
SSHPort: commPort,
WinRMPort: commPort,
}, },
&common.StepProvision{}, &common.StepProvision{},
&stepShutdownInstance{}, &stepShutdownInstance{},

View File

@ -59,8 +59,6 @@ type Config struct {
TemplateTag string `mapstructure:"template_tag"` TemplateTag string `mapstructure:"template_tag"`
ctx interpolate.Context ctx interpolate.Context
hostAddress string // The host address used by the communicators.
instanceSource string // This can be either a template ID or an ISO ID.
} }
// NewConfig parses and validates the given config. // NewConfig parses and validates the given config.

View File

@ -7,28 +7,29 @@ import (
packerssh "github.com/hashicorp/packer/communicator/ssh" packerssh "github.com/hashicorp/packer/communicator/ssh"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/xanzy/go-cloudstack/cloudstack"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent" "golang.org/x/crypto/ssh/agent"
) )
func commHost(state multistep.StateBag) (string, error) { func commHost(state multistep.StateBag) (string, error) {
client := state.Get("client").(*cloudstack.CloudStackClient) ip, hasIP := state.Get("ipaddress").(string)
config := state.Get("config").(*Config) if !hasIP {
return "", fmt.Errorf("Failed to retrieve IP address")
if config.hostAddress == "" {
ipAddr, _, err := client.Address.GetPublicIpAddressByID(config.PublicIPAddress)
if err != nil {
return "", fmt.Errorf("Failed to retrieve IP address: %s", err)
} }
config.hostAddress = ipAddr.Ipaddress return ip, nil
} }
return config.hostAddress, nil func commPort(state multistep.StateBag) (int, error) {
commPort, hasPort := state.Get("commPort").(int)
if !hasPort {
return 0, fmt.Errorf("Failed to retrieve communication port")
} }
func SSHConfig(useAgent bool, username, password string) func(state multistep.StateBag) (*ssh.ClientConfig, error) { return commPort, nil
}
func sshConfig(useAgent bool, username, password string) func(state multistep.StateBag) (*ssh.ClientConfig, error) {
return func(state multistep.StateBag) (*ssh.ClientConfig, error) { return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
if useAgent { if useAgent {
authSock := os.Getenv("SSH_AUTH_SOCK") authSock := os.Getenv("SSH_AUTH_SOCK")

View File

@ -25,6 +25,7 @@ func (s *stepSetupNetworking) Run(state multistep.StateBag) multistep.StepAction
if config.UseLocalIPAddress { if config.UseLocalIPAddress {
ui.Message("Using the local IP address...") ui.Message("Using the local IP address...")
state.Put("commPort", config.Comm.Port())
ui.Message("Networking has been setup!") ui.Message("Networking has been setup!")
return multistep.ActionContinue return multistep.ActionContinue
} }
@ -32,18 +33,11 @@ func (s *stepSetupNetworking) Run(state multistep.StateBag) multistep.StepAction
// Generate a random public port used to configure our port forward. // Generate a random public port used to configure our port forward.
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
s.publicPort = 50000 + rand.Intn(10000) s.publicPort = 50000 + rand.Intn(10000)
state.Put("commPort", s.publicPort)
// Set the currently configured port to be the private port. // Set the currently configured port to be the private port.
s.privatePort = config.Comm.Port() s.privatePort = config.Comm.Port()
// Set the SSH or WinRM port to be the randomly generated public port.
switch config.Comm.Type {
case "ssh":
config.Comm.SSHPort = s.publicPort
case "winrm":
config.Comm.WinRMPort = s.publicPort
}
// Retrieve the instance ID from the previously saved state. // Retrieve the instance ID from the previously saved state.
instanceID, ok := state.Get("instance_id").(string) instanceID, ok := state.Get("instance_id").(string)
if !ok || instanceID == "" { if !ok || instanceID == "" {
@ -91,7 +85,7 @@ func (s *stepSetupNetworking) Run(state multistep.StateBag) multistep.StepAction
// Set the IP address and it's ID. // Set the IP address and it's ID.
config.PublicIPAddress = ipAddr.Id config.PublicIPAddress = ipAddr.Id
config.hostAddress = ipAddr.Ipaddress state.Put("ipaddress", ipAddr.Ipaddress)
// Store the IP address ID. // Store the IP address ID.
state.Put("ip_address_id", ipAddr.Id) state.Put("ip_address_id", ipAddr.Id)

View File

@ -37,7 +37,7 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction
// Create a new parameter struct. // Create a new parameter struct.
p := client.VirtualMachine.NewDeployVirtualMachineParams( p := client.VirtualMachine.NewDeployVirtualMachineParams(
config.ServiceOffering, config.ServiceOffering,
config.instanceSource, state.Get("source").(string),
config.Zone, config.Zone,
) )
@ -140,7 +140,7 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction
// Set the host address when using the local IP address to connect. // Set the host address when using the local IP address to connect.
if config.UseLocalIPAddress { if config.UseLocalIPAddress {
config.hostAddress = instance.Nic[0].Ipaddress state.Put("ipaddress", instance.Nic[0].Ipaddress)
} }
// Store the instance ID so we can remove it later. // Store the instance ID so we can remove it later.

View File

@ -53,9 +53,16 @@ func (s *stepPrepareConfig) Run(state multistep.StateBag) multistep.StepAction {
} }
} }
if config.PublicIPAddress != "" && !isUUID(config.PublicIPAddress) { if config.PublicIPAddress != "" {
if isUUID(config.PublicIPAddress) {
ip, _, err := client.Address.GetPublicIpAddressByID(config.PublicIPAddress)
if err != nil {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed to retrieve IP address: %s", err))
}
state.Put("ipaddress", ip.Ipaddress)
} else {
// Save the public IP address before replacing it with it's UUID. // Save the public IP address before replacing it with it's UUID.
config.hostAddress = config.PublicIPAddress state.Put("ipaddress", config.PublicIPAddress)
p := client.Address.NewListPublicIpAddressesParams() p := client.Address.NewListPublicIpAddressesParams()
p.SetIpaddress(config.PublicIPAddress) p.SetIpaddress(config.PublicIPAddress)
@ -75,6 +82,7 @@ func (s *stepPrepareConfig) Run(state multistep.StateBag) multistep.StepAction {
config.PublicIPAddress = ipAddrs.PublicIpAddresses[0].Id config.PublicIPAddress = ipAddrs.PublicIpAddresses[0].Id
} }
} }
}
if !isUUID(config.Network) { if !isUUID(config.Network) {
config.Network, _, err = client.Network.GetNetworkID(config.Network, cloudstack.WithProject(config.Project)) config.Network, _, err = client.Network.GetNetworkID(config.Network, cloudstack.WithProject(config.Project))
@ -104,23 +112,25 @@ func (s *stepPrepareConfig) Run(state multistep.StateBag) multistep.StepAction {
if config.SourceISO != "" { if config.SourceISO != "" {
if isUUID(config.SourceISO) { if isUUID(config.SourceISO) {
config.instanceSource = config.SourceISO state.Put("source", config.SourceISO)
} else { } else {
config.instanceSource, _, err = client.ISO.GetIsoID(config.SourceISO, "executable", config.Zone) isoID, _, err := client.ISO.GetIsoID(config.SourceISO, "executable", config.Zone)
if err != nil { if err != nil {
errs = packer.MultiErrorAppend(errs, &retrieveErr{"ISO", config.SourceISO, err}) errs = packer.MultiErrorAppend(errs, &retrieveErr{"ISO", config.SourceISO, err})
} }
state.Put("source", isoID)
} }
} }
if config.SourceTemplate != "" { if config.SourceTemplate != "" {
if isUUID(config.SourceTemplate) { if isUUID(config.SourceTemplate) {
config.instanceSource = config.SourceTemplate state.Put("source", config.SourceTemplate)
} else { } else {
config.instanceSource, _, err = client.Template.GetTemplateID(config.SourceTemplate, "executable", config.Zone) templateID, _, err := client.Template.GetTemplateID(config.SourceTemplate, "executable", config.Zone)
if err != nil { if err != nil {
errs = packer.MultiErrorAppend(errs, &retrieveErr{"template", config.SourceTemplate, err}) errs = packer.MultiErrorAppend(errs, &retrieveErr{"template", config.SourceTemplate, err})
} }
state.Put("source", templateID)
} }
} }