github.com/kimor79/packer@v0.8.7-0.20151221212622-d507b18eb4cf/builder/openstack/step_key_pair.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "runtime" 8 9 "github.com/mitchellh/multistep" 10 "github.com/mitchellh/packer/common/uuid" 11 "github.com/mitchellh/packer/packer" 12 "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs" 13 ) 14 15 type StepKeyPair struct { 16 Debug bool 17 DebugKeyPath string 18 KeyPairName string 19 PrivateKeyFile string 20 21 keyName string 22 } 23 24 func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction { 25 if s.PrivateKeyFile != "" { 26 privateKeyBytes, err := ioutil.ReadFile(s.PrivateKeyFile) 27 if err != nil { 28 state.Put("error", fmt.Errorf( 29 "Error loading configured private key file: %s", err)) 30 return multistep.ActionHalt 31 } 32 33 state.Put("keyPair", s.KeyPairName) 34 state.Put("privateKey", string(privateKeyBytes)) 35 36 return multistep.ActionContinue 37 } 38 39 config := state.Get("config").(Config) 40 ui := state.Get("ui").(packer.Ui) 41 42 // We need the v2 compute client 43 computeClient, err := config.computeV2Client() 44 if err != nil { 45 err = fmt.Errorf("Error initializing compute client: %s", err) 46 state.Put("error", err) 47 return multistep.ActionHalt 48 } 49 50 keyName := fmt.Sprintf("packer %s", uuid.TimeOrderedUUID()) 51 ui.Say(fmt.Sprintf("Creating temporary keypair: %s ...", keyName)) 52 keypair, err := keypairs.Create(computeClient, keypairs.CreateOpts{ 53 Name: keyName, 54 }).Extract() 55 if err != nil { 56 state.Put("error", fmt.Errorf("Error creating temporary keypair: %s", err)) 57 return multistep.ActionHalt 58 } 59 60 if keypair.PrivateKey == "" { 61 state.Put("error", fmt.Errorf("The temporary keypair returned was blank")) 62 return multistep.ActionHalt 63 } 64 65 ui.Say(fmt.Sprintf("Created temporary keypair: %s", keyName)) 66 67 // If we're in debug mode, output the private key to the working 68 // directory. 69 if s.Debug { 70 ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath)) 71 f, err := os.Create(s.DebugKeyPath) 72 if err != nil { 73 state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) 74 return multistep.ActionHalt 75 } 76 defer f.Close() 77 78 // Write the key out 79 if _, err := f.Write([]byte(keypair.PrivateKey)); err != nil { 80 state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) 81 return multistep.ActionHalt 82 } 83 84 // Chmod it so that it is SSH ready 85 if runtime.GOOS != "windows" { 86 if err := f.Chmod(0600); err != nil { 87 state.Put("error", fmt.Errorf("Error setting permissions of debug key: %s", err)) 88 return multistep.ActionHalt 89 } 90 } 91 } 92 93 // Set the keyname so we know to delete it later 94 s.keyName = keyName 95 96 // Set some state data for use in future steps 97 state.Put("keyPair", keyName) 98 state.Put("privateKey", keypair.PrivateKey) 99 100 return multistep.ActionContinue 101 } 102 103 func (s *StepKeyPair) Cleanup(state multistep.StateBag) { 104 // If we used an SSH private key file, do not go about deleting 105 // keypairs 106 if s.PrivateKeyFile != "" { 107 return 108 } 109 // If no key name is set, then we never created it, so just return 110 if s.keyName == "" { 111 return 112 } 113 114 config := state.Get("config").(Config) 115 ui := state.Get("ui").(packer.Ui) 116 117 // We need the v2 compute client 118 computeClient, err := config.computeV2Client() 119 if err != nil { 120 ui.Error(fmt.Sprintf( 121 "Error cleaning up keypair. Please delete the key manually: %s", s.keyName)) 122 return 123 } 124 125 ui.Say(fmt.Sprintf("Deleting temporary keypair: %s ...", s.keyName)) 126 err = keypairs.Delete(computeClient, s.keyName).ExtractErr() 127 if err != nil { 128 ui.Error(fmt.Sprintf( 129 "Error cleaning up keypair. Please delete the key manually: %s", s.keyName)) 130 } 131 }