Change back to make sure all durations are a time.Duration

It is simply the best/simplest solution and trying to prevent users from passing and integer here would be like opening a can of worms. Because:

* we cannot make mapstructure validate our duration string ( with an UnmarshalJSON func etc.)
* we cannot make mapstructure spit a string instead of a duration and packer will decode-encode-decode config.
* the hcl2 generated code asks for a string, so this will be enforced by default.
This commit is contained in:
Adrien Delorme 2019-10-31 15:49:34 +01:00
parent bf3d9841c6
commit 819329228a
105 changed files with 315 additions and 493 deletions

View File

@ -9,10 +9,10 @@ import (
"os"
"regexp"
"strings"
"time"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
@ -371,7 +371,7 @@ type RunConfig struct {
// The timeout for waiting for a Windows
// password for Windows instances. Defaults to 20 minutes. Example value:
// 10m
WindowsPasswordTimeout config.DurationString `mapstructure:"windows_password_timeout" required:"false"`
WindowsPasswordTimeout time.Duration `mapstructure:"windows_password_timeout" required:"false"`
// Communicator settings
Comm communicator.Config `mapstructure:",squash"`
@ -389,8 +389,8 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
c.Comm.SSHTemporaryKeyPairName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID())
}
if c.WindowsPasswordTimeout == "" {
c.WindowsPasswordTimeout = "20m"
if c.WindowsPasswordTimeout == 0 {
c.WindowsPasswordTimeout = 20 * time.Minute
}
if c.RunTags == nil {

View File

@ -229,7 +229,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&awscommon.StepGetPassword{
Debug: b.config.PackerDebug,
Comm: &b.config.RunConfig.Comm,
Timeout: b.config.WindowsPasswordTimeout.Duration(),
Timeout: b.config.WindowsPasswordTimeout,
BuildName: b.config.PackerBuildName,
},
&communicator.StepConnect{

View File

@ -271,7 +271,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&awscommon.StepGetPassword{
Debug: b.config.PackerDebug,
Comm: &b.config.RunConfig.Comm,
Timeout: b.config.WindowsPasswordTimeout.Duration(),
Timeout: b.config.WindowsPasswordTimeout,
BuildName: b.config.PackerBuildName,
},
&communicator.StepConnect{

View File

@ -237,7 +237,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&awscommon.StepGetPassword{
Debug: b.config.PackerDebug,
Comm: &b.config.RunConfig.Comm,
Timeout: b.config.WindowsPasswordTimeout.Duration(),
Timeout: b.config.WindowsPasswordTimeout,
BuildName: b.config.PackerBuildName,
},
&communicator.StepConnect{

View File

@ -322,7 +322,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&awscommon.StepGetPassword{
Debug: b.config.PackerDebug,
Comm: &b.config.RunConfig.Comm,
Timeout: b.config.WindowsPasswordTimeout.Duration(),
Timeout: b.config.WindowsPasswordTimeout,
BuildName: b.config.PackerBuildName,
},
&communicator.StepConnect{

View File

@ -80,8 +80,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
b.config.ResourceGroupName,
b.config.StorageAccount,
b.config.ClientConfig.CloudEnvironment(),
b.config.SharedGalleryTimeout.Duration(),
b.config.PollingDurationTimeout.Duration(),
b.config.SharedGalleryTimeout,
b.config.PollingDurationTimeout,
spnCloud,
spnKeyVault)

View File

@ -139,7 +139,7 @@ type Config struct {
// Azure dashboard, then you probably need to increase this timeout from
// its default of "60m" (valid time units include `s` for seconds, `m` for
// minutes, and `h` for hours.)
SharedGalleryTimeout config.DurationString `mapstructure:"shared_image_gallery_timeout"`
SharedGalleryTimeout time.Duration `mapstructure:"shared_image_gallery_timeout"`
// PublisherName for your base image. See
// [documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/)
// for details.
@ -320,7 +320,7 @@ type Config struct {
// context deadline exceeded`, then you probably need to increase this timeout from
// its default of "15m" (valid time units include `s` for seconds, `m` for
// minutes, and `h` for hours.)
PollingDurationTimeout config.DurationString `mapstructure:"polling_duration_timeout" required:"false"`
PollingDurationTimeout time.Duration `mapstructure:"polling_duration_timeout" required:"false"`
// If either Linux or Windows is specified Packer will
// automatically configure authentication credentials for the provisioned
// machine. For Linux this configures an SSH authorized key. For Windows
@ -550,8 +550,8 @@ func newConfig(raws ...interface{}) (*Config, []string, error) {
}
func setSshValues(c *Config) error {
if c.Comm.SSHTimeout == "" {
c.Comm.SSHTimeout = "20m"
if c.Comm.SSHTimeout == 0 {
c.Comm.SSHTimeout = 20 * time.Minute
}
if c.Comm.SSHPrivateKeyFile != "" {
@ -867,9 +867,9 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("A list of replication_regions must be specified for shared_image_gallery_destination"))
}
}
if c.SharedGalleryTimeout == "" {
if c.SharedGalleryTimeout == 0 {
// default to a one-hour timeout. In the sdk, the default is 15 m.
c.SharedGalleryTimeout = "60m"
c.SharedGalleryTimeout = 60 * time.Minute
}
if c.ManagedImageOSDiskSnapshotName != "" {
@ -920,9 +920,9 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) {
/////////////////////////////////////////////
// Polling Duration Timeout
if c.PollingDurationTimeout == "" {
if c.PollingDurationTimeout == 0 {
// In the sdk, the default is 15 m.
c.PollingDurationTimeout = "15m"
c.PollingDurationTimeout = 15 * time.Minute
}
/////////////////////////////////////////////

View File

@ -539,11 +539,11 @@ func TestConfigShouldSupportPackersConfigElements(t *testing.T) {
t.Fatal(err)
}
if c.Comm.SSHTimeout.Duration() != 1*time.Hour {
if c.Comm.SSHTimeout != 1*time.Hour {
t.Errorf("Expected Comm.SSHTimeout to be a duration of an hour, but got '%s' instead.", c.Comm.SSHTimeout)
}
if c.Comm.WinRMTimeout.Duration() != 2*time.Hour {
if c.Comm.WinRMTimeout != 2*time.Hour {
t.Errorf("Expected Comm.WinRMTimeout to be a durationof two hours, but got '%s' instead.", c.Comm.WinRMTimeout)
}
}

View File

@ -44,7 +44,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
)
// Set the time to wait before timing out
client.AsyncTimeout(int64(b.config.AsyncTimeout.Duration().Seconds()))
client.AsyncTimeout(int64(b.config.AsyncTimeout.Seconds()))
// Some CloudStack service providers only allow HTTP GET calls.
client.HTTPGETOnly = b.config.HTTPGetOnly

View File

@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"os"
"time"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/uuid"
@ -34,7 +35,7 @@ type Config struct {
SecretKey string `mapstructure:"secret_key" required:"true"`
// The time duration to wait for async calls to
// finish. Defaults to 30m.
AsyncTimeout config.DurationString `mapstructure:"async_timeout" required:"false"`
AsyncTimeout time.Duration `mapstructure:"async_timeout" required:"false"`
// Some cloud providers only allow HTTP GET calls
// to their CloudStack API. If using such a provider, you need to set this to
// true in order for the provider to only make GET calls and no POST calls.
@ -67,7 +68,7 @@ type Config struct {
// Configure the duration time to wait, making sure virtual machine is able
// to finish installing OS before it ejects safely. Requires `eject_iso`
// set to `true` and this option is only available when using `source_iso`.
EjectISODelay config.DurationString `mapstructure:"eject_iso_delay"`
EjectISODelay time.Duration `mapstructure:"eject_iso_delay"`
// Set to true to expunge the instance when it is
// destroyed. Defaults to false.
Expunge bool `mapstructure:"expunge" required:"false"`
@ -199,8 +200,8 @@ func NewConfig(raws ...interface{}) (*Config, error) {
c.SecretKey = os.Getenv("CLOUDSTACK_SECRET_KEY")
}
if c.AsyncTimeout == "" {
c.AsyncTimeout = "30m"
if c.AsyncTimeout == 0 {
c.AsyncTimeout = 30 * time.Minute
}
if len(c.CIDRList) == 0 {

View File

@ -25,9 +25,9 @@ func (s *stepDetachIso) Run(ctx context.Context, state multistep.StateBag) multi
ui.Say("Checking attached iso...")
// Wait to make call detachIso
if config.EjectISODelay.Duration() > 0 {
if config.EjectISODelay > 0 {
ui.Message(fmt.Sprintf("Waiting for %v before detaching ISO from virtual machine...", config.EjectISODelay))
time.Sleep(config.EjectISODelay.Duration())
time.Sleep(config.EjectISODelay)
}
client := state.Get("client").(*cloudstack.CloudStackClient)

View File

@ -96,7 +96,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
new(stepShutdown),
new(stepPowerOff),
&stepSnapshot{
snapshotTimeout: b.config.SnapshotTimeout.Duration(),
snapshotTimeout: b.config.SnapshotTimeout,
},
}

View File

@ -165,7 +165,7 @@ func TestBuilderPrepare_StateTimeout(t *testing.T) {
t.Fatalf("should not have error: %s", err)
}
if b.config.StateTimeout.Duration() != 6*time.Minute {
if b.config.StateTimeout != 6*time.Minute {
t.Errorf("invalid: %s", b.config.StateTimeout)
}
@ -205,7 +205,7 @@ func TestBuilderPrepare_SnapshotTimeout(t *testing.T) {
t.Fatalf("should not have error: %s", err)
}
if b.config.SnapshotTimeout.Duration() != 60*time.Minute {
if b.config.SnapshotTimeout != 60*time.Minute {
t.Errorf("invalid: %s", b.config.SnapshotTimeout)
}

View File

@ -8,6 +8,7 @@ import (
"fmt"
"os"
"regexp"
"time"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/uuid"
@ -63,7 +64,7 @@ type Config struct {
// The time to wait, as a duration string, for a
// droplet to enter a desired state (such as "active") before timing out. The
// default state timeout is "6m".
StateTimeout config.DurationString `mapstructure:"state_timeout" required:"false"`
StateTimeout time.Duration `mapstructure:"state_timeout" required:"false"`
// How long to wait for an image to be published to the shared image
// gallery before timing out. If your Packer build is failing on the
// Publishing to Shared Image Gallery step with the error `Original Error:
@ -71,7 +72,7 @@ type Config struct {
// Azure dashboard, then you probably need to increase this timeout from
// its default of "60m" (valid time units include `s` for seconds, `m` for
// minutes, and `h` for hours.)
SnapshotTimeout config.DurationString `mapstructure:"snapshot_timeout" required:"false"`
SnapshotTimeout time.Duration `mapstructure:"snapshot_timeout" required:"false"`
// The name assigned to the droplet. DigitalOcean
// sets the hostname of the machine to this value.
DropletName string `mapstructure:"droplet_name" required:"false"`
@ -129,27 +130,19 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
c.DropletName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())
}
if c.StateTimeout == "" {
if c.StateTimeout == 0 {
// Default to 6 minute timeouts waiting for
// desired state. i.e waiting for droplet to become active
c.StateTimeout = "6m"
c.StateTimeout = 6 * time.Minute
}
if c.SnapshotTimeout == "" {
if c.SnapshotTimeout == 0 {
// Default to 60 minutes timeout, waiting for snapshot action to finish
c.SnapshotTimeout = "60m"
c.SnapshotTimeout = 60 * time.Minute
}
var errs *packer.MultiError
if err := c.StateTimeout.Validate(); err != nil {
errs = packer.MultiErrorAppend(errs, err)
}
if err := c.SnapshotTimeout.Validate(); err != nil {
errs = packer.MultiErrorAppend(errs, err)
}
if es := c.Comm.Prepare(&c.ctx); len(es) > 0 {
errs = packer.MultiErrorAppend(errs, es...)
}

View File

@ -19,7 +19,7 @@ func (s *stepDropletInfo) Run(ctx context.Context, state multistep.StateBag) mul
ui.Say("Waiting for droplet to become active...")
err := waitForDropletState("active", dropletID, client, c.StateTimeout.Duration())
err := waitForDropletState("active", dropletID, client, c.StateTimeout)
if err != nil {
err := fmt.Errorf("Error waiting for droplet to become active: %s", err)
state.Put("error", err)

View File

@ -42,7 +42,7 @@ func (s *stepPowerOff) Run(ctx context.Context, state multistep.StateBag) multis
}
log.Println("Waiting for poweroff event to complete...")
err = waitForDropletState("off", dropletId, client, c.StateTimeout.Duration())
err = waitForDropletState("off", dropletId, client, c.StateTimeout)
if err != nil {
state.Put("error", err)
ui.Error(err.Error())
@ -50,7 +50,7 @@ func (s *stepPowerOff) Run(ctx context.Context, state multistep.StateBag) multis
}
// Wait for the droplet to become unlocked for future steps
if err := waitForDropletUnlocked(client, dropletId, c.StateTimeout.Duration()); err != nil {
if err := waitForDropletUnlocked(client, dropletId, c.StateTimeout); err != nil {
// If we get an error the first time, actually report it
err := fmt.Errorf("Error powering off droplet: %s", err)
state.Put("error", err)

View File

@ -65,7 +65,7 @@ func (s *stepShutdown) Run(ctx context.Context, state multistep.StateBag) multis
}
}()
err = waitForDropletState("off", dropletId, client, c.StateTimeout.Duration())
err = waitForDropletState("off", dropletId, client, c.StateTimeout)
if err != nil {
// If we get an error the first time, actually report it
err := fmt.Errorf("Error shutting down droplet: %s", err)
@ -74,7 +74,7 @@ func (s *stepShutdown) Run(ctx context.Context, state multistep.StateBag) multis
return multistep.ActionHalt
}
if err := waitForDropletUnlocked(client, dropletId, c.StateTimeout.Duration()); err != nil {
if err := waitForDropletUnlocked(client, dropletId, c.StateTimeout); err != nil {
// If we get an error the first time, actually report it
err := fmt.Errorf("Error shutting down droplet: %s", err)
state.Put("error", err)

View File

@ -8,6 +8,7 @@ import (
"fmt"
"os"
"regexp"
"time"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/uuid"
@ -120,7 +121,7 @@ type Config struct {
// If true, launch a preemptible instance.
Preemptible bool `mapstructure:"preemptible" required:"false"`
// The time to wait for instance state changes. Defaults to "5m".
StateTimeout config.DurationString `mapstructure:"state_timeout" required:"false"`
StateTimeout time.Duration `mapstructure:"state_timeout" required:"false"`
// The region in which to launch the instance. Defaults to the region
// hosting the specified zone.
Region string `mapstructure:"region" required:"false"`
@ -291,12 +292,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
c.MachineType = "n1-standard-1"
}
if c.StateTimeout == "" {
c.StateTimeout = "5m"
}
if err := c.StateTimeout.Validate(); err != nil {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed parsing state_timeout: %s", err))
if c.StateTimeout == 0 {
c.StateTimeout = 5 * time.Minute
}
if es := c.Comm.Prepare(&c.ctx); len(es) > 0 {

View File

@ -44,7 +44,7 @@ func (s *StepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
var err error
select {
case err = <-errCh:
case <-time.After(config.StateTimeout.Duration()):
case <-time.After(config.StateTimeout):
err = errors.New("time out while waiting for image to register")
}

View File

@ -154,7 +154,7 @@ func (s *StepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
ui.Message("Waiting for creation operation to complete...")
select {
case err = <-errCh:
case <-time.After(c.StateTimeout.Duration()):
case <-time.After(c.StateTimeout):
err = errors.New("time out while waiting for instance to create")
}
}
@ -200,7 +200,7 @@ func (s *StepCreateInstance) Cleanup(state multistep.StateBag) {
if err == nil {
select {
case err = <-errCh:
case <-time.After(config.StateTimeout.Duration()):
case <-time.After(config.StateTimeout):
err = errors.New("time out while waiting for instance to delete")
}
}
@ -222,7 +222,7 @@ func (s *StepCreateInstance) Cleanup(state multistep.StateBag) {
if err == nil {
select {
case err = <-errCh:
case <-time.After(config.StateTimeout.Duration()):
case <-time.After(config.StateTimeout):
err = errors.New("time out while waiting for disk to delete")
}
}

View File

@ -5,6 +5,7 @@ import (
"errors"
"strings"
"testing"
"time"
"github.com/hashicorp/packer/helper/multistep"
"github.com/stretchr/testify/assert"
@ -231,7 +232,7 @@ func TestStepCreateInstance_errorTimeout(t *testing.T) {
errCh := make(chan error, 1)
config := state.Get("config").(*Config)
config.StateTimeout = "1ms"
config.StateTimeout = 1 * time.Millisecond
d := state.Get("driver").(*DriverMock)
d.RunInstanceErrCh = errCh

View File

@ -99,7 +99,7 @@ func (s *StepCreateWindowsPassword) Run(ctx context.Context, state multistep.Sta
ui.Message("Waiting for windows password to complete...")
select {
case err = <-errCh:
case <-time.After(c.StateTimeout.Duration()):
case <-time.After(c.StateTimeout):
err = errors.New("time out while waiting for the password to be created")
}
}

View File

@ -29,7 +29,7 @@ func (s *StepInstanceInfo) Run(ctx context.Context, state multistep.StateBag) mu
var err error
select {
case err = <-errCh:
case <-time.After(config.StateTimeout.Duration()):
case <-time.After(config.StateTimeout):
err = errors.New("time out while waiting for instance to become running")
}

View File

@ -156,7 +156,7 @@ func TestStepInstanceInfo_errorTimeout(t *testing.T) {
state.Put("instance_name", "foo")
config := state.Get("config").(*Config)
config.StateTimeout = "1ms"
config.StateTimeout = 1 * time.Millisecond
driver := state.Get("driver").(*DriverMock)
driver.WaitForInstanceErrCh = errCh

View File

@ -34,7 +34,7 @@ func (s *StepTeardownInstance) Run(ctx context.Context, state multistep.StateBag
if err == nil {
select {
case err = <-errCh:
case <-time.After(config.StateTimeout.Duration()):
case <-time.After(config.StateTimeout):
err = errors.New("time out while waiting for instance to delete")
}
}
@ -64,7 +64,7 @@ func (s *StepTeardownInstance) Cleanup(state multistep.StateBag) {
if err == nil {
select {
case err = <-errCh:
case <-time.After(config.StateTimeout.Duration()):
case <-time.After(config.StateTimeout):
err = errors.New("time out while waiting for disk to delete")
}
}

View File

@ -35,7 +35,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
opts := []hcloud.ClientOption{
hcloud.WithToken(b.config.HCloudToken),
hcloud.WithEndpoint(b.config.Endpoint),
hcloud.WithPollInterval(b.config.PollInterval.Duration()),
hcloud.WithPollInterval(b.config.PollInterval),
hcloud.WithApplication("hcloud-packer", pluginVersion),
}
b.hcloudClient = hcloud.NewClient(opts...)

View File

@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"os"
"time"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/uuid"
@ -25,7 +26,7 @@ type Config struct {
HCloudToken string `mapstructure:"token"`
Endpoint string `mapstructure:"endpoint"`
PollInterval config.DurationString `mapstructure:"poll_interval"`
PollInterval time.Duration `mapstructure:"poll_interval"`
ServerName string `mapstructure:"server_name"`
Location string `mapstructure:"location"`
@ -78,8 +79,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
c.Endpoint = hcloud.Endpoint
}
}
if c.PollInterval == "" {
c.PollInterval = "500ms"
if c.PollInterval == 0 {
c.PollInterval = 500 * time.Millisecond
}
if c.SnapshotName == "" {

View File

@ -38,7 +38,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
cfg.BasePath = b.config.APIURL
}
prefer := fmt.Sprintf("respond-async,wait=%d", int(b.config.StateTimeout.Duration().Seconds()))
prefer := fmt.Sprintf("respond-async,wait=%d", int(b.config.StateTimeout.Seconds()))
cfg.AddDefaultHeader("Prefer", prefer)
b.client = openapi.NewAPIClient(cfg)

View File

@ -8,6 +8,7 @@ import (
"fmt"
"io/ioutil"
"os"
"time"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/json"
@ -27,7 +28,7 @@ const (
defaultDiskType = "ssd"
defaultImageService = "564639bc052c084e2f2e3266"
defaultStateTimeout = "5m"
defaultStateTimeout = 5 * time.Minute
defaultUserName = "guru"
)
@ -50,7 +51,7 @@ type Config struct {
TokenLogin string `mapstructure:"token_login" required:"false"`
// Timeout for waiting on the API to complete
// a request. Defaults to 5m.
StateTimeout config.DurationString `mapstructure:"state_timeout" required:"false"`
StateTimeout time.Duration `mapstructure:"state_timeout" required:"false"`
// ID or name of the image to launch server from.
SourceImage string `mapstructure:"source_image" required:"true"`
// The name of the resulting image. Defaults to
@ -145,8 +146,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
c.Comm.SSHUsername = defaultUserName
}
if c.Comm.SSHTimeout == "" {
c.Comm.SSHTimeout = "10m"
if c.Comm.SSHTimeout == 0 {
c.Comm.SSHTimeout = 10 * time.Minute
}
if c.APIURL == "" {
@ -173,7 +174,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
c.Project = cliConfig.Profile.Project.ID
}
if c.StateTimeout == "" {
if c.StateTimeout == 0 {
c.StateTimeout = defaultStateTimeout
}

View File

@ -270,10 +270,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&hypervcommon.StepTypeBootCommand{
BootCommand: b.config.FlatBootCommand(),
BootWait: b.config.BootWait.Duration(),
BootWait: b.config.BootWait,
SwitchName: b.config.SwitchName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval.Duration(),
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
// configure the communicator ssh, winrm
@ -293,7 +293,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&hypervcommon.StepShutdown{
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout.Duration(),
Timeout: b.config.ShutdownTimeout,
},
// wait for the vm to be powered off

View File

@ -318,10 +318,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&hypervcommon.StepTypeBootCommand{
BootCommand: b.config.FlatBootCommand(),
BootWait: b.config.BootWait.Duration(),
BootWait: b.config.BootWait,
SwitchName: b.config.SwitchName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval.Duration(),
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
// configure the communicator ssh, winrm
@ -341,7 +341,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&hypervcommon.StepShutdown{
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout.Duration(),
Timeout: b.config.ShutdownTimeout,
},
// wait for the vm to be powered off

View File

@ -36,10 +36,9 @@ type Config struct {
ImageLabel string `mapstructure:"image_label"`
Description string `mapstructure:"image_description"`
RawStateTimeout string `mapstructure:"state_timeout"`
StateTimeout time.Duration `mapstructure:"state_timeout"`
stateTimeout time.Duration
interCtx interpolate.Context
interCtx interpolate.Context
}
func createRandomRootPassword() (string, error) {
@ -101,14 +100,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
}
}
if c.RawStateTimeout == "" {
c.stateTimeout = 5 * time.Minute
} else {
if stateTimeout, err := time.ParseDuration(c.RawStateTimeout); err == nil {
c.stateTimeout = stateTimeout
} else {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Unable to parse state timeout: %s", err))
}
if c.StateTimeout == 0 {
c.StateTimeout = 5 * time.Minute
}
if es := c.Comm.Prepare(&c.ctx); len(es) > 0 {

View File

@ -67,7 +67,6 @@ type FlatConfig struct {
RootSSHKey *string `mapstructure:"root_ssh_key" cty:"root_ssh_key"`
ImageLabel *string `mapstructure:"image_label" cty:"image_label"`
Description *string `mapstructure:"image_description" cty:"image_description"`
RawStateTimeout *string `mapstructure:"state_timeout" cty:"state_timeout"`
}
// FlatMapstructure returns a new FlatConfig.
@ -137,7 +136,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"root_ssh_key": &hcldec.AttrSpec{Name: "root_ssh_key", Type: cty.String, Required: false},
"image_label": &hcldec.AttrSpec{Name: "image_label", Type: cty.String, Required: false},
"image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false},
"state_timeout": &hcldec.AttrSpec{Name: "state_timeout", Type: cty.String, Required: false},
}
return s
}

View File

@ -31,7 +31,8 @@ type Config struct {
CommandWrapper string `mapstructure:"command_wrapper" required:"false"`
// The timeout in seconds to wait for the the
// container to start. Defaults to 20 seconds.
RawInitTimeout string `mapstructure:"init_timeout" required:"false"`
InitTimeout time.Duration `mapstructure:"init_timeout" required:"false"`
// Options to pass to lxc-create. For
// instance, you can specify a custom LXC container configuration file with
// ["-f", "/path/to/lxc.conf"]. Defaults to []. See man 1 lxc-create for
@ -62,7 +63,6 @@ type Config struct {
// container to reach. Note some distributions (Ubuntu) simulate run levels
// and may report 5 rather than 3.
TargetRunlevel int `mapstructure:"target_runlevel" required:"false"`
InitTimeout time.Duration
ctx interpolate.Context
}
@ -98,13 +98,8 @@ func NewConfig(raws ...interface{}) (*Config, error) {
c.CommandWrapper = "{{.Command}}"
}
if c.RawInitTimeout == "" {
c.RawInitTimeout = "20s"
}
c.InitTimeout, err = time.ParseDuration(c.RawInitTimeout)
if err != nil {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed parsing init_timeout: %s", err))
if c.InitTimeout == 0 {
c.InitTimeout = 20 * time.Second
}
if _, err := os.Stat(c.ConfigFile); os.IsNotExist(err) {

View File

@ -9,6 +9,7 @@ import (
"net/url"
"os"
"regexp"
"time"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/communicator"
@ -31,12 +32,12 @@ type Config struct {
apiEndpointURL *url.URL
// Image
ImageName string `mapstructure:"image_name"`
Shape string `mapstructure:"shape"`
SourceImageList string `mapstructure:"source_image_list"`
SourceImageListEntry int `mapstructure:"source_image_list_entry"`
SnapshotTimeout config.DurationString `mapstructure:"snapshot_timeout"`
DestImageList string `mapstructure:"dest_image_list"`
ImageName string `mapstructure:"image_name"`
Shape string `mapstructure:"shape"`
SourceImageList string `mapstructure:"source_image_list"`
SourceImageListEntry int `mapstructure:"source_image_list_entry"`
SnapshotTimeout time.Duration `mapstructure:"snapshot_timeout"`
DestImageList string `mapstructure:"dest_image_list"`
// Attributes and Attributes file are both optional and mutually exclusive.
Attributes string `mapstructure:"attributes"`
AttributesFile string `mapstructure:"attributes_file"`
@ -77,8 +78,8 @@ func NewConfig(raws ...interface{}) (*Config, error) {
c.SSHSourceList = "seciplist:/oracle/public/public-internet"
}
if c.SnapshotTimeout == "" {
c.SnapshotTimeout = "20m"
if c.SnapshotTimeout == 0 {
c.SnapshotTimeout = 20 * time.Minute
}
// Validate that all required fields are present

View File

@ -28,7 +28,7 @@ func (s *stepSnapshot) Run(ctx context.Context, state multistep.StateBag) multis
snapshotInput := &compute.CreateSnapshotInput{
Instance: fmt.Sprintf("%s/%s", config.ImageName, instanceID),
MachineImage: config.ImageName,
Timeout: config.SnapshotTimeout.Duration(),
Timeout: config.SnapshotTimeout,
}
snap, err := snapshotClient.CreateSnapshot(snapshotInput)

View File

@ -1,8 +1,9 @@
package common
import (
"time"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
@ -12,13 +13,13 @@ type SSHConfig struct {
// These are deprecated, but we keep them around for BC
// TODO(@mitchellh): remove
SSHWaitTimeout config.DurationString `mapstructure:"ssh_wait_timeout"`
SSHWaitTimeout time.Duration `mapstructure:"ssh_wait_timeout"`
}
// Prepare sets the default values for SSH communicator properties.
func (c *SSHConfig) Prepare(ctx *interpolate.Context) []error {
// TODO: backwards compatibility, write fixer instead
if c.SSHWaitTimeout != "" {
if c.SSHWaitTimeout != 0 {
c.Comm.SSHTimeout = c.SSHWaitTimeout
}

View File

@ -224,12 +224,12 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&parallelscommon.StepRun{},
&parallelscommon.StepTypeBootCommand{
BootWait: b.config.BootWait.Duration(),
BootWait: b.config.BootWait,
BootCommand: b.config.FlatBootCommand(),
HostInterfaces: b.config.HostInterfaces,
VMName: b.config.VMName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval.Duration(),
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
@ -251,7 +251,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&parallelscommon.StepShutdown{
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout.Duration(),
Timeout: b.config.ShutdownTimeout,
},
&parallelscommon.StepPrlctl{
Commands: b.config.PrlctlPost,

View File

@ -78,11 +78,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&parallelscommon.StepRun{},
&parallelscommon.StepTypeBootCommand{
BootCommand: b.config.FlatBootCommand(),
BootWait: b.config.BootWait.Duration(),
BootWait: b.config.BootWait,
HostInterfaces: []string{},
VMName: b.config.VMName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval.Duration(),
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
@ -101,7 +101,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
new(common.StepProvision),
&parallelscommon.StepShutdown{
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout.Duration(),
Timeout: b.config.ShutdownTimeout,
},
&common.StepCleanupTempKeys{
Comm: &b.config.SSHConfig.Comm,

View File

@ -24,8 +24,7 @@ type Config struct {
common.PackerConfig `mapstructure:",squash"`
common.HTTPConfig `mapstructure:",squash"`
bootcommand.BootConfig `mapstructure:",squash"`
RawBootKeyInterval string `mapstructure:"boot_key_interval"`
BootKeyInterval time.Duration ``
BootKeyInterval time.Duration `mapstructure:"boot_key_interval"`
Comm communicator.Config `mapstructure:",squash"`
ProxmoxURLRaw string `mapstructure:"proxmox_url"`
@ -104,18 +103,16 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
if c.Password == "" {
c.Password = os.Getenv("PROXMOX_PASSWORD")
}
if c.RawBootKeyInterval == "" {
c.RawBootKeyInterval = os.Getenv(common.PackerKeyEnv)
}
if c.RawBootKeyInterval == "" {
c.BootKeyInterval = 5 * time.Millisecond
} else {
if interval, err := time.ParseDuration(c.RawBootKeyInterval); err == nil {
c.BootKeyInterval = interval
} else {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Could not parse boot_key_interval: %v", err))
if c.BootKeyInterval == 0 && os.Getenv(common.PackerKeyEnv) != "" {
var err error
c.BootKeyInterval, err = time.ParseDuration(os.Getenv(common.PackerKeyEnv))
if err != nil {
errs = packer.MultiErrorAppend(errs, err)
}
}
if c.BootKeyInterval == 0 {
c.BootKeyInterval = 5 * time.Millisecond
}
if c.VMName == "" {
// Default to packer-[time-ordered-uuid]

View File

@ -22,7 +22,7 @@ type FlatConfig struct {
BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval"`
BootWait *string `mapstructure:"boot_wait" cty:"boot_wait"`
BootCommand []string `mapstructure:"boot_command" cty:"boot_command"`
RawBootKeyInterval *string `mapstructure:"boot_key_interval" cty:"boot_key_interval"`
BootKeyInterval *string `mapstructure:"boot_key_interval" cty:"boot_key_interval"`
Type *string `mapstructure:"communicator" cty:"communicator"`
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`

View File

@ -46,10 +46,10 @@ func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag)
return multistep.ActionContinue
}
if int64(s.BootWait.Duration()) > 0 {
if int64(s.BootWait) > 0 {
ui.Say(fmt.Sprintf("Waiting %s for boot", s.BootWait))
select {
case <-time.After(s.BootWait.Duration()):
case <-time.After(s.BootWait):
break
case <-ctx.Done():
return multistep.ActionHalt

View File

@ -12,6 +12,7 @@ import (
"os/exec"
"path/filepath"
"runtime"
"time"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/bootcommand"
@ -319,7 +320,7 @@ type Config struct {
// These are deprecated, but we keep them around for BC
// TODO(@mitchellh): remove
SSHWaitTimeout config.DurationString `mapstructure:"ssh_wait_timeout" required:"false"`
SSHWaitTimeout time.Duration `mapstructure:"ssh_wait_timeout" required:"false"`
// TODO(mitchellh): deprecate
RunOnce bool `mapstructure:"run_once"`
@ -445,7 +446,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
}
// TODO: backwards compatibility, write fixer instead
if b.config.SSHWaitTimeout != "" {
if b.config.SSHWaitTimeout != 0 {
b.config.Comm.SSHTimeout = b.config.SSHWaitTimeout
}
@ -462,10 +463,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
errs = packer.MultiErrorAppend(errs, es...)
}
if err := b.config.SSHWaitTimeout.Validate(); err != nil {
errs = packer.MultiErrorAppend(errs, err)
}
if !(b.config.Format == "qcow2" || b.config.Format == "raw") {
errs = packer.MultiErrorAppend(
errs, errors.New("invalid format, only 'qcow2' or 'raw' are allowed"))

View File

@ -33,7 +33,7 @@ func (s *stepShutdown) Run(ctx context.Context, state multistep.StateBag) multis
cancelCh := make(chan struct{}, 1)
go func() {
defer close(cancelCh)
<-time.After(config.ShutdownTimeout.Duration())
<-time.After(config.ShutdownTimeout)
}()
ui.Say("Waiting for shutdown...")
if ok := driver.WaitForShutdown(cancelCh); ok {
@ -63,7 +63,7 @@ func (s *stepShutdown) Run(ctx context.Context, state multistep.StateBag) multis
cancelCh := make(chan struct{}, 1)
go func() {
defer close(cancelCh)
<-time.After(config.ShutdownTimeout.Duration())
<-time.After(config.ShutdownTimeout)
}()
log.Printf("Waiting max %s for shutdown to complete", config.ShutdownTimeout)

View File

@ -50,10 +50,10 @@ func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag)
}
// Wait the for the vm to boot.
if int64(config.BootWait.Duration()) > 0 {
if int64(config.BootWait) > 0 {
ui.Say(fmt.Sprintf("Waiting %s for boot...", config.BootWait))
select {
case <-time.After(config.BootWait.Duration()):
case <-time.After(config.BootWait):
break
case <-ctx.Done():
return multistep.ActionHalt
@ -105,7 +105,7 @@ func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag)
config.VMName,
}
d := bootcommand.NewVNCDriver(c, config.VNCConfig.BootKeyInterval.Duration())
d := bootcommand.NewVNCDriver(c, config.VNCConfig.BootKeyInterval)
ui.Say("Typing the boot command over VNC...")
command, err := interpolate.Render(config.VNCConfig.FlatBootCommand(), &configCtx)

View File

@ -10,6 +10,7 @@ import (
"os"
"path/filepath"
"strings"
"time"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/bootcommand"
@ -154,8 +155,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b.config.OutputDir = fmt.Sprintf("output-%s", b.config.PackerBuildName)
}
if b.config.Comm.SSHTimeout == "" {
b.config.Comm.SSHTimeout = "10m"
if b.config.Comm.SSHTimeout == 0 {
b.config.Comm.SSHTimeout = 10 * time.Minute
}
if b.config.Comm.Type != "ssh" {

View File

@ -3,9 +3,8 @@
package common
import (
"fmt"
"time"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
@ -22,31 +21,18 @@ type ShutdownConfig struct {
// shutdown_command for the virtual machine to actually shut down. If it
// doesn't shut down in this time, it is an error. By default, the timeout is
// 5m or five minutes.
ShutdownTimeout config.DurationString `mapstructure:"shutdown_timeout" required:"false"`
ShutdownTimeout time.Duration `mapstructure:"shutdown_timeout" required:"false"`
// The amount of time to wait after shutting
// down the virtual machine. If you get the error
// Error removing floppy controller, you might need to set this to 5m
// or so. By default, the delay is 0s or disabled.
PostShutdownDelay config.DurationString `mapstructure:"post_shutdown_delay" required:"false"`
PostShutdownDelay time.Duration `mapstructure:"post_shutdown_delay" required:"false"`
}
func (c *ShutdownConfig) Prepare(ctx *interpolate.Context) []error {
if c.ShutdownTimeout == "" {
c.ShutdownTimeout = "5m"
if c.ShutdownTimeout == 0 {
c.ShutdownTimeout = 5 * time.Minute
}
if c.PostShutdownDelay == "" {
c.PostShutdownDelay = "0s"
}
var errs []error
if err := c.ShutdownTimeout.Validate(); err != nil {
errs = append(errs, fmt.Errorf("Failed parsing shutdown_timeout: %s", err))
}
if err := c.PostShutdownDelay.Validate(); err != nil {
errs = append(errs, fmt.Errorf("Failed parsing post_shutdown_delay: %s", err))
}
return errs
return nil
}

View File

@ -26,22 +26,14 @@ func TestShutdownConfigPrepare_ShutdownTimeout(t *testing.T) {
var c *ShutdownConfig
var errs []error
// Test with a bad value
c = testShutdownConfig()
c.ShutdownTimeout = "this is not good"
errs = c.Prepare(interpolate.NewContext())
if len(errs) == 0 {
t.Fatalf("should have error")
}
// Test with a good one
c = testShutdownConfig()
c.ShutdownTimeout = "5s"
c.ShutdownTimeout = 5 * time.Second
errs = c.Prepare(interpolate.NewContext())
if len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if c.ShutdownTimeout.Duration() != 5*time.Second {
if c.ShutdownTimeout != 5*time.Second {
t.Fatalf("bad: %s", c.ShutdownTimeout)
}
}
@ -50,33 +42,25 @@ func TestShutdownConfigPrepare_PostShutdownDelay(t *testing.T) {
var c *ShutdownConfig
var errs []error
// Test with a bad value
c = testShutdownConfig()
c.PostShutdownDelay = "this is not good"
errs = c.Prepare(interpolate.NewContext())
if len(errs) == 0 {
t.Fatalf("should have error")
}
// Test with default value
c = testShutdownConfig()
c.PostShutdownDelay = ""
c.PostShutdownDelay = 0
errs = c.Prepare(interpolate.NewContext())
if len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if c.PostShutdownDelay.Duration().Nanoseconds() != 0 {
if c.PostShutdownDelay.Nanoseconds() != 0 {
t.Fatalf("bad: %s", c.PostShutdownDelay)
}
// Test with a good one
c = testShutdownConfig()
c.PostShutdownDelay = "5s"
c.PostShutdownDelay = 5 * time.Millisecond
errs = c.Prepare(interpolate.NewContext())
if len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if c.PostShutdownDelay.Duration() != 5*time.Second {
if c.PostShutdownDelay != 5*time.Millisecond {
t.Fatalf("bad: %s", c.PostShutdownDelay)
}
}

View File

@ -4,9 +4,9 @@ package common
import (
"errors"
"time"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
@ -26,7 +26,7 @@ type SSHConfig struct {
// These are deprecated, but we keep them around for BC
// TODO(@mitchellh): remove
SSHWaitTimeout config.DurationString `mapstructure:"ssh_wait_timeout"`
SSHWaitTimeout time.Duration `mapstructure:"ssh_wait_timeout"`
}
func (c *SSHConfig) Prepare(ctx *interpolate.Context) []error {
@ -43,7 +43,7 @@ func (c *SSHConfig) Prepare(ctx *interpolate.Context) []error {
}
// TODO: backwards compatibility, write fixer instead
if c.SSHWaitTimeout != "" {
if c.SSHWaitTimeout != 0 {
c.Comm.SSHTimeout = c.SSHWaitTimeout
}

View File

@ -319,11 +319,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Headless: b.config.Headless,
},
&vboxcommon.StepTypeBootCommand{
BootWait: b.config.BootWait.Duration(),
BootWait: b.config.BootWait,
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval.Duration(),
GroupInterval: b.config.BootConfig.BootGroupInterval,
Comm: &b.config.Comm,
},
&communicator.StepConnect{
@ -347,8 +347,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&vboxcommon.StepShutdown{
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout.Duration(),
Delay: b.config.PostShutdownDelay.Duration(),
Timeout: b.config.ShutdownTimeout,
Delay: b.config.PostShutdownDelay,
},
&vboxcommon.StepRemoveDevices{
Bundling: b.config.VBoxBundleConfig,

View File

@ -112,11 +112,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Headless: b.config.Headless,
},
&vboxcommon.StepTypeBootCommand{
BootWait: b.config.BootWait.Duration(),
BootWait: b.config.BootWait,
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval.Duration(),
GroupInterval: b.config.BootConfig.BootGroupInterval,
Comm: &b.config.Comm,
},
&communicator.StepConnect{
@ -140,8 +140,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&vboxcommon.StepShutdown{
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout.Duration(),
Delay: b.config.PostShutdownDelay.Duration(),
Timeout: b.config.ShutdownTimeout,
Delay: b.config.PostShutdownDelay,
},
&vboxcommon.StepRemoveDevices{
GuestAdditionsInterface: b.config.GuestAdditionsInterface,

View File

@ -96,11 +96,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Headless: b.config.Headless,
},
&vboxcommon.StepTypeBootCommand{
BootWait: b.config.BootWait.Duration(),
BootWait: b.config.BootWait,
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval.Duration(),
GroupInterval: b.config.BootConfig.BootGroupInterval,
Comm: &b.config.Comm,
},
&communicator.StepConnect{
@ -124,8 +124,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&vboxcommon.StepShutdown{
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout.Duration(),
Delay: b.config.PostShutdownDelay.Duration(),
Timeout: b.config.ShutdownTimeout,
Delay: b.config.PostShutdownDelay,
},
&vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManagePost,

View File

@ -6,6 +6,7 @@ import (
"fmt"
"log"
"strings"
"time"
vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common"
"github.com/hashicorp/packer/common"
@ -71,8 +72,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
c.GuestAdditionsPath = "VBoxGuestAdditions.iso"
}
if c.PostShutdownDelay == "" {
c.PostShutdownDelay = "2s"
if c.PostShutdownDelay == 0 {
c.PostShutdownDelay = 2 * time.Second
}
// Prepare the errors

View File

@ -3,8 +3,9 @@
package common
import (
"time"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
@ -16,12 +17,12 @@ type SSHConfig struct {
SSHSkipRequestPty bool `mapstructure:"ssh_skip_request_pty"`
// These are deprecated, but we keep them around for BC
// TODO(@mitchellh): remove
SSHWaitTimeout config.DurationString `mapstructure:"ssh_wait_timeout"`
SSHWaitTimeout time.Duration `mapstructure:"ssh_wait_timeout"`
}
func (c *SSHConfig) Prepare(ctx *interpolate.Context) []error {
// TODO: backwards compatibility, write fixer instead
if c.SSHWaitTimeout != "" {
if c.SSHWaitTimeout != 0 {
c.Comm.SSHTimeout = c.SSHWaitTimeout
}
if c.SSHSkipRequestPty {

View File

@ -131,12 +131,12 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Headless: b.config.Headless,
},
&vmwcommon.StepTypeBootCommand{
BootWait: b.config.BootWait.Duration(),
BootWait: b.config.BootWait,
VNCEnabled: !b.config.DisableVNC,
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
KeyInterval: b.config.VNCConfig.BootKeyInterval.Duration(),
KeyInterval: b.config.VNCConfig.BootKeyInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
@ -155,7 +155,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&vmwcommon.StepShutdown{
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout.Duration(),
Timeout: b.config.ShutdownTimeout,
},
&vmwcommon.StepCleanFiles{},
&vmwcommon.StepCompactDisk{

View File

@ -128,12 +128,12 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Headless: b.config.Headless,
},
&vmwcommon.StepTypeBootCommand{
BootWait: b.config.BootWait.Duration(),
BootWait: b.config.BootWait,
VNCEnabled: !b.config.DisableVNC,
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
KeyInterval: b.config.VNCConfig.BootKeyInterval.Duration(),
KeyInterval: b.config.VNCConfig.BootKeyInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
@ -152,7 +152,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&vmwcommon.StepShutdown{
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout.Duration(),
Timeout: b.config.ShutdownTimeout,
},
&vmwcommon.StepCleanFiles{},
&vmwcommon.StepCompactDisk{

View File

@ -8,6 +8,7 @@ import (
"fmt"
"os"
"regexp"
"time"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/uuid"
@ -118,7 +119,7 @@ type Config struct {
ctx interpolate.Context
// The time to wait for instance state changes.
// Defaults to `5m`.
StateTimeout config.DurationString `mapstructure:"state_timeout" required:"false"`
StateTimeout time.Duration `mapstructure:"state_timeout" required:"false"`
}
func NewConfig(raws ...interface{}) (*Config, []string, error) {
@ -279,12 +280,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
}
}
if c.StateTimeout == "" {
c.StateTimeout = "5m"
}
if err := c.StateTimeout.Validate(); err != nil {
errs = packer.MultiErrorAppend(errs, err)
if c.StateTimeout == 0 {
c.StateTimeout = 5 * time.Minute
}
// Check for any errors.

View File

@ -22,7 +22,7 @@ func (stepCreateImage) Run(ctx context.Context, state multistep.StateBag) multis
diskID := state.Get("disk_id").(string)
ui.Say(fmt.Sprintf("Creating image: %v", c.ImageName))
ctx, cancel := context.WithTimeout(ctx, c.StateTimeout.Duration())
ctx, cancel := context.WithTimeout(ctx, c.StateTimeout)
defer cancel()
op, err := sdk.WrapOperation(sdk.Compute().Image().Create(ctx, &compute.CreateImageRequest{

View File

@ -112,7 +112,7 @@ func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
config := state.Get("config").(*Config)
driver := state.Get("driver").(Driver)
ctx, cancel := context.WithTimeout(ctx, config.StateTimeout.Duration())
ctx, cancel := context.WithTimeout(ctx, config.StateTimeout)
defer cancel()
sourceImage, err := getImage(ctx, config, driver)
@ -263,7 +263,7 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
ctx, cancel := context.WithTimeout(context.Background(), config.StateTimeout.Duration())
ctx, cancel := context.WithTimeout(context.Background(), config.StateTimeout)
defer cancel()
if s.SerialLogFile != "" {

View File

@ -22,7 +22,7 @@ func (s *stepInstanceInfo) Run(ctx context.Context, state multistep.StateBag) mu
ui.Say(fmt.Sprintf("Waiting for instance with id %s to become active...", instanceID))
ctx, cancel := context.WithTimeout(ctx, c.StateTimeout.Duration())
ctx, cancel := context.WithTimeout(ctx, c.StateTimeout)
defer cancel()
instance, err := sdk.Compute().Instance().Get(ctx, &compute.GetInstanceRequest{

View File

@ -21,7 +21,7 @@ func (s *stepTeardownInstance) Run(ctx context.Context, state multistep.StateBag
instanceID := state.Get("instance_id").(string)
ui.Say("Stopping instance...")
ctx, cancel := context.WithTimeout(ctx, c.StateTimeout.Duration())
ctx, cancel := context.WithTimeout(ctx, c.StateTimeout)
defer cancel()
op, err := sdk.WrapOperation(sdk.Compute().Instance().Stop(ctx, &compute.StopInstanceRequest{
InstanceId: instanceID,

View File

@ -431,7 +431,7 @@ func getMapstructureSquashedStruct(topPkg *types.Package, utStruct *types.Struct
switch f := field.Type().(type) {
case *types.Named:
switch f.String() {
case "time.Duration", "github.com/hashicorp/packer/helper/config.DurationString":
case "time.Duration":
field = types.NewField(field.Pos(), field.Pkg(), field.Name(), types.NewPointer(types.Typ[types.String]), field.Embedded())
case "github.com/hashicorp/packer/helper/config.Trilean": // TODO(azr): unhack this situation
field = types.NewField(field.Pos(), field.Pkg(), field.Name(), types.NewPointer(types.Typ[types.Bool]), field.Embedded())

View File

@ -112,8 +112,8 @@ func main() {
fieldType := string(b[field.Type.Pos()-1 : field.Type.End()-1])
fieldType = strings.ReplaceAll(fieldType, "*", `\*`)
switch fieldType {
case "config.DurationString":
fieldType = "duration string. ex: \"1h5m2s\""
case "time.Duration":
fieldType = `duration string | ex: "1h5m2s"`
}
field := Field{

View File

@ -5,8 +5,8 @@ package bootcommand
import (
"fmt"
"strings"
"time"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
@ -112,13 +112,13 @@ type BootConfig struct {
// Packer to wait five seconds and one minute 30 seconds, respectively. If
// this isn't specified, a sensible default value is picked depending on
// the builder type.
BootGroupInterval config.DurationString `mapstructure:"boot_keygroup_interval"`
BootGroupInterval time.Duration `mapstructure:"boot_keygroup_interval"`
// The time to wait after booting the initial virtual machine before typing
// the `boot_command`. The value of this should be a duration. Examples are
// `5s` and `1m30s` which will cause Packer to wait five seconds and one
// minute 30 seconds, respectively. If this isn't specified, the default is
// `10s` or 10 seconds.
BootWait config.DurationString `mapstructure:"boot_wait"`
BootWait time.Duration `mapstructure:"boot_wait"`
// This is an array of commands to type when the virtual machine is first
// booted. The goal of these commands should be to type just enough to
// initialize the operating system installer. Special keys can be typed as
@ -140,26 +140,12 @@ type VNCConfig struct {
// when this is true. Defaults to false.
DisableVNC bool `mapstructure:"disable_vnc"`
// Time in ms to wait between each key press
BootKeyInterval config.DurationString `mapstructure:"boot_key_interval"`
BootKeyInterval time.Duration `mapstructure:"boot_key_interval"`
}
func (c *BootConfig) Prepare(ctx *interpolate.Context) (errs []error) {
if c.BootWait == "" {
c.BootWait = "10s"
}
if err := c.BootWait.Validate(); err != nil {
errs = append(
errs, fmt.Errorf("Failed parsing boot_wait: %s", err))
}
if c.BootGroupInterval == "" {
c.BootGroupInterval = "0ms"
}
if err := c.BootGroupInterval.Validate(); err != nil {
errs = append(
errs, fmt.Errorf("Failed parsing boot_keygroup_interval: %s", err))
if c.BootWait == 0 {
c.BootWait = 10 * time.Second
}
if c.BootCommand != nil {
@ -184,15 +170,6 @@ func (c *VNCConfig) Prepare(ctx *interpolate.Context) (errs []error) {
fmt.Errorf("A boot command cannot be used when vnc is disabled."))
}
if c.BootKeyInterval == "" {
c.BootKeyInterval = "0ms"
}
if err := c.BootKeyInterval.Validate(); err != nil {
errs = append(
errs, fmt.Errorf("Failed parsing boot_key_interval: %s", err))
}
errs = append(errs, c.BootConfig.Prepare(ctx)...)
return
}

View File

@ -2,6 +2,7 @@ package bootcommand
import (
"testing"
"time"
"github.com/hashicorp/packer/template/interpolate"
)
@ -11,26 +12,18 @@ func TestConfigPrepare(t *testing.T) {
// Test a default boot_wait
c = new(BootConfig)
c.BootWait = ""
c.BootWait = 0
errs := c.Prepare(&interpolate.Context{})
if len(errs) > 0 {
t.Fatalf("bad: %#v", errs)
}
if c.BootWait != "10s" {
if c.BootWait != 10*time.Second {
t.Fatalf("bad value: %s", c.BootWait)
}
// Test with a bad boot_wait
c = new(BootConfig)
c.BootWait = "this is not good"
errs = c.Prepare(&interpolate.Context{})
if len(errs) == 0 {
t.Fatal("should error")
}
// Test with a good one
c = new(BootConfig)
c.BootWait = "5s"
c.BootWait = 5 * time.Second
errs = c.Prepare(&interpolate.Context{})
if len(errs) > 0 {
t.Fatalf("bad: %#v", errs)

View File

@ -3,7 +3,8 @@
package shutdowncommand
import (
"github.com/hashicorp/packer/helper/config"
"time"
"github.com/hashicorp/packer/template/interpolate"
)
@ -21,16 +22,12 @@ type ShutdownConfig struct {
// virtual machine to actually shut down. If the machine doesn't shut down
// in this time it is considered an error. By default, the time out is "5m"
// (five minutes).
ShutdownTimeout config.DurationString `mapstructure:"shutdown_timeout" required:"false"`
ShutdownTimeout time.Duration `mapstructure:"shutdown_timeout" required:"false"`
}
func (c *ShutdownConfig) Prepare(ctx *interpolate.Context) []error {
if c.ShutdownTimeout == "" {
c.ShutdownTimeout = "5m"
}
if err := c.ShutdownTimeout.Validate(); err != nil {
return []error{err}
if c.ShutdownTimeout == 0 {
c.ShutdownTimeout = 5 * time.Minute
}
return nil

View File

@ -26,22 +26,14 @@ func TestShutdownConfigPrepare_ShutdownTimeout(t *testing.T) {
var c *ShutdownConfig
var errs []error
// Test with a bad value
c = testShutdownConfig()
c.ShutdownTimeout = "this is not good"
errs = c.Prepare(interpolate.NewContext())
if len(errs) == 0 {
t.Fatalf("should have error")
}
// Test with a good one
c = testShutdownConfig()
c.ShutdownTimeout = "5s"
c.ShutdownTimeout = 5 * time.Second
errs = c.Prepare(interpolate.NewContext())
if len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if c.ShutdownTimeout.Duration() != 5*time.Second {
if c.ShutdownTimeout != 5*time.Second {
t.Fatalf("bad: %s", c.ShutdownTimeout)
}
}

View File

@ -9,9 +9,9 @@ import (
"io/ioutil"
"net"
"os"
"time"
packerssh "github.com/hashicorp/packer/communicator/ssh"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
helperssh "github.com/hashicorp/packer/helper/ssh"
"github.com/hashicorp/packer/packer"
@ -58,7 +58,7 @@ type Config struct {
// In this example, Packer will check whether it can connect, as normal. But once
// a connection attempt is successful, it will disconnect and then wait 10 minutes
// before connecting to the guest and beginning provisioning.
PauseBeforeConnect config.DurationString `mapstructure:"pause_before_connecting"`
PauseBeforeConnect time.Duration `mapstructure:"pause_before_connecting"`
SSH `mapstructure:",squash"`
WinRM `mapstructure:",squash"`
@ -104,7 +104,7 @@ type SSH struct {
// The time to wait for SSH to become available. Packer uses this to
// determine when the machine has booted so this is usually quite long.
// Example value: `10m`.
SSHTimeout config.DurationString `mapstructure:"ssh_timeout"`
SSHTimeout time.Duration `mapstructure:"ssh_timeout"`
// If true, the local SSH agent will be used to authenticate connections to
// the source instance. No temporary keypair will be created, and the
// values of `ssh_password` and `ssh_private_key_file` will be ignored. To
@ -146,11 +146,11 @@ type SSH struct {
SSHProxyPassword string `mapstructure:"ssh_proxy_password"`
// How often to send "keep alive" messages to the server. Set to a negative
// value (`-1s`) to disable. Example value: `10s`. Defaults to `5s`.
SSHKeepAliveInterval config.DurationString `mapstructure:"ssh_keep_alive_interval"`
SSHKeepAliveInterval time.Duration `mapstructure:"ssh_keep_alive_interval"`
// The amount of time to wait for a remote command to end. This might be
// useful if, for example, packer hangs on a connection after a reboot.
// Example: `5m`. Disabled by default.
SSHReadWriteTimeout config.DurationString `mapstructure:"ssh_read_write_timeout"`
SSHReadWriteTimeout time.Duration `mapstructure:"ssh_read_write_timeout"`
// Tunneling
@ -201,7 +201,7 @@ type WinRM struct {
WinRMPort int `mapstructure:"winrm_port"`
// The amount of time to wait for WinRM to become available. This defaults
// to `30m` since setting up a Windows machine generally takes a long time.
WinRMTimeout config.DurationString `mapstructure:"winrm_timeout"`
WinRMTimeout time.Duration `mapstructure:"winrm_timeout"`
// If `true`, use HTTPS for WinRM.
WinRMUseSSL bool `mapstructure:"winrm_use_ssl"`
// If `true`, do not check server certificate chain and host name.
@ -370,12 +370,12 @@ func (c *Config) prepareSSH(ctx *interpolate.Context) []error {
c.SSHPort = 22
}
if c.SSHTimeout == "" {
c.SSHTimeout = "5m"
if c.SSHTimeout == 0 {
c.SSHTimeout = 5 * time.Minute
}
if c.SSHKeepAliveInterval == "" {
c.SSHKeepAliveInterval = "5s"
if c.SSHKeepAliveInterval == 0 {
c.SSHKeepAliveInterval = 5 * time.Second
}
if c.SSHHandshakeAttempts == 0 {
@ -404,13 +404,6 @@ func (c *Config) prepareSSH(ctx *interpolate.Context) []error {
// Validation
var errs []error
for _, d := range []config.DurationString{c.SSHTimeout, c.SSHKeepAliveInterval} {
if err := d.Validate(); err != nil {
errs = append(errs, err)
}
}
if c.SSHUsername == "" {
errs = append(errs, errors.New("An ssh_username must be specified\n Note: some builders used to default ssh_username to \"root\"."))
}
@ -484,12 +477,8 @@ func (c *Config) prepareWinRM(ctx *interpolate.Context) (errs []error) {
c.WinRMPort = 5985
}
if c.WinRMTimeout == "" {
c.WinRMTimeout = "30m"
}
if err := c.WinRMTimeout.Validate(); err != nil {
errs = append(errs, err)
if c.WinRMTimeout == 0 {
c.WinRMTimeout = 30 * time.Minute
}
if c.WinRMUseNTLM == true {

View File

@ -112,8 +112,8 @@ func (s *StepConnect) Run(ctx context.Context, state multistep.StateBag) multist
return action
}
if s.Config.PauseBeforeConnect.Duration() > 0 {
cancelled := s.pause(s.Config.PauseBeforeConnect.Duration(), ctx)
if s.Config.PauseBeforeConnect > 0 {
cancelled := s.pause(s.Config.PauseBeforeConnect, ctx)
if cancelled {
return multistep.ActionHalt
}

View File

@ -46,7 +46,7 @@ func (s *StepConnectSSH) Run(ctx context.Context, state multistep.StateBag) mult
}()
log.Printf("[INFO] Waiting for SSH, up to timeout: %s", s.Config.SSHTimeout)
timeout := time.After(s.Config.SSHTimeout.Duration())
timeout := time.After(s.Config.SSHTimeout)
for {
// Wait for either SSH to become available, a timeout to occur,
// or an interrupt to come through.
@ -198,8 +198,8 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, ctx context.Contex
Pty: s.Config.SSHPty,
DisableAgentForwarding: s.Config.SSHDisableAgentForwarding,
UseSftp: s.Config.SSHFileTransferMethod == "sftp",
KeepAliveInterval: s.Config.SSHKeepAliveInterval.Duration(),
Timeout: s.Config.SSHReadWriteTimeout.Duration(),
KeepAliveInterval: s.Config.SSHKeepAliveInterval,
Timeout: s.Config.SSHReadWriteTimeout,
Tunnels: tunnels,
}

View File

@ -49,7 +49,7 @@ func (s *StepConnectWinRM) Run(ctx context.Context, state multistep.StateBag) mu
}()
log.Printf("Waiting for WinRM, up to timeout: %s", s.Config.WinRMTimeout)
timeout := time.After(s.Config.WinRMTimeout.Duration())
timeout := time.After(s.Config.WinRMTimeout)
for {
// Wait for either WinRM to become available, a timeout to occur,
// or an interrupt to come through.
@ -136,7 +136,7 @@ func (s *StepConnectWinRM) waitForWinRM(state multistep.StateBag, ctx context.Co
Port: port,
Username: user,
Password: password,
Timeout: s.Config.WinRMTimeout.Duration(),
Timeout: s.Config.WinRMTimeout,
Https: s.Config.WinRMUseSSL,
Insecure: s.Config.WinRMInsecure,
TransportDecorator: s.Config.WinRMTransportDecorator,

View File

@ -31,6 +31,7 @@ var DefaultDecodeHookFuncs = []mapstructure.DecodeHookFunc{
uint8ToStringHook,
stringToTrilean,
mapstructure.StringToSliceHookFunc(","),
mapstructure.StringToTimeDurationHookFunc(),
}
// Decode decodes the configuration into the target and optionally

View File

@ -3,6 +3,7 @@ package config
import (
"reflect"
"testing"
"time"
"github.com/hashicorp/packer/template/interpolate"
)
@ -11,7 +12,7 @@ func TestDecode(t *testing.T) {
type Target struct {
Name string
Address string
Time DurationString
Time time.Duration
Trilean Trilean
}
@ -30,7 +31,7 @@ func TestDecode(t *testing.T) {
},
&Target{
Name: "bar",
Time: "5s",
Time: 5 * time.Second,
Trilean: TriTrue,
},
nil,

View File

@ -1,36 +0,0 @@
package config
import (
"fmt"
"time"
)
// DurationString is a string that represents a time duration.
//
// A DurationString is validated using time.ParseDuration.
//
// An empty string ("") is a valid (0) DurationString. A time.Sleep(0) returns
// immediately.
type DurationString string
// Duration returns the parsed duration.
// Duration panics if d is invalid.
func (d DurationString) Duration() time.Duration {
if d == "" {
return 0
}
du, err := time.ParseDuration(string(d))
if err != nil {
s := fmt.Sprintf("DurationString: Could not parse '%s' : %v", d, err)
panic(s)
}
return du
}
func (d DurationString) Validate() error {
if d == "" {
return nil
}
_, err := time.ParseDuration(string(d))
return err
}

View File

@ -135,14 +135,14 @@ func (c *Core) generateCoreBuildProvisioner(rawP *template.Provisioner, rawName
}
}
// If we're pausing, we wrap the provisioner in a special pauser.
if rawP.PauseBefore != "" {
if rawP.PauseBefore != 0 {
provisioner = &PausedProvisioner{
PauseBefore: rawP.PauseBefore.Duration(),
PauseBefore: rawP.PauseBefore,
Provisioner: provisioner,
}
} else if rawP.Timeout != "" {
} else if rawP.Timeout != 0 {
provisioner = &TimeoutProvisioner{
Timeout: rawP.Timeout.Duration(),
Timeout: rawP.Timeout,
Provisioner: provisioner,
}
}

View File

@ -45,7 +45,7 @@ type Config struct {
Distribution string `mapstructure:"image_distribution"`
ImageRegions []string `mapstructure:"image_regions"`
Timeout config.DurationString `mapstructure:"timeout"`
Timeout time.Duration `mapstructure:"timeout"`
ctx interpolate.Context
}
@ -104,8 +104,8 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
p.config.Distribution = "Unkown"
}
if p.config.Timeout == "" {
p.config.Timeout = "20m"
if p.config.Timeout == 0 {
p.config.Timeout = 20 * time.Minute
}
errs := new(packer.MultiError)
@ -208,7 +208,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
}
ui.Message(fmt.Sprintf("Waiting for import of image %s to complete (may take a while)", p.config.Name))
err = waitUntilImageAvailable(client, image.ID, p.config.Timeout.Duration())
err = waitUntilImageAvailable(client, image.ID, p.config.Timeout)
if err != nil {
return nil, false, false, fmt.Errorf("Import of image %s failed with error: %s", p.config.Name, err)
}
@ -222,7 +222,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
regions = regions[:len(regions)-1]
ui.Message(fmt.Sprintf("Distributing image %s to additional regions: %v", p.config.Name, regions))
err = distributeImageToRegions(client, image.ID, regions, p.config.Timeout.Duration())
err = distributeImageToRegions(client, image.ID, regions, p.config.Timeout)
if err != nil {
return nil, false, false, err
}

View File

@ -6,6 +6,7 @@ import (
"context"
"fmt"
"strings"
"time"
"github.com/hashicorp/packer/builder/googlecompute"
"github.com/hashicorp/packer/common"
@ -138,7 +139,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
Metadata: exporterMetadata,
Network: p.config.Network,
NetworkProjectId: builderProjectId,
StateTimeout: "5m",
StateTimeout: 5 * time.Minute,
SourceImageFamily: "debian-9-worker",
SourceImageProjectId: "compute-image-tools",
Subnetwork: p.config.Subnetwork,

View File

@ -53,7 +53,7 @@ type Config struct {
// The timeout for retrying to start the process. Until this timeout is
// reached, if the provisioner can't start a process, it retries. This
// can be set high to allow for reboots.
StartRetryTimeout config.DurationString `mapstructure:"start_retry_timeout"`
StartRetryTimeout time.Duration `mapstructure:"start_retry_timeout"`
// This is used in the template generation to format environment variables
// inside the `ExecuteCommand` template.
@ -143,8 +143,8 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
p.config.Inline = nil
}
if p.config.StartRetryTimeout == "" {
p.config.StartRetryTimeout = "5m"
if p.config.StartRetryTimeout == 0 {
p.config.StartRetryTimeout = 5 * time.Minute
}
if p.config.RemotePath == "" {
@ -279,7 +279,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
// that the upload succeeded, a restart is initiated, and then the
// command is executed but the file doesn't exist any longer.
var cmd *packer.RemoteCmd
err = retry.Config{StartTimeout: p.config.StartRetryTimeout.Duration()}.Run(ctx, func(ctx context.Context) error {
err = retry.Config{StartTimeout: p.config.StartRetryTimeout}.Run(ctx, func(ctx context.Context) error {
if _, err := f.Seek(0, 0); err != nil {
return err
}
@ -391,7 +391,7 @@ func (p *Provisioner) uploadEnvVars(flattenedEnvVars string) (err error) {
// a system restart
envVarReader := strings.NewReader(flattenedEnvVars)
log.Printf("Uploading env vars to %s", p.config.RemoteEnvVarPath)
err = retry.Config{StartTimeout: p.config.StartRetryTimeout.Duration()}.Run(ctx, func(context.Context) error {
err = retry.Config{StartTimeout: p.config.StartRetryTimeout}.Run(ctx, func(context.Context) error {
if err := p.communicator.Upload(p.config.RemoteEnvVarPath, envVarReader, nil); err != nil {
return fmt.Errorf("Error uploading ps script containing env vars: %s", err)
}

View File

@ -8,6 +8,7 @@ import (
"regexp"
"strings"
"testing"
"time"
"github.com/hashicorp/packer/packer"
)
@ -509,7 +510,7 @@ func TestProvisionerProvision_UploadFails(t *testing.T) {
p := new(Provisioner)
comm := new(packer.ScriptUploadErrorMockCommunicator)
p.Prepare(config)
p.config.StartRetryTimeout = "1s"
p.config.StartRetryTimeout = 1 * time.Second
err := p.Provision(context.Background(), ui, comm)
if !strings.Contains(err.Error(), packer.ScriptUploadErrorMockCommunicatorError.Error()) {
t.Fatalf("expected Provision() error %q to contain %q",

View File

@ -33,9 +33,7 @@ type Config struct {
InlineShebang string `mapstructure:"inline_shebang"`
// A duration of how long to pause after the provisioner
RawPauseAfter string `mapstructure:"pause_after"`
PauseAfter time.Duration
PauseAfter time.Duration `mapstructure:"pause_after"`
// Write the Vars to a file and source them from there rather than declaring
// inline
@ -52,15 +50,14 @@ type Config struct {
// The timeout for retrying to start the process. Until this timeout
// is reached, if the provisioner can't start a process, it retries.
// This can be set high to allow for reboots.
RawStartRetryTimeout string `mapstructure:"start_retry_timeout"`
StartRetryTimeout time.Duration `mapstructure:"start_retry_timeout"`
// Whether to clean scripts up
SkipClean bool `mapstructure:"skip_clean"`
ExpectDisconnect bool `mapstructure:"expect_disconnect"`
startRetryTimeout time.Duration
ctx interpolate.Context
ctx interpolate.Context
// name of the tmp environment variable file, if UseEnvVarFile is true
envVarFile string
}
@ -104,8 +101,8 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
p.config.InlineShebang = "/bin/sh -e"
}
if p.config.RawStartRetryTimeout == "" {
p.config.RawStartRetryTimeout = "5m"
if p.config.StartRetryTimeout == 0 {
p.config.StartRetryTimeout = 5 * time.Minute
}
if p.config.RemoteFolder == "" {
@ -163,22 +160,6 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
}
}
if p.config.RawStartRetryTimeout != "" {
p.config.startRetryTimeout, err = time.ParseDuration(p.config.RawStartRetryTimeout)
if err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Failed parsing start_retry_timeout: %s", err))
}
}
if p.config.RawPauseAfter != "" {
p.config.PauseAfter, err = time.ParseDuration(p.config.RawPauseAfter)
if err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Failed parsing pause_after: %s", err))
}
}
if errs != nil && len(errs.Errors) > 0 {
return errs
}
@ -240,7 +221,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
// upload the var file
var cmd *packer.RemoteCmd
err = retry.Config{StartTimeout: p.config.startRetryTimeout}.Run(ctx, func(ctx context.Context) error {
err = retry.Config{StartTimeout: p.config.StartRetryTimeout}.Run(ctx, func(ctx context.Context) error {
if _, err := tf.Seek(0, 0); err != nil {
return err
}
@ -303,7 +284,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
// and then the command is executed but the file doesn't exist
// any longer.
var cmd *packer.RemoteCmd
err = retry.Config{StartTimeout: p.config.startRetryTimeout}.Run(ctx, func(ctx context.Context) error {
err = retry.Config{StartTimeout: p.config.StartRetryTimeout}.Run(ctx, func(ctx context.Context) error {
if _, err := f.Seek(0, 0); err != nil {
return err
}
@ -365,7 +346,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
}
}
if p.config.RawPauseAfter != "" {
if p.config.PauseAfter != 0 {
ui.Say(fmt.Sprintf("Pausing %s after this provisioner...", p.config.PauseAfter))
select {
case <-time.After(p.config.PauseAfter):
@ -378,7 +359,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
func (p *Provisioner) cleanupRemoteFile(path string, comm packer.Communicator) error {
ctx := context.TODO()
err := retry.Config{StartTimeout: p.config.startRetryTimeout}.Run(ctx, func(ctx context.Context) error {
err := retry.Config{StartTimeout: p.config.StartRetryTimeout}.Run(ctx, func(ctx context.Context) error {
cmd := &packer.RemoteCmd{
Command: fmt.Sprintf("rm -f %s", path),
}

View File

@ -9,29 +9,29 @@ import (
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
Binary *bool `cty:"binary"`
ExecuteCommand *string `mapstructure:"execute_command" cty:"execute_command"`
Inline []string `cty:"inline"`
RemotePath *string `mapstructure:"remote_path" cty:"remote_path"`
Script *string `cty:"script"`
Scripts []string `cty:"scripts"`
ValidExitCodes []int `mapstructure:"valid_exit_codes" cty:"valid_exit_codes"`
Vars []string `mapstructure:"environment_vars" cty:"environment_vars"`
InlineShebang *string `mapstructure:"inline_shebang" cty:"inline_shebang"`
RawPauseAfter *string `mapstructure:"pause_after" cty:"pause_after"`
UseEnvVarFile *bool `mapstructure:"use_env_var_file" cty:"use_env_var_file"`
RemoteFolder *string `mapstructure:"remote_folder" cty:"remote_folder"`
RemoteFile *string `mapstructure:"remote_file" cty:"remote_file"`
RawStartRetryTimeout *string `mapstructure:"start_retry_timeout" cty:"start_retry_timeout"`
SkipClean *bool `mapstructure:"skip_clean" cty:"skip_clean"`
ExpectDisconnect *bool `mapstructure:"expect_disconnect" cty:"expect_disconnect"`
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
Binary *bool `cty:"binary"`
ExecuteCommand *string `mapstructure:"execute_command" cty:"execute_command"`
Inline []string `cty:"inline"`
RemotePath *string `mapstructure:"remote_path" cty:"remote_path"`
Script *string `cty:"script"`
Scripts []string `cty:"scripts"`
ValidExitCodes []int `mapstructure:"valid_exit_codes" cty:"valid_exit_codes"`
Vars []string `mapstructure:"environment_vars" cty:"environment_vars"`
InlineShebang *string `mapstructure:"inline_shebang" cty:"inline_shebang"`
PauseAfter *string `mapstructure:"pause_after" cty:"pause_after"`
UseEnvVarFile *bool `mapstructure:"use_env_var_file" cty:"use_env_var_file"`
RemoteFolder *string `mapstructure:"remote_folder" cty:"remote_folder"`
RemoteFile *string `mapstructure:"remote_file" cty:"remote_file"`
StartRetryTimeout *string `mapstructure:"start_retry_timeout" cty:"start_retry_timeout"`
SkipClean *bool `mapstructure:"skip_clean" cty:"skip_clean"`
ExpectDisconnect *bool `mapstructure:"expect_disconnect" cty:"expect_disconnect"`
}
// FlatMapstructure returns a new FlatConfig.

View File

@ -11,7 +11,7 @@ import (
)
type Provisioner struct {
Duration config.DurationString
Duration time.Duration
}
var _ packer.Provisioner = new(Provisioner)
@ -24,7 +24,7 @@ func (p *Provisioner) Provision(ctx context.Context, _ packer.Ui, _ packer.Commu
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(p.Duration.Duration()):
case <-time.After(p.Duration):
return nil
}
}

View File

@ -4,8 +4,6 @@ import (
"context"
"testing"
"time"
"github.com/hashicorp/packer/helper/config"
)
func test1sConfig() map[string]interface{} {
@ -22,7 +20,7 @@ func TestConfigPrepare_1s(t *testing.T) {
t.Fatalf("prerare failed: %v", err)
}
if p.Duration.Duration() != time.Second {
if p.Duration != time.Second {
t.Fatal("wrong duration")
}
}
@ -31,7 +29,7 @@ func TestProvisioner_Provision(t *testing.T) {
ctxCancelled, cancel := context.WithCancel(context.Background())
cancel()
type fields struct {
Duration config.DurationString
Duration time.Duration
}
type args struct {
ctx context.Context
@ -42,8 +40,8 @@ func TestProvisioner_Provision(t *testing.T) {
args args
wantErr bool
}{
{"valid sleep", fields{"1ms"}, args{context.Background()}, false},
{"timeout", fields{"1ms"}, args{ctxCancelled}, true},
{"valid sleep", fields{1 * time.Millisecond}, args{context.Background()}, false},
{"timeout", fields{1 * time.Millisecond}, args{ctxCancelled}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@ -44,7 +44,7 @@ type Config struct {
RestartCheckCommand string `mapstructure:"restart_check_command"`
// The timeout for waiting for the machine to restart
RestartTimeout config.DurationString `mapstructure:"restart_timeout"`
RestartTimeout time.Duration `mapstructure:"restart_timeout"`
// Whether to check the registry (see RegistryKeys) for pending reboots
CheckKey bool `mapstructure:"check_registry"`
@ -85,11 +85,8 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
p.config.RestartCheckCommand = DefaultRestartCheckCommand
}
if p.config.RestartTimeout == "" {
p.config.RestartTimeout = "5m"
}
if err := p.config.RestartTimeout.Validate(); err != nil {
return err
if p.config.RestartTimeout == 0 {
p.config.RestartTimeout = 5 * time.Minute
}
if len(p.config.RegistryKeys) == 0 {
@ -110,7 +107,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
var cmd *packer.RemoteCmd
command := p.config.RestartCommand
err := retry.Config{StartTimeout: p.config.RestartTimeout.Duration()}.Run(ctx, func(context.Context) error {
err := retry.Config{StartTimeout: p.config.RestartTimeout}.Run(ctx, func(context.Context) error {
cmd = &packer.RemoteCmd{Command: command}
return cmd.RunWithUi(ctx, comm, ui)
})
@ -130,7 +127,7 @@ var waitForRestart = func(ctx context.Context, p *Provisioner, comm packer.Commu
ui := p.ui
ui.Say("Waiting for machine to restart...")
waitDone := make(chan bool, 1)
timeout := time.After(p.config.RestartTimeout.Duration())
timeout := time.After(p.config.RestartTimeout)
var err error
p.comm = comm

View File

@ -31,7 +31,7 @@ func TestProvisionerPrepare_Defaults(t *testing.T) {
t.Fatalf("err: %s", err)
}
if p.config.RestartTimeout.Duration() != 5*time.Minute {
if p.config.RestartTimeout != 5*time.Minute {
t.Errorf("unexpected restart timeout: %s", p.config.RestartTimeout)
}
@ -50,7 +50,7 @@ func TestProvisionerPrepare_ConfigRetryTimeout(t *testing.T) {
t.Fatalf("err: %s", err)
}
if p.config.RestartTimeout.Duration() != 1*time.Minute {
if p.config.RestartTimeout != 1*time.Minute {
t.Errorf("unexpected restart timeout: %s", p.config.RestartTimeout)
}
}

View File

@ -35,7 +35,7 @@ type Config struct {
// The timeout for retrying to start the process. Until this timeout
// is reached, if the provisioner can't start a process, it retries.
// This can be set high to allow for reboots.
StartRetryTimeout config.DurationString `mapstructure:"start_retry_timeout"`
StartRetryTimeout time.Duration `mapstructure:"start_retry_timeout"`
// This is used in the template generation to format environment variables
// inside the `ExecuteCommand` template.
@ -79,8 +79,8 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
p.config.Inline = nil
}
if p.config.StartRetryTimeout == "" {
p.config.StartRetryTimeout = "5m"
if p.config.StartRetryTimeout == 0 {
p.config.StartRetryTimeout = 5 * time.Minute
}
if p.config.RemotePath == "" {
@ -202,7 +202,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
// and then the command is executed but the file doesn't exist
// any longer.
var cmd *packer.RemoteCmd
err = retry.Config{StartTimeout: p.config.StartRetryTimeout.Duration()}.Run(ctx, func(ctx context.Context) error {
err = retry.Config{StartTimeout: p.config.StartRetryTimeout}.Run(ctx, func(ctx context.Context) error {
if _, err := f.Seek(0, 0); err != nil {
return err
}

View File

@ -273,7 +273,7 @@ func (r *rawTemplate) decoder(
result interface{},
md *mapstructure.Metadata) *mapstructure.Decoder {
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: nil,
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
Metadata: md,
Result: result,
})

View File

@ -9,6 +9,7 @@ import (
"reflect"
"strings"
"testing"
"time"
"github.com/google/go-cmp/cmp"
)
@ -98,7 +99,7 @@ func TestParse(t *testing.T) {
Provisioners: []*Provisioner{
{
Type: "something",
PauseBefore: "1s",
PauseBefore: 1 * time.Second,
},
},
},
@ -111,7 +112,7 @@ func TestParse(t *testing.T) {
Provisioners: []*Provisioner{
{
Type: "something",
Timeout: "5m",
Timeout: 5 * time.Minute,
},
},
},
@ -357,12 +358,6 @@ func TestParse(t *testing.T) {
false,
},
{
"parse-bad-prov-timeout.json",
nil,
true,
},
{
"parse-comment.json",
&Template{

View File

@ -6,9 +6,9 @@ import (
"encoding/json"
"errors"
"fmt"
"time"
multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/packer/helper/config"
)
// Template represents the parsed template that is used to configure
@ -140,8 +140,8 @@ type Provisioner struct {
Type string `json:"type"`
Config map[string]interface{} `json:"config,omitempty"`
Override map[string]interface{} `json:"override,omitempty"`
PauseBefore config.DurationString `mapstructure:"pause_before" json:"pause_before,omitempty"`
Timeout config.DurationString `mapstructure:"timeout" json:"timeout,omitempty"`
PauseBefore time.Duration `mapstructure:"pause_before" json:"pause_before,omitempty"`
Timeout time.Duration `mapstructure:"timeout" json:"timeout,omitempty"`
}
// MarshalJSON conducts the necessary flattening of the Provisioner struct

View File

@ -1,11 +0,0 @@
{
"builders": [{
"type": "foo"
}],
"provisioners": [{
"timeout": 555,
"type": "bar",
"only": ["foo"]
}]
}

View File

@ -279,7 +279,7 @@
subnet_id to be set. If this field is left blank, Packer will try to get
the VPC ID from the subnet_id.
- `windows_password_timeout` (duration string. ex: "1h5m2s") - The timeout for waiting for a Windows
- `windows_password_timeout` (duration string | ex: "1h5m2s") - The timeout for waiting for a Windows
password for Windows instances. Defaults to 20 minutes. Example value:
10m

View File

@ -34,7 +34,7 @@
"managed_image_name": "TargetImageName",
"managed_image_resource_group_name": "TargetResourceGroup"
- `shared_image_gallery_timeout` (duration string. ex: "1h5m2s") - How long to wait for an image to be published to the shared image
- `shared_image_gallery_timeout` (duration string | ex: "1h5m2s") - How long to wait for an image to be published to the shared image
gallery before timing out. If your Packer build is failing on the
Publishing to Shared Image Gallery step with the error `Original Error:
context deadline exceeded`, but the image is present when you check your
@ -187,7 +187,7 @@
3. PlanPublisher
4. PlanPromotionCode
- `polling_duration_timeout` (duration string. ex: "1h5m2s") - The default PollingDuration for azure is 15mins, this property will override
- `polling_duration_timeout` (duration string | ex: "1h5m2s") - The default PollingDuration for azure is 15mins, this property will override
that value. See [Azure DefaultPollingDuration](https://godoc.org/github.com/Azure/go-autorest/autorest#pkg-constants)
If your Packer build is failing on the
ARM deployment step with the error `Original Error:

View File

@ -1,6 +1,6 @@
<!-- Code generated from the comments of the Config struct in builder/cloudstack/config.go; DO NOT EDIT MANUALLY -->
- `async_timeout` (duration string. ex: "1h5m2s") - The time duration to wait for async calls to
- `async_timeout` (duration string | ex: "1h5m2s") - The time duration to wait for async calls to
finish. Defaults to 30m.
- `http_get_only` (bool) - Some cloud providers only allow HTTP GET calls
@ -32,7 +32,7 @@
attached to a virtual machine. Defaults to `false`. This option is only
available when using `source_iso`.
- `eject_iso_delay` (duration string. ex: "1h5m2s") - Configure the duration time to wait, making sure virtual machine is able
- `eject_iso_delay` (duration string | ex: "1h5m2s") - Configure the duration time to wait, making sure virtual machine is able
to finish installing OS before it ejects safely. Requires `eject_iso`
set to `true` and this option is only available when using `source_iso`.

View File

@ -20,11 +20,11 @@
- `snapshot_regions` ([]string) - The regions of the resulting
snapshot that will appear in your account.
- `state_timeout` (duration string. ex: "1h5m2s") - The time to wait, as a duration string, for a
- `state_timeout` (duration string | ex: "1h5m2s") - The time to wait, as a duration string, for a
droplet to enter a desired state (such as "active") before timing out. The
default state timeout is "6m".
- `snapshot_timeout` (duration string. ex: "1h5m2s") - How long to wait for an image to be published to the shared image
- `snapshot_timeout` (duration string | ex: "1h5m2s") - How long to wait for an image to be published to the shared image
gallery before timing out. If your Packer build is failing on the
Publishing to Shared Image Gallery step with the error `Original Error:
context deadline exceeded`, but the image is present when you check your

View File

@ -88,7 +88,7 @@
- `preemptible` (bool) - If true, launch a preemptible instance.
- `state_timeout` (duration string. ex: "1h5m2s") - The time to wait for instance state changes. Defaults to "5m".
- `state_timeout` (duration string | ex: "1h5m2s") - The time to wait for instance state changes. Defaults to "5m".
- `region` (string) - The region in which to launch the instance. Defaults to the region
hosting the specified zone.

View File

@ -6,7 +6,7 @@
- `token_login` (string) - Login (an e-mail) on HyperOne platform. Set this
if you want to fetch the token by SSH authentication.
- `state_timeout` (duration string. ex: "1h5m2s") - Timeout for waiting on the API to complete
- `state_timeout` (duration string | ex: "1h5m2s") - Timeout for waiting on the API to complete
a request. Defaults to 5m.
- `image_name` (string) - The name of the resulting image. Defaults to

View File

@ -11,7 +11,7 @@
as ssh so you can execute packer builds on a remote host. Defaults to
Empty.
- `init_timeout` (string) - The timeout in seconds to wait for the the
- `init_timeout` (duration string | ex: "1h5m2s") - The timeout in seconds to wait for the the
container to start. Defaults to 20 seconds.
- `create_options` ([]string) - Options to pass to lxc-create. For

View File

@ -8,12 +8,12 @@
since reboots may fail and specify the final shutdown command in your
last script.
- `shutdown_timeout` (duration string. ex: "1h5m2s") - The amount of time to wait after executing the
- `shutdown_timeout` (duration string | ex: "1h5m2s") - The amount of time to wait after executing the
shutdown_command for the virtual machine to actually shut down. If it
doesn't shut down in this time, it is an error. By default, the timeout is
5m or five minutes.
- `post_shutdown_delay` (duration string. ex: "1h5m2s") - The amount of time to wait after shutting
- `post_shutdown_delay` (duration string | ex: "1h5m2s") - The amount of time to wait after shutting
down the virtual machine. If you get the error
Error removing floppy controller, you might need to set this to 5m
or so. By default, the delay is 0s or disabled.

View File

@ -73,6 +73,6 @@
- `zone` (string) - The name of the zone to launch the instance. This defaults to `ru-central1-a`.
- `state_timeout` (duration string. ex: "1h5m2s") - The time to wait for instance state changes.
- `state_timeout` (duration string | ex: "1h5m2s") - The time to wait for instance state changes.
Defaults to `5m`.

View File

@ -1,12 +1,12 @@
<!-- Code generated from the comments of the BootConfig struct in common/bootcommand/config.go; DO NOT EDIT MANUALLY -->
- `boot_keygroup_interval` (duration string. ex: "1h5m2s") - Time to wait after sending a group of key pressses. The value of this
- `boot_keygroup_interval` (duration string | ex: "1h5m2s") - Time to wait after sending a group of key pressses. The value of this
should be a duration. Examples are `5s` and `1m30s` which will cause
Packer to wait five seconds and one minute 30 seconds, respectively. If
this isn't specified, a sensible default value is picked depending on
the builder type.
- `boot_wait` (duration string. ex: "1h5m2s") - The time to wait after booting the initial virtual machine before typing
- `boot_wait` (duration string | ex: "1h5m2s") - The time to wait after booting the initial virtual machine before typing
the `boot_command`. The value of this should be a duration. Examples are
`5s` and `1m30s` which will cause Packer to wait five seconds and one
minute 30 seconds, respectively. If this isn't specified, the default is

Some files were not shown because too many files have changed in this diff Show More