Cleanup duplicated stuff from sdk
This commit is contained in:
parent
3cb985d134
commit
f60e1b6a7f
@ -2,14 +2,7 @@ package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer-plugin-sdk/communicator"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
@ -22,47 +15,6 @@ func SSHAddress(state multistep.StateBag) (string, error) {
|
||||
return fmt.Sprintf("%s:%d", sshIP, sshHostPort), nil
|
||||
}
|
||||
|
||||
func SSHLocalAddress(state multistep.StateBag) (string, error) {
|
||||
sshLocalPort, ok := state.Get("local_ssh_port").(uint)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("SSH port forwarding hasn't been set up yet")
|
||||
}
|
||||
conn_str := fmt.Sprintf("%s:%d", "127.0.0.1", sshLocalPort)
|
||||
return conn_str, nil
|
||||
}
|
||||
|
||||
func SSHPort(state multistep.StateBag) (int, error) {
|
||||
sshHostPort := state.Get("local_ssh_port").(uint)
|
||||
return int(sshHostPort), nil
|
||||
}
|
||||
|
||||
func CommHost(state multistep.StateBag) (string, error) {
|
||||
return "127.0.0.1", nil
|
||||
}
|
||||
|
||||
func SSHConfigFunc(commConfig communicator.Config) func(multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||
return func(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||
auth := []gossh.AuthMethod{
|
||||
gossh.Password(commConfig.SSHPassword),
|
||||
}
|
||||
|
||||
if commConfig.SSHPrivateKeyFile != "" {
|
||||
signer, err := FileSigner(commConfig.SSHPrivateKeyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
auth = append(auth, gossh.PublicKeys(signer))
|
||||
}
|
||||
|
||||
return &gossh.ClientConfig{
|
||||
User: commConfig.SSHUsername,
|
||||
Auth: auth,
|
||||
HostKeyCallback: gossh.InsecureIgnoreHostKey(),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func doExecuteSSHCmd(cmd, target string, config *gossh.ClientConfig) (stdout string, err error) {
|
||||
client, err := gossh.Dial("tcp", target, config)
|
||||
if err != nil {
|
||||
@ -99,119 +51,3 @@ func ExecuteHostSSHCmd(state multistep.StateBag, cmd string) (stdout string, err
|
||||
}
|
||||
return doExecuteSSHCmd(cmd, sshAddress, sshConfig)
|
||||
}
|
||||
|
||||
func ExecuteGuestSSHCmd(state multistep.StateBag, cmd string) (stdout string, err error) {
|
||||
config := state.Get("commonconfig").(CommonConfig)
|
||||
localAddress, err := SSHLocalAddress(state)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sshConfig, err := SSHConfigFunc(config.Comm)(state)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return doExecuteSSHCmd(cmd, localAddress, sshConfig)
|
||||
}
|
||||
|
||||
func forward(local_conn net.Conn, config *gossh.ClientConfig, server, remote_dest string, remote_port uint) error {
|
||||
defer local_conn.Close()
|
||||
|
||||
ssh_client_conn, err := gossh.Dial("tcp", server+":22", config)
|
||||
if err != nil {
|
||||
log.Printf("local ssh.Dial error: %s", err)
|
||||
return err
|
||||
}
|
||||
defer ssh_client_conn.Close()
|
||||
|
||||
remote_loc := fmt.Sprintf("%s:%d", remote_dest, remote_port)
|
||||
ssh_conn, err := ssh_client_conn.Dial("tcp", remote_loc)
|
||||
if err != nil {
|
||||
log.Printf("ssh.Dial error: %s", err)
|
||||
return err
|
||||
}
|
||||
defer ssh_conn.Close()
|
||||
|
||||
txDone := make(chan struct{})
|
||||
rxDone := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
_, err = io.Copy(ssh_conn, local_conn)
|
||||
if err != nil {
|
||||
log.Printf("io.copy failed: %v", err)
|
||||
}
|
||||
close(txDone)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
_, err = io.Copy(local_conn, ssh_conn)
|
||||
if err != nil {
|
||||
log.Printf("io.copy failed: %v", err)
|
||||
}
|
||||
close(rxDone)
|
||||
}()
|
||||
|
||||
<-txDone
|
||||
<-rxDone
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest, host, username, password string) error {
|
||||
|
||||
config := &gossh.ClientConfig{
|
||||
User: username,
|
||||
Auth: []gossh.AuthMethod{
|
||||
gossh.Password(password),
|
||||
},
|
||||
HostKeyCallback: gossh.InsecureIgnoreHostKey(),
|
||||
}
|
||||
|
||||
for {
|
||||
local_connection, err := local_listener.Accept()
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Local accept failed: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Forward to a remote port
|
||||
go forward(local_connection, config, host, remote_dest, uint(remote_port))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FileSigner returns an gossh.Signer for a key file.
|
||||
func FileSigner(path string) (gossh.Signer, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
keyBytes, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We parse the private key on our own first so that we can
|
||||
// show a nicer error if the private key has a password.
|
||||
block, _ := pem.Decode(keyBytes)
|
||||
if block == nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Failed to read key '%s': no key found", path)
|
||||
}
|
||||
if block.Headers["Proc-Type"] == "4,ENCRYPTED" {
|
||||
return nil, fmt.Errorf(
|
||||
"Failed to read key '%s': password protected keys are\n"+
|
||||
"not supported. Please decrypt the key prior to use.", path)
|
||||
}
|
||||
|
||||
signer, err := gossh.ParsePrivateKey(keyBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
||||
}
|
||||
|
||||
return signer, nil
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
"github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
type StepForwardPortOverSSH struct {
|
||||
RemotePort func(state multistep.StateBag) (int, error)
|
||||
RemoteDest func(state multistep.StateBag) (string, error)
|
||||
|
||||
HostPortMin int
|
||||
HostPortMax int
|
||||
|
||||
ResultKey string
|
||||
}
|
||||
|
||||
func (self *StepForwardPortOverSSH) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
config := state.Get("commonconfig").(CommonConfig)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
// Find a free local port:
|
||||
|
||||
l, sshHostPort := FindPort(self.HostPortMin, self.HostPortMax)
|
||||
|
||||
if l == nil || sshHostPort == 0 {
|
||||
ui.Error("Error: unable to find free host port. Try providing a larger range [host_port_min, host_port_max]")
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Creating a local port forward over SSH on local port %d", sshHostPort))
|
||||
|
||||
hostAddress, _ := state.Get("ssh_address").(string)
|
||||
remotePort, _ := self.RemotePort(state)
|
||||
remoteDest, _ := self.RemoteDest(state)
|
||||
|
||||
go ssh_port_forward(l, remotePort, remoteDest, hostAddress, config.Username, config.Password)
|
||||
ui.Say(fmt.Sprintf("Port forward setup. %d ---> %s:%d on %s", sshHostPort, remoteDest, remotePort, hostAddress))
|
||||
|
||||
// Provide the local port to future steps.
|
||||
state.Put(self.ResultKey, sshHostPort)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (self *StepForwardPortOverSSH) Cleanup(state multistep.StateBag) {}
|
@ -3,6 +3,7 @@ package common
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
@ -29,11 +30,13 @@ func (StepShutdown) Run(ctx context.Context, state multistep.StateBag) multistep
|
||||
// Shutdown the VM
|
||||
success := func() bool {
|
||||
if config.ShutdownCommand != "" {
|
||||
ui.Message("Executing shutdown command...")
|
||||
comm := state.Get("communicator").(packer.Communicator)
|
||||
ui.Say("Gracefully halting virtual machine...")
|
||||
log.Printf("Executing shutdown command: %s", config.ShutdownCommand)
|
||||
|
||||
_, err := ExecuteGuestSSHCmd(state, config.ShutdownCommand)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Shutdown command failed: %s", err.Error()))
|
||||
cmd := &packer.RemoteCmd{Command: config.ShutdownCommand}
|
||||
if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
|
||||
ui.Error(fmt.Sprintf("Failed to send shutdown command: %s", err.Error()))
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -267,13 +267,6 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
Chan: httpReqChan,
|
||||
Timeout: self.config.InstallTimeout, // @todo change this
|
||||
},
|
||||
&xscommon.StepForwardPortOverSSH{
|
||||
RemotePort: xscommon.InstanceSSHPort,
|
||||
RemoteDest: xscommon.InstanceSSHIP,
|
||||
HostPortMin: self.config.HostPortMin,
|
||||
HostPortMax: self.config.HostPortMax,
|
||||
ResultKey: "local_ssh_port",
|
||||
},
|
||||
&communicator.StepConnect{
|
||||
Config: &self.config.Comm,
|
||||
Host: xscommon.InstanceSSHIP,
|
||||
|
@ -156,9 +156,9 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
},
|
||||
&communicator.StepConnect{
|
||||
Config: &self.config.Comm,
|
||||
Host: xscommon.CommHost,
|
||||
SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.Comm),
|
||||
SSHPort: xscommon.SSHPort,
|
||||
Host: xscommon.InstanceSSHIP,
|
||||
SSHConfig: self.config.Comm.SSHConfigFunc(),
|
||||
SSHPort: xscommon.InstanceSSHPort,
|
||||
},
|
||||
new(commonsteps.StepProvision),
|
||||
new(xscommon.StepShutdown),
|
||||
|
Loading…
Reference in New Issue
Block a user