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  }