diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index d6b528695..d15713339 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -77,6 +77,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("os_%s.pem", b.config.PackerBuildName), + KeyPairName: b.config.SSHKeyPairName, + PrivateKeyFile: b.config.RunConfig.Comm.SSHPrivateKey, }, &StepRunSourceServer{ Name: b.config.ImageName, diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index 128e36b5b..00f34c9c4 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -11,6 +11,7 @@ import ( // image and details on how to access that launched image. type RunConfig struct { Comm communicator.Config `mapstructure:",squash"` + SSHKeyPairName string `mapstructure:"ssh_keypair_name"` SSHInterface string `mapstructure:"ssh_interface"` SourceImage string `mapstructure:"source_image"` diff --git a/builder/openstack/step_key_pair.go b/builder/openstack/step_key_pair.go index 06bcbf9ea..97dbf7515 100644 --- a/builder/openstack/step_key_pair.go +++ b/builder/openstack/step_key_pair.go @@ -2,6 +2,7 @@ package openstack import ( "fmt" + "io/ioutil" "os" "runtime" @@ -14,10 +15,27 @@ import ( type StepKeyPair struct { Debug bool DebugKeyPath string + KeyPairName string + PrivateKeyFile string + keyName string } func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction { + if s.PrivateKeyFile != "" { + privateKeyBytes, err := ioutil.ReadFile(s.PrivateKeyFile) + if err != nil { + state.Put("error", fmt.Errorf( + "Error loading configured private key file: %s", err)) + return multistep.ActionHalt + } + + state.Put("keyPair", s.KeyPairName) + state.Put("privateKey", string(privateKeyBytes)) + + return multistep.ActionContinue + } + config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) @@ -81,6 +99,11 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction { } func (s *StepKeyPair) Cleanup(state multistep.StateBag) { + // If we used an SSH private key file, do not go about deleting + // keypairs + if s.PrivateKeyFile != "" { + return + } // If no key name is set, then we never created it, so just return if s.keyName == "" { return