github.com/prasannakumarik25/packer@v1.3.2/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 ui := state.Get("ui").(packer.Ui) 49 50 typeMap := map[string]multistep.Step{ 51 "none": nil, 52 "ssh": &StepConnectSSH{ 53 Config: s.Config, 54 Host: s.Host, 55 SSHConfig: s.SSHConfig, 56 SSHPort: s.SSHPort, 57 }, 58 "winrm": &StepConnectWinRM{ 59 Config: s.Config, 60 Host: s.Host, 61 WinRMConfig: s.WinRMConfig, 62 WinRMPort: s.WinRMPort, 63 }, 64 } 65 for k, v := range s.CustomConnect { 66 typeMap[k] = v 67 } 68 69 step, ok := typeMap[s.Config.Type] 70 if !ok { 71 state.Put("error", fmt.Errorf("unknown communicator type: %s", s.Config.Type)) 72 return multistep.ActionHalt 73 } 74 75 if step == nil { 76 if comm, err := none.New("none"); err != nil { 77 err := fmt.Errorf("Failed to set communicator 'none': %s", err) 78 state.Put("error", err) 79 ui.Error(err.Error()) 80 return multistep.ActionHalt 81 82 } else { 83 state.Put("communicator", comm) 84 log.Printf("[INFO] communicator disabled, will not connect") 85 } 86 return multistep.ActionContinue 87 } 88 89 if host, err := s.Host(state); err == nil { 90 ui.Say(fmt.Sprintf("Using %s communicator to connect: %s", s.Config.Type, host)) 91 92 } else { 93 log.Printf("[DEBUG] Unable to get address during connection step: %s", err) 94 } 95 96 s.substep = step 97 return s.substep.Run(ctx, state) 98 } 99 100 func (s *StepConnect) Cleanup(state multistep.StateBag) { 101 if s.substep != nil { 102 s.substep.Cleanup(state) 103 } 104 }