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) { 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) conn_str := fmt.Sprintf("%s:%d", "127.0.0.1", sshLocalPort)
log.Printf("sshLocalAddress: %s", conn_str)
return conn_str, nil return conn_str, nil
} }
@ -49,24 +51,14 @@ func SSHConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {
}, nil }, nil
} }
func execute_ssh_cmd(cmd, host, port, username, password string) (stdout string, err error) { func doExecuteSSHCmd(cmd, target string, config *gossh.ClientConfig) (stdout string, err error) {
// Setup connection config client, err := gossh.Dial("tcp", target, config)
config := &gossh.ClientConfig{
User: username,
Auth: []gossh.AuthMethod{
gossh.Password(password),
},
}
client, err := gossh.Dial("tcp", host+":"+port, config)
if err != nil { if err != nil {
return "", err return "", err
} }
//Create session //Create session
session, err := client.NewSession() session, err := client.NewSession()
if err != nil { if err != nil {
return "", err 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 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 { func forward(local_conn net.Conn, config *gossh.ClientConfig, server, remote_dest string, remote_port uint) error {
defer local_conn.Close() defer local_conn.Close()

View File

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

View File

@ -63,7 +63,7 @@ func (StepShutdownAndExport) Run(state multistep.StateBag) multistep.StepAction
if config.ShutdownCommand != "" { if config.ShutdownCommand != "" {
ui.Say("Executing shutdown command...") 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 { if err != nil {
ui.Error(fmt.Sprintf("Shutdown command failed: %s", err.Error())) ui.Error(fmt.Sprintf("Shutdown command failed: %s", err.Error()))
return false return false

View File

@ -23,7 +23,6 @@ func (self *StepStartOnHIMN) Run(state multistep.StateBag) multistep.StepAction
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(XenAPIClient) client := state.Get("client").(XenAPIClient)
config := state.Get("commonconfig").(CommonConfig)
ui.Say("Step: Start VM on the Host Internal Mangement Network") 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{ err = InterruptibleWait{
Predicate: func() (success bool, err error) { Predicate: func() (success bool, err error) {
ui.Message(fmt.Sprintf("Attempting to ping interface: %s", ping_cmd)) 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) { switch err.(type) {
case nil: 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) log.Printf("Connected to the VNC console: %s", c.DesktopName)
// find local ip // 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 { if err != nil {
ui.Error(fmt.Sprintf("Error detecting local IP: %s", err)) ui.Error(fmt.Sprintf("Error detecting local IP: %s", err))
return multistep.ActionHalt return multistep.ActionHalt