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  }