Fix shutdown_command bug

Fixes the somewhat embarrassing bug where the shutdown_command would be
run on the host rather than the guest.

This commit also rejigs things so that it is easier to do SSH commands
on either the host or the guest
This commit is contained in:
Cheng Sun 2015-01-02 16:22:36 +00:00
parent d2b7f3a7d8
commit 16f8c25d84
5 changed files with 35 additions and 21 deletions

View File

@ -20,9 +20,11 @@ func SSHAddress(state multistep.StateBag) (string, error) {
}
func SSHLocalAddress(state multistep.StateBag) (string, error) {
sshLocalPort := state.Get("local_ssh_port").(uint)
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)
log.Printf("sshLocalAddress: %s", conn_str)
return conn_str, nil
}
@ -49,24 +51,14 @@ func SSHConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {
}, nil
}
func execute_ssh_cmd(cmd, host, port, username, password string) (stdout string, err error) {
// Setup connection config
config := &gossh.ClientConfig{
User: username,
Auth: []gossh.AuthMethod{
gossh.Password(password),
},
}
client, err := gossh.Dial("tcp", host+":"+port, config)
func doExecuteSSHCmd(cmd, target string, config *gossh.ClientConfig) (stdout string, err error) {
client, err := gossh.Dial("tcp", target, config)
if err != nil {
return "", err
}
//Create session
session, err := client.NewSession()
if err != nil {
return "", err
}
@ -82,6 +74,31 @@ func execute_ssh_cmd(cmd, host, port, username, password string) (stdout string,
return strings.Trim(b.String(), "\n"), nil
}
func ExecuteHostSSHCmd(state multistep.StateBag, cmd string) (stdout string, err error) {
config := state.Get("commonconfig").(CommonConfig)
// Setup connection config
sshConfig := &gossh.ClientConfig{
User: config.Username,
Auth: []gossh.AuthMethod{
gossh.Password(config.Password),
},
}
return doExecuteSSHCmd(cmd, config.HostIp+":22", sshConfig)
}
func ExecuteGuestSSHCmd(state multistep.StateBag, cmd string) (stdout string, err error) {
localAddress, err := SSHLocalAddress(state)
if err != nil {
return
}
sshConfig, err := SSHConfig(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()

View File

@ -10,8 +10,6 @@ import (
type StepGetVNCPort struct{}
func (self *StepGetVNCPort) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("commonconfig").(CommonConfig)
ui := state.Get("ui").(packer.Ui)
ui.Say("Step: forward the instances VNC port over SSH")
@ -19,7 +17,7 @@ func (self *StepGetVNCPort) Run(state multistep.StateBag) multistep.StepAction {
domid := state.Get("domid").(string)
cmd := fmt.Sprintf("xenstore-read /local/domain/%s/console/vnc-port", domid)
remote_vncport, err := execute_ssh_cmd(cmd, config.HostIp, "22", config.Username, config.Password)
remote_vncport, err := ExecuteHostSSHCmd(state, cmd)
if err != nil {
ui.Error(fmt.Sprintf("Unable to get VNC port (is the VM running?): %s", err.Error()))
return multistep.ActionHalt

View File

@ -63,7 +63,7 @@ func (StepShutdownAndExport) Run(state multistep.StateBag) multistep.StepAction
if config.ShutdownCommand != "" {
ui.Say("Executing shutdown command...")
_, err := execute_ssh_cmd(config.ShutdownCommand, config.HostIp, "22", config.Username, config.Password)
_, err := ExecuteGuestSSHCmd(state, config.ShutdownCommand)
if err != nil {
ui.Error(fmt.Sprintf("Shutdown command failed: %s", err.Error()))
return false

View File

@ -23,7 +23,6 @@ func (self *StepStartOnHIMN) Run(state multistep.StateBag) multistep.StepAction
ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(XenAPIClient)
config := state.Get("commonconfig").(CommonConfig)
ui.Say("Step: Start VM on the Host Internal Mangement Network")
@ -96,7 +95,7 @@ func (self *StepStartOnHIMN) Run(state multistep.StateBag) multistep.StepAction
err = InterruptibleWait{
Predicate: func() (success bool, err error) {
ui.Message(fmt.Sprintf("Attempting to ping interface: %s", ping_cmd))
_, err = execute_ssh_cmd(ping_cmd, config.HostIp, "22", config.Username, config.Password)
_, err = ExecuteHostSSHCmd(state, ping_cmd)
switch err.(type) {
case nil:

View File

@ -61,7 +61,7 @@ func (self *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAct
log.Printf("Connected to the VNC console: %s", c.DesktopName)
// find local ip
envVar, err := execute_ssh_cmd("echo $SSH_CLIENT", config.HostIp, "22", config.Username, config.Password)
envVar, err := ExecuteHostSSHCmd(state, "echo $SSH_CLIENT")
if err != nil {
ui.Error(fmt.Sprintf("Error detecting local IP: %s", err))
return multistep.ActionHalt