github.com/rothwerx/packer@v0.9.0/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 37 // CustomConnect can be set to have custom connectors for specific 38 // types. These take highest precedence so you can also override 39 // existing types. 40 CustomConnect map[string]multistep.Step 41 42 substep multistep.Step 43 } 44 45 func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction { 46 typeMap := map[string]multistep.Step{ 47 "none": nil, 48 "ssh": &StepConnectSSH{ 49 Config: s.Config, 50 Host: s.Host, 51 SSHConfig: s.SSHConfig, 52 SSHPort: s.SSHPort, 53 }, 54 "winrm": &StepConnectWinRM{ 55 Config: s.Config, 56 Host: s.Host, 57 WinRMConfig: s.WinRMConfig, 58 WinRMPort: s.SSHPort, 59 }, 60 } 61 for k, v := range s.CustomConnect { 62 typeMap[k] = v 63 } 64 65 step, ok := typeMap[s.Config.Type] 66 if !ok { 67 state.Put("error", fmt.Errorf("unknown communicator type: %s", s.Config.Type)) 68 return multistep.ActionHalt 69 } 70 71 if step == nil { 72 comm, err := none.New("none") 73 if err != nil { 74 err := fmt.Errorf("Failed to set communicator 'none': %s", err) 75 state.Put("error", err) 76 ui := state.Get("ui").(packer.Ui) 77 ui.Error(err.Error()) 78 return multistep.ActionHalt 79 } 80 state.Put("communicator", comm) 81 log.Printf("[INFO] communicator disabled, will not connect") 82 return multistep.ActionContinue 83 } 84 85 s.substep = step 86 return s.substep.Run(state) 87 } 88 89 func (s *StepConnect) Cleanup(state multistep.StateBag) { 90 if s.substep != nil { 91 s.substep.Cleanup(state) 92 } 93 }