make tunnel timeout configurable

This commit is contained in:
Megan Marsh 2020-07-07 15:37:45 -07:00
parent cf5537d5d2
commit af009c2aa0
5 changed files with 20 additions and 11 deletions

View File

@ -425,6 +425,9 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
c.IAPConfig.IAPExt = ".cmd" c.IAPConfig.IAPExt = ".cmd"
} }
} }
if c.IAPConfig.IAPTunnelLaunchTimeout == 0 {
c.IAPConfig.IAPTunnelLaunchTimeout = 30
}
// Configure IAP: Update SSH config to use localhost proxy instead // Configure IAP: Update SSH config to use localhost proxy instead
if c.IAPConfig.IAP { if c.IAPConfig.IAP {

View File

@ -51,14 +51,17 @@ type IAPConfig struct {
// What file extension to use for script that sets up gcloud. // What file extension to use for script that sets up gcloud.
// Default: ".sh" // Default: ".sh"
IAPExt string `mapstructure:"iap_ext" required:"false"` IAPExt string `mapstructure:"iap_ext" required:"false"`
// How long to wait, in seconds, before assuming a tunnel launch was
// successful. Defaults to 30 seconds.
IAPTunnelLaunchTimeout int `mapstructure:"iap_tunnel_launch_timeout" required:"false"`
} }
type TunnelDriver interface { type TunnelDriver interface {
StartTunnel(context.Context, string) error StartTunnel(context.Context, string, int) error
StopTunnel() StopTunnel()
} }
func RunTunnelCommand(cmd *exec.Cmd) error { func RunTunnelCommand(cmd *exec.Cmd, timeout int) error {
// set stdout and stderr so we can read what's going on. // set stdout and stderr so we can read what's going on.
var stdout, stderr bytes.Buffer var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout cmd.Stdout = &stdout
@ -78,7 +81,8 @@ func RunTunnelCommand(cmd *exec.Cmd) error {
// afternoon trying to figure out how to get the SDK to actually send // afternoon trying to figure out how to get the SDK to actually send
// the "Listening on port [n]" line I see when I run it manually, and I // the "Listening on port [n]" line I see when I run it manually, and I
// can't justify spending more time than that on aesthetics. // can't justify spending more time than that on aesthetics.
for i := 0; i < 30; i++ {
for i := 0; i < timeout; i++ {
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
lineStderr, err := stderr.ReadString('\n') lineStderr, err := stderr.ReadString('\n')
@ -307,7 +311,7 @@ func (s *StepStartTunnel) Run(ctx context.Context, state multistep.StateBag) mul
RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 30 * time.Second, Multiplier: 2}).Linear, RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 30 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error { }.Run(ctx, func(ctx context.Context) error {
// tunnel launcher/destroyer has to be different on windows vs. unix. // tunnel launcher/destroyer has to be different on windows vs. unix.
err := s.tunnelDriver.StartTunnel(ctx, tempScriptFileName) err := s.tunnelDriver.StartTunnel(ctx, tempScriptFileName, s.IAPConf.IAPTunnelLaunchTimeout)
return err return err
}) })
if err != nil { if err != nil {

View File

@ -12,16 +12,18 @@ import (
) )
type MockTunnelDriver struct { type MockTunnelDriver struct {
StopTunnelCalled bool StopTunnelCalled bool
StartTunnelCalled bool StartTunnelCalled bool
StartTunnelTimeout int
} }
func (m *MockTunnelDriver) StopTunnel() { func (m *MockTunnelDriver) StopTunnel() {
m.StopTunnelCalled = true m.StopTunnelCalled = true
} }
func (m *MockTunnelDriver) StartTunnel(context.Context, string) error { func (m *MockTunnelDriver) StartTunnel(_ context.Context, _ string, timeout int) error {
m.StartTunnelCalled = true m.StartTunnelCalled = true
m.StartTunnelTimeout = timeout
return nil return nil
} }

View File

@ -17,11 +17,11 @@ type TunnelDriverLinux struct {
cmd *exec.Cmd cmd *exec.Cmd
} }
func (t *TunnelDriverLinux) StartTunnel(cancelCtx context.Context, tempScriptFileName string) error { func (t *TunnelDriverLinux) StartTunnel(cancelCtx context.Context, tempScriptFileName string, timeout int) error {
cmd := exec.CommandContext(cancelCtx, tempScriptFileName) cmd := exec.CommandContext(cancelCtx, tempScriptFileName)
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
err := RunTunnelCommand(cmd) err := RunTunnelCommand(cmd, timeout)
if err != nil { if err != nil {
return err return err
} }

View File

@ -16,10 +16,10 @@ type TunnelDriverWindows struct {
cmd *exec.Cmd cmd *exec.Cmd
} }
func (t *TunnelDriverWindows) StartTunnel(cancelCtx context.Context, tempScriptFileName string) error { func (t *TunnelDriverWindows) StartTunnel(cancelCtx context.Context, tempScriptFileName string, timeout int) error {
args := []string{"/C", "call", tempScriptFileName} args := []string{"/C", "call", tempScriptFileName}
cmd := exec.CommandContext(cancelCtx, "cmd", args...) cmd := exec.CommandContext(cancelCtx, "cmd", args...)
err := RunTunnelCommand(cmd) err := RunTunnelCommand(cmd, timeout)
if err != nil { if err != nil {
return err return err
} }