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