From a1ceb5a7ef8a39d78c88783c58f330e52d2cb852 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 13 Jun 2015 18:10:37 -0400 Subject: [PATCH] common: remove StepConnectSSH --- common/step_connect_ssh.go | 171 -------------------------------- common/step_connect_ssh_test.go | 14 --- 2 files changed, 185 deletions(-) delete mode 100644 common/step_connect_ssh.go delete mode 100644 common/step_connect_ssh_test.go diff --git a/common/step_connect_ssh.go b/common/step_connect_ssh.go deleted file mode 100644 index 0c1c624bb..000000000 --- a/common/step_connect_ssh.go +++ /dev/null @@ -1,171 +0,0 @@ -package common - -import ( - "errors" - "fmt" - "log" - "strings" - "time" - - "github.com/mitchellh/multistep" - "github.com/mitchellh/packer/communicator/ssh" - "github.com/mitchellh/packer/packer" - gossh "golang.org/x/crypto/ssh" -) - -// StepConnectSSH is a multistep Step implementation that waits for SSH -// to become available. It gets the connection information from a single -// configuration when creating the step. -// -// Uses: -// ui packer.Ui -// -// Produces: -// communicator packer.Communicator -type StepConnectSSH struct { - // SSHAddress is a function that returns the TCP address to connect to - // for SSH. This is a function so that you can query information - // if necessary for this address. - SSHAddress func(multistep.StateBag) (string, error) - - // SSHConfig is a function that returns the proper client configuration - // for SSH access. - SSHConfig func(multistep.StateBag) (*gossh.ClientConfig, error) - - // SSHWaitTimeout is the total timeout to wait for SSH to become available. - SSHWaitTimeout time.Duration - - // Pty, if true, will request a Pty from the remote end. - Pty bool - - comm packer.Communicator -} - -func (s *StepConnectSSH) Run(state multistep.StateBag) multistep.StepAction { - ui := state.Get("ui").(packer.Ui) - - var comm packer.Communicator - var err error - - cancel := make(chan struct{}) - waitDone := make(chan bool, 1) - go func() { - ui.Say("Waiting for SSH to become available...") - comm, err = s.waitForSSH(state, cancel) - waitDone <- true - }() - - log.Printf("Waiting for SSH, up to timeout: %s", s.SSHWaitTimeout) - timeout := time.After(s.SSHWaitTimeout) -WaitLoop: - for { - // Wait for either SSH to become available, a timeout to occur, - // or an interrupt to come through. - select { - case <-waitDone: - if err != nil { - ui.Error(fmt.Sprintf("Error waiting for SSH: %s", err)) - state.Put("error", err) - return multistep.ActionHalt - } - - ui.Say("Connected to SSH!") - s.comm = comm - state.Put("communicator", comm) - break WaitLoop - case <-timeout: - err := fmt.Errorf("Timeout waiting for SSH.") - state.Put("error", err) - ui.Error(err.Error()) - close(cancel) - return multistep.ActionHalt - case <-time.After(1 * time.Second): - if _, ok := state.GetOk(multistep.StateCancelled); ok { - // The step sequence was cancelled, so cancel waiting for SSH - // and just start the halting process. - close(cancel) - log.Println("Interrupt detected, quitting waiting for SSH.") - return multistep.ActionHalt - } - } - } - - return multistep.ActionContinue -} - -func (s *StepConnectSSH) Cleanup(multistep.StateBag) { -} - -func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan struct{}) (packer.Communicator, error) { - handshakeAttempts := 0 - - var comm packer.Communicator - first := true - for { - // Don't check for cancel or wait on first iteration - if !first { - select { - case <-cancel: - log.Println("SSH wait cancelled. Exiting loop.") - return nil, errors.New("SSH wait cancelled") - case <-time.After(5 * time.Second): - } - } - first = false - - // First we request the TCP connection information - address, err := s.SSHAddress(state) - if err != nil { - log.Printf("Error getting SSH address: %s", err) - continue - } - - // Retrieve the SSH configuration - sshConfig, err := s.SSHConfig(state) - if err != nil { - log.Printf("Error getting SSH config: %s", err) - continue - } - - // Attempt to connect to SSH port - connFunc := ssh.ConnectFunc("tcp", address) - nc, err := connFunc() - if err != nil { - log.Printf("TCP connection to SSH ip/port failed: %s", err) - continue - } - nc.Close() - - // Then we attempt to connect via SSH - config := &ssh.Config{ - Connection: connFunc, - SSHConfig: sshConfig, - Pty: s.Pty, - } - - log.Println("Attempting SSH connection...") - comm, err = ssh.New(address, config) - if err != nil { - log.Printf("SSH handshake err: %s", err) - - // Only count this as an attempt if we were able to attempt - // to authenticate. Note this is very brittle since it depends - // on the string of the error... but I don't see any other way. - if strings.Contains(err.Error(), "authenticate") { - log.Printf("Detected authentication error. Increasing handshake attempts.") - handshakeAttempts += 1 - } - - if handshakeAttempts < 10 { - // Try to connect via SSH a handful of times - continue - } - - return nil, err - } - - break - } - - return comm, nil -} diff --git a/common/step_connect_ssh_test.go b/common/step_connect_ssh_test.go deleted file mode 100644 index 49b0e52b4..000000000 --- a/common/step_connect_ssh_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package common - -import ( - "github.com/mitchellh/multistep" - "testing" -) - -func TestStepConnectSSH_Impl(t *testing.T) { - var raw interface{} - raw = new(StepConnectSSH) - if _, ok := raw.(multistep.Step); !ok { - t.Fatalf("connect ssh should be a step") - } -}