github.com/kikitux/packer@v0.10.1-0.20160322154024-6237df566f9f/builder/openstack/step_get_password.go (about) 1 package openstack 2 3 import ( 4 "crypto/rsa" 5 "fmt" 6 "log" 7 "time" 8 9 "github.com/mitchellh/multistep" 10 "github.com/mitchellh/packer/helper/communicator" 11 "github.com/mitchellh/packer/packer" 12 "github.com/rackspace/gophercloud/openstack/compute/v2/servers" 13 "golang.org/x/crypto/ssh" 14 ) 15 16 // StepGetPassword reads the password from a booted OpenStack server and sets 17 // it on the WinRM config. 18 type StepGetPassword struct { 19 Debug bool 20 Comm *communicator.Config 21 } 22 23 func (s *StepGetPassword) Run(state multistep.StateBag) multistep.StepAction { 24 config := state.Get("config").(Config) 25 ui := state.Get("ui").(packer.Ui) 26 27 // Skip if we're not using winrm 28 if s.Comm.Type != "winrm" { 29 log.Printf("[INFO] Not using winrm communicator, skipping get password...") 30 return multistep.ActionContinue 31 } 32 33 // If we already have a password, skip it 34 if s.Comm.WinRMPassword != "" { 35 ui.Say("Skipping waiting for password since WinRM password set...") 36 return multistep.ActionContinue 37 } 38 39 // We need the v2 compute client 40 computeClient, err := config.computeV2Client() 41 if err != nil { 42 err = fmt.Errorf("Error initializing compute client: %s", err) 43 state.Put("error", err) 44 return multistep.ActionHalt 45 } 46 47 ui.Say("Waiting for password since WinRM password is not set...") 48 server := state.Get("server").(*servers.Server) 49 var password string 50 51 privateKey, err := ssh.ParseRawPrivateKey([]byte(state.Get("privateKey").(string))) 52 if err != nil { 53 err = fmt.Errorf("Error parsing private key: %s", err) 54 state.Put("error", err) 55 return multistep.ActionHalt 56 } 57 58 for ; password == "" && err == nil; password, err = servers.GetPassword(computeClient, server.ID).ExtractPassword(privateKey.(*rsa.PrivateKey)) { 59 60 // Check for an interrupt in between attempts. 61 if _, ok := state.GetOk(multistep.StateCancelled); ok { 62 return multistep.ActionHalt 63 } 64 65 log.Printf("Retrying to get a administrator password evry 5 seconds.") 66 time.Sleep(5 * time.Second) 67 } 68 69 ui.Message(fmt.Sprintf("Password retrieved!")) 70 s.Comm.WinRMPassword = password 71 72 // In debug-mode, we output the password 73 if s.Debug { 74 ui.Message(fmt.Sprintf( 75 "Password (since debug is enabled) \"%s\"", s.Comm.WinRMPassword)) 76 } 77 78 return multistep.ActionContinue 79 } 80 81 func (s *StepGetPassword) Cleanup(multistep.StateBag) {}