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{
Config: &b.config.Comm,
Host: commHost,
SSHConfig: SSHConfig(
SSHConfig: sshConfig(
b.config.Comm.SSHAgentAuth,
b.config.Comm.SSHUsername,
b.config.Comm.SSHPassword),
SSHPort: commPort,
WinRMPort: commPort,
},
&common.StepProvision{},
&stepShutdownInstance{},

View File

@ -58,9 +58,7 @@ type Config struct {
TemplateScalable bool `mapstructure:"template_scalable"`
TemplateTag string `mapstructure:"template_tag"`
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.
ctx interpolate.Context
}
// NewConfig parses and validates the given config.

View File

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

View File

@ -25,6 +25,7 @@ func (s *stepSetupNetworking) Run(state multistep.StateBag) multistep.StepAction
if config.UseLocalIPAddress {
ui.Message("Using the local IP address...")
state.Put("commPort", config.Comm.Port())
ui.Message("Networking has been setup!")
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.
rand.Seed(time.Now().UnixNano())
s.publicPort = 50000 + rand.Intn(10000)
state.Put("commPort", s.publicPort)
// Set the currently configured port to be the private 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.
instanceID, ok := state.Get("instance_id").(string)
if !ok || instanceID == "" {
@ -91,7 +85,7 @@ func (s *stepSetupNetworking) Run(state multistep.StateBag) multistep.StepAction
// Set the IP address and it's ID.
config.PublicIPAddress = ipAddr.Id
config.hostAddress = ipAddr.Ipaddress
state.Put("ipaddress", ipAddr.Ipaddress)
// Store the IP address 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.
p := client.VirtualMachine.NewDeployVirtualMachineParams(
config.ServiceOffering,
config.instanceSource,
state.Get("source").(string),
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.
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.

View File

@ -53,26 +53,34 @@ func (s *stepPrepareConfig) Run(state multistep.StateBag) multistep.StepAction {
}
}
if config.PublicIPAddress != "" && !isUUID(config.PublicIPAddress) {
// Save the public IP address before replacing it with it's UUID.
config.hostAddress = 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.
state.Put("ipaddress", config.PublicIPAddress)
p := client.Address.NewListPublicIpAddressesParams()
p.SetIpaddress(config.PublicIPAddress)
p := client.Address.NewListPublicIpAddressesParams()
p.SetIpaddress(config.PublicIPAddress)
if config.Project != "" {
p.SetProjectid(config.Project)
}
if config.Project != "" {
p.SetProjectid(config.Project)
}
ipAddrs, err := client.Address.ListPublicIpAddresses(p)
if err != nil {
errs = packer.MultiErrorAppend(errs, &retrieveErr{"IP address", config.PublicIPAddress, err})
}
if err == nil && ipAddrs.Count != 1 {
errs = packer.MultiErrorAppend(errs, &retrieveErr{"IP address", config.PublicIPAddress, ipAddrs})
}
if err == nil && ipAddrs.Count == 1 {
config.PublicIPAddress = ipAddrs.PublicIpAddresses[0].Id
ipAddrs, err := client.Address.ListPublicIpAddresses(p)
if err != nil {
errs = packer.MultiErrorAppend(errs, &retrieveErr{"IP address", config.PublicIPAddress, err})
}
if err == nil && ipAddrs.Count != 1 {
errs = packer.MultiErrorAppend(errs, &retrieveErr{"IP address", config.PublicIPAddress, ipAddrs})
}
if err == nil && ipAddrs.Count == 1 {
config.PublicIPAddress = ipAddrs.PublicIpAddresses[0].Id
}
}
}
@ -104,23 +112,25 @@ func (s *stepPrepareConfig) Run(state multistep.StateBag) multistep.StepAction {
if config.SourceISO != "" {
if isUUID(config.SourceISO) {
config.instanceSource = config.SourceISO
state.Put("source", config.SourceISO)
} 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 {
errs = packer.MultiErrorAppend(errs, &retrieveErr{"ISO", config.SourceISO, err})
}
state.Put("source", isoID)
}
}
if config.SourceTemplate != "" {
if isUUID(config.SourceTemplate) {
config.instanceSource = config.SourceTemplate
state.Put("source", config.SourceTemplate)
} 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 {
errs = packer.MultiErrorAppend(errs, &retrieveErr{"template", config.SourceTemplate, err})
}
state.Put("source", templateID)
}
}