Skip to content

Commit

Permalink
Merge pull request #50 from chhaj5236/feature/image_without_datadisks
Browse files Browse the repository at this point in the history
support creating image without data disks
  • Loading branch information
chhaj5236 authored Nov 18, 2018
2 parents ad51f07 + e9de3e8 commit 6c0a5d3
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 9 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## 1.3.0 (Unreleased)

## 1.2.5 (November 18, 2018)

IMPROVEMENTS:

- Support creating image without data disks ([#50](https://github.com/alibaba/packer-provider/pull/50))

## 1.2.4 (October 31, 2018)

IMPROVEMENTS:
Expand Down
10 changes: 9 additions & 1 deletion ecs/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,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,
},
Expand Down
43 changes: 43 additions & 0 deletions ecs/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,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)
}
}
1 change: 1 addition & 0 deletions ecs/image_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
9 changes: 9 additions & 0 deletions ecs/packer_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
27 changes: 19 additions & 8 deletions ecs/step_create_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
Expand Down
92 changes: 92 additions & 0 deletions ecs/step_create_snapshot.go
Original file line number Diff line number Diff line change
@@ -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
}
}

0 comments on commit 6c0a5d3

Please sign in to comment.