95 lines
2.5 KiB
Go
95 lines
2.5 KiB
Go
package communicator
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/hashicorp/packer/communicator/none"
|
|
"github.com/hashicorp/packer/packer"
|
|
"github.com/mitchellh/multistep"
|
|
gossh "golang.org/x/crypto/ssh"
|
|
)
|
|
|
|
// StepConnect is a multistep Step implementation that connects to
|
|
// the proper communicator and stores it in the "communicator" key in the
|
|
// state bag.
|
|
type StepConnect struct {
|
|
// Config is the communicator config struct
|
|
Config *Config
|
|
|
|
// Host should return a host that can be connected to for communicator
|
|
// connections.
|
|
Host func(multistep.StateBag) (string, error)
|
|
|
|
// The fields below are callbacks to assist with connecting to SSH.
|
|
//
|
|
// SSHConfig should return the default configuration for
|
|
// connecting via SSH.
|
|
SSHConfig func(multistep.StateBag) (*gossh.ClientConfig, error)
|
|
SSHPort func(multistep.StateBag) (int, error)
|
|
|
|
// The fields below are callbacks to assist with connecting to WinRM.
|
|
//
|
|
// WinRMConfig should return the default configuration for
|
|
// connecting via WinRM.
|
|
WinRMConfig func(multistep.StateBag) (*WinRMConfig, error)
|
|
WinRMPort func(multistep.StateBag) (int, error)
|
|
|
|
// CustomConnect can be set to have custom connectors for specific
|
|
// types. These take highest precedence so you can also override
|
|
// existing types.
|
|
CustomConnect map[string]multistep.Step
|
|
|
|
substep multistep.Step
|
|
}
|
|
|
|
func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction {
|
|
typeMap := map[string]multistep.Step{
|
|
"none": nil,
|
|
"ssh": &StepConnectSSH{
|
|
Config: s.Config,
|
|
Host: s.Host,
|
|
SSHConfig: s.SSHConfig,
|
|
SSHPort: s.SSHPort,
|
|
},
|
|
"winrm": &StepConnectWinRM{
|
|
Config: s.Config,
|
|
Host: s.Host,
|
|
WinRMConfig: s.WinRMConfig,
|
|
WinRMPort: s.WinRMPort,
|
|
},
|
|
}
|
|
for k, v := range s.CustomConnect {
|
|
typeMap[k] = v
|
|
}
|
|
|
|
step, ok := typeMap[s.Config.Type]
|
|
if !ok {
|
|
state.Put("error", fmt.Errorf("unknown communicator type: %s", s.Config.Type))
|
|
return multistep.ActionHalt
|
|
}
|
|
|
|
if step == nil {
|
|
comm, err := none.New("none")
|
|
if err != nil {
|
|
err := fmt.Errorf("Failed to set communicator 'none': %s", err)
|
|
state.Put("error", err)
|
|
ui := state.Get("ui").(packer.Ui)
|
|
ui.Error(err.Error())
|
|
return multistep.ActionHalt
|
|
}
|
|
state.Put("communicator", comm)
|
|
log.Printf("[INFO] communicator disabled, will not connect")
|
|
return multistep.ActionContinue
|
|
}
|
|
|
|
s.substep = step
|
|
return s.substep.Run(state)
|
|
}
|
|
|
|
func (s *StepConnect) Cleanup(state multistep.StateBag) {
|
|
if s.substep != nil {
|
|
s.substep.Cleanup(state)
|
|
}
|
|
}
|