From cab52872f499289d9c5883b322f9a77dbee0bb61 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Tue, 30 Jan 2018 22:00:37 -0800 Subject: [PATCH 1/2] add session level keep-alives for ssh communicator --- communicator/ssh/communicator.go | 18 ++++++++++++++++++ helper/communicator/config.go | 5 +++++ helper/communicator/step_connect_ssh.go | 1 + .../source/docs/templates/communicator.html.md | 4 ++++ 4 files changed, 28 insertions(+) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index c10e97dcc..eabf32aea 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -55,6 +55,10 @@ type Config struct { // UseSftp, if true, sftp will be used instead of scp for file transfers 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 @@ -104,6 +108,20 @@ func (c *comm) Start(cmd *packer.RemoteCmd) (err error) { 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 // exit boolean and status. go func() { diff --git a/helper/communicator/config.go b/helper/communicator/config.go index 5ecbdfc65..8fe1032cb 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -37,6 +37,7 @@ type Config struct { SSHProxyPort int `mapstructure:"ssh_proxy_port"` SSHProxyUsername string `mapstructure:"ssh_proxy_username"` SSHProxyPassword string `mapstructure:"ssh_proxy_password"` + SSHKeepAliveInterval time.Duration `mapstructure:"ssh_keep_alive_interval"` // WinRM WinRMUser string `mapstructure:"winrm_username"` @@ -131,6 +132,10 @@ func (c *Config) prepareSSH(ctx *interpolate.Context) []error { c.SSHTimeout = 5 * time.Minute } + if c.SSHKeepAliveInterval == 0 { + c.SSHKeepAliveInterval = 5 * time.Second + } + if c.SSHHandshakeAttempts == 0 { c.SSHHandshakeAttempts = 10 } diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 680b88a02..192dba739 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -182,6 +182,7 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru Pty: s.Config.SSHPty, DisableAgentForwarding: s.Config.SSHDisableAgentForwarding, UseSftp: s.Config.SSHFileTransferMethod == "sftp", + KeepAliveInterval: s.Config.SSHKeepAliveInterval, } log.Println("[INFO] Attempting SSH connection...") diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 6bb5150b9..e8a5d56fc 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -91,6 +91,10 @@ The SSH communicator has the following options: - `ssh_host` (string) - The address to SSH to. This usually is automatically configured by the builder. +* `ssh_keep_alive_interval` (string) - How often to send "keep alive" + messages to the server. Set to a negative value (`-1`) to disable. Example value: + "10s". Defaults to "5s". + - `ssh_password` (string) - A plaintext password to use to authenticate with SSH. From 55977be8f37427b4ff1fb1ab3084e601f76ead92 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Tue, 30 Jan 2018 23:26:26 -0800 Subject: [PATCH 2/2] Update communicator.html.md --- website/source/docs/templates/communicator.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index e8a5d56fc..5fbb8a3d5 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -92,7 +92,7 @@ The SSH communicator has the following options: configured by the builder. * `ssh_keep_alive_interval` (string) - How often to send "keep alive" - messages to the server. Set to a negative value (`-1`) to disable. Example value: + 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