add:argument key SourceImageName to get source image by name.

This commit is contained in:
piggona 2020-07-20 17:12:46 +08:00
parent 8fc4e03139
commit a1b6f809c7
3 changed files with 48 additions and 11 deletions

View File

@ -31,7 +31,8 @@ type FlatConfig struct {
ImageCopyRegions []string `mapstructure:"image_copy_regions" required:"false" cty:"image_copy_regions" hcl:"image_copy_regions"` ImageCopyRegions []string `mapstructure:"image_copy_regions" required:"false" cty:"image_copy_regions" hcl:"image_copy_regions"`
ImageShareAccounts []string `mapstructure:"image_share_accounts" required:"false" cty:"image_share_accounts" hcl:"image_share_accounts"` ImageShareAccounts []string `mapstructure:"image_share_accounts" required:"false" cty:"image_share_accounts" hcl:"image_share_accounts"`
AssociatePublicIpAddress *bool `mapstructure:"associate_public_ip_address" required:"false" cty:"associate_public_ip_address" hcl:"associate_public_ip_address"` AssociatePublicIpAddress *bool `mapstructure:"associate_public_ip_address" required:"false" cty:"associate_public_ip_address" hcl:"associate_public_ip_address"`
SourceImageId *string `mapstructure:"source_image_id" required:"true" cty:"source_image_id" hcl:"source_image_id"` SourceImageId *string `mapstructure:"source_image_id" required:"false" cty:"source_image_id" hcl:"source_image_id"`
SourceImageName *string `mapstructure:"source_image_name" required:"false" cty:"source_image_name" hcl:"source_image_name"`
InstanceType *string `mapstructure:"instance_type" required:"true" cty:"instance_type" hcl:"instance_type"` InstanceType *string `mapstructure:"instance_type" required:"true" cty:"instance_type" hcl:"instance_type"`
InstanceName *string `mapstructure:"instance_name" required:"false" cty:"instance_name" hcl:"instance_name"` InstanceName *string `mapstructure:"instance_name" required:"false" cty:"instance_name" hcl:"instance_name"`
DiskType *string `mapstructure:"disk_type" required:"false" cty:"disk_type" hcl:"disk_type"` DiskType *string `mapstructure:"disk_type" required:"false" cty:"disk_type" hcl:"disk_type"`
@ -136,6 +137,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"image_share_accounts": &hcldec.AttrSpec{Name: "image_share_accounts", Type: cty.List(cty.String), Required: false}, "image_share_accounts": &hcldec.AttrSpec{Name: "image_share_accounts", Type: cty.List(cty.String), Required: false},
"associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false}, "associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false},
"source_image_id": &hcldec.AttrSpec{Name: "source_image_id", Type: cty.String, Required: false}, "source_image_id": &hcldec.AttrSpec{Name: "source_image_id", Type: cty.String, Required: false},
"source_image_name": &hcldec.AttrSpec{Name: "source_image_name", Type: cty.String, Required: false},
"instance_type": &hcldec.AttrSpec{Name: "instance_type", Type: cty.String, Required: false}, "instance_type": &hcldec.AttrSpec{Name: "instance_type", Type: cty.String, Required: false},
"instance_name": &hcldec.AttrSpec{Name: "instance_name", Type: cty.String, Required: false}, "instance_name": &hcldec.AttrSpec{Name: "instance_name", Type: cty.String, Required: false},
"disk_type": &hcldec.AttrSpec{Name: "disk_type", Type: cty.String, Required: false}, "disk_type": &hcldec.AttrSpec{Name: "disk_type", Type: cty.String, Required: false},

View File

@ -27,7 +27,10 @@ type TencentCloudRunConfig struct {
AssociatePublicIpAddress bool `mapstructure:"associate_public_ip_address" required:"false"` AssociatePublicIpAddress bool `mapstructure:"associate_public_ip_address" required:"false"`
// The base image id of Image you want to create // The base image id of Image you want to create
// your customized image from. // your customized image from.
SourceImageId string `mapstructure:"source_image_id" required:"true"` SourceImageId string `mapstructure:"source_image_id" required:"false"`
// The base image name of Image you want to create your
// customized image from.Conflict with SourceImageId.
SourceImageName string `mapstructure:"source_image_name" required:"false"`
// The instance type your cvm will be launched by. // The instance type your cvm will be launched by.
// You should reference Instace Type // You should reference Instace Type
// for parameter taking. // for parameter taking.
@ -108,11 +111,11 @@ func (cf *TencentCloudRunConfig) Prepare(ctx *interpolate.Context) []error {
} }
errs := cf.Comm.Prepare(ctx) errs := cf.Comm.Prepare(ctx)
if cf.SourceImageId == "" { if cf.SourceImageId == "" && cf.SourceImageName == "" {
errs = append(errs, errors.New("source_image_id must be specified")) errs = append(errs, errors.New("source_image_id or source_image_name must be specified"))
} }
if !CheckResourceIdFormat("img", cf.SourceImageId) { if cf.SourceImageId != "" && !CheckResourceIdFormat("img", cf.SourceImageId) {
errs = append(errs, errors.New("source_image_id wrong format")) errs = append(errs, errors.New("source_image_id wrong format"))
} }

View File

@ -3,6 +3,7 @@ package cvm
import ( import (
"context" "context"
"fmt" "fmt"
"regexp"
"github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/helper/multistep"
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
@ -13,16 +14,36 @@ type stepCheckSourceImage struct {
} }
func (s *stepCheckSourceImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { func (s *stepCheckSourceImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
var (
imageNameRegex *regexp.Regexp
err error
)
config := state.Get("config").(*Config) config := state.Get("config").(*Config)
client := state.Get("cvm_client").(*cvm.Client) client := state.Get("cvm_client").(*cvm.Client)
Say(state, config.SourceImageId, "Trying to check source image") Say(state, config.SourceImageId, "Trying to check source image")
req := cvm.NewDescribeImagesRequest() req := cvm.NewDescribeImagesRequest()
req.ImageIds = []*string{&config.SourceImageId} // req.InstanceType = &config.InstanceType
req.InstanceType = &config.InstanceType if config.SourceImageId != "" {
req.ImageIds = []*string{&config.SourceImageId}
} else {
imageNameRegex, err = regexp.Compile(config.SourceImageName)
if err != nil {
return Halt(state, fmt.Errorf("regex compilation error"), "Bad input")
}
private := "PRIVATE_IMAGE"
public := "PUBLIC_IMAGE"
shared := "SHARED_IMAGE"
filterType := "image-type"
filter := &cvm.Filter{
Name: &filterType,
Values: []*string{&private, &public, &shared},
}
req.Filters = []*cvm.Filter{filter}
}
var resp *cvm.DescribeImagesResponse var resp *cvm.DescribeImagesResponse
err := Retry(ctx, func(ctx context.Context) error { err = Retry(ctx, func(ctx context.Context) error {
var err error var err error
resp, err = client.DescribeImages(req) resp, err = client.DescribeImages(req)
return err return err
@ -32,9 +53,20 @@ func (s *stepCheckSourceImage) Run(ctx context.Context, state multistep.StateBag
} }
if *resp.Response.TotalCount > 0 { if *resp.Response.TotalCount > 0 {
state.Put("source_image", resp.Response.ImageSet[0]) images := resp.Response.ImageSet
Message(state, *resp.Response.ImageSet[0].ImageName, "Image found") if imageNameRegex != nil {
return multistep.ActionContinue for _, image := range images {
if imageNameRegex.MatchString(*image.ImageName) {
state.Put("source_image", image)
Message(state, *image.ImageName, "Image found")
return multistep.ActionContinue
}
}
} else {
state.Put("source_image", images[0])
Message(state, *resp.Response.ImageSet[0].ImageName, "Image found")
return multistep.ActionContinue
}
} }
return Halt(state, fmt.Errorf("No image found under current instance_type(%s) restriction", config.InstanceType), "") return Halt(state, fmt.Errorf("No image found under current instance_type(%s) restriction", config.InstanceType), "")