Merge pull request #3976 from rickard-von-essen/os-pwd

builder/openstack: Support using SSH password.
This commit is contained in:
Matthew Hooker 2016-10-10 09:20:17 -07:00 committed by GitHub
commit 1747e31b54
4 changed files with 60 additions and 30 deletions

View File

@ -108,7 +108,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
computeClient, computeClient,
b.config.SSHInterface, b.config.SSHInterface,
b.config.SSHIPVersion), b.config.SSHIPVersion),
SSHConfig: SSHConfig(b.config.RunConfig.Comm.SSHUsername), SSHConfig: SSHConfig(b.config.RunConfig.Comm.SSHUsername,
b.config.RunConfig.Comm.SSHPassword),
}, },
&common.StepProvision{}, &common.StepProvision{},
&StepStopServer{}, &StepStopServer{},

View File

@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
packerssh "github.com/mitchellh/packer/communicator/ssh"
"github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip" "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip"
"github.com/rackspace/gophercloud/openstack/compute/v2/servers" "github.com/rackspace/gophercloud/openstack/compute/v2/servers"
@ -60,23 +61,37 @@ func CommHost(
} }
// SSHConfig returns a function that can be used for the SSH communicator // SSHConfig returns a function that can be used for the SSH communicator
// config for connecting to the instance created over SSH using the generated // config for connecting to the instance created over SSH using a private key
// private key. // or a password.
func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) { func SSHConfig(username, password string) func(multistep.StateBag) (*ssh.ClientConfig, error) {
return func(state multistep.StateBag) (*ssh.ClientConfig, error) { return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
privateKey := state.Get("privateKey").(string)
signer, err := ssh.ParsePrivateKey([]byte(privateKey)) privateKey, hasKey := state.GetOk("privateKey")
if err != nil {
return nil, fmt.Errorf("Error setting up SSH config: %s", err) if hasKey {
signer, err := ssh.ParsePrivateKey([]byte(privateKey.(string)))
if err != nil {
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
}
return &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
}, nil
} else {
return &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.Password(password),
ssh.KeyboardInteractive(
packerssh.PasswordKeyboardInteractive(password)),
}}, nil
} }
return &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
}, nil
} }
} }

View File

@ -42,6 +42,11 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(Config) config := state.Get("config").(Config)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
if config.Comm.Type == "ssh" && config.Comm.SSHPassword != "" {
ui.Say("Not creating temporary keypair when using password.")
return multistep.ActionContinue
}
// We need the v2 compute client // We need the v2 compute client
computeClient, err := config.computeV2Client() computeClient, err := config.computeV2Client()
if err != nil { if err != nil {

View File

@ -27,7 +27,6 @@ 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) flavor := state.Get("flavor_id").(string)
keyName := state.Get("keyPair").(string)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
// We need the v2 compute client // We need the v2 compute client
@ -54,21 +53,31 @@ func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction
} }
ui.Say("Launching server...") ui.Say("Launching server...")
s.server, err = servers.Create(computeClient, keypairs.CreateOptsExt{
CreateOptsBuilder: servers.CreateOpts{
Name: s.Name,
ImageRef: s.SourceImage,
ImageName: s.SourceImageName,
FlavorRef: flavor,
SecurityGroups: s.SecurityGroups,
Networks: networks,
AvailabilityZone: s.AvailabilityZone,
UserData: userData,
ConfigDrive: s.ConfigDrive,
},
KeyName: keyName, serverOpts := servers.CreateOpts{
}).Extract() Name: s.Name,
ImageRef: s.SourceImage,
ImageName: s.SourceImageName,
FlavorRef: flavor,
SecurityGroups: s.SecurityGroups,
Networks: networks,
AvailabilityZone: s.AvailabilityZone,
UserData: userData,
ConfigDrive: s.ConfigDrive,
}
var serverOptsExt servers.CreateOptsBuilder
keyName, hasKey := state.GetOk("keyPair")
if hasKey {
serverOptsExt = keypairs.CreateOptsExt{
CreateOptsBuilder: serverOpts,
KeyName: keyName.(string),
}
} else {
serverOptsExt = serverOpts
}
s.server, err = servers.Create(computeClient, serverOptsExt).Extract()
if err != nil { if err != nil {
err := fmt.Errorf("Error launching source server: %s", err) err := fmt.Errorf("Error launching source server: %s", err)
state.Put("error", err) state.Put("error", err)