diff --git a/builder/cloudstack/builder.go b/builder/cloudstack/builder.go index 369fe0cc6..51254983a 100644 --- a/builder/cloudstack/builder.go +++ b/builder/cloudstack/builder.go @@ -68,10 +68,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{}, diff --git a/builder/cloudstack/config.go b/builder/cloudstack/config.go index 68fe778d4..c91b65b04 100644 --- a/builder/cloudstack/config.go +++ b/builder/cloudstack/config.go @@ -55,8 +55,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. + ctx interpolate.Context } // NewConfig parses and validates the given config. diff --git a/builder/cloudstack/ssh.go b/builder/cloudstack/ssh.go index ab350d053..725961504 100644 --- a/builder/cloudstack/ssh.go +++ b/builder/cloudstack/ssh.go @@ -7,28 +7,30 @@ 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) - } + ip, hasIp := state.Get("ipaddress").(string) + if !hasIp { + return "", fmt.Errorf("Failed to retrieve IP address") + } + + return ip, nil +} - config.hostAddress = ipAddr.Ipaddress +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 config.hostAddress, nil + return commPort, nil } -func SSHConfig(useAgent bool, username, password string) func(state multistep.StateBag) (*ssh.ClientConfig, error) { +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") diff --git a/builder/cloudstack/step_configure_networking.go b/builder/cloudstack/step_configure_networking.go index 48a3742ab..d9a6a365c 100644 --- a/builder/cloudstack/step_configure_networking.go +++ b/builder/cloudstack/step_configure_networking.go @@ -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) diff --git a/builder/cloudstack/step_create_instance.go b/builder/cloudstack/step_create_instance.go index 90db2d960..aa032eecb 100644 --- a/builder/cloudstack/step_create_instance.go +++ b/builder/cloudstack/step_create_instance.go @@ -130,7 +130,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. diff --git a/builder/cloudstack/step_prepare_config.go b/builder/cloudstack/step_prepare_config.go index 8fafc809e..45b6068f8 100644 --- a/builder/cloudstack/step_prepare_config.go +++ b/builder/cloudstack/step_prepare_config.go @@ -64,7 +64,7 @@ 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 + state.Put("ipaddress", config.PublicIPAddress) p := client.Address.NewListPublicIpAddressesParams() p.SetIpaddress(config.PublicIPAddress)