github.phpd.cn/hashicorp/packer@v1.3.2/builder/cloudstack/step_keypair.go (about) 1 package cloudstack 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "runtime" 9 10 "github.com/hashicorp/packer/helper/communicator" 11 "github.com/hashicorp/packer/helper/multistep" 12 "github.com/hashicorp/packer/packer" 13 "github.com/xanzy/go-cloudstack/cloudstack" 14 ) 15 16 type stepKeypair struct { 17 Debug bool 18 Comm *communicator.Config 19 DebugKeyPath string 20 } 21 22 func (s *stepKeypair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 23 ui := state.Get("ui").(packer.Ui) 24 25 if s.Comm.SSHPrivateKeyFile != "" { 26 privateKeyBytes, err := ioutil.ReadFile(s.Comm.SSHPrivateKeyFile) 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 s.Comm.SSHPrivateKey = privateKeyBytes 34 35 return multistep.ActionContinue 36 } 37 38 if s.Comm.SSHAgentAuth && s.Comm.SSHKeyPairName == "" { 39 ui.Say("Using SSH Agent with keypair in Source image") 40 return multistep.ActionContinue 41 } 42 43 if s.Comm.SSHAgentAuth && s.Comm.SSHKeyPairName != "" { 44 ui.Say(fmt.Sprintf("Using SSH Agent for existing keypair %s", s.Comm.SSHKeyPairName)) 45 return multistep.ActionContinue 46 } 47 48 if s.Comm.SSHTemporaryKeyPairName == "" { 49 ui.Say("Not using a keypair") 50 s.Comm.SSHKeyPairName = "" 51 return multistep.ActionContinue 52 } 53 54 client := state.Get("client").(*cloudstack.CloudStackClient) 55 56 ui.Say(fmt.Sprintf("Creating temporary keypair: %s ...", s.Comm.SSHTemporaryKeyPairName)) 57 58 p := client.SSH.NewCreateSSHKeyPairParams(s.Comm.SSHTemporaryKeyPairName) 59 60 cfg := state.Get("config").(*Config) 61 if cfg.Project != "" { 62 p.SetProjectid(cfg.Project) 63 } 64 65 keypair, err := client.SSH.CreateSSHKeyPair(p) 66 if err != nil { 67 err := fmt.Errorf("Error creating temporary keypair: %s", err) 68 state.Put("error", err) 69 ui.Error(err.Error()) 70 return multistep.ActionHalt 71 } 72 73 if keypair.Privatekey == "" { 74 err := fmt.Errorf("The temporary keypair returned was blank") 75 state.Put("error", err) 76 ui.Error(err.Error()) 77 return multistep.ActionHalt 78 } 79 80 ui.Say(fmt.Sprintf("Created temporary keypair: %s", s.Comm.SSHTemporaryKeyPairName)) 81 82 // If we're in debug mode, output the private key to the working directory. 83 if s.Debug { 84 ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath)) 85 f, err := os.Create(s.DebugKeyPath) 86 if err != nil { 87 state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) 88 return multistep.ActionHalt 89 } 90 defer f.Close() 91 92 // Write the key out 93 if _, err := f.Write([]byte(keypair.Privatekey)); err != nil { 94 err := fmt.Errorf("Error saving debug key: %s", err) 95 state.Put("error", err) 96 ui.Error(err.Error()) 97 return multistep.ActionHalt 98 } 99 100 // Chmod it so that it is SSH ready 101 if runtime.GOOS != "windows" { 102 if err := f.Chmod(0600); err != nil { 103 err := fmt.Errorf("Error setting permissions of debug key: %s", err) 104 state.Put("error", err) 105 ui.Error(err.Error()) 106 return multistep.ActionHalt 107 } 108 } 109 } 110 111 // Set some data for use in future steps 112 s.Comm.SSHKeyPairName = s.Comm.SSHTemporaryKeyPairName 113 s.Comm.SSHPrivateKey = []byte(keypair.Privatekey) 114 115 return multistep.ActionContinue 116 } 117 118 func (s *stepKeypair) Cleanup(state multistep.StateBag) { 119 if s.Comm.SSHTemporaryKeyPairName == "" { 120 return 121 } 122 123 ui := state.Get("ui").(packer.Ui) 124 client := state.Get("client").(*cloudstack.CloudStackClient) 125 cfg := state.Get("config").(*Config) 126 127 p := client.SSH.NewDeleteSSHKeyPairParams(s.Comm.SSHTemporaryKeyPairName) 128 if cfg.Project != "" { 129 p.SetProjectid(cfg.Project) 130 } 131 132 ui.Say(fmt.Sprintf("Deleting temporary keypair: %s ...", s.Comm.SSHTemporaryKeyPairName)) 133 134 _, err := client.SSH.DeleteSSHKeyPair(p) 135 if err != nil { 136 ui.Error(err.Error()) 137 ui.Error(fmt.Sprintf( 138 "Error cleaning up keypair. Please delete the key manually: %s", s.Comm.SSHTemporaryKeyPairName)) 139 } 140 }