From 8c87b1cc00618632ef1a80e4d349e2918bf92c8b Mon Sep 17 00:00:00 2001 From: "Lesko, Matthew (NIH/NLM/NCBI) [C]" Date: Tue, 13 Jan 2015 12:20:31 -0500 Subject: [PATCH] First attempt for re-using a named EC2 keypair Adds a 'ssh_keypair_name' option to the configuration for AWS, along with some munging to create the temporarily keypair if one isn't specific. NOT YET WORKING. From a 'make' I get the following errors: builder/amazon/ebs/builder.go:94: b.config.SSHKeyPairName undefined (type config has no field or method SSHKeyPairName) builder/amazon/instance/builder.go:199: b.config.SSHKeyPairName undefined (type Config has no field or method SSHKeyPairName) --- builder/amazon/common/run_config.go | 7 +++++-- builder/amazon/common/run_config_test.go | 4 ++-- builder/amazon/common/step_key_pair.go | 22 ++++++++++++---------- builder/amazon/ebs/builder.go | 2 +- builder/amazon/instance/builder.go | 2 +- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index a71387623..f6e859c03 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -24,6 +24,7 @@ type RunConfig struct { RawSSHTimeout string `mapstructure:"ssh_timeout"` SSHUsername string `mapstructure:"ssh_username"` SSHPrivateKeyFile string `mapstructure:"ssh_private_key_file"` + SSHKeyPairName string `mapstructure:"ssh_keypair_name"` SSHPrivateIp bool `mapstructure:"ssh_private_ip"` SSHPort int `mapstructure:"ssh_port"` SecurityGroupId string `mapstructure:"security_group_id"` @@ -55,6 +56,7 @@ func (c *RunConfig) Prepare(t *packer.ConfigTemplate) []error { "ssh_timeout": &c.RawSSHTimeout, "ssh_username": &c.SSHUsername, "ssh_private_key_file": &c.SSHPrivateKeyFile, + "ssh_keypair_name": &c.SSHKeyPairName, "source_ami": &c.SourceAmi, "subnet_id": &c.SubnetId, "temporary_key_pair_name": &c.TemporaryKeyPairName, @@ -84,8 +86,9 @@ func (c *RunConfig) Prepare(t *packer.ConfigTemplate) []error { c.RawSSHTimeout = "5m" } - if c.TemporaryKeyPairName == "" { - c.TemporaryKeyPairName = fmt.Sprintf( + // if we are not given an explicit keypairname, create a temporary one + if c.SSHKeyPairName == "" { + c.SSHKeyPairName = fmt.Sprintf( "packer %s", uuid.TimeOrderedUUID()) } diff --git a/builder/amazon/common/run_config_test.go b/builder/amazon/common/run_config_test.go index 8e9c4b6b9..c4e1fa110 100644 --- a/builder/amazon/common/run_config_test.go +++ b/builder/amazon/common/run_config_test.go @@ -142,12 +142,12 @@ func TestRunConfigPrepare_UserDataFile(t *testing.T) { func TestRunConfigPrepare_TemporaryKeyPairName(t *testing.T) { c := testConfig() - c.TemporaryKeyPairName = "" + c.SSHKeyPairName = "" if err := c.Prepare(nil); len(err) != 0 { t.Fatalf("err: %s", err) } - if c.TemporaryKeyPairName == "" { + if c.SSHKeyPairName == "" { t.Fatal("keypair empty") } } diff --git a/builder/amazon/common/step_key_pair.go b/builder/amazon/common/step_key_pair.go index 3a7eb9f35..db60e1e40 100644 --- a/builder/amazon/common/step_key_pair.go +++ b/builder/amazon/common/step_key_pair.go @@ -21,7 +21,7 @@ type StepKeyPair struct { func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction { if s.PrivateKeyFile != "" { - s.keyName = "" + s.keyName = s.KeyPairName // need to get from config privateKeyBytes, err := ioutil.ReadFile(s.PrivateKeyFile) if err != nil { @@ -29,7 +29,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } - state.Put("keyPair", "") + state.Put("keyPair", s.keyName) state.Put("privateKey", string(privateKeyBytes)) return multistep.ActionContinue @@ -83,17 +83,19 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction { func (s *StepKeyPair) Cleanup(state multistep.StateBag) { // If no key name is set, then we never created it, so just return - if s.keyName == "" { + // If we used an SSH private key file, do not go about deleting + // keypairs + if s.PrivateKeyFile != "" { return } - ec2conn := state.Get("ec2").(*ec2.EC2) + //ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) - ui.Say("Deleting temporary keypair...") - _, err := ec2conn.DeleteKeyPair(s.keyName) - if err != nil { - ui.Error(fmt.Sprintf( - "Error cleaning up keypair. Please delete the key manually: %s", s.keyName)) - } + ui.Say("DANGER: Deleting temporary keypair (not really)...") + //_, err := ec2conn.DeleteKeyPair(s.keyName) + //if err != nil { + //ui.Error(fmt.Sprintf( + //"Error cleaning up keypair. Please delete the key manually: %s", s.keyName)) + //} } diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 889cc7b60..083507993 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -91,7 +91,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &awscommon.StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName), - KeyPairName: b.config.TemporaryKeyPairName, + KeyPairName: b.config.SSHKeyPairName, PrivateKeyFile: b.config.SSHPrivateKeyFile, }, &awscommon.StepSecurityGroup{ diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 1f5c1d9c8..ce582e039 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -196,7 +196,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &awscommon.StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName), - KeyPairName: b.config.TemporaryKeyPairName, + KeyPairName: b.config.SSHKeyPairName, PrivateKeyFile: b.config.SSHPrivateKeyFile, }, &awscommon.StepSecurityGroup{