Merge pull request #4034 from mitchellh/sshdisconnect
handle case when remote ssh server disconnects
This commit is contained in:
commit
1a87d49abf
|
@ -118,15 +118,13 @@ func (c *comm) Start(cmd *packer.RemoteCmd) (err error) {
|
|||
log.Printf("Remote command exited with '%d': %s", exitStatus, cmd.Command)
|
||||
case *ssh.ExitMissingError:
|
||||
log.Printf("Remote command exited without exit status or exit signal.")
|
||||
exitStatus = -1
|
||||
exitStatus = packer.CmdDisconnect
|
||||
default:
|
||||
log.Printf("Error occurred waiting for ssh session: %s", err.Error())
|
||||
exitStatus = -1
|
||||
}
|
||||
}
|
||||
cmd.SetExited(exitStatus)
|
||||
}()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,10 @@ import (
|
|||
"github.com/mitchellh/iochan"
|
||||
)
|
||||
|
||||
// CmdDisconnect is a sentry value to indicate a RemoteCmd
|
||||
// exited because the remote side disconnected us.
|
||||
const CmdDisconnect int = 2300218
|
||||
|
||||
// RemoteCmd represents a remote command being prepared or run.
|
||||
type RemoteCmd struct {
|
||||
// Command is the command to run remotely. This is executed as if
|
||||
|
|
|
@ -70,6 +70,8 @@ type Config struct {
|
|||
// Whether to clean scripts up
|
||||
SkipClean bool `mapstructure:"skip_clean"`
|
||||
|
||||
ExpectDisconnect *bool `mapstructure:"expect_disconnect"`
|
||||
|
||||
startRetryTimeout time.Duration
|
||||
ctx interpolate.Context
|
||||
}
|
||||
|
@ -101,6 +103,11 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
p.config.ExecuteCommand = "chmod +x {{.Path}}; {{.Vars}} {{.Path}}"
|
||||
}
|
||||
|
||||
if p.config.ExpectDisconnect == nil {
|
||||
t := true
|
||||
p.config.ExpectDisconnect = &t
|
||||
}
|
||||
|
||||
if p.config.Inline != nil && len(p.config.Inline) == 0 {
|
||||
p.config.Inline = nil
|
||||
}
|
||||
|
@ -283,11 +290,18 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
|||
cmd = &packer.RemoteCmd{Command: command}
|
||||
return cmd.StartWithUi(comm, ui)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.ExitStatus != 0 {
|
||||
// If the exit code indicates a remote disconnect, fail unless
|
||||
// we were expecting it.
|
||||
if cmd.ExitStatus == packer.CmdDisconnect {
|
||||
if !*p.config.ExpectDisconnect {
|
||||
return fmt.Errorf("Script disconnected unexpectedly.")
|
||||
}
|
||||
} else if cmd.ExitStatus != 0 {
|
||||
return fmt.Errorf("Script exited with non-zero exit status: %d", cmd.ExitStatus)
|
||||
}
|
||||
|
||||
|
|
|
@ -32,11 +32,42 @@ func TestProvisionerPrepare_Defaults(t *testing.T) {
|
|||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if *p.config.ExpectDisconnect != true {
|
||||
t.Errorf("expected ExpectDisconnect to be true")
|
||||
}
|
||||
|
||||
if p.config.RemotePath == "" {
|
||||
t.Errorf("unexpected remote path: %s", p.config.RemotePath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvisionerPrepare_ExpectDisconnect(t *testing.T) {
|
||||
config := testConfig()
|
||||
p := new(Provisioner)
|
||||
config["expect_disconnect"] = false
|
||||
|
||||
err := p.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if *p.config.ExpectDisconnect != false {
|
||||
t.Errorf("expected ExpectDisconnect to be false")
|
||||
}
|
||||
|
||||
config["expect_disconnect"] = true
|
||||
p = new(Provisioner)
|
||||
err = p.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if *p.config.ExpectDisconnect != true {
|
||||
t.Errorf("expected ExpectDisconnect to be true")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestProvisionerPrepare_InlineShebang(t *testing.T) {
|
||||
config := testConfig()
|
||||
|
||||
|
|
|
@ -71,6 +71,10 @@ Optional parameters:
|
|||
available variables: `Path`, which is the path to the script to run, and
|
||||
`Vars`, which is the list of `environment_vars`, if configured.
|
||||
|
||||
- `expect_disconnect` (bool) - Defaults to true. Whether to error if the
|
||||
server disconnects us. A disconnect might happen if you restart the ssh
|
||||
server or reboot the host. May default to false in the future.
|
||||
|
||||
- `inline_shebang` (string) - The
|
||||
[shebang](https://en.wikipedia.org/wiki/Shebang_%28Unix%29) value to use when
|
||||
running commands specified by `inline`. By default, this is `/bin/sh -e`. If
|
||||
|
|
Loading…
Reference in New Issue