Merge pull request #9545 from hashicorp/fix_9528
builder/googlecompute: Make IAP tunnel timeout configurable.
This commit is contained in:
commit
48a3a859d2
|
@ -425,6 +425,9 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
c.IAPConfig.IAPExt = ".cmd"
|
c.IAPConfig.IAPExt = ".cmd"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if c.IAPConfig.IAPTunnelLaunchWait == 0 {
|
||||||
|
c.IAPConfig.IAPTunnelLaunchWait = 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 {
|
||||||
|
|
|
@ -78,6 +78,7 @@ type FlatConfig struct {
|
||||||
IAPLocalhostPort *int `mapstructure:"iap_localhost_port" cty:"iap_localhost_port" hcl:"iap_localhost_port"`
|
IAPLocalhostPort *int `mapstructure:"iap_localhost_port" cty:"iap_localhost_port" hcl:"iap_localhost_port"`
|
||||||
IAPHashBang *string `mapstructure:"iap_hashbang" required:"false" cty:"iap_hashbang" hcl:"iap_hashbang"`
|
IAPHashBang *string `mapstructure:"iap_hashbang" required:"false" cty:"iap_hashbang" hcl:"iap_hashbang"`
|
||||||
IAPExt *string `mapstructure:"iap_ext" required:"false" cty:"iap_ext" hcl:"iap_ext"`
|
IAPExt *string `mapstructure:"iap_ext" required:"false" cty:"iap_ext" hcl:"iap_ext"`
|
||||||
|
IAPTunnelLaunchWait *int `mapstructure:"iap_tunnel_launch_wait" required:"false" cty:"iap_tunnel_launch_wait" hcl:"iap_tunnel_launch_wait"`
|
||||||
ImageName *string `mapstructure:"image_name" required:"false" cty:"image_name" hcl:"image_name"`
|
ImageName *string `mapstructure:"image_name" required:"false" cty:"image_name" hcl:"image_name"`
|
||||||
ImageDescription *string `mapstructure:"image_description" required:"false" cty:"image_description" hcl:"image_description"`
|
ImageDescription *string `mapstructure:"image_description" required:"false" cty:"image_description" hcl:"image_description"`
|
||||||
ImageEncryptionKey *FlatCustomerEncryptionKey `mapstructure:"image_encryption_key" required:"false" cty:"image_encryption_key" hcl:"image_encryption_key"`
|
ImageEncryptionKey *FlatCustomerEncryptionKey `mapstructure:"image_encryption_key" required:"false" cty:"image_encryption_key" hcl:"image_encryption_key"`
|
||||||
|
@ -194,6 +195,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
"iap_localhost_port": &hcldec.AttrSpec{Name: "iap_localhost_port", Type: cty.Number, Required: false},
|
"iap_localhost_port": &hcldec.AttrSpec{Name: "iap_localhost_port", Type: cty.Number, Required: false},
|
||||||
"iap_hashbang": &hcldec.AttrSpec{Name: "iap_hashbang", Type: cty.String, Required: false},
|
"iap_hashbang": &hcldec.AttrSpec{Name: "iap_hashbang", Type: cty.String, Required: false},
|
||||||
"iap_ext": &hcldec.AttrSpec{Name: "iap_ext", Type: cty.String, Required: false},
|
"iap_ext": &hcldec.AttrSpec{Name: "iap_ext", Type: cty.String, Required: false},
|
||||||
|
"iap_tunnel_launch_wait": &hcldec.AttrSpec{Name: "iap_tunnel_launch_wait", Type: cty.Number, Required: false},
|
||||||
"image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false},
|
"image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false},
|
||||||
"image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false},
|
"image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false},
|
||||||
"image_encryption_key": &hcldec.BlockSpec{TypeName: "image_encryption_key", Nested: hcldec.ObjectSpec((*FlatCustomerEncryptionKey)(nil).HCL2Spec())},
|
"image_encryption_key": &hcldec.BlockSpec{TypeName: "image_encryption_key", Nested: hcldec.ObjectSpec((*FlatCustomerEncryptionKey)(nil).HCL2Spec())},
|
||||||
|
|
|
@ -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.
|
||||||
|
IAPTunnelLaunchWait int `mapstructure:"iap_tunnel_launch_wait" 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.IAPTunnelLaunchWait)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,10 +9,11 @@ import (
|
||||||
// FlatIAPConfig is an auto-generated flat version of IAPConfig.
|
// FlatIAPConfig is an auto-generated flat version of IAPConfig.
|
||||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||||
type FlatIAPConfig struct {
|
type FlatIAPConfig struct {
|
||||||
IAP *bool `mapstructure:"use_iap" required:"false" cty:"use_iap" hcl:"use_iap"`
|
IAP *bool `mapstructure:"use_iap" required:"false" cty:"use_iap" hcl:"use_iap"`
|
||||||
IAPLocalhostPort *int `mapstructure:"iap_localhost_port" cty:"iap_localhost_port" hcl:"iap_localhost_port"`
|
IAPLocalhostPort *int `mapstructure:"iap_localhost_port" cty:"iap_localhost_port" hcl:"iap_localhost_port"`
|
||||||
IAPHashBang *string `mapstructure:"iap_hashbang" required:"false" cty:"iap_hashbang" hcl:"iap_hashbang"`
|
IAPHashBang *string `mapstructure:"iap_hashbang" required:"false" cty:"iap_hashbang" hcl:"iap_hashbang"`
|
||||||
IAPExt *string `mapstructure:"iap_ext" required:"false" cty:"iap_ext" hcl:"iap_ext"`
|
IAPExt *string `mapstructure:"iap_ext" required:"false" cty:"iap_ext" hcl:"iap_ext"`
|
||||||
|
IAPTunnelLaunchWait *int `mapstructure:"iap_tunnel_launch_wait" required:"false" cty:"iap_tunnel_launch_wait" hcl:"iap_tunnel_launch_wait"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlatMapstructure returns a new FlatIAPConfig.
|
// FlatMapstructure returns a new FlatIAPConfig.
|
||||||
|
@ -27,10 +28,11 @@ func (*IAPConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spe
|
||||||
// The decoded values from this spec will then be applied to a FlatIAPConfig.
|
// The decoded values from this spec will then be applied to a FlatIAPConfig.
|
||||||
func (*FlatIAPConfig) HCL2Spec() map[string]hcldec.Spec {
|
func (*FlatIAPConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
s := map[string]hcldec.Spec{
|
s := map[string]hcldec.Spec{
|
||||||
"use_iap": &hcldec.AttrSpec{Name: "use_iap", Type: cty.Bool, Required: false},
|
"use_iap": &hcldec.AttrSpec{Name: "use_iap", Type: cty.Bool, Required: false},
|
||||||
"iap_localhost_port": &hcldec.AttrSpec{Name: "iap_localhost_port", Type: cty.Number, Required: false},
|
"iap_localhost_port": &hcldec.AttrSpec{Name: "iap_localhost_port", Type: cty.Number, Required: false},
|
||||||
"iap_hashbang": &hcldec.AttrSpec{Name: "iap_hashbang", Type: cty.String, Required: false},
|
"iap_hashbang": &hcldec.AttrSpec{Name: "iap_hashbang", Type: cty.String, Required: false},
|
||||||
"iap_ext": &hcldec.AttrSpec{Name: "iap_ext", Type: cty.String, Required: false},
|
"iap_ext": &hcldec.AttrSpec{Name: "iap_ext", Type: cty.String, Required: false},
|
||||||
|
"iap_tunnel_launch_wait": &hcldec.AttrSpec{Name: "iap_tunnel_launch_wait", Type: cty.Number, Required: false},
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,3 +22,6 @@
|
||||||
|
|
||||||
- `iap_ext` (string) - What file extension to use for script that sets up gcloud.
|
- `iap_ext` (string) - What file extension to use for script that sets up gcloud.
|
||||||
Default: ".sh"
|
Default: ".sh"
|
||||||
|
|
||||||
|
- `iap_tunnel_launch_wait` (int) - How long to wait, in seconds, before assuming a tunnel launch was
|
||||||
|
successful. Defaults to 30 seconds.
|
||||||
|
|
Loading…
Reference in New Issue