From d70e7834555a7830d2497e8884651715bcb49cb0 Mon Sep 17 00:00:00 2001 From: Lars Wander Date: Wed, 2 Nov 2016 16:24:48 -0400 Subject: [PATCH] builder/googlecompute: Use ssh_private_key_file if provided This seemed to be missing from the googlecompute provider. Now if the ssh_private_key_file is provided, that will be used in place of a temporary key. I didn't update the googlecompute specific docs under `./website/`, since this parameter is already documented under the communicators templates page. --- builder/googlecompute/builder.go | 5 +++-- builder/googlecompute/step_create_instance.go | 22 +++++++++++++------ builder/googlecompute/step_create_ssh_key.go | 20 +++++++++++++++-- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/builder/googlecompute/builder.go b/builder/googlecompute/builder.go index 7be284b50..b39b92b4b 100644 --- a/builder/googlecompute/builder.go +++ b/builder/googlecompute/builder.go @@ -52,8 +52,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steps := []multistep.Step{ new(StepCheckExistingImage), &StepCreateSSHKey{ - Debug: b.config.PackerDebug, - DebugKeyPath: fmt.Sprintf("gce_%s.pem", b.config.PackerBuildName), + Debug: b.config.PackerDebug, + DebugKeyPath: fmt.Sprintf("gce_%s.pem", b.config.PackerBuildName), + PrivateKeyFile: b.config.Comm.SSHPrivateKey, }, &StepCreateInstance{ Debug: b.config.PackerDebug, diff --git a/builder/googlecompute/step_create_instance.go b/builder/googlecompute/step_create_instance.go index ab70fd450..813295f30 100644 --- a/builder/googlecompute/step_create_instance.go +++ b/builder/googlecompute/step_create_instance.go @@ -24,13 +24,17 @@ func (c *Config) createInstanceMetadata(sourceImage *Image, sshPublicKey string) instanceMetadata[k] = v } - // Merge any existing ssh keys with our public key. - sshMetaKey := "sshKeys" - sshKeys := fmt.Sprintf("%s:%s", c.Comm.SSHUsername, sshPublicKey) - if confSshKeys, exists := instanceMetadata[sshMetaKey]; exists { - sshKeys = fmt.Sprintf("%s\n%s", sshKeys, confSshKeys) + // Merge any existing ssh keys with our public key, unless there is no + // supplied public key. This is possible if a private_key_file was + // specified. + if sshPublicKey != "" { + sshMetaKey := "sshKeys" + sshKeys := fmt.Sprintf("%s:%s", c.Comm.SSHUsername, sshPublicKey) + if confSshKeys, exists := instanceMetadata[sshMetaKey]; exists { + sshKeys = fmt.Sprintf("%s\n%s", sshKeys, confSshKeys) + } + instanceMetadata[sshMetaKey] = sshKeys } - instanceMetadata[sshMetaKey] = sshKeys // Wrap any startup script with our own startup script. if c.StartupScriptFile != "" { @@ -65,9 +69,13 @@ func getImage(c *Config, d Driver) (*Image, error) { func (s *StepCreateInstance) Run(state multistep.StateBag) multistep.StepAction { c := state.Get("config").(*Config) d := state.Get("driver").(Driver) - sshPublicKey := state.Get("ssh_public_key").(string) ui := state.Get("ui").(packer.Ui) + sshPublicKey := "" + if sshPublicKeyRaw, ok := state.GetOk("ssh_public_key"); ok { + sshPublicKey = sshPublicKeyRaw.(string) + } + sourceImage, err := getImage(c, d) if err != nil { err := fmt.Errorf("Error getting source image for instance creation: %s", err) diff --git a/builder/googlecompute/step_create_ssh_key.go b/builder/googlecompute/step_create_ssh_key.go index 4c4894fba..7d6c27622 100644 --- a/builder/googlecompute/step_create_ssh_key.go +++ b/builder/googlecompute/step_create_ssh_key.go @@ -6,6 +6,7 @@ import ( "crypto/x509" "encoding/pem" "fmt" + "io/ioutil" "os" "github.com/mitchellh/multistep" @@ -15,8 +16,9 @@ import ( // StepCreateSSHKey represents a Packer build step that generates SSH key pairs. type StepCreateSSHKey struct { - Debug bool - DebugKeyPath string + Debug bool + DebugKeyPath string + PrivateKeyFile string } // Run executes the Packer build step that generates SSH key pairs. @@ -25,6 +27,20 @@ type StepCreateSSHKey struct { func (s *StepCreateSSHKey) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) + if s.PrivateKeyFile != "" { + ui.Say("Using existing SSH private key") + 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("ssh_private_key", string(privateKeyBytes)) + + return multistep.ActionContinue + } + ui.Say("Creating temporary SSH key for instance...") priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil {