Skip to content

Add a "skip_create_image" option #144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .web-docs/components/builder/cvm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ a [communicator](/packer/docs/templates/legacy_json_templates/communicator) can

- `image_tags` (map[string]string) - Key/value pair tags that will be applied to the resulting image.

- `skip_create_image` (bool) - Skip creating the image. Defaults to `false`.

<!-- End of code generated from the comments of the TencentCloudImageConfig struct in builder/tencentcloud/cvm/image_config.go; -->


Expand Down
12 changes: 8 additions & 4 deletions builder/tencentcloud/cvm/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
// Build the steps
var steps []multistep.Step
steps = []multistep.Step{
&stepPreValidate{},
&stepPreValidate{
b.config.SkipCreateImage,
},
&stepCheckSourceImage{
b.config.SourceImageId,
},
Expand Down Expand Up @@ -145,13 +147,15 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
// We need this step to detach keypair from instance, otherwise
// it always fails to delete the key.
&stepDetachTempKeyPair{},
&stepCreateImage{},
&stepCreateImage{
b.config.SkipCreateImage,
},
&stepShareImage{
b.config.ImageShareAccounts,
},
&stepCopyImage{
DesinationRegions: b.config.ImageCopyRegions,
SourceRegion: b.config.Region,
DestinationRegions: b.config.ImageCopyRegions,
SourceRegion: b.config.Region,
},
}

Expand Down
2 changes: 2 additions & 0 deletions builder/tencentcloud/cvm/builder.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions builder/tencentcloud/cvm/image_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ type TencentCloudImageConfig struct {
// Key/value pair tags that will be applied to the resulting image.
ImageTags map[string]string `mapstructure:"image_tags" required:"false"`
skipValidation bool
// Skip creating the image. Defaults to `false`.
SkipCreateImage bool `mapstructure:"skip_create_image" required:"false"`
}

func (cf *TencentCloudImageConfig) Prepare(ctx *interpolate.Context) []error {
Expand Down
17 changes: 10 additions & 7 deletions builder/tencentcloud/cvm/step_copy_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,29 @@ import (
)

type stepCopyImage struct {
DesinationRegions []string
SourceRegion string
DestinationRegions []string
SourceRegion string
}

func (s *stepCopyImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
if len(s.DesinationRegions) == 0 || (len(s.DesinationRegions) == 1 && s.DesinationRegions[0] == s.SourceRegion) {
image, ok := state.GetOk("image")

// Skip if we don't have an image to copy or no regions to copy to
if !ok || len(s.DestinationRegions) == 0 || (len(s.DestinationRegions) == 1 && s.DestinationRegions[0] == s.SourceRegion) {
return multistep.ActionContinue
}

config := state.Get("config").(*Config)
client := state.Get("cvm_client").(*cvm.Client)

imageId := state.Get("image").(*cvm.Image).ImageId
imageId := image.(*cvm.Image).ImageId

Say(state, strings.Join(s.DesinationRegions, ","), "Trying to copy image to")
Say(state, strings.Join(s.DestinationRegions, ","), "Trying to copy image to")

req := cvm.NewSyncImagesRequest()
req.ImageIds = []*string{imageId}
copyRegions := make([]*string, 0, len(s.DesinationRegions))
for _, region := range s.DesinationRegions {
copyRegions := make([]*string, 0, len(s.DestinationRegions))
for _, region := range s.DestinationRegions {
if region != s.SourceRegion {
copyRegions = append(copyRegions, common.StringPtr(region))
}
Expand Down
23 changes: 16 additions & 7 deletions builder/tencentcloud/cvm/step_create_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

type stepCreateImage struct {
imageId string
SkipCreateImage bool
}

func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
Expand All @@ -21,6 +21,12 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
config := state.Get("config").(*Config)
instance := state.Get("instance").(*cvm.Instance)

// Optionally skip this step
if s.SkipCreateImage {
Say(state, "Skipping image creation step", "")
return multistep.ActionContinue
}

Say(state, config.ImageName, "Trying to create a new image")

req := cvm.NewCreateImageRequest()
Expand Down Expand Up @@ -95,22 +101,25 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
return Halt(state, fmt.Errorf("No image return"), "Failed to crate image")
}

s.imageId = *image.ImageId
state.Put("image", image)
Message(state, s.imageId, "Image created")
Message(state, *image.ImageId, "Image created")

tencentCloudImages := make(map[string]string)
tencentCloudImages[config.Region] = s.imageId
tencentCloudImages[config.Region] = *image.ImageId
state.Put("tencentcloudimages", tencentCloudImages)

return multistep.ActionContinue
}

func (s *stepCreateImage) Cleanup(state multistep.StateBag) {
if s.imageId == "" {
// Skip cleanup if we never created an image
image, ok := state.GetOk("image")
if !ok {
return
}

imageId := image.(*cvm.Image).ImageId

_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if !cancelled && !halted {
Expand All @@ -123,12 +132,12 @@ func (s *stepCreateImage) Cleanup(state multistep.StateBag) {
SayClean(state, "image")

req := cvm.NewDeleteImagesRequest()
req.ImageIds = []*string{&s.imageId}
req.ImageIds = []*string{imageId}
err := Retry(ctx, func(ctx context.Context) error {
_, e := client.DeleteImages(req)
return e
})
if err != nil {
Error(state, err, fmt.Sprintf("Failed to delete image(%s), please delete it manually", s.imageId))
Error(state, err, fmt.Sprintf("Failed to delete image(%s), please delete it manually", imageId))
}
}
6 changes: 6 additions & 0 deletions builder/tencentcloud/cvm/step_pre_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@ import (
)

type stepPreValidate struct {
SkipCreateImage bool
}

func (s *stepPreValidate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
// No need to validate the image name if we're not creating an image
if s.SkipCreateImage {
return multistep.ActionContinue
}

config := state.Get("config").(*Config)
client := state.Get("cvm_client").(*cvm.Client)

Expand Down
11 changes: 9 additions & 2 deletions builder/tencentcloud/cvm/step_share_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ type stepShareImage struct {
}

func (s *stepShareImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
if len(s.ShareAccounts) == 0 {
// Skip step if we don't have an image to share or no accounts to share to
_, ok := state.GetOk("image")
if !ok || len(s.ShareAccounts) == 0 {
return multistep.ActionContinue
}

Expand Down Expand Up @@ -58,7 +60,12 @@ func (s *stepShareImage) Cleanup(state multistep.StateBag) {
ctx := context.TODO()
client := state.Get("cvm_client").(*cvm.Client)

imageId := state.Get("image").(*cvm.Image).ImageId
image, ok := state.GetOk("image")
if !ok {
return
}

imageId := image.(*cvm.Image).ImageId
SayClean(state, "image share")

req := cvm.NewModifyImageSharePermissionRequest()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@

- `image_tags` (map[string]string) - Key/value pair tags that will be applied to the resulting image.

- `skip_create_image` (bool) - Skip creating the image. Defaults to `false`.

<!-- End of code generated from the comments of the TencentCloudImageConfig struct in builder/tencentcloud/cvm/image_config.go; -->