github.com/tappoz/packer@v1.0.0-rc1/helper/communicator/step_connect.go (about) 1 package communicator 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/mitchellh/multistep" 8 "github.com/mitchellh/packer/communicator/none" 9 "github.com/mitchellh/packer/packer" 10 gossh "golang.org/x/crypto/ssh" 11 ) 12 13 // StepConnect is a multistep Step implementation that connects to 14 // the proper communicator and stores it in the "communicator" key in the 15 // state bag. 16 type StepConnect struct { 17 // Config is the communicator config struct 18 Config *Config 19 20 // Host should return a host that can be connected to for communicator 21 // connections. 22 Host func(multistep.StateBag) (string, error) 23 24 // The fields below are callbacks to assist with connecting to SSH. 25 // 26 // SSHConfig should return the default configuration for 27 // connecting via SSH. 28 SSHConfig func(multistep.StateBag) (*gossh.ClientConfig, error) 29 SSHPort func(multistep.StateBag) (int, error) 30 31 // The fields below are callbacks to assist with connecting to WinRM. 32 // 33 // WinRMConfig should return the default configuration for 34 // connecting via WinRM. 35 WinRMConfig func(multistep.StateBag) (*WinRMConfig, error) 36 WinRMPort func(multistep.StateBag) (int, error) 37 38 // CustomConnect can be set to have custom connectors for specific 39 // types. These take highest precedence so you can also override 40 // existing types. 41 CustomConnect map[string]multistep.Step 42 43 substep multistep.Step 44 } 45 46 func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction { 47 typeMap := map[string]multistep.Step{ 48 "none": nil, 49 "ssh": &StepConnectSSH{ 50 Config: s.Config, 51 Host: s.Host, 52 SSHConfig: s.SSHConfig, 53 SSHPort: s.SSHPort, 54 }, 55 "winrm": &StepConnectWinRM{ 56 Config: s.Config, 57 Host: s.Host, 58 WinRMConfig: s.WinRMConfig, 59 WinRMPort: s.WinRMPort, 60 }, 61 } 62 for k, v := range s.CustomConnect { 63 typeMap[k] = v 64 } 65 66 step, ok := typeMap[s.Config.Type] 67 if !ok { 68 state.Put("error", fmt.Errorf("unknown communicator type: %s", s.Config.Type)) 69 return multistep.ActionHalt 70 } 71 72 if step == nil { 73 comm, err := none.New("none") 74 if err != nil { 75 err := fmt.Errorf("Failed to set communicator 'none': %s", err) 76 state.Put("error", err) 77 ui := state.Get("ui").(packer.Ui) 78 ui.Error(err.Error()) 79 return multistep.ActionHalt 80 } 81 state.Put("communicator", comm) 82 log.Printf("[INFO] communicator disabled, will not connect") 83 return multistep.ActionContinue 84 } 85 86 s.substep = step 87 return s.substep.Run(state) 88 } 89 90 func (s *StepConnect) Cleanup(state multistep.StateBag) { 91 if s.substep != nil { 92 s.substep.Cleanup(state) 93 } 94 }