Merge pull request #5830 from hashicorp/sshkeepalive

add session level keep-alives for ssh communicator
This commit is contained in:
Matthew Hooker 2018-01-31 12:23:02 -08:00 committed by GitHub
commit b9c0d3ab56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 0 deletions

View File

@ -55,6 +55,10 @@ type Config struct {
// UseSftp, if true, sftp will be used instead of scp for file transfers // UseSftp, if true, sftp will be used instead of scp for file transfers
UseSftp bool UseSftp bool
// KeepAliveInterval sets how often we send a channel request to the
// server. A value < 0 disables.
KeepAliveInterval time.Duration
} }
// Creates a new packer.Communicator implementation over SSH. This takes // Creates a new packer.Communicator implementation over SSH. This takes
@ -104,6 +108,20 @@ func (c *comm) Start(cmd *packer.RemoteCmd) (err error) {
return return
} }
go func() {
if c.config.KeepAliveInterval < 0 {
return
}
c := time.NewTicker(c.config.KeepAliveInterval)
defer c.Stop()
for range c.C {
_, err := session.SendRequest("keepalive@packer.io", true, nil)
if err != nil {
return
}
}
}()
// Start a goroutine to wait for the session to end and set the // Start a goroutine to wait for the session to end and set the
// exit boolean and status. // exit boolean and status.
go func() { go func() {

View File

@ -37,6 +37,7 @@ type Config struct {
SSHProxyPort int `mapstructure:"ssh_proxy_port"` SSHProxyPort int `mapstructure:"ssh_proxy_port"`
SSHProxyUsername string `mapstructure:"ssh_proxy_username"` SSHProxyUsername string `mapstructure:"ssh_proxy_username"`
SSHProxyPassword string `mapstructure:"ssh_proxy_password"` SSHProxyPassword string `mapstructure:"ssh_proxy_password"`
SSHKeepAliveInterval time.Duration `mapstructure:"ssh_keep_alive_interval"`
// WinRM // WinRM
WinRMUser string `mapstructure:"winrm_username"` WinRMUser string `mapstructure:"winrm_username"`
@ -131,6 +132,10 @@ func (c *Config) prepareSSH(ctx *interpolate.Context) []error {
c.SSHTimeout = 5 * time.Minute c.SSHTimeout = 5 * time.Minute
} }
if c.SSHKeepAliveInterval == 0 {
c.SSHKeepAliveInterval = 5 * time.Second
}
if c.SSHHandshakeAttempts == 0 { if c.SSHHandshakeAttempts == 0 {
c.SSHHandshakeAttempts = 10 c.SSHHandshakeAttempts = 10
} }

View File

@ -182,6 +182,7 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru
Pty: s.Config.SSHPty, Pty: s.Config.SSHPty,
DisableAgentForwarding: s.Config.SSHDisableAgentForwarding, DisableAgentForwarding: s.Config.SSHDisableAgentForwarding,
UseSftp: s.Config.SSHFileTransferMethod == "sftp", UseSftp: s.Config.SSHFileTransferMethod == "sftp",
KeepAliveInterval: s.Config.SSHKeepAliveInterval,
} }
log.Println("[INFO] Attempting SSH connection...") log.Println("[INFO] Attempting SSH connection...")

View File

@ -91,6 +91,10 @@ The SSH communicator has the following options:
- `ssh_host` (string) - The address to SSH to. This usually is automatically - `ssh_host` (string) - The address to SSH to. This usually is automatically
configured by the builder. configured by the builder.
* `ssh_keep_alive_interval` (string) - How often to send "keep alive"
messages to the server. Set to a negative value (`-1s`) to disable. Example value:
"10s". Defaults to "5s".
- `ssh_password` (string) - A plaintext password to use to authenticate - `ssh_password` (string) - A plaintext password to use to authenticate
with SSH. with SSH.