support creating image without data disks
This commit is contained in:
parent
06c2c35e4c
commit
3c2c13a021
|
@ -169,8 +169,16 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
AlicloudImageForceDeleteSnapshots: b.config.AlicloudImageForceDeleteSnapshots,
|
||||
AlicloudImageForceDelete: b.config.AlicloudImageForceDelete,
|
||||
AlicloudImageName: b.config.AlicloudImageName,
|
||||
})
|
||||
|
||||
if b.config.AlicloudImageIgnoreDataDisks {
|
||||
steps = append(steps, &stepCreateAlicloudSnapshot{})
|
||||
}
|
||||
|
||||
steps = append(steps,
|
||||
&stepCreateAlicloudImage{
|
||||
AlicloudImageIgnoreDataDisks: b.config.AlicloudImageIgnoreDataDisks,
|
||||
},
|
||||
&stepCreateAlicloudImage{},
|
||||
&stepCreateTags{
|
||||
Tags: b.config.AlicloudImageTags,
|
||||
},
|
||||
|
|
|
@ -152,3 +152,46 @@ func TestBuilderPrepare_Devices(t *testing.T) {
|
|||
t.Fatalf("data disks are not set properly, actual: %#v", b.config.ECSImagesDiskMappings)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_IgnoreDataDisks(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.AlicloudImageIgnoreDataDisks != false {
|
||||
t.Fatalf("image_ignore_data_disks is not set properly, expect: %t, actual: %t", false, b.config.AlicloudImageIgnoreDataDisks)
|
||||
}
|
||||
|
||||
config["image_ignore_data_disks"] = "false"
|
||||
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.AlicloudImageIgnoreDataDisks != false {
|
||||
t.Fatalf("image_ignore_data_disks is not set properly, expect: %t, actual: %t", false, b.config.AlicloudImageIgnoreDataDisks)
|
||||
}
|
||||
|
||||
config["image_ignore_data_disks"] = "true"
|
||||
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.AlicloudImageIgnoreDataDisks != true {
|
||||
t.Fatalf("image_ignore_data_disks is not set properly, expect: %t, actual: %t", true, b.config.AlicloudImageIgnoreDataDisks)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ type AlicloudImageConfig struct {
|
|||
AlicloudImageForceDelete bool `mapstructure:"image_force_delete"`
|
||||
AlicloudImageForceDeleteSnapshots bool `mapstructure:"image_force_delete_snapshots"`
|
||||
AlicloudImageForceDeleteInstances bool `mapstructure:"image_force_delete_instances"`
|
||||
AlicloudImageIgnoreDataDisks bool `mapstructure:"image_ignore_data_disks"`
|
||||
AlicloudImageSkipRegionValidation bool `mapstructure:"skip_region_validation"`
|
||||
AlicloudImageTags map[string]string `mapstructure:"tags"`
|
||||
AlicloudDiskDevices `mapstructure:",squash"`
|
||||
|
|
|
@ -20,3 +20,12 @@ func message(state multistep.StateBag, module string) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
func halt(state multistep.StateBag, err error, prefix string) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
err = fmt.Errorf("%s: %s", prefix, err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
|
|
@ -11,7 +11,8 @@ import (
|
|||
)
|
||||
|
||||
type stepCreateAlicloudImage struct {
|
||||
image *ecs.ImageType
|
||||
AlicloudImageIgnoreDataDisks bool
|
||||
image *ecs.ImageType
|
||||
}
|
||||
|
||||
func (s *stepCreateAlicloudImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
|
@ -24,13 +25,23 @@ func (s *stepCreateAlicloudImage) Run(_ context.Context, state multistep.StateBa
|
|||
var imageId string
|
||||
var err error
|
||||
|
||||
instance := state.Get("instance").(*ecs.InstanceAttributesType)
|
||||
imageId, err = client.CreateImage(&ecs.CreateImageArgs{
|
||||
RegionId: common.Region(config.AlicloudRegion),
|
||||
InstanceId: instance.InstanceId,
|
||||
ImageName: config.AlicloudImageName,
|
||||
ImageVersion: config.AlicloudImageVersion,
|
||||
Description: config.AlicloudImageDescription})
|
||||
if s.AlicloudImageIgnoreDataDisks {
|
||||
snapshotId := state.Get("alicloudsnapshot").(string)
|
||||
imageId, err = client.CreateImage(&ecs.CreateImageArgs{
|
||||
RegionId: common.Region(config.AlicloudRegion),
|
||||
SnapshotId: snapshotId,
|
||||
ImageName: config.AlicloudImageName,
|
||||
ImageVersion: config.AlicloudImageVersion,
|
||||
Description: config.AlicloudImageDescription})
|
||||
} else {
|
||||
instance := state.Get("instance").(*ecs.InstanceAttributesType)
|
||||
imageId, err = client.CreateImage(&ecs.CreateImageArgs{
|
||||
RegionId: common.Region(config.AlicloudRegion),
|
||||
InstanceId: instance.InstanceId,
|
||||
ImageName: config.AlicloudImageName,
|
||||
ImageVersion: config.AlicloudImageVersion,
|
||||
Description: config.AlicloudImageDescription})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error creating image: %s", err)
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/ecs"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type stepCreateAlicloudSnapshot struct {
|
||||
snapshot *ecs.SnapshotType
|
||||
}
|
||||
|
||||
func (s *stepCreateAlicloudSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*Config)
|
||||
client := state.Get("client").(*ecs.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
instance := state.Get("instance").(*ecs.InstanceAttributesType)
|
||||
disks, _, err := client.DescribeDisks(&ecs.DescribeDisksArgs{
|
||||
RegionId: common.Region(config.AlicloudRegion),
|
||||
InstanceId: instance.InstanceId,
|
||||
DiskType: ecs.DiskTypeAllSystem,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, "Error describe disks")
|
||||
}
|
||||
if len(disks) == 0 {
|
||||
return halt(state, err, "Unable to find system disk of instance")
|
||||
}
|
||||
|
||||
// Create the alicloud snapshot
|
||||
ui.Say(fmt.Sprintf("Creating snapshot from system disk: %s", disks[0].DiskId))
|
||||
|
||||
snapshotId, err := client.CreateSnapshot(&ecs.CreateSnapshotArgs{
|
||||
DiskId: disks[0].DiskId,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, "Error creating snapshot")
|
||||
}
|
||||
|
||||
err = client.WaitForSnapShotReady(common.Region(config.AlicloudRegion),
|
||||
snapshotId, ALICLOUD_DEFAULT_LONG_TIMEOUT)
|
||||
if err != nil {
|
||||
return halt(state, err, "Timeout waiting for snapshot to be created")
|
||||
}
|
||||
|
||||
snapshots, _, err := client.DescribeSnapshots(&ecs.DescribeSnapshotsArgs{
|
||||
RegionId: common.Region(config.AlicloudRegion),
|
||||
SnapshotIds: []string{snapshotId},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, "Error querying created snapshot")
|
||||
}
|
||||
if len(snapshots) == 0 {
|
||||
return halt(state, err, "Unable to find created snapshot")
|
||||
}
|
||||
s.snapshot = &snapshots[0]
|
||||
|
||||
state.Put("alicloudsnapshot", snapshotId)
|
||||
alicloudSnapshots := make(map[string]string)
|
||||
alicloudSnapshots[config.AlicloudRegion] = snapshotId
|
||||
state.Put("alicloudsnapshots", alicloudSnapshots)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepCreateAlicloudSnapshot) Cleanup(state multistep.StateBag) {
|
||||
if s.snapshot == nil {
|
||||
return
|
||||
}
|
||||
_, cancelled := state.GetOk(multistep.StateCancelled)
|
||||
_, halted := state.GetOk(multistep.StateHalted)
|
||||
if !cancelled && !halted {
|
||||
return
|
||||
}
|
||||
|
||||
client := state.Get("client").(*ecs.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Deleting the snapshot because of cancellation or error...")
|
||||
if err := client.DeleteSnapshot(s.snapshot.SnapshotId); err != nil {
|
||||
ui.Error(fmt.Sprintf("Error deleting snapshot, it may still be around: %s", err))
|
||||
return
|
||||
}
|
||||
}
|
|
@ -147,6 +147,11 @@ builder.
|
|||
|
||||
Snapshots from on or before July 15, 2013 cannot be used to create a
|
||||
disk.
|
||||
|
||||
- `image_ignore_data_disks`(boolean) - If this value is true, the image created
|
||||
will not include any snapshot of data disks. This option would be useful for
|
||||
any circumstance that default data disks with instance types are not concerned.
|
||||
The default value is false.
|
||||
|
||||
- `image_force_delete` (boolean) - If this value is true, when the target
|
||||
image name is duplicated with an existing image, it will delete the
|
||||
|
|
Loading…
Reference in New Issue