diff --git a/builder/alicloud/ecs/builder.go b/builder/alicloud/ecs/builder.go index af339c718..46e6889fc 100644 --- a/builder/alicloud/ecs/builder.go +++ b/builder/alicloud/ecs/builder.go @@ -172,12 +172,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }) if b.config.AlicloudImageIgnoreDataDisks { - steps = append(steps, &stepCreateAlicloudSnapshot{}) + steps = append(steps, &stepCreateAlicloudSnapshot{ + WaitSnapshotReadyTimeout: b.getSnapshotReadyTimeout(), + }) } steps = append(steps, &stepCreateAlicloudImage{ AlicloudImageIgnoreDataDisks: b.config.AlicloudImageIgnoreDataDisks, + WaitSnapshotReadyTimeout: b.getSnapshotReadyTimeout(), }, &stepCreateTags{ Tags: b.config.AlicloudImageTags, @@ -253,3 +256,11 @@ func (b *Builder) isUserDataNeeded() bool { func (b *Builder) isKeyPairNeeded() bool { return b.config.Comm.SSHKeyPairName != "" || b.config.Comm.SSHTemporaryKeyPairName != "" } + +func (b *Builder) getSnapshotReadyTimeout() int { + if b.config.WaitSnapshotReadyTimeout > 0 { + return b.config.WaitSnapshotReadyTimeout + } + + return ALICLOUD_DEFAULT_LONG_TIMEOUT +} diff --git a/builder/alicloud/ecs/builder_test.go b/builder/alicloud/ecs/builder_test.go index 153291f73..c6e54d793 100644 --- a/builder/alicloud/ecs/builder_test.go +++ b/builder/alicloud/ecs/builder_test.go @@ -195,3 +195,40 @@ func TestBuilderPrepare_IgnoreDataDisks(t *testing.T) { t.Fatalf("image_ignore_data_disks is not set properly, expect: %t, actual: %t", true, b.config.AlicloudImageIgnoreDataDisks) } } + +func TestBuilderPrepare_WaitSnapshotReadyTimeout(t *testing.T) { + var b Builder + config := testBuilderConfig() + + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.WaitSnapshotReadyTimeout != 0 { + t.Fatalf("wait_snapshot_ready_timeout is not set properly, expect: %d, actual: %d", 0, b.config.WaitSnapshotReadyTimeout) + } + if b.getSnapshotReadyTimeout() != ALICLOUD_DEFAULT_LONG_TIMEOUT { + t.Fatalf("default timeout is not set properly, expect: %d, actual: %d", ALICLOUD_DEFAULT_LONG_TIMEOUT, b.getSnapshotReadyTimeout()) + } + + config["wait_snapshot_ready_timeout"] = ALICLOUD_DEFAULT_TIMEOUT + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.WaitSnapshotReadyTimeout != ALICLOUD_DEFAULT_TIMEOUT { + t.Fatalf("wait_snapshot_ready_timeout is not set properly, expect: %d, actual: %d", ALICLOUD_DEFAULT_TIMEOUT, b.config.WaitSnapshotReadyTimeout) + } + + if b.getSnapshotReadyTimeout() != ALICLOUD_DEFAULT_TIMEOUT { + t.Fatalf("default timeout is not set properly, expect: %d, actual: %d", ALICLOUD_DEFAULT_TIMEOUT, b.getSnapshotReadyTimeout()) + } +} diff --git a/builder/alicloud/ecs/run_config.go b/builder/alicloud/ecs/run_config.go index aaab9f785..e36a33854 100644 --- a/builder/alicloud/ecs/run_config.go +++ b/builder/alicloud/ecs/run_config.go @@ -32,6 +32,7 @@ type RunConfig struct { InstanceName string `mapstructure:"instance_name"` InternetChargeType string `mapstructure:"internet_charge_type"` InternetMaxBandwidthOut int `mapstructure:"internet_max_bandwidth_out"` + WaitSnapshotReadyTimeout int `mapstructure:"wait_snapshot_ready_timeout"` // Communicator settings Comm communicator.Config `mapstructure:",squash"` diff --git a/builder/alicloud/ecs/step_create_image.go b/builder/alicloud/ecs/step_create_image.go index fafb5819d..d80dca8ea 100644 --- a/builder/alicloud/ecs/step_create_image.go +++ b/builder/alicloud/ecs/step_create_image.go @@ -12,6 +12,7 @@ import ( type stepCreateAlicloudImage struct { AlicloudImageIgnoreDataDisks bool + WaitSnapshotReadyTimeout int image *ecs.ImageType } @@ -49,8 +50,7 @@ func (s *stepCreateAlicloudImage) Run(_ context.Context, state multistep.StateBa ui.Error(err.Error()) return multistep.ActionHalt } - err = client.WaitForImageReady(common.Region(config.AlicloudRegion), - imageId, ALICLOUD_DEFAULT_LONG_TIMEOUT) + err = client.WaitForImageReady(common.Region(config.AlicloudRegion), imageId, s.WaitSnapshotReadyTimeout) if err != nil { err := fmt.Errorf("Timeout waiting for image to be created: %s", err) state.Put("error", err) diff --git a/builder/alicloud/ecs/step_create_snapshot.go b/builder/alicloud/ecs/step_create_snapshot.go index 875db37b8..a9f5ae590 100644 --- a/builder/alicloud/ecs/step_create_snapshot.go +++ b/builder/alicloud/ecs/step_create_snapshot.go @@ -11,7 +11,8 @@ import ( ) type stepCreateAlicloudSnapshot struct { - snapshot *ecs.SnapshotType + snapshot *ecs.SnapshotType + WaitSnapshotReadyTimeout int } func (s *stepCreateAlicloudSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { @@ -44,8 +45,7 @@ func (s *stepCreateAlicloudSnapshot) Run(_ context.Context, state multistep.Stat return halt(state, err, "Error creating snapshot") } - err = client.WaitForSnapShotReady(common.Region(config.AlicloudRegion), - snapshotId, ALICLOUD_DEFAULT_LONG_TIMEOUT) + err = client.WaitForSnapShotReady(common.Region(config.AlicloudRegion), snapshotId, s.WaitSnapshotReadyTimeout) if err != nil { return halt(state, err, "Timeout waiting for snapshot to be created") } diff --git a/website/source/docs/builders/alicloud-ecs.html.md b/website/source/docs/builders/alicloud-ecs.html.md index 10766bb76..0c743ca4b 100644 --- a/website/source/docs/builders/alicloud-ecs.html.md +++ b/website/source/docs/builders/alicloud-ecs.html.md @@ -153,6 +153,10 @@ builder. any circumstance that default data disks with instance types are not concerned. The default value is false. +- `wait_snapshot_ready_timeout`(number) - Timeout of creating snapshot(s). The + default timeout is 3600 seconds if this option is not set or is set to 0. For + those disks containing lots of data, it may require a higher timeout value. + - `image_force_delete` (boolean) - If this value is true, when the target image name is duplicated with an existing image, it will delete the existing image and then create the target image, otherwise, the creation