helper/communicator: make host more generic

This commit is contained in:
Mitchell Hashimoto 2015-06-13 19:23:33 -04:00
parent 68e4734caf
commit 115d583cff
30 changed files with 113 additions and 103 deletions

View File

@ -10,9 +10,9 @@ import (
"golang.org/x/crypto/ssh"
)
// SSHAddress returns a function that can be given to the SSH communicator
// SSHHost returns a function that can be given to the SSH communicator
// for determining the SSH address based on the instance DNS name.
func SSHAddress(e *ec2.EC2, port int, private bool) func(multistep.StateBag) (string, error) {
func SSHHost(e *ec2.EC2, private bool) func(multistep.StateBag) (string, error) {
return func(state multistep.StateBag) (string, error) {
for j := 0; j < 2; j++ {
var host string
@ -28,7 +28,7 @@ func SSHAddress(e *ec2.EC2, port int, private bool) func(multistep.StateBag) (st
}
if host != "" {
return fmt.Sprintf("%s:%d", host, port), nil
return host, nil
}
r, err := e.DescribeInstances(&ec2.DescribeInstancesInput{

View File

@ -115,9 +115,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.RunConfig.Comm,
SSHAddress: awscommon.SSHAddress(
Host: awscommon.SSHHost(
ec2conn,
b.config.RunConfig.Comm.SSHPort,
b.config.SSHPrivateIp),
SSHConfig: awscommon.SSHConfig(
b.config.RunConfig.Comm.SSHUsername),

View File

@ -200,9 +200,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.RunConfig.Comm,
SSHAddress: awscommon.SSHAddress(
Host: awscommon.SSHHost(
ec2conn,
b.config.RunConfig.Comm.SSHPort,
b.config.SSHPrivateIp),
SSHConfig: awscommon.SSHConfig(
b.config.RunConfig.Comm.SSHUsername),

View File

@ -55,7 +55,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
new(stepDropletInfo),
&communicator.StepConnect{
Config: &b.config.Comm,
SSHAddress: sshAddress,
Host: commHost,
SSHConfig: sshConfig,
},
new(common.StepProvision),

View File

@ -2,14 +2,14 @@ package digitalocean
import (
"fmt"
"github.com/mitchellh/multistep"
"golang.org/x/crypto/ssh"
"github.com/mitchellh/multistep"
)
func sshAddress(state multistep.StateBag) (string, error) {
config := state.Get("config").(Config)
func commHost(state multistep.StateBag) (string, error) {
ipAddress := state.Get("droplet_ip").(string)
return fmt.Sprintf("%s:%d", ipAddress, config.Comm.SSHPort), nil
return ipAddress, nil
}
func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) {

View File

@ -63,7 +63,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.Comm,
SSHAddress: sshAddress,
Host: commHost,
SSHConfig: sshConfig,
},
new(common.StepProvision),

View File

@ -2,15 +2,14 @@ package googlecompute
import (
"fmt"
"github.com/mitchellh/multistep"
"golang.org/x/crypto/ssh"
)
// sshAddress returns the ssh address.
func sshAddress(state multistep.StateBag) (string, error) {
config := state.Get("config").(*Config)
func commHost(state multistep.StateBag) (string, error) {
ipAddress := state.Get("instance_ip").(string)
return fmt.Sprintf("%s:%d", ipAddress, config.Comm.SSHPort), nil
return ipAddress, nil
}
// sshConfig returns the ssh configuration.

View File

@ -30,8 +30,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
steps := []multistep.Step{
&communicator.StepConnect{
Config: &b.config.CommConfig,
SSHAddress: SSHAddress(
b.config.CommConfig.SSHHost, b.config.CommConfig.SSHPort),
Host: CommHost(b.config.CommConfig.SSHHost),
SSHConfig: SSHConfig(
b.config.CommConfig.SSHUsername,
b.config.CommConfig.SSHPassword,

View File

@ -8,11 +8,9 @@ import (
"io/ioutil"
)
// SSHAddress returns a function that can be given to the SSH communicator
// for determining the SSH address
func SSHAddress(host string, port int) func(multistep.StateBag) (string, error) {
func CommHost(host string) func(multistep.StateBag) (string, error) {
return func(state multistep.StateBag) (string, error) {
return fmt.Sprintf("%s:%d", host, port), nil
return host, nil
}
}

View File

@ -92,10 +92,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.RunConfig.Comm,
SSHAddress: SSHAddress(
Host: CommHost(
computeClient,
b.config.SSHInterface,
b.config.RunConfig.Comm.SSHPort),
b.config.SSHInterface),
SSHConfig: SSHConfig(b.config.RunConfig.Comm.SSHUsername),
},
&common.StepProvision{},

View File

@ -13,22 +13,21 @@ import (
"golang.org/x/crypto/ssh"
)
// SSHAddress returns a function that can be given to the SSH communicator
// for determining the SSH address based on the server AccessIPv4 setting..
func SSHAddress(
// CommHost looks up the host for the communicator.
func CommHost(
client *gophercloud.ServiceClient,
sshinterface string, port int) func(multistep.StateBag) (string, error) {
sshinterface string) func(multistep.StateBag) (string, error) {
return func(state multistep.StateBag) (string, error) {
s := state.Get("server").(*servers.Server)
// If we have a floating IP, use that
ip := state.Get("access_ip").(*floatingip.FloatingIP)
if ip != nil && ip.IP != "" {
return fmt.Sprintf("%s:%d", ip.IP, port), nil
return ip.IP, nil
}
if s.AccessIPv4 != "" {
return fmt.Sprintf("%s:%d", s.AccessIPv4, port), nil
return s.AccessIPv4, nil
}
// Get all the addresses associated with this server. This
@ -53,7 +52,7 @@ func SSHAddress(
}
}
if addr != "" {
return fmt.Sprintf("%s:%d", addr, port), nil
return addr, nil
}
}
}

View File

@ -1,15 +1,13 @@
package common
import (
"fmt"
"github.com/mitchellh/multistep"
commonssh "github.com/mitchellh/packer/common/ssh"
packerssh "github.com/mitchellh/packer/communicator/ssh"
"golang.org/x/crypto/ssh"
)
func SSHAddress(state multistep.StateBag) (string, error) {
func CommHost(state multistep.StateBag) (string, error) {
vmName := state.Get("vmName").(string)
driver := state.Get("driver").(Driver)
@ -23,7 +21,7 @@ func SSHAddress(state multistep.StateBag) (string, error) {
return "", err
}
return fmt.Sprintf("%s:22", ip), nil
return ip, nil
}
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*ssh.ClientConfig, error) {

View File

@ -248,7 +248,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
SSHAddress: parallelscommon.SSHAddress,
Host: parallelscommon.CommHost,
SSHConfig: parallelscommon.SSHConfigFunc(b.config.SSHConfig),
},
&parallelscommon.StepUploadVersion{

View File

@ -84,7 +84,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
SSHAddress: parallelscommon.SSHAddress,
Host: parallelscommon.CommHost,
SSHConfig: parallelscommon.SSHConfigFunc(b.config.SSHConfig),
},
&parallelscommon.StepUploadVersion{

View File

@ -394,8 +394,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&stepTypeBootCommand{},
&communicator.StepConnect{
Config: &b.config.Comm,
SSHAddress: sshAddress,
Host: commHost,
SSHConfig: sshConfig,
SSHPort: commPort,
},
new(common.StepProvision),
new(stepShutdown),

View File

@ -1,17 +1,19 @@
package qemu
import (
"fmt"
"github.com/mitchellh/multistep"
commonssh "github.com/mitchellh/packer/common/ssh"
"github.com/mitchellh/packer/communicator/ssh"
gossh "golang.org/x/crypto/ssh"
)
func sshAddress(state multistep.StateBag) (string, error) {
func commHost(state multistep.StateBag) (string, error) {
return "127.0.0.1", nil
}
func commPort(state multistep.StateBag) (int, error) {
sshHostPort := state.Get("sshHostPort").(uint)
return fmt.Sprintf("127.0.0.1:%d", sshHostPort), nil
return int(sshHostPort), nil
}
func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {

View File

@ -1,17 +1,19 @@
package common
import (
"fmt"
"github.com/mitchellh/multistep"
commonssh "github.com/mitchellh/packer/common/ssh"
"github.com/mitchellh/packer/communicator/ssh"
gossh "golang.org/x/crypto/ssh"
)
func SSHAddress(state multistep.StateBag) (string, error) {
func CommHost(state multistep.StateBag) (string, error) {
return "127.0.0.1", nil
}
func SSHPort(state multistep.StateBag) (int, error) {
sshHostPort := state.Get("sshHostPort").(uint)
return fmt.Sprintf("127.0.0.1:%d", sshHostPort), nil
return int(sshHostPort), nil
}
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) {

View File

@ -274,8 +274,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
SSHAddress: vboxcommon.SSHAddress,
Host: vboxcommon.CommHost,
SSHConfig: vboxcommon.SSHConfigFunc(b.config.SSHConfig),
SSHPort: vboxcommon.SSHPort,
},
&vboxcommon.StepUploadVersion{
Path: b.config.VBoxVersionFile,

View File

@ -103,8 +103,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
SSHAddress: vboxcommon.SSHAddress,
Host: vboxcommon.CommHost,
SSHConfig: vboxcommon.SSHConfigFunc(b.config.SSHConfig),
SSHPort: vboxcommon.SSHPort,
},
&vboxcommon.StepUploadVersion{
Path: b.config.VBoxVersionFile,

View File

@ -29,9 +29,9 @@ type Driver interface {
// Checks if the VMX file at the given path is running.
IsRunning(string) (bool, error)
// SSHAddress returns the SSH address for the VM that is being
// CommHost returns the host address for the VM that is being
// managed by this driver.
SSHAddress(multistep.StateBag) (string, error)
CommHost(multistep.StateBag) (string, error)
// Start starts a VM specified by the path to the VMX given.
Start(string, bool) error

View File

@ -69,8 +69,8 @@ func (d *Fusion5Driver) IsRunning(vmxPath string) (bool, error) {
return false, nil
}
func (d *Fusion5Driver) SSHAddress(state multistep.StateBag) (string, error) {
return SSHAddressFunc(d.SSHConfig)(state)
func (d *Fusion5Driver) CommHost(state multistep.StateBag) (string, error) {
return CommHost(d.SSHConfig)(state)
}
func (d *Fusion5Driver) Start(vmxPath string, headless bool) error {

View File

@ -29,10 +29,10 @@ type DriverMock struct {
IsRunningResult bool
IsRunningErr error
SSHAddressCalled bool
SSHAddressState multistep.StateBag
SSHAddressResult string
SSHAddressErr error
CommHostCalled bool
CommHostState multistep.StateBag
CommHostResult string
CommHostErr error
StartCalled bool
StartPath string
@ -92,10 +92,10 @@ func (d *DriverMock) IsRunning(path string) (bool, error) {
return d.IsRunningResult, d.IsRunningErr
}
func (d *DriverMock) SSHAddress(state multistep.StateBag) (string, error) {
d.SSHAddressCalled = true
d.SSHAddressState = state
return d.SSHAddressResult, d.SSHAddressErr
func (d *DriverMock) CommHost(state multistep.StateBag) (string, error) {
d.CommHostCalled = true
d.CommHostState = state
return d.CommHostResult, d.CommHostErr
}
func (d *DriverMock) Start(path string, headless bool) error {

View File

@ -97,8 +97,8 @@ func (d *Player5Driver) IsRunning(vmxPath string) (bool, error) {
return false, nil
}
func (d *Player5Driver) SSHAddress(state multistep.StateBag) (string, error) {
return SSHAddressFunc(d.SSHConfig)(state)
func (d *Player5Driver) CommHost(state multistep.StateBag) (string, error) {
return CommHost(d.SSHConfig)(state)
}
func (d *Player5Driver) Start(vmxPath string, headless bool) error {

View File

@ -70,8 +70,8 @@ func (d *Workstation9Driver) IsRunning(vmxPath string) (bool, error) {
return false, nil
}
func (d *Workstation9Driver) SSHAddress(state multistep.StateBag) (string, error) {
return SSHAddressFunc(d.SSHConfig)(state)
func (d *Workstation9Driver) CommHost(state multistep.StateBag) (string, error) {
return CommHost(d.SSHConfig)(state)
}
func (d *Workstation9Driver) Start(vmxPath string, headless bool) error {

View File

@ -13,13 +13,13 @@ import (
gossh "golang.org/x/crypto/ssh"
)
func SSHAddressFunc(config *SSHConfig) func(multistep.StateBag) (string, error) {
func CommHost(config *SSHConfig) func(multistep.StateBag) (string, error) {
return func(state multistep.StateBag) (string, error) {
driver := state.Get("driver").(Driver)
vmxPath := state.Get("vmx_path").(string)
if config.Comm.SSHHost != "" {
return fmt.Sprintf("%s:%d", config.Comm.SSHHost, config.Comm.SSHPort), nil
return config.Comm.SSHHost, nil
}
log.Println("Lookup up IP information...")
@ -62,7 +62,7 @@ func SSHAddressFunc(config *SSHConfig) func(multistep.StateBag) (string, error)
}
log.Printf("Detected IP: %s", ipAddress)
return fmt.Sprintf("%s:%d", ipAddress, config.Comm.SSHPort), nil
return ipAddress, nil
}
}

View File

@ -301,7 +301,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
SSHAddress: driver.SSHAddress,
Host: driver.CommHost,
SSHConfig: vmwcommon.SSHConfigFunc(&b.config.SSHConfig),
},
&vmwcommon.StepUploadTools{

View File

@ -218,7 +218,7 @@ func (d *ESX5Driver) VNCAddress(portMin, portMax uint) (string, uint, error) {
return d.Host, vncPort, nil
}
func (d *ESX5Driver) SSHAddress(state multistep.StateBag) (string, error) {
func (d *ESX5Driver) CommHost(state multistep.StateBag) (string, error) {
config := state.Get("config").(*Config)
if address, ok := state.GetOk("vm_address"); ok {
@ -253,7 +253,7 @@ func (d *ESX5Driver) SSHAddress(state multistep.StateBag) (string, error) {
return "", errors.New("VM network port found, but no IP address")
}
address := fmt.Sprintf("%s:%d", record["IPAddress"], config.Comm.SSHPort)
address := record["IPAddress"]
state.Put("vm_address", address)
return address, nil
}

View File

@ -93,7 +93,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
SSHAddress: driver.SSHAddress,
Host: driver.CommHost,
SSHConfig: vmwcommon.SSHConfigFunc(&b.config.SSHConfig),
},
&vmwcommon.StepUploadTools{

View File

@ -15,15 +15,16 @@ type StepConnect struct {
// Config is the communicator config struct
Config *Config
// Host should return a host that can be connected to for communicator
// connections.
Host func(multistep.StateBag) (string, error)
// The fields below are callbacks to assist with connecting to SSH.
//
// SSHAddress should return the default host to connect to for SSH.
// This is only called if ssh_host isn't specified in the config.
//
// SSHConfig should return the default configuration for
// connecting via SSH.
SSHAddress func(multistep.StateBag) (string, error)
SSHConfig func(multistep.StateBag) (*gossh.ClientConfig, error)
SSHPort func(multistep.StateBag) (int, error)
substep multistep.Step
}
@ -33,8 +34,9 @@ func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction {
"none": nil,
"ssh": &StepConnectSSH{
Config: s.Config,
SSHAddress: s.SSHAddress,
Host: s.Host,
SSHConfig: s.SSHConfig,
SSHPort: s.SSHPort,
},
}

View File

@ -19,8 +19,9 @@ import (
type StepConnectSSH struct {
// All the fields below are documented on StepConnect
Config *Config
SSHAddress func(multistep.StateBag) (string, error)
Host func(multistep.StateBag) (string, error)
SSHConfig func(multistep.StateBag) (*gossh.ClientConfig, error)
SSHPort func(multistep.StateBag) (int, error)
}
func (s *StepConnectSSH) Run(state multistep.StateBag) multistep.StepAction {
@ -95,11 +96,19 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru
first = false
// First we request the TCP connection information
address, err := s.SSHAddress(state)
host, err := s.Host(state)
if err != nil {
log.Printf("[DEBUG] Error getting SSH address: %s", err)
continue
}
port := s.Config.SSHPort
if s.SSHPort != nil {
port, err = s.SSHPort(state)
if err != nil {
log.Printf("[DEBUG] Error getting SSH port: %s", err)
continue
}
}
// Retrieve the SSH configuration
sshConfig, err := s.SSHConfig(state)
@ -108,6 +117,8 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru
continue
}
address := fmt.Sprintf("%s:%d", host, port)
// Attempt to connect to SSH port
connFunc := ssh.ConnectFunc("tcp", address)
nc, err := connFunc()