From bcb25f191642e9f0c8250040cdeed43c079b7fd2 Mon Sep 17 00:00:00 2001 From: Sylvia Moss Date: Thu, 22 Apr 2021 15:21:34 +0200 Subject: [PATCH] Extract Tencent Cloud (#10967) * extract and vendor tencentcloud plugin * fix fmt --- builder/tencentcloud/cvm/access_config.go | 159 ------------ .../tencentcloud/cvm/access_config_test.go | 31 --- builder/tencentcloud/cvm/artifact.go | 150 ----------- builder/tencentcloud/cvm/builder.go | 163 ------------ builder/tencentcloud/cvm/builder.hcl2spec.go | 220 ---------------- builder/tencentcloud/cvm/common.go | 229 ----------------- builder/tencentcloud/cvm/image_config.go | 79 ------ builder/tencentcloud/cvm/image_config_test.go | 34 --- builder/tencentcloud/cvm/run_config.go | 208 ---------------- .../tencentcloud/cvm/run_config.hcl2spec.go | 35 --- builder/tencentcloud/cvm/run_config_test.go | 135 ---------- .../cvm/step_check_source_image.go | 66 ----- .../tencentcloud/cvm/step_config_key_pair.go | 120 --------- .../cvm/step_config_security_group.go | 128 ---------- .../tencentcloud/cvm/step_config_subnet.go | 93 ------- builder/tencentcloud/cvm/step_config_vpc.go | 85 ------- builder/tencentcloud/cvm/step_copy_image.go | 81 ------ builder/tencentcloud/cvm/step_create_image.go | 111 --------- .../cvm/step_detach_temp_key_pair.go | 49 ---- builder/tencentcloud/cvm/step_pre_validate.go | 34 --- builder/tencentcloud/cvm/step_run_instance.go | 222 ----------------- builder/tencentcloud/cvm/step_share_image.go | 76 ------ .../examples/basic-with-data-disk.json | 40 --- builder/tencentcloud/examples/basic.json | 34 --- builder/tencentcloud/examples/centos.json | 42 ---- builder/tencentcloud/version/version.go | 13 - command/plugin.go | 18 +- command/vendored_plugins.go | 2 + go.mod | 3 +- go.sum | 3 + website/content/docs/builders/cloudstack.mdx | 235 ------------------ .../docs/builders/tencentcloud-cvm.mdx | 186 -------------- website/content/docs/builders/vagrant.mdx | 217 ---------------- .../TencentCloudAccessConfig-not-required.mdx | 5 - .../cvm/TencentCloudAccessConfig-required.mdx | 17 -- .../TencentCloudImageConfig-not-required.mdx | 23 -- .../cvm/TencentCloudImageConfig-required.mdx | 7 - .../TencentCloudRunConfig-not-required.mdx | 73 ------ .../cvm/TencentCloudRunConfig-required.mdx | 7 - .../cvm/tencentCloudDataDisk-not-required.mdx | 9 - website/data/docs-nav-data.json | 4 - website/data/docs-remote-plugins.json | 6 + 42 files changed, 20 insertions(+), 3432 deletions(-) delete mode 100644 builder/tencentcloud/cvm/access_config.go delete mode 100644 builder/tencentcloud/cvm/access_config_test.go delete mode 100644 builder/tencentcloud/cvm/artifact.go delete mode 100644 builder/tencentcloud/cvm/builder.go delete mode 100644 builder/tencentcloud/cvm/builder.hcl2spec.go delete mode 100644 builder/tencentcloud/cvm/common.go delete mode 100644 builder/tencentcloud/cvm/image_config.go delete mode 100644 builder/tencentcloud/cvm/image_config_test.go delete mode 100644 builder/tencentcloud/cvm/run_config.go delete mode 100644 builder/tencentcloud/cvm/run_config.hcl2spec.go delete mode 100644 builder/tencentcloud/cvm/run_config_test.go delete mode 100644 builder/tencentcloud/cvm/step_check_source_image.go delete mode 100644 builder/tencentcloud/cvm/step_config_key_pair.go delete mode 100644 builder/tencentcloud/cvm/step_config_security_group.go delete mode 100644 builder/tencentcloud/cvm/step_config_subnet.go delete mode 100644 builder/tencentcloud/cvm/step_config_vpc.go delete mode 100644 builder/tencentcloud/cvm/step_copy_image.go delete mode 100644 builder/tencentcloud/cvm/step_create_image.go delete mode 100644 builder/tencentcloud/cvm/step_detach_temp_key_pair.go delete mode 100644 builder/tencentcloud/cvm/step_pre_validate.go delete mode 100644 builder/tencentcloud/cvm/step_run_instance.go delete mode 100644 builder/tencentcloud/cvm/step_share_image.go delete mode 100644 builder/tencentcloud/examples/basic-with-data-disk.json delete mode 100644 builder/tencentcloud/examples/basic.json delete mode 100644 builder/tencentcloud/examples/centos.json delete mode 100644 builder/tencentcloud/version/version.go delete mode 100644 website/content/docs/builders/cloudstack.mdx delete mode 100644 website/content/docs/builders/tencentcloud-cvm.mdx delete mode 100644 website/content/docs/builders/vagrant.mdx delete mode 100644 website/content/partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-not-required.mdx delete mode 100644 website/content/partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-required.mdx delete mode 100644 website/content/partials/builder/tencentcloud/cvm/TencentCloudImageConfig-not-required.mdx delete mode 100644 website/content/partials/builder/tencentcloud/cvm/TencentCloudImageConfig-required.mdx delete mode 100644 website/content/partials/builder/tencentcloud/cvm/TencentCloudRunConfig-not-required.mdx delete mode 100644 website/content/partials/builder/tencentcloud/cvm/TencentCloudRunConfig-required.mdx delete mode 100644 website/content/partials/builder/tencentcloud/cvm/tencentCloudDataDisk-not-required.mdx diff --git a/builder/tencentcloud/cvm/access_config.go b/builder/tencentcloud/cvm/access_config.go deleted file mode 100644 index f900b0c80..000000000 --- a/builder/tencentcloud/cvm/access_config.go +++ /dev/null @@ -1,159 +0,0 @@ -//go:generate packer-sdc struct-markdown - -package cvm - -import ( - "context" - "fmt" - "os" - - "github.com/hashicorp/packer-plugin-sdk/template/interpolate" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" - vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" -) - -type Region string - -// below would be moved to tencentcloud sdk git repo -const ( - Bangkok = Region("ap-bangkok") - Beijing = Region("ap-beijing") - Chengdu = Region("ap-chengdu") - Chongqing = Region("ap-chongqing") - Guangzhou = Region("ap-guangzhou") - GuangzhouOpen = Region("ap-guangzhou-open") - Hongkong = Region("ap-hongkong") - Mumbai = Region("ap-mumbai") - Seoul = Region("ap-seoul") - Shanghai = Region("ap-shanghai") - ShanghaiFsi = Region("ap-shanghai-fsi") - ShenzhenFsi = Region("ap-shenzhen-fsi") - Singapore = Region("ap-singapore") - Tokyo = Region("ap-tokyo") - Frankfurt = Region("eu-frankfurt") - Moscow = Region("eu-moscow") - Ashburn = Region("na-ashburn") - Siliconvalley = Region("na-siliconvalley") - Toronto = Region("na-toronto") -) - -var ValidRegions = []Region{ - Bangkok, Beijing, Chengdu, Chongqing, Guangzhou, GuangzhouOpen, Hongkong, Shanghai, - ShanghaiFsi, ShenzhenFsi, - Mumbai, Seoul, Singapore, Tokyo, Moscow, - Frankfurt, Ashburn, Siliconvalley, Toronto, -} - -type TencentCloudAccessConfig struct { - // Tencentcloud secret id. You should set it directly, - // or set the TENCENTCLOUD_ACCESS_KEY environment variable. - SecretId string `mapstructure:"secret_id" required:"true"` - // Tencentcloud secret key. You should set it directly, - // or set the TENCENTCLOUD_SECRET_KEY environment variable. - SecretKey string `mapstructure:"secret_key" required:"true"` - // The region where your cvm will be launch. You should - // reference Region and Zone - // for parameter taking. - Region string `mapstructure:"region" required:"true"` - // The zone where your cvm will be launch. You should - // reference Region and Zone - // for parameter taking. - Zone string `mapstructure:"zone" required:"true"` - // Do not check region and zone when validate. - SkipValidation bool `mapstructure:"skip_region_validation" required:"false"` -} - -func (cf *TencentCloudAccessConfig) Client() (*cvm.Client, *vpc.Client, error) { - var ( - err error - cvm_client *cvm.Client - vpc_client *vpc.Client - resp *cvm.DescribeZonesResponse - ) - - if err = cf.validateRegion(); err != nil { - return nil, nil, err - } - - if cf.Zone == "" { - return nil, nil, fmt.Errorf("parameter zone must be set") - } - - if cvm_client, err = NewCvmClient(cf.SecretId, cf.SecretKey, cf.Region); err != nil { - return nil, nil, err - } - - if vpc_client, err = NewVpcClient(cf.SecretId, cf.SecretKey, cf.Region); err != nil { - return nil, nil, err - } - - ctx := context.TODO() - err = Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = cvm_client.DescribeZones(nil) - return e - }) - if err != nil { - return nil, nil, err - } - - for _, zone := range resp.Response.ZoneSet { - if cf.Zone == *zone.Zone { - return cvm_client, vpc_client, nil - } - } - - return nil, nil, fmt.Errorf("unknown zone: %s", cf.Zone) -} - -func (cf *TencentCloudAccessConfig) Prepare(ctx *interpolate.Context) []error { - var errs []error - - if err := cf.Config(); err != nil { - errs = append(errs, err) - } - - if cf.Region == "" { - errs = append(errs, fmt.Errorf("parameter region must be set")) - } else if !cf.SkipValidation { - if err := cf.validateRegion(); err != nil { - errs = append(errs, err) - } - } - - if len(errs) > 0 { - return errs - } - - return nil -} - -func (cf *TencentCloudAccessConfig) Config() error { - if cf.SecretId == "" { - cf.SecretId = os.Getenv("TENCENTCLOUD_SECRET_ID") - } - - if cf.SecretKey == "" { - cf.SecretKey = os.Getenv("TENCENTCLOUD_SECRET_KEY") - } - - if cf.SecretId == "" || cf.SecretKey == "" { - return fmt.Errorf("parameter secret_id and secret_key must be set") - } - - return nil -} - -func (cf *TencentCloudAccessConfig) validateRegion() error { - return validRegion(cf.Region) -} - -func validRegion(region string) error { - for _, valid := range ValidRegions { - if Region(region) == valid { - return nil - } - } - - return fmt.Errorf("unknown region: %s", region) -} diff --git a/builder/tencentcloud/cvm/access_config_test.go b/builder/tencentcloud/cvm/access_config_test.go deleted file mode 100644 index 4d0a79cd1..000000000 --- a/builder/tencentcloud/cvm/access_config_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package cvm - -import ( - "testing" -) - -func TestTencentCloudAccessConfig_Prepare(t *testing.T) { - cf := TencentCloudAccessConfig{ - SecretId: "secret-id", - SecretKey: "secret-key", - } - - if err := cf.Prepare(nil); err == nil { - t.Fatal("should raise error: region not set") - } - - cf.Region = "ap-guangzhou" - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't raise error: %v", err) - } - - cf.Region = "unknown-region" - if err := cf.Prepare(nil); err == nil { - t.Fatal("should raise error: unknown region") - } - - cf.SkipValidation = true - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't raise error: %v", err) - } -} diff --git a/builder/tencentcloud/cvm/artifact.go b/builder/tencentcloud/cvm/artifact.go deleted file mode 100644 index 6ee430d4a..000000000 --- a/builder/tencentcloud/cvm/artifact.go +++ /dev/null @@ -1,150 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - "log" - "sort" - "strings" - - packersdk "github.com/hashicorp/packer-plugin-sdk/packer" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" -) - -type Artifact struct { - TencentCloudImages map[string]string - BuilderIdValue string - Client *cvm.Client - - // StateData should store data such as GeneratedData - // to be shared with post-processors - StateData map[string]interface{} -} - -func (a *Artifact) BuilderId() string { - return a.BuilderIdValue -} - -func (*Artifact) Files() []string { - return nil -} - -func (a *Artifact) Id() string { - parts := make([]string, 0, len(a.TencentCloudImages)) - for region, imageId := range a.TencentCloudImages { - parts = append(parts, fmt.Sprintf("%s:%s", region, imageId)) - } - sort.Strings(parts) - - return strings.Join(parts, ",") -} - -func (a *Artifact) String() string { - parts := make([]string, 0, len(a.TencentCloudImages)) - for region, imageId := range a.TencentCloudImages { - parts = append(parts, fmt.Sprintf("%s: %s", region, imageId)) - } - sort.Strings(parts) - - return fmt.Sprintf("Tencentcloud images(%s) were created.\n\n", strings.Join(parts, "\n")) -} - -func (a *Artifact) State(name string) interface{} { - if _, ok := a.StateData[name]; ok { - return a.StateData[name] - } - - switch name { - case "atlas.artifact.metadata": - return a.stateAtlasMetadata() - default: - return nil - } -} - -func (a *Artifact) Destroy() error { - ctx := context.TODO() - errors := make([]error, 0) - - for region, imageId := range a.TencentCloudImages { - log.Printf("Delete tencentcloud image ID(%s) from region(%s)", imageId, region) - - describeReq := cvm.NewDescribeImagesRequest() - describeReq.ImageIds = []*string{&imageId} - var describeResp *cvm.DescribeImagesResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - describeResp, e = a.Client.DescribeImages(describeReq) - return e - }) - if err != nil { - errors = append(errors, err) - continue - } - - if *describeResp.Response.TotalCount == 0 { - errors = append(errors, fmt.Errorf( - "describe images failed, region(%s) ImageId(%s)", region, imageId)) - } - - var shareAccountIds []*string = nil - describeShareReq := cvm.NewDescribeImageSharePermissionRequest() - describeShareReq.ImageId = &imageId - var describeShareResp *cvm.DescribeImageSharePermissionResponse - err = Retry(ctx, func(ctx context.Context) error { - var e error - describeShareResp, e = a.Client.DescribeImageSharePermission(describeShareReq) - return e - }) - if err != nil { - errors = append(errors, err) - } else { - for _, sharePermission := range describeShareResp.Response.SharePermissionSet { - shareAccountIds = append(shareAccountIds, sharePermission.AccountId) - } - } - - if len(shareAccountIds) != 0 { - cancelShareReq := cvm.NewModifyImageSharePermissionRequest() - cancelShareReq.ImageId = &imageId - cancelShareReq.AccountIds = shareAccountIds - CANCEL := "CANCEL" - cancelShareReq.Permission = &CANCEL - err := Retry(ctx, func(ctx context.Context) error { - _, e := a.Client.ModifyImageSharePermission(cancelShareReq) - return e - }) - if err != nil { - errors = append(errors, err) - } - } - - deleteReq := cvm.NewDeleteImagesRequest() - deleteReq.ImageIds = []*string{&imageId} - err = Retry(ctx, func(ctx context.Context) error { - _, e := a.Client.DeleteImages(deleteReq) - return e - }) - if err != nil { - errors = append(errors, err) - } - } - - if len(errors) == 1 { - return errors[0] - } else if len(errors) > 1 { - return &packersdk.MultiError{Errors: errors} - } else { - return nil - } -} - -func (a *Artifact) stateAtlasMetadata() interface{} { - metadata := make(map[string]string) - for region, imageId := range a.TencentCloudImages { - k := fmt.Sprintf("region.%s", region) - metadata[k] = imageId - } - - return metadata -} diff --git a/builder/tencentcloud/cvm/builder.go b/builder/tencentcloud/cvm/builder.go deleted file mode 100644 index 3c1e42f0e..000000000 --- a/builder/tencentcloud/cvm/builder.go +++ /dev/null @@ -1,163 +0,0 @@ -//go:generate packer-sdc mapstructure-to-hcl2 -type Config - -package cvm - -import ( - "context" - "fmt" - - "github.com/hashicorp/hcl/v2/hcldec" - "github.com/hashicorp/packer-plugin-sdk/common" - "github.com/hashicorp/packer-plugin-sdk/communicator" - "github.com/hashicorp/packer-plugin-sdk/multistep" - "github.com/hashicorp/packer-plugin-sdk/multistep/commonsteps" - packersdk "github.com/hashicorp/packer-plugin-sdk/packer" - "github.com/hashicorp/packer-plugin-sdk/template/config" - "github.com/hashicorp/packer-plugin-sdk/template/interpolate" -) - -const BuilderId = "tencent.cloud" - -type Config struct { - common.PackerConfig `mapstructure:",squash"` - TencentCloudAccessConfig `mapstructure:",squash"` - TencentCloudImageConfig `mapstructure:",squash"` - TencentCloudRunConfig `mapstructure:",squash"` - - ctx interpolate.Context -} - -type Builder struct { - config Config - runner multistep.Runner -} - -func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() } - -func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { - err := config.Decode(&b.config, &config.DecodeOpts{ - PluginType: BuilderId, - Interpolate: true, - InterpolateContext: &b.config.ctx, - InterpolateFilter: &interpolate.RenderFilter{ - Exclude: []string{ - "run_command", - }, - }, - }, raws...) - b.config.ctx.EnableEnv = true - if err != nil { - return nil, nil, err - } - - // Accumulate any errors - var errs *packersdk.MultiError - errs = packersdk.MultiErrorAppend(errs, b.config.TencentCloudAccessConfig.Prepare(&b.config.ctx)...) - errs = packersdk.MultiErrorAppend(errs, b.config.TencentCloudImageConfig.Prepare(&b.config.ctx)...) - errs = packersdk.MultiErrorAppend(errs, b.config.TencentCloudRunConfig.Prepare(&b.config.ctx)...) - if errs != nil && len(errs.Errors) > 0 { - return nil, nil, errs - } - - packersdk.LogSecretFilter.Set(b.config.SecretId, b.config.SecretKey) - - return nil, nil, nil -} - -func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) (packersdk.Artifact, error) { - cvmClient, vpcClient, err := b.config.Client() - if err != nil { - return nil, err - } - - state := new(multistep.BasicStateBag) - state.Put("config", &b.config) - state.Put("cvm_client", cvmClient) - state.Put("vpc_client", vpcClient) - state.Put("hook", hook) - state.Put("ui", ui) - - // Build the steps - var steps []multistep.Step - steps = []multistep.Step{ - &stepPreValidate{}, - &stepCheckSourceImage{ - b.config.SourceImageId, - }, - &stepConfigKeyPair{ - Debug: b.config.PackerDebug, - Comm: &b.config.Comm, - DebugKeyPath: fmt.Sprintf("cvm_%s.pem", b.config.PackerBuildName), - }, - &stepConfigVPC{ - VpcId: b.config.VpcId, - CidrBlock: b.config.CidrBlock, - VpcName: b.config.VpcName, - }, - &stepConfigSubnet{ - SubnetId: b.config.SubnetId, - SubnetCidrBlock: b.config.SubnectCidrBlock, - SubnetName: b.config.SubnetName, - Zone: b.config.Zone, - }, - &stepConfigSecurityGroup{ - SecurityGroupId: b.config.SecurityGroupId, - SecurityGroupName: b.config.SecurityGroupName, - Description: "securitygroup for packer", - }, - &stepRunInstance{ - InstanceType: b.config.InstanceType, - UserData: b.config.UserData, - UserDataFile: b.config.UserDataFile, - ZoneId: b.config.Zone, - InstanceName: b.config.InstanceName, - DiskType: b.config.DiskType, - DiskSize: b.config.DiskSize, - DataDisks: b.config.DataDisks, - HostName: b.config.HostName, - InternetMaxBandwidthOut: b.config.InternetMaxBandwidthOut, - AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, - Tags: b.config.RunTags, - }, - &communicator.StepConnect{ - Config: &b.config.TencentCloudRunConfig.Comm, - SSHConfig: b.config.TencentCloudRunConfig.Comm.SSHConfigFunc(), - Host: SSHHost(b.config.AssociatePublicIpAddress), - }, - &commonsteps.StepProvision{}, - &commonsteps.StepCleanupTempKeys{ - Comm: &b.config.TencentCloudRunConfig.Comm, - }, - // We need this step to detach keypair from instance, otherwise - // it always fails to delete the key. - &stepDetachTempKeyPair{}, - &stepCreateImage{}, - &stepShareImage{ - b.config.ImageShareAccounts, - }, - &stepCopyImage{ - DesinationRegions: b.config.ImageCopyRegions, - SourceRegion: b.config.Region, - }, - } - - b.runner = commonsteps.NewRunner(steps, b.config.PackerConfig, ui) - b.runner.Run(ctx, state) - - if rawErr, ok := state.GetOk("error"); ok { - return nil, rawErr.(error) - } - - if _, ok := state.GetOk("image"); !ok { - return nil, nil - } - - artifact := &Artifact{ - TencentCloudImages: state.Get("tencentcloudimages").(map[string]string), - BuilderIdValue: BuilderId, - Client: cvmClient, - StateData: map[string]interface{}{"generated_data": state.Get("generated_data")}, - } - - return artifact, nil -} diff --git a/builder/tencentcloud/cvm/builder.hcl2spec.go b/builder/tencentcloud/cvm/builder.hcl2spec.go deleted file mode 100644 index 89a9126b9..000000000 --- a/builder/tencentcloud/cvm/builder.hcl2spec.go +++ /dev/null @@ -1,220 +0,0 @@ -// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT. - -package cvm - -import ( - "github.com/hashicorp/hcl/v2/hcldec" - "github.com/hashicorp/packer-plugin-sdk/template/config" - "github.com/zclconf/go-cty/cty" -) - -// FlatConfig is an auto-generated flat version of Config. -// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. -type FlatConfig struct { - PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"` - PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"` - PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"` - PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"` - PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"` - PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` - PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"` - PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"` - SecretId *string `mapstructure:"secret_id" required:"true" cty:"secret_id" hcl:"secret_id"` - SecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key" hcl:"secret_key"` - Region *string `mapstructure:"region" required:"true" cty:"region" hcl:"region"` - Zone *string `mapstructure:"zone" required:"true" cty:"zone" hcl:"zone"` - SkipValidation *bool `mapstructure:"skip_region_validation" required:"false" cty:"skip_region_validation" hcl:"skip_region_validation"` - ImageName *string `mapstructure:"image_name" required:"true" cty:"image_name" hcl:"image_name"` - ImageDescription *string `mapstructure:"image_description" required:"false" cty:"image_description" hcl:"image_description"` - Reboot *bool `mapstructure:"reboot" required:"false" cty:"reboot" hcl:"reboot"` - ForcePoweroff *bool `mapstructure:"force_poweroff" required:"false" cty:"force_poweroff" hcl:"force_poweroff"` - Sysprep *bool `mapstructure:"sysprep" required:"false" cty:"sysprep" hcl:"sysprep"` - ImageForceDelete *bool `mapstructure:"image_force_delete" cty:"image_force_delete" hcl:"image_force_delete"` - 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"` - 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:"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"` - 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"` - DiskSize *int64 `mapstructure:"disk_size" required:"false" cty:"disk_size" hcl:"disk_size"` - DataDisks []FlattencentCloudDataDisk `mapstructure:"data_disks" cty:"data_disks" hcl:"data_disks"` - VpcId *string `mapstructure:"vpc_id" required:"false" cty:"vpc_id" hcl:"vpc_id"` - VpcName *string `mapstructure:"vpc_name" required:"false" cty:"vpc_name" hcl:"vpc_name"` - VpcIp *string `mapstructure:"vpc_ip" cty:"vpc_ip" hcl:"vpc_ip"` - SubnetId *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id" hcl:"subnet_id"` - SubnetName *string `mapstructure:"subnet_name" required:"false" cty:"subnet_name" hcl:"subnet_name"` - CidrBlock *string `mapstructure:"cidr_block" required:"false" cty:"cidr_block" hcl:"cidr_block"` - SubnectCidrBlock *string `mapstructure:"subnect_cidr_block" required:"false" cty:"subnect_cidr_block" hcl:"subnect_cidr_block"` - InternetChargeType *string `mapstructure:"internet_charge_type" cty:"internet_charge_type" hcl:"internet_charge_type"` - InternetMaxBandwidthOut *int64 `mapstructure:"internet_max_bandwidth_out" required:"false" cty:"internet_max_bandwidth_out" hcl:"internet_max_bandwidth_out"` - SecurityGroupId *string `mapstructure:"security_group_id" required:"false" cty:"security_group_id" hcl:"security_group_id"` - SecurityGroupName *string `mapstructure:"security_group_name" required:"false" cty:"security_group_name" hcl:"security_group_name"` - UserData *string `mapstructure:"user_data" required:"false" cty:"user_data" hcl:"user_data"` - UserDataFile *string `mapstructure:"user_data_file" required:"false" cty:"user_data_file" hcl:"user_data_file"` - HostName *string `mapstructure:"host_name" required:"false" cty:"host_name" hcl:"host_name"` - RunTags map[string]string `mapstructure:"run_tags" required:"false" cty:"run_tags" hcl:"run_tags"` - RunTag []config.FlatKeyValue `mapstructure:"run_tag" required:"false" cty:"run_tag" hcl:"run_tag"` - Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"` - PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"` - SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"` - SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port" hcl:"ssh_port"` - SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username" hcl:"ssh_username"` - SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"` - SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"` - SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" undocumented:"true" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"` - SSHTemporaryKeyPairType *string `mapstructure:"temporary_key_pair_type" cty:"temporary_key_pair_type" hcl:"temporary_key_pair_type"` - SSHTemporaryKeyPairBits *int `mapstructure:"temporary_key_pair_bits" cty:"temporary_key_pair_bits" hcl:"temporary_key_pair_bits"` - SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"` - SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"` - SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"` - SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" undocumented:"true" cty:"ssh_private_key_file" hcl:"ssh_private_key_file"` - SSHCertificateFile *string `mapstructure:"ssh_certificate_file" cty:"ssh_certificate_file" hcl:"ssh_certificate_file"` - SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty" hcl:"ssh_pty"` - SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout" hcl:"ssh_timeout"` - SSHWaitTimeout *string `mapstructure:"ssh_wait_timeout" undocumented:"true" cty:"ssh_wait_timeout" hcl:"ssh_wait_timeout"` - SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" undocumented:"true" cty:"ssh_agent_auth" hcl:"ssh_agent_auth"` - SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding" hcl:"ssh_disable_agent_forwarding"` - SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts" hcl:"ssh_handshake_attempts"` - SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host" hcl:"ssh_bastion_host"` - SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port" hcl:"ssh_bastion_port"` - SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth" hcl:"ssh_bastion_agent_auth"` - SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username" hcl:"ssh_bastion_username"` - SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password" hcl:"ssh_bastion_password"` - SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive" hcl:"ssh_bastion_interactive"` - SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file" hcl:"ssh_bastion_private_key_file"` - SSHBastionCertificateFile *string `mapstructure:"ssh_bastion_certificate_file" cty:"ssh_bastion_certificate_file" hcl:"ssh_bastion_certificate_file"` - SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method" hcl:"ssh_file_transfer_method"` - SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host" hcl:"ssh_proxy_host"` - SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port" hcl:"ssh_proxy_port"` - SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username" hcl:"ssh_proxy_username"` - SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password" hcl:"ssh_proxy_password"` - SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval" hcl:"ssh_keep_alive_interval"` - SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout" hcl:"ssh_read_write_timeout"` - SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels" hcl:"ssh_remote_tunnels"` - SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels" hcl:"ssh_local_tunnels"` - SSHPublicKey []byte `mapstructure:"ssh_public_key" undocumented:"true" cty:"ssh_public_key" hcl:"ssh_public_key"` - SSHPrivateKey []byte `mapstructure:"ssh_private_key" undocumented:"true" cty:"ssh_private_key" hcl:"ssh_private_key"` - WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username" hcl:"winrm_username"` - WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password" hcl:"winrm_password"` - WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host" hcl:"winrm_host"` - WinRMNoProxy *bool `mapstructure:"winrm_no_proxy" cty:"winrm_no_proxy" hcl:"winrm_no_proxy"` - WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port" hcl:"winrm_port"` - WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout" hcl:"winrm_timeout"` - WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl" hcl:"winrm_use_ssl"` - WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure" hcl:"winrm_insecure"` - WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm" hcl:"winrm_use_ntlm"` - SSHPrivateIp *bool `mapstructure:"ssh_private_ip" cty:"ssh_private_ip" hcl:"ssh_private_ip"` -} - -// FlatMapstructure returns a new FlatConfig. -// FlatConfig is an auto-generated flat version of Config. -// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. -func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { - return new(FlatConfig) -} - -// HCL2Spec returns the hcl spec of a Config. -// This spec is used by HCL to read the fields of Config. -// The decoded values from this spec will then be applied to a FlatConfig. -func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { - s := map[string]hcldec.Spec{ - "packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false}, - "packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false}, - "packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false}, - "packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false}, - "packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false}, - "packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false}, - "packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false}, - "packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false}, - "secret_id": &hcldec.AttrSpec{Name: "secret_id", Type: cty.String, Required: false}, - "secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false}, - "region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false}, - "zone": &hcldec.AttrSpec{Name: "zone", Type: cty.String, Required: false}, - "skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false}, - "image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false}, - "image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false}, - "reboot": &hcldec.AttrSpec{Name: "reboot", Type: cty.Bool, Required: false}, - "force_poweroff": &hcldec.AttrSpec{Name: "force_poweroff", Type: cty.Bool, Required: false}, - "sysprep": &hcldec.AttrSpec{Name: "sysprep", Type: cty.Bool, Required: false}, - "image_force_delete": &hcldec.AttrSpec{Name: "image_force_delete", Type: cty.Bool, Required: false}, - "image_copy_regions": &hcldec.AttrSpec{Name: "image_copy_regions", 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}, - "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_name": &hcldec.AttrSpec{Name: "instance_name", Type: cty.String, Required: false}, - "disk_type": &hcldec.AttrSpec{Name: "disk_type", Type: cty.String, Required: false}, - "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false}, - "data_disks": &hcldec.BlockListSpec{TypeName: "data_disks", Nested: hcldec.ObjectSpec((*FlattencentCloudDataDisk)(nil).HCL2Spec())}, - "vpc_id": &hcldec.AttrSpec{Name: "vpc_id", Type: cty.String, Required: false}, - "vpc_name": &hcldec.AttrSpec{Name: "vpc_name", Type: cty.String, Required: false}, - "vpc_ip": &hcldec.AttrSpec{Name: "vpc_ip", Type: cty.String, Required: false}, - "subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false}, - "subnet_name": &hcldec.AttrSpec{Name: "subnet_name", Type: cty.String, Required: false}, - "cidr_block": &hcldec.AttrSpec{Name: "cidr_block", Type: cty.String, Required: false}, - "subnect_cidr_block": &hcldec.AttrSpec{Name: "subnect_cidr_block", Type: cty.String, Required: false}, - "internet_charge_type": &hcldec.AttrSpec{Name: "internet_charge_type", Type: cty.String, Required: false}, - "internet_max_bandwidth_out": &hcldec.AttrSpec{Name: "internet_max_bandwidth_out", Type: cty.Number, Required: false}, - "security_group_id": &hcldec.AttrSpec{Name: "security_group_id", Type: cty.String, Required: false}, - "security_group_name": &hcldec.AttrSpec{Name: "security_group_name", Type: cty.String, Required: false}, - "user_data": &hcldec.AttrSpec{Name: "user_data", Type: cty.String, Required: false}, - "user_data_file": &hcldec.AttrSpec{Name: "user_data_file", Type: cty.String, Required: false}, - "host_name": &hcldec.AttrSpec{Name: "host_name", Type: cty.String, Required: false}, - "run_tags": &hcldec.AttrSpec{Name: "run_tags", Type: cty.Map(cty.String), Required: false}, - "run_tag": &hcldec.BlockListSpec{TypeName: "run_tag", Nested: hcldec.ObjectSpec((*config.FlatKeyValue)(nil).HCL2Spec())}, - "communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false}, - "pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false}, - "ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false}, - "ssh_port": &hcldec.AttrSpec{Name: "ssh_port", Type: cty.Number, Required: false}, - "ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false}, - "ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false}, - "ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false}, - "temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false}, - "temporary_key_pair_type": &hcldec.AttrSpec{Name: "temporary_key_pair_type", Type: cty.String, Required: false}, - "temporary_key_pair_bits": &hcldec.AttrSpec{Name: "temporary_key_pair_bits", Type: cty.Number, Required: false}, - "ssh_ciphers": &hcldec.AttrSpec{Name: "ssh_ciphers", Type: cty.List(cty.String), Required: false}, - "ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false}, - "ssh_key_exchange_algorithms": &hcldec.AttrSpec{Name: "ssh_key_exchange_algorithms", Type: cty.List(cty.String), Required: false}, - "ssh_private_key_file": &hcldec.AttrSpec{Name: "ssh_private_key_file", Type: cty.String, Required: false}, - "ssh_certificate_file": &hcldec.AttrSpec{Name: "ssh_certificate_file", Type: cty.String, Required: false}, - "ssh_pty": &hcldec.AttrSpec{Name: "ssh_pty", Type: cty.Bool, Required: false}, - "ssh_timeout": &hcldec.AttrSpec{Name: "ssh_timeout", Type: cty.String, Required: false}, - "ssh_wait_timeout": &hcldec.AttrSpec{Name: "ssh_wait_timeout", Type: cty.String, Required: false}, - "ssh_agent_auth": &hcldec.AttrSpec{Name: "ssh_agent_auth", Type: cty.Bool, Required: false}, - "ssh_disable_agent_forwarding": &hcldec.AttrSpec{Name: "ssh_disable_agent_forwarding", Type: cty.Bool, Required: false}, - "ssh_handshake_attempts": &hcldec.AttrSpec{Name: "ssh_handshake_attempts", Type: cty.Number, Required: false}, - "ssh_bastion_host": &hcldec.AttrSpec{Name: "ssh_bastion_host", Type: cty.String, Required: false}, - "ssh_bastion_port": &hcldec.AttrSpec{Name: "ssh_bastion_port", Type: cty.Number, Required: false}, - "ssh_bastion_agent_auth": &hcldec.AttrSpec{Name: "ssh_bastion_agent_auth", Type: cty.Bool, Required: false}, - "ssh_bastion_username": &hcldec.AttrSpec{Name: "ssh_bastion_username", Type: cty.String, Required: false}, - "ssh_bastion_password": &hcldec.AttrSpec{Name: "ssh_bastion_password", Type: cty.String, Required: false}, - "ssh_bastion_interactive": &hcldec.AttrSpec{Name: "ssh_bastion_interactive", Type: cty.Bool, Required: false}, - "ssh_bastion_private_key_file": &hcldec.AttrSpec{Name: "ssh_bastion_private_key_file", Type: cty.String, Required: false}, - "ssh_bastion_certificate_file": &hcldec.AttrSpec{Name: "ssh_bastion_certificate_file", Type: cty.String, Required: false}, - "ssh_file_transfer_method": &hcldec.AttrSpec{Name: "ssh_file_transfer_method", Type: cty.String, Required: false}, - "ssh_proxy_host": &hcldec.AttrSpec{Name: "ssh_proxy_host", Type: cty.String, Required: false}, - "ssh_proxy_port": &hcldec.AttrSpec{Name: "ssh_proxy_port", Type: cty.Number, Required: false}, - "ssh_proxy_username": &hcldec.AttrSpec{Name: "ssh_proxy_username", Type: cty.String, Required: false}, - "ssh_proxy_password": &hcldec.AttrSpec{Name: "ssh_proxy_password", Type: cty.String, Required: false}, - "ssh_keep_alive_interval": &hcldec.AttrSpec{Name: "ssh_keep_alive_interval", Type: cty.String, Required: false}, - "ssh_read_write_timeout": &hcldec.AttrSpec{Name: "ssh_read_write_timeout", Type: cty.String, Required: false}, - "ssh_remote_tunnels": &hcldec.AttrSpec{Name: "ssh_remote_tunnels", Type: cty.List(cty.String), Required: false}, - "ssh_local_tunnels": &hcldec.AttrSpec{Name: "ssh_local_tunnels", Type: cty.List(cty.String), Required: false}, - "ssh_public_key": &hcldec.AttrSpec{Name: "ssh_public_key", Type: cty.List(cty.Number), Required: false}, - "ssh_private_key": &hcldec.AttrSpec{Name: "ssh_private_key", Type: cty.List(cty.Number), Required: false}, - "winrm_username": &hcldec.AttrSpec{Name: "winrm_username", Type: cty.String, Required: false}, - "winrm_password": &hcldec.AttrSpec{Name: "winrm_password", Type: cty.String, Required: false}, - "winrm_host": &hcldec.AttrSpec{Name: "winrm_host", Type: cty.String, Required: false}, - "winrm_no_proxy": &hcldec.AttrSpec{Name: "winrm_no_proxy", Type: cty.Bool, Required: false}, - "winrm_port": &hcldec.AttrSpec{Name: "winrm_port", Type: cty.Number, Required: false}, - "winrm_timeout": &hcldec.AttrSpec{Name: "winrm_timeout", Type: cty.String, Required: false}, - "winrm_use_ssl": &hcldec.AttrSpec{Name: "winrm_use_ssl", Type: cty.Bool, Required: false}, - "winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false}, - "winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false}, - "ssh_private_ip": &hcldec.AttrSpec{Name: "ssh_private_ip", Type: cty.Bool, Required: false}, - } - return s -} diff --git a/builder/tencentcloud/cvm/common.go b/builder/tencentcloud/cvm/common.go deleted file mode 100644 index d827e8f39..000000000 --- a/builder/tencentcloud/cvm/common.go +++ /dev/null @@ -1,229 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - "regexp" - "strings" - "time" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - packersdk "github.com/hashicorp/packer-plugin-sdk/packer" - "github.com/hashicorp/packer-plugin-sdk/retry" - "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" - "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" - "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" - vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" -) - -// DefaultWaitForInterval is sleep interval when wait statue -const DefaultWaitForInterval = 5 - -// WaitForInstance wait for instance reaches statue -func WaitForInstance(ctx context.Context, client *cvm.Client, instanceId string, status string, timeout int) error { - req := cvm.NewDescribeInstancesRequest() - req.InstanceIds = []*string{&instanceId} - - for { - var resp *cvm.DescribeInstancesResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = client.DescribeInstances(req) - return e - }) - if err != nil { - return err - } - if *resp.Response.TotalCount == 0 { - return fmt.Errorf("instance(%s) not exist", instanceId) - } - if *resp.Response.InstanceSet[0].InstanceState == status && - (resp.Response.InstanceSet[0].LatestOperationState == nil || *resp.Response.InstanceSet[0].LatestOperationState != "OPERATING") { - break - } - time.Sleep(DefaultWaitForInterval * time.Second) - timeout = timeout - DefaultWaitForInterval - if timeout <= 0 { - return fmt.Errorf("wait instance(%s) status(%s) timeout", instanceId, status) - } - } - - return nil -} - -// WaitForImageReady wait for image reaches statue -func WaitForImageReady(ctx context.Context, client *cvm.Client, imageName string, status string, timeout int) error { - for { - image, err := GetImageByName(ctx, client, imageName) - if err != nil { - return err - } - - if image != nil && *image.ImageState == status { - return nil - } - - time.Sleep(DefaultWaitForInterval * time.Second) - timeout = timeout - DefaultWaitForInterval - if timeout <= 0 { - return fmt.Errorf("wait image(%s) status(%s) timeout", imageName, status) - } - } -} - -// GetImageByName get image by image name -func GetImageByName(ctx context.Context, client *cvm.Client, imageName string) (*cvm.Image, error) { - req := cvm.NewDescribeImagesRequest() - req.Filters = []*cvm.Filter{ - { - Name: common.StringPtr("image-name"), - Values: []*string{&imageName}, - }, - } - - var resp *cvm.DescribeImagesResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = client.DescribeImages(req) - return e - }) - if err != nil { - return nil, err - } - - if *resp.Response.TotalCount > 0 { - for _, image := range resp.Response.ImageSet { - if *image.ImageName == imageName { - return image, nil - } - } - } - - return nil, nil -} - -// NewCvmClient returns a new cvm client -func NewCvmClient(secretId, secretKey, region string) (client *cvm.Client, err error) { - cpf := profile.NewClientProfile() - cpf.HttpProfile.ReqMethod = "POST" - cpf.HttpProfile.ReqTimeout = 300 - cpf.Language = "en-US" - - credential := common.NewCredential(secretId, secretKey) - client, err = cvm.NewClient(credential, region, cpf) - - return -} - -// NewVpcClient returns a new vpc client -func NewVpcClient(secretId, secretKey, region string) (client *vpc.Client, err error) { - cpf := profile.NewClientProfile() - cpf.HttpProfile.ReqMethod = "POST" - cpf.HttpProfile.ReqTimeout = 300 - cpf.Language = "en-US" - - credential := common.NewCredential(secretId, secretKey) - client, err = vpc.NewClient(credential, region, cpf) - - return -} - -// CheckResourceIdFormat check resource id format -func CheckResourceIdFormat(resource string, id string) bool { - regex := regexp.MustCompile(fmt.Sprintf("%s-[0-9a-z]{8}$", resource)) - return regex.MatchString(id) -} - -// SSHHost returns a function that can be given to the SSH communicator -func SSHHost(pubilcIp bool) func(multistep.StateBag) (string, error) { - return func(state multistep.StateBag) (string, error) { - instance := state.Get("instance").(*cvm.Instance) - if pubilcIp { - return *instance.PublicIpAddresses[0], nil - } else { - return *instance.PrivateIpAddresses[0], nil - } - } -} - -// Retry do retry on api request -func Retry(ctx context.Context, fn func(context.Context) error) error { - return retry.Config{ - Tries: 60, - ShouldRetry: func(err error) bool { - e, ok := err.(*errors.TencentCloudSDKError) - if !ok { - return false - } - if e.Code == "ClientError.NetworkError" || e.Code == "ClientError.HttpStatusCodeError" || - e.Code == "InvalidKeyPair.NotSupported" || e.Code == "InvalidParameterValue.KeyPairNotSupported" || - e.Code == "InvalidInstance.NotSupported" || e.Code == "OperationDenied.InstanceOperationInProgress" || - strings.Contains(e.Code, "RequestLimitExceeded") || strings.Contains(e.Code, "InternalError") || - strings.Contains(e.Code, "ResourceInUse") || strings.Contains(e.Code, "ResourceBusy") { - return true - } - return false - }, - RetryDelay: (&retry.Backoff{ - InitialBackoff: 1 * time.Second, - MaxBackoff: 5 * time.Second, - Multiplier: 2, - }).Linear, - }.Run(ctx, fn) -} - -// SayClean tell you clean module message -func SayClean(state multistep.StateBag, module string) { - _, halted := state.GetOk(multistep.StateHalted) - _, cancelled := state.GetOk(multistep.StateCancelled) - if halted { - Say(state, fmt.Sprintf("Deleting %s because of error...", module), "") - } else if cancelled { - Say(state, fmt.Sprintf("Deleting %s because of cancellation...", module), "") - } else { - Say(state, fmt.Sprintf("Cleaning up %s...", module), "") - } -} - -// Say tell you a message -func Say(state multistep.StateBag, message, prefix string) { - if prefix != "" { - message = fmt.Sprintf("%s: %s", prefix, message) - } - - if strings.HasPrefix(message, "Trying to") { - message += "..." - } - - ui := state.Get("ui").(packersdk.Ui) - ui.Say(message) -} - -// Message print a message -func Message(state multistep.StateBag, message, prefix string) { - if prefix != "" { - message = fmt.Sprintf("%s: %s", prefix, message) - } - - ui := state.Get("ui").(packersdk.Ui) - ui.Message(message) -} - -// Error print error message -func Error(state multistep.StateBag, err error, prefix string) { - if prefix != "" { - err = fmt.Errorf("%s: %s", prefix, err) - } - - ui := state.Get("ui").(packersdk.Ui) - ui.Error(err.Error()) -} - -// Halt print error message and exit -func Halt(state multistep.StateBag, err error, prefix string) multistep.StepAction { - Error(state, err, prefix) - state.Put("error", err) - - return multistep.ActionHalt -} diff --git a/builder/tencentcloud/cvm/image_config.go b/builder/tencentcloud/cvm/image_config.go deleted file mode 100644 index 96cf192dd..000000000 --- a/builder/tencentcloud/cvm/image_config.go +++ /dev/null @@ -1,79 +0,0 @@ -//go:generate packer-sdc struct-markdown - -package cvm - -import ( - "fmt" - "unicode/utf8" - - "github.com/hashicorp/packer-plugin-sdk/template/interpolate" -) - -type TencentCloudImageConfig struct { - // The name you want to create your customize image, - // it should be composed of no more than 60 characters, of letters, numbers - // or minus sign. - ImageName string `mapstructure:"image_name" required:"true"` - // Image description. - ImageDescription string `mapstructure:"image_description" required:"false"` - // Whether shutdown cvm to create Image. Default value is - // false. - Reboot bool `mapstructure:"reboot" required:"false"` - // Whether to force power off cvm when create image. - // Default value is false. - ForcePoweroff bool `mapstructure:"force_poweroff" required:"false"` - // Whether enable Sysprep during creating windows image. - Sysprep bool `mapstructure:"sysprep" required:"false"` - ImageForceDelete bool `mapstructure:"image_force_delete"` - // regions that will be copied to after - // your image created. - ImageCopyRegions []string `mapstructure:"image_copy_regions" required:"false"` - // accounts that will be shared to - // after your image created. - ImageShareAccounts []string `mapstructure:"image_share_accounts" required:"false"` - // Do not check region and zone when validate. - SkipValidation bool `mapstructure:"skip_region_validation" required:"false"` -} - -func (cf *TencentCloudImageConfig) Prepare(ctx *interpolate.Context) []error { - var errs []error - - cf.ForcePoweroff = true - if cf.ImageName == "" { - errs = append(errs, fmt.Errorf("image_name must be specified")) - } else if utf8.RuneCountInString(cf.ImageName) > 60 { - errs = append(errs, fmt.Errorf("image_name length should not exceed 60 characters")) - } - - if utf8.RuneCountInString(cf.ImageDescription) > 60 { - errs = append(errs, fmt.Errorf("image_description length should not exceed 60 characters")) - } - - if len(cf.ImageCopyRegions) > 0 { - regionSet := make(map[string]struct{}) - regions := make([]string, 0, len(cf.ImageCopyRegions)) - - for _, region := range cf.ImageCopyRegions { - if _, ok := regionSet[region]; ok { - continue - } - - regionSet[region] = struct{}{} - - if !cf.SkipValidation { - if err := validRegion(region); err != nil { - errs = append(errs, err) - continue - } - } - regions = append(regions, region) - } - cf.ImageCopyRegions = regions - } - - if len(errs) > 0 { - return errs - } - - return nil -} diff --git a/builder/tencentcloud/cvm/image_config_test.go b/builder/tencentcloud/cvm/image_config_test.go deleted file mode 100644 index 505dcf3a5..000000000 --- a/builder/tencentcloud/cvm/image_config_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package cvm - -import "testing" - -func TestTencentCloudImageConfig_Prepare(t *testing.T) { - cf := &TencentCloudImageConfig{ - ImageName: "foo", - } - - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have err: %v", err) - } - - cf.ImageName = "foo.:" - if err := cf.Prepare(nil); err != nil { - t.Fatal("shouldn't have error") - } - - cf.ImageName = "foo" - cf.ImageCopyRegions = []string{"ap-guangzhou", "ap-hongkong"} - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have err: %v", err) - } - - cf.ImageCopyRegions = []string{"unknown"} - if err := cf.Prepare(nil); err == nil { - t.Fatal("should have err") - } - - cf.SkipValidation = true - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have err:%v", err) - } -} diff --git a/builder/tencentcloud/cvm/run_config.go b/builder/tencentcloud/cvm/run_config.go deleted file mode 100644 index 79936ce50..000000000 --- a/builder/tencentcloud/cvm/run_config.go +++ /dev/null @@ -1,208 +0,0 @@ -//go:generate packer-sdc struct-markdown -//go:generate packer-sdc mapstructure-to-hcl2 -type tencentCloudDataDisk - -package cvm - -import ( - "fmt" - "os" - "strings" - - "github.com/hashicorp/packer-plugin-sdk/communicator" - "github.com/hashicorp/packer-plugin-sdk/template/config" - "github.com/hashicorp/packer-plugin-sdk/template/interpolate" - "github.com/hashicorp/packer-plugin-sdk/uuid" - "github.com/pkg/errors" -) - -type tencentCloudDataDisk struct { - DiskType string `mapstructure:"disk_type"` - DiskSize int64 `mapstructure:"disk_size"` - SnapshotId string `mapstructure:"disk_snapshot_id"` -} - -type TencentCloudRunConfig struct { - // Whether allocate public ip to your cvm. - // Default value is false. - AssociatePublicIpAddress bool `mapstructure:"associate_public_ip_address" required:"false"` - // The base image id of Image you want to create - // your customized image from. - 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. - // You should reference Instace Type - // for parameter taking. - InstanceType string `mapstructure:"instance_type" required:"true"` - // Instance name. - InstanceName string `mapstructure:"instance_name" required:"false"` - // Root disk type your cvm will be launched by, default is `CLOUD_PREMIUM`. you could - // reference Disk Type - // for parameter taking. - DiskType string `mapstructure:"disk_type" required:"false"` - // Root disk size your cvm will be launched by. values range(in GB): - DiskSize int64 `mapstructure:"disk_size" required:"false"` - // Add one or more data disks to the instance before creating the image. - // Note that if the source image has data disk snapshots, this argument - // will be ignored, and the running instance will use source image data - // disk settings, in such case, `disk_type` argument will be used as disk - // type for all data disks, and each data disk size will use the origin - // value in source image. - // The data disks allow for the following argument: - // - `disk_type` - Type of the data disk. Valid choices: `CLOUD_BASIC`, `CLOUD_PREMIUM` and `CLOUD_SSD`. - // - `disk_size` - Size of the data disk. - // - `disk_snapshot_id` - Id of the snapshot for a data disk. - DataDisks []tencentCloudDataDisk `mapstructure:"data_disks"` - // Specify vpc your cvm will be launched by. - VpcId string `mapstructure:"vpc_id" required:"false"` - // Specify vpc name you will create. if vpc_id is not set, packer will - // create a vpc for you named this parameter. - VpcName string `mapstructure:"vpc_name" required:"false"` - VpcIp string `mapstructure:"vpc_ip"` - // Specify subnet your cvm will be launched by. - SubnetId string `mapstructure:"subnet_id" required:"false"` - // Specify subnet name you will create. if subnet_id is not set, packer will - // create a subnet for you named this parameter. - SubnetName string `mapstructure:"subnet_name" required:"false"` - // Specify cider block of the vpc you will create if vpc_id not set - CidrBlock string `mapstructure:"cidr_block" required:"false"` // 10.0.0.0/16(default), 172.16.0.0/12, 192.168.0.0/16 - // Specify cider block of the subnet you will create if - // subnet_id not set - SubnectCidrBlock string `mapstructure:"subnect_cidr_block" required:"false"` - InternetChargeType string `mapstructure:"internet_charge_type"` - // Max bandwidth out your cvm will be launched by(in MB). - // values can be set between 1 ~ 100. - InternetMaxBandwidthOut int64 `mapstructure:"internet_max_bandwidth_out" required:"false"` - // Specify securitygroup your cvm will be launched by. - SecurityGroupId string `mapstructure:"security_group_id" required:"false"` - // Specify security name you will create if security_group_id not set. - SecurityGroupName string `mapstructure:"security_group_name" required:"false"` - // userdata. - UserData string `mapstructure:"user_data" required:"false"` - // userdata file. - UserDataFile string `mapstructure:"user_data_file" required:"false"` - // host name. - HostName string `mapstructure:"host_name" required:"false"` - // Key/value pair tags to apply to the instance that is *launched* to - // create the image. These tags are *not* applied to the resulting image. - RunTags map[string]string `mapstructure:"run_tags" required:"false"` - // Same as [`run_tags`](#run_tags) but defined as a singular repeatable - // block containing a `key` and a `value` field. In HCL2 mode the - // [`dynamic_block`](/docs/templates/hcl_templates/expressions#dynamic-blocks) - // will allow you to create those programatically. - RunTag config.KeyValues `mapstructure:"run_tag" required:"false"` - - // Communicator settings - Comm communicator.Config `mapstructure:",squash"` - SSHPrivateIp bool `mapstructure:"ssh_private_ip"` -} - -var ValidCBSType = []string{ - "LOCAL_BASIC", "LOCAL_SSD", "CLOUD_BASIC", "CLOUD_SSD", "CLOUD_PREMIUM", -} - -func (cf *TencentCloudRunConfig) Prepare(ctx *interpolate.Context) []error { - packerId := fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()[:8]) - if cf.Comm.SSHKeyPairName == "" && cf.Comm.SSHTemporaryKeyPairName == "" && - cf.Comm.SSHPrivateKeyFile == "" && cf.Comm.SSHPassword == "" && cf.Comm.WinRMPassword == "" { - //tencentcloud support key pair name length max to 25 - cf.Comm.SSHTemporaryKeyPairName = packerId - } - - errs := cf.Comm.Prepare(ctx) - if cf.SourceImageId == "" && cf.SourceImageName == "" { - errs = append(errs, errors.New("source_image_id or source_image_name must be specified")) - } - - if cf.SourceImageId != "" && !CheckResourceIdFormat("img", cf.SourceImageId) { - errs = append(errs, errors.New("source_image_id wrong format")) - } - - if cf.InstanceType == "" { - errs = append(errs, errors.New("instance_type must be specified")) - } - - if cf.UserData != "" && cf.UserDataFile != "" { - errs = append(errs, errors.New("only one of user_data or user_data_file can be specified")) - } else if cf.UserDataFile != "" { - if _, err := os.Stat(cf.UserDataFile); err != nil { - errs = append(errs, errors.New("user_data_file not exist")) - } - } - - if (cf.VpcId != "" || cf.CidrBlock != "") && cf.SubnetId == "" && cf.SubnectCidrBlock == "" { - errs = append(errs, errors.New("if vpc cidr_block is specified, then "+ - "subnet_cidr_block must also be specified.")) - } - - if cf.VpcId == "" { - if cf.VpcName == "" { - cf.VpcName = packerId - } - if cf.CidrBlock == "" { - cf.CidrBlock = "10.0.0.0/16" - } - if cf.SubnetId != "" { - errs = append(errs, errors.New("can't set subnet_id without set vpc_id")) - } - } - - if cf.SubnetId == "" { - if cf.SubnetName == "" { - cf.SubnetName = packerId - } - if cf.SubnectCidrBlock == "" { - cf.SubnectCidrBlock = "10.0.8.0/24" - } - } - - if cf.SecurityGroupId == "" && cf.SecurityGroupName == "" { - cf.SecurityGroupName = packerId - } - - if cf.DiskType != "" && !checkDiskType(cf.DiskType) { - errs = append(errs, errors.New(fmt.Sprintf("specified disk_type(%s) is invalid", cf.DiskType))) - } else if cf.DiskType == "" { - cf.DiskType = "CLOUD_PREMIUM" - } - - if cf.DiskSize <= 0 { - cf.DiskSize = 50 - } - - if cf.AssociatePublicIpAddress && cf.InternetMaxBandwidthOut <= 0 { - cf.InternetMaxBandwidthOut = 1 - } - - if cf.InstanceName == "" { - cf.InstanceName = packerId - } - - if cf.HostName == "" { - cf.HostName = cf.InstanceName - } - - if len(cf.HostName) > 15 { - cf.HostName = cf.HostName[:15] - } - cf.HostName = strings.Replace(cf.HostName, "_", "-", -1) - - if cf.RunTags == nil { - cf.RunTags = make(map[string]string) - } - - errs = append(errs, cf.RunTag.CopyOn(&cf.RunTags)...) - - return errs -} - -func checkDiskType(diskType string) bool { - for _, valid := range ValidCBSType { - if valid == diskType { - return true - } - } - - return false -} diff --git a/builder/tencentcloud/cvm/run_config.hcl2spec.go b/builder/tencentcloud/cvm/run_config.hcl2spec.go deleted file mode 100644 index 0d0dfe9f4..000000000 --- a/builder/tencentcloud/cvm/run_config.hcl2spec.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT. - -package cvm - -import ( - "github.com/hashicorp/hcl/v2/hcldec" - "github.com/zclconf/go-cty/cty" -) - -// FlattencentCloudDataDisk is an auto-generated flat version of tencentCloudDataDisk. -// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. -type FlattencentCloudDataDisk struct { - DiskType *string `mapstructure:"disk_type" cty:"disk_type" hcl:"disk_type"` - DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size" hcl:"disk_size"` - SnapshotId *string `mapstructure:"disk_snapshot_id" cty:"disk_snapshot_id" hcl:"disk_snapshot_id"` -} - -// FlatMapstructure returns a new FlattencentCloudDataDisk. -// FlattencentCloudDataDisk is an auto-generated flat version of tencentCloudDataDisk. -// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. -func (*tencentCloudDataDisk) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { - return new(FlattencentCloudDataDisk) -} - -// HCL2Spec returns the hcl spec of a tencentCloudDataDisk. -// This spec is used by HCL to read the fields of tencentCloudDataDisk. -// The decoded values from this spec will then be applied to a FlattencentCloudDataDisk. -func (*FlattencentCloudDataDisk) HCL2Spec() map[string]hcldec.Spec { - s := map[string]hcldec.Spec{ - "disk_type": &hcldec.AttrSpec{Name: "disk_type", Type: cty.String, Required: false}, - "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false}, - "disk_snapshot_id": &hcldec.AttrSpec{Name: "disk_snapshot_id", Type: cty.String, Required: false}, - } - return s -} diff --git a/builder/tencentcloud/cvm/run_config_test.go b/builder/tencentcloud/cvm/run_config_test.go deleted file mode 100644 index e53d380ca..000000000 --- a/builder/tencentcloud/cvm/run_config_test.go +++ /dev/null @@ -1,135 +0,0 @@ -package cvm - -import ( - "io/ioutil" - "os" - "testing" - - "github.com/hashicorp/packer-plugin-sdk/communicator" -) - -func testConfig() *TencentCloudRunConfig { - return &TencentCloudRunConfig{ - SourceImageId: "img-qwer1234", - InstanceType: "S3.SMALL2", - Comm: communicator.Config{ - SSH: communicator.SSH{ - SSHUsername: "tencentcloud", - }, - }, - } -} - -func TestTencentCloudRunConfig_Prepare(t *testing.T) { - cf := testConfig() - - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have err: %v", err) - } - - cf.InstanceType = "" - if err := cf.Prepare(nil); err == nil { - t.Fatal("should have err") - } - - cf.InstanceType = "S3.SMALL2" - cf.SourceImageId = "" - if err := cf.Prepare(nil); err == nil { - t.Fatal("should have err") - } - - cf.SourceImageId = "img-qwer1234" - cf.Comm.SSHPort = 0 - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have err: %v", err) - } - - if cf.Comm.SSHPort != 22 { - t.Fatalf("invalid ssh port value: %v", cf.Comm.SSHPort) - } - - cf.Comm.SSHPort = 44 - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have err: %v", err) - } - - if cf.Comm.SSHPort != 44 { - t.Fatalf("invalid ssh port value: %v", cf.Comm.SSHPort) - } -} - -func TestTencentCloudRunConfigPrepare_UserData(t *testing.T) { - cf := testConfig() - - tf, err := ioutil.TempFile("", "packer") - if err != nil { - t.Fatalf("new temp file failed: %v", err) - } - defer os.Remove(tf.Name()) - defer tf.Close() - - cf.UserData = "text user_data" - cf.UserDataFile = tf.Name() - if err := cf.Prepare(nil); err == nil { - t.Fatal("should have error") - } -} - -func TestTencentCloudRunConfigPrepare_UserDataFile(t *testing.T) { - cf := testConfig() - - cf.UserDataFile = "not-exist-file" - if err := cf.Prepare(nil); err == nil { - t.Fatal("should have error") - } - - tf, err := ioutil.TempFile("", "packer") - if err != nil { - t.Fatalf("new temp file failed: %v", err) - } - defer os.Remove(tf.Name()) - defer tf.Close() - - cf.UserDataFile = tf.Name() - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have error: %v", err) - } -} - -func TestTencentCloudRunConfigPrepare_TemporaryKeyPairName(t *testing.T) { - cf := testConfig() - cf.Comm.SSHTemporaryKeyPairName = "" - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have error: %v", err) - } - - if cf.Comm.SSHTemporaryKeyPairName == "" { - t.Fatal("invalid ssh key pair value") - } - - cf.Comm.SSHTemporaryKeyPairName = "ssh-key-123" - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have error: %v", err) - } - - if cf.Comm.SSHTemporaryKeyPairName != "ssh-key-123" { - t.Fatalf("invalid ssh key pair value: %v", cf.Comm.SSHTemporaryKeyPairName) - } -} - -func TestTencentCloudRunConfigPrepare_SSHPrivateIp(t *testing.T) { - cf := testConfig() - - if cf.SSHPrivateIp != false { - t.Fatalf("invalid ssh_private_ip value: %v", cf.SSHPrivateIp) - } - - cf.SSHPrivateIp = true - if err := cf.Prepare(nil); err != nil { - t.Fatalf("shouldn't have error: %v", err) - } - - if cf.SSHPrivateIp != true { - t.Fatalf("invalud ssh_private_ip value: %v", cf.SSHPrivateIp) - } -} diff --git a/builder/tencentcloud/cvm/step_check_source_image.go b/builder/tencentcloud/cvm/step_check_source_image.go deleted file mode 100644 index 0ddf21c47..000000000 --- a/builder/tencentcloud/cvm/step_check_source_image.go +++ /dev/null @@ -1,66 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - "regexp" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" -) - -type stepCheckSourceImage struct { - sourceImageId string -} - -func (s *stepCheckSourceImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - var ( - imageNameRegex *regexp.Regexp - err error - ) - config := state.Get("config").(*Config) - client := state.Get("cvm_client").(*cvm.Client) - - Say(state, config.SourceImageId, "Trying to check source image") - - req := cvm.NewDescribeImagesRequest() - 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") - } - } - var resp *cvm.DescribeImagesResponse - err = Retry(ctx, func(ctx context.Context) error { - var err error - resp, err = client.DescribeImages(req) - return err - }) - if err != nil { - return Halt(state, err, "Failed to get source image info") - } - - if *resp.Response.TotalCount > 0 { - images := resp.Response.ImageSet - if imageNameRegex != nil { - 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), "") -} - -func (s *stepCheckSourceImage) Cleanup(bag multistep.StateBag) {} diff --git a/builder/tencentcloud/cvm/step_config_key_pair.go b/builder/tencentcloud/cvm/step_config_key_pair.go deleted file mode 100644 index 7b05da19e..000000000 --- a/builder/tencentcloud/cvm/step_config_key_pair.go +++ /dev/null @@ -1,120 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - "io/ioutil" - "os" - "runtime" - - "github.com/hashicorp/packer-plugin-sdk/communicator" - "github.com/hashicorp/packer-plugin-sdk/multistep" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" -) - -type stepConfigKeyPair struct { - Debug bool - Comm *communicator.Config - DebugKeyPath string - keyID string -} - -func (s *stepConfigKeyPair) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - client := state.Get("cvm_client").(*cvm.Client) - - if s.Comm.SSHPrivateKeyFile != "" { - Say(state, "Using existing SSH private key", "") - privateKeyBytes, err := ioutil.ReadFile(s.Comm.SSHPrivateKeyFile) - if err != nil { - return Halt(state, err, fmt.Sprintf("Failed to load configured private key(%s)", s.Comm.SSHPrivateKeyFile)) - } - s.Comm.SSHPrivateKey = privateKeyBytes - Message(state, fmt.Sprintf("Loaded %d bytes private key data", len(s.Comm.SSHPrivateKey)), "") - return multistep.ActionContinue - } - - if s.Comm.SSHAgentAuth { - if s.Comm.SSHKeyPairName == "" { - Say(state, "Using SSH agent with key pair in source image", "") - return multistep.ActionContinue - } - Say(state, fmt.Sprintf("Using SSH agent with exists key pair(%s)", s.Comm.SSHKeyPairName), "") - return multistep.ActionContinue - } - - if s.Comm.SSHTemporaryKeyPairName == "" { - Say(state, "Not to use temporary keypair", "") - s.Comm.SSHKeyPairName = "" - return multistep.ActionContinue - } - - Say(state, s.Comm.SSHTemporaryKeyPairName, "Trying to create a new keypair") - - req := cvm.NewCreateKeyPairRequest() - req.KeyName = &s.Comm.SSHTemporaryKeyPairName - defaultProjectId := int64(0) - req.ProjectId = &defaultProjectId - var resp *cvm.CreateKeyPairResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = client.CreateKeyPair(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to create keypair") - } - - // set keyId to delete when Cleanup - s.keyID = *resp.Response.KeyPair.KeyId - state.Put("temporary_key_pair_id", s.keyID) - Message(state, s.keyID, "Keypair created") - - s.Comm.SSHKeyPairName = *resp.Response.KeyPair.KeyId - s.Comm.SSHPrivateKey = []byte(*resp.Response.KeyPair.PrivateKey) - - if s.Debug { - Message(state, fmt.Sprintf("Saving temporary key to %s for debug purposes", s.DebugKeyPath), "") - f, err := os.Create(s.DebugKeyPath) - if err != nil { - return Halt(state, err, "Failed to saving debug key file") - } - defer f.Close() - if _, err := f.Write([]byte(*resp.Response.KeyPair.PrivateKey)); err != nil { - return Halt(state, err, "Failed to writing debug key file") - } - if runtime.GOOS != "windows" { - if err := f.Chmod(0600); err != nil { - return Halt(state, err, "Failed to chmod debug key file") - } - } - } - - return multistep.ActionContinue -} - -func (s *stepConfigKeyPair) Cleanup(state multistep.StateBag) { - if s.Comm.SSHPrivateKeyFile != "" || (s.Comm.SSHKeyPairName == "" && s.keyID == "") { - return - } - - ctx := context.TODO() - client := state.Get("cvm_client").(*cvm.Client) - - SayClean(state, "keypair") - - req := cvm.NewDeleteKeyPairsRequest() - req.KeyIds = []*string{&s.keyID} - err := Retry(ctx, func(ctx context.Context) error { - _, e := client.DeleteKeyPairs(req) - return e - }) - if err != nil { - Error(state, err, fmt.Sprintf("Failed to delete keypair(%s), please delete it manually", s.keyID)) - } - - if s.Debug { - if err := os.Remove(s.DebugKeyPath); err != nil { - Error(state, err, fmt.Sprintf("Failed to delete debug key file(%s), please delete it manually", s.DebugKeyPath)) - } - } -} diff --git a/builder/tencentcloud/cvm/step_config_security_group.go b/builder/tencentcloud/cvm/step_config_security_group.go deleted file mode 100644 index d8e0cbe2f..000000000 --- a/builder/tencentcloud/cvm/step_config_security_group.go +++ /dev/null @@ -1,128 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" -) - -type stepConfigSecurityGroup struct { - SecurityGroupId string - SecurityGroupName string - Description string - isCreate bool -} - -func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - vpcClient := state.Get("vpc_client").(*vpc.Client) - - if len(s.SecurityGroupId) != 0 { - Say(state, s.SecurityGroupId, "Trying to use existing securitygroup") - req := vpc.NewDescribeSecurityGroupsRequest() - req.SecurityGroupIds = []*string{&s.SecurityGroupId} - var resp *vpc.DescribeSecurityGroupsResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = vpcClient.DescribeSecurityGroups(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to get securitygroup info") - } - if *resp.Response.TotalCount > 0 { - s.isCreate = false - state.Put("security_group_id", s.SecurityGroupId) - Message(state, *resp.Response.SecurityGroupSet[0].SecurityGroupName, "Securitygroup found") - return multistep.ActionContinue - } - return Halt(state, fmt.Errorf("The specified securitygroup(%s) does not exists", s.SecurityGroupId), "") - } - - Say(state, "Trying to create a new securitygroup", "") - - req := vpc.NewCreateSecurityGroupRequest() - req.GroupName = &s.SecurityGroupName - req.GroupDescription = &s.Description - var resp *vpc.CreateSecurityGroupResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = vpcClient.CreateSecurityGroup(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to create securitygroup") - } - - s.isCreate = true - s.SecurityGroupId = *resp.Response.SecurityGroup.SecurityGroupId - state.Put("security_group_id", s.SecurityGroupId) - Message(state, s.SecurityGroupId, "Securitygroup created") - - // bind securitygroup ingress police - Say(state, "Trying to create securitygroup polices", "") - pReq := vpc.NewCreateSecurityGroupPoliciesRequest() - ACCEPT := "ACCEPT" - DEFAULT_CIDR := "0.0.0.0/0" - pReq.SecurityGroupId = &s.SecurityGroupId - pReq.SecurityGroupPolicySet = &vpc.SecurityGroupPolicySet{ - Ingress: []*vpc.SecurityGroupPolicy{ - { - CidrBlock: &DEFAULT_CIDR, - Action: &ACCEPT, - }, - }, - } - err = Retry(ctx, func(ctx context.Context) error { - _, e := vpcClient.CreateSecurityGroupPolicies(pReq) - return e - }) - if err != nil { - return Halt(state, err, "Failed to create securitygroup polices") - } - - // bind securitygroup engress police - pReq = vpc.NewCreateSecurityGroupPoliciesRequest() - pReq.SecurityGroupId = &s.SecurityGroupId - pReq.SecurityGroupPolicySet = &vpc.SecurityGroupPolicySet{ - Egress: []*vpc.SecurityGroupPolicy{ - { - CidrBlock: &DEFAULT_CIDR, - Action: &ACCEPT, - }, - }, - } - err = Retry(ctx, func(ctx context.Context) error { - _, e := vpcClient.CreateSecurityGroupPolicies(pReq) - return e - }) - if err != nil { - return Halt(state, err, "Failed to create securitygroup polices") - } - - Message(state, "Securitygroup polices created", "") - - return multistep.ActionContinue -} - -func (s *stepConfigSecurityGroup) Cleanup(state multistep.StateBag) { - if !s.isCreate { - return - } - - ctx := context.TODO() - vpcClient := state.Get("vpc_client").(*vpc.Client) - - SayClean(state, "securitygroup") - - req := vpc.NewDeleteSecurityGroupRequest() - req.SecurityGroupId = &s.SecurityGroupId - err := Retry(ctx, func(ctx context.Context) error { - _, e := vpcClient.DeleteSecurityGroup(req) - return e - }) - if err != nil { - Error(state, err, fmt.Sprintf("Failed to delete securitygroup(%s), please delete it manually", s.SecurityGroupId)) - } -} diff --git a/builder/tencentcloud/cvm/step_config_subnet.go b/builder/tencentcloud/cvm/step_config_subnet.go deleted file mode 100644 index eb13568d1..000000000 --- a/builder/tencentcloud/cvm/step_config_subnet.go +++ /dev/null @@ -1,93 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" -) - -type stepConfigSubnet struct { - SubnetId string - SubnetCidrBlock string - SubnetName string - Zone string - isCreate bool -} - -func (s *stepConfigSubnet) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - vpcClient := state.Get("vpc_client").(*vpc.Client) - - vpcId := state.Get("vpc_id").(string) - - if len(s.SubnetId) != 0 { - Say(state, s.SubnetId, "Trying to use existing subnet") - req := vpc.NewDescribeSubnetsRequest() - req.SubnetIds = []*string{&s.SubnetId} - var resp *vpc.DescribeSubnetsResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = vpcClient.DescribeSubnets(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to get subnet info") - } - if *resp.Response.TotalCount > 0 { - s.isCreate = false - if *resp.Response.SubnetSet[0].VpcId != vpcId { - return Halt(state, fmt.Errorf("The specified subnet(%s) does not belong to the specified vpc(%s)", s.SubnetId, vpcId), "") - } - state.Put("subnet_id", *resp.Response.SubnetSet[0].SubnetId) - Message(state, *resp.Response.SubnetSet[0].SubnetName, "Subnet found") - return multistep.ActionContinue - } - return Halt(state, fmt.Errorf("The specified subnet(%s) does not exist", s.SubnetId), "") - } - - Say(state, "Trying to create a new subnet", "") - - req := vpc.NewCreateSubnetRequest() - req.VpcId = &vpcId - req.SubnetName = &s.SubnetName - req.CidrBlock = &s.SubnetCidrBlock - req.Zone = &s.Zone - var resp *vpc.CreateSubnetResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = vpcClient.CreateSubnet(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to create subnet") - } - - s.isCreate = true - s.SubnetId = *resp.Response.Subnet.SubnetId - state.Put("subnet_id", s.SubnetId) - Message(state, s.SubnetId, "Subnet created") - - return multistep.ActionContinue -} - -func (s *stepConfigSubnet) Cleanup(state multistep.StateBag) { - if !s.isCreate { - return - } - - ctx := context.TODO() - vpcClient := state.Get("vpc_client").(*vpc.Client) - - SayClean(state, "subnet") - - req := vpc.NewDeleteSubnetRequest() - req.SubnetId = &s.SubnetId - err := Retry(ctx, func(ctx context.Context) error { - _, e := vpcClient.DeleteSubnet(req) - return e - }) - if err != nil { - Error(state, err, fmt.Sprintf("Failed to delete subnet(%s), please delete it manually", s.SubnetId)) - } -} diff --git a/builder/tencentcloud/cvm/step_config_vpc.go b/builder/tencentcloud/cvm/step_config_vpc.go deleted file mode 100644 index 279e49e4e..000000000 --- a/builder/tencentcloud/cvm/step_config_vpc.go +++ /dev/null @@ -1,85 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" -) - -type stepConfigVPC struct { - VpcId string - CidrBlock string - VpcName string - isCreate bool -} - -func (s *stepConfigVPC) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - vpcClient := state.Get("vpc_client").(*vpc.Client) - - if len(s.VpcId) != 0 { - Say(state, s.VpcId, "Trying to use existing vpc") - req := vpc.NewDescribeVpcsRequest() - req.VpcIds = []*string{&s.VpcId} - var resp *vpc.DescribeVpcsResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = vpcClient.DescribeVpcs(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to get vpc info") - } - if *resp.Response.TotalCount > 0 { - s.isCreate = false - state.Put("vpc_id", *resp.Response.VpcSet[0].VpcId) - Message(state, *resp.Response.VpcSet[0].VpcName, "Vpc found") - return multistep.ActionContinue - } - return Halt(state, fmt.Errorf("The specified vpc(%s) does not exist", s.VpcId), "") - } - - Say(state, "Trying to create a new vpc", "") - - req := vpc.NewCreateVpcRequest() - req.VpcName = &s.VpcName - req.CidrBlock = &s.CidrBlock - var resp *vpc.CreateVpcResponse - err := Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = vpcClient.CreateVpc(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to create vpc") - } - - s.isCreate = true - s.VpcId = *resp.Response.Vpc.VpcId - state.Put("vpc_id", s.VpcId) - Message(state, s.VpcId, "Vpc created") - - return multistep.ActionContinue -} - -func (s *stepConfigVPC) Cleanup(state multistep.StateBag) { - if !s.isCreate { - return - } - - ctx := context.TODO() - vpcClient := state.Get("vpc_client").(*vpc.Client) - - SayClean(state, "vpc") - - req := vpc.NewDeleteVpcRequest() - req.VpcId = &s.VpcId - err := Retry(ctx, func(ctx context.Context) error { - _, e := vpcClient.DeleteVpc(req) - return e - }) - if err != nil { - Error(state, err, fmt.Sprintf("Failed to delete vpc(%s), please delete it manually", s.VpcId)) - } -} diff --git a/builder/tencentcloud/cvm/step_copy_image.go b/builder/tencentcloud/cvm/step_copy_image.go deleted file mode 100644 index 036203995..000000000 --- a/builder/tencentcloud/cvm/step_copy_image.go +++ /dev/null @@ -1,81 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - "strings" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" -) - -type stepCopyImage struct { - DesinationRegions []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) { - return multistep.ActionContinue - } - - config := state.Get("config").(*Config) - client := state.Get("cvm_client").(*cvm.Client) - - imageId := state.Get("image").(*cvm.Image).ImageId - - Say(state, strings.Join(s.DesinationRegions, ","), "Trying to copy image to") - - req := cvm.NewSyncImagesRequest() - req.ImageIds = []*string{imageId} - copyRegions := make([]*string, 0, len(s.DesinationRegions)) - for _, region := range s.DesinationRegions { - if region != s.SourceRegion { - copyRegions = append(copyRegions, common.StringPtr(region)) - } - } - req.DestinationRegions = copyRegions - - err := Retry(ctx, func(ctx context.Context) error { - _, e := client.SyncImages(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to copy image") - } - - Message(state, "Waiting for image ready", "") - tencentCloudImages := state.Get("tencentcloudimages").(map[string]string) - - for _, region := range req.DestinationRegions { - rc, err := NewCvmClient(config.SecretId, config.SecretKey, *region) - if err != nil { - return Halt(state, err, "Failed to init client") - } - - err = WaitForImageReady(ctx, rc, config.ImageName, "NORMAL", 1800) - if err != nil { - return Halt(state, err, "Failed to wait for image ready") - } - - image, err := GetImageByName(ctx, rc, config.ImageName) - if err != nil { - return Halt(state, err, "Failed to get image") - } - - if image == nil { - return Halt(state, err, "Failed to wait for image ready") - } - - tencentCloudImages[*region] = *image.ImageId - Message(state, fmt.Sprintf("Copy image from %s(%s) to %s(%s)", s.SourceRegion, *imageId, *region, *image.ImageId), "") - } - - state.Put("tencentcloudimages", tencentCloudImages) - Message(state, "Image copied", "") - - return multistep.ActionContinue -} - -func (s *stepCopyImage) Cleanup(state multistep.StateBag) {} diff --git a/builder/tencentcloud/cvm/step_create_image.go b/builder/tencentcloud/cvm/step_create_image.go deleted file mode 100644 index 74d309569..000000000 --- a/builder/tencentcloud/cvm/step_create_image.go +++ /dev/null @@ -1,111 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" -) - -type stepCreateImage struct { - imageId string -} - -func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - client := state.Get("cvm_client").(*cvm.Client) - - config := state.Get("config").(*Config) - instance := state.Get("instance").(*cvm.Instance) - - Say(state, config.ImageName, "Trying to create a new image") - - req := cvm.NewCreateImageRequest() - req.ImageName = &config.ImageName - req.ImageDescription = &config.ImageDescription - req.InstanceId = instance.InstanceId - - // TODO: We should allow user to specify which data disk should be - // included into created image. - var dataDiskIds []*string - for _, disk := range instance.DataDisks { - dataDiskIds = append(dataDiskIds, disk.DiskId) - } - if len(dataDiskIds) > 0 { - req.DataDiskIds = dataDiskIds - } - - True := "True" - False := "False" - if config.ForcePoweroff { - req.ForcePoweroff = &True - } else { - req.ForcePoweroff = &False - } - - if config.Sysprep { - req.Sysprep = &True - } else { - req.Sysprep = &False - } - - err := Retry(ctx, func(ctx context.Context) error { - _, e := client.CreateImage(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to create image") - } - - Message(state, "Waiting for image ready", "") - err = WaitForImageReady(ctx, client, config.ImageName, "NORMAL", 3600) - if err != nil { - return Halt(state, err, "Failed to wait for image ready") - } - - image, err := GetImageByName(ctx, client, config.ImageName) - if err != nil { - return Halt(state, err, "Failed to get image") - } - - if image == nil { - 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") - - tencentCloudImages := make(map[string]string) - tencentCloudImages[config.Region] = s.imageId - state.Put("tencentcloudimages", tencentCloudImages) - - return multistep.ActionContinue -} - -func (s *stepCreateImage) Cleanup(state multistep.StateBag) { - if s.imageId == "" { - return - } - - _, cancelled := state.GetOk(multistep.StateCancelled) - _, halted := state.GetOk(multistep.StateHalted) - if !cancelled && !halted { - return - } - - ctx := context.TODO() - client := state.Get("cvm_client").(*cvm.Client) - - SayClean(state, "image") - - req := cvm.NewDeleteImagesRequest() - req.ImageIds = []*string{&s.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)) - } -} diff --git a/builder/tencentcloud/cvm/step_detach_temp_key_pair.go b/builder/tencentcloud/cvm/step_detach_temp_key_pair.go deleted file mode 100644 index e0a83cb90..000000000 --- a/builder/tencentcloud/cvm/step_detach_temp_key_pair.go +++ /dev/null @@ -1,49 +0,0 @@ -package cvm - -import ( - "context" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" -) - -type stepDetachTempKeyPair struct { -} - -func (s *stepDetachTempKeyPair) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - client := state.Get("cvm_client").(*cvm.Client) - - if _, ok := state.GetOk("temporary_key_pair_id"); !ok { - return multistep.ActionContinue - } - - keyId := state.Get("temporary_key_pair_id").(string) - instance := state.Get("instance").(*cvm.Instance) - - Say(state, keyId, "Trying to detach keypair") - - req := cvm.NewDisassociateInstancesKeyPairsRequest() - req.KeyIds = []*string{&keyId} - req.InstanceIds = []*string{instance.InstanceId} - req.ForceStop = common.BoolPtr(true) - err := Retry(ctx, func(ctx context.Context) error { - _, e := client.DisassociateInstancesKeyPairs(req) - return e - }) - if err != nil { - return Halt(state, err, "Fail to detach keypair from instance") - } - - Message(state, "Waiting for keypair detached", "") - err = WaitForInstance(ctx, client, *instance.InstanceId, "RUNNING", 1800) - if err != nil { - return Halt(state, err, "Failed to wait for keypair detached") - } - - Message(state, "Keypair detached", "") - - return multistep.ActionContinue -} - -func (s *stepDetachTempKeyPair) Cleanup(state multistep.StateBag) {} diff --git a/builder/tencentcloud/cvm/step_pre_validate.go b/builder/tencentcloud/cvm/step_pre_validate.go deleted file mode 100644 index f1f24bf21..000000000 --- a/builder/tencentcloud/cvm/step_pre_validate.go +++ /dev/null @@ -1,34 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" -) - -type stepPreValidate struct { -} - -func (s *stepPreValidate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - client := state.Get("cvm_client").(*cvm.Client) - - Say(state, config.ImageName, "Trying to check image name") - - image, err := GetImageByName(ctx, client, config.ImageName) - if err != nil { - return Halt(state, err, "Failed to get images info") - } - - if image != nil { - return Halt(state, fmt.Errorf("Image name %s has exists", config.ImageName), "") - } - - Message(state, "useable", "Image name") - - return multistep.ActionContinue -} - -func (s *stepPreValidate) Cleanup(multistep.StateBag) {} diff --git a/builder/tencentcloud/cvm/step_run_instance.go b/builder/tencentcloud/cvm/step_run_instance.go deleted file mode 100644 index 51ba12791..000000000 --- a/builder/tencentcloud/cvm/step_run_instance.go +++ /dev/null @@ -1,222 +0,0 @@ -package cvm - -import ( - "context" - "encoding/base64" - "fmt" - "io/ioutil" - "log" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" -) - -type stepRunInstance struct { - InstanceType string - UserData string - UserDataFile string - instanceId string - ZoneId string - InstanceName string - DiskType string - DiskSize int64 - HostName string - InternetMaxBandwidthOut int64 - AssociatePublicIpAddress bool - Tags map[string]string - DataDisks []tencentCloudDataDisk -} - -func (s *stepRunInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - client := state.Get("cvm_client").(*cvm.Client) - - config := state.Get("config").(*Config) - source_image := state.Get("source_image").(*cvm.Image) - vpc_id := state.Get("vpc_id").(string) - subnet_id := state.Get("subnet_id").(string) - security_group_id := state.Get("security_group_id").(string) - - password := config.Comm.SSHPassword - if password == "" && config.Comm.WinRMPassword != "" { - password = config.Comm.WinRMPassword - } - - userData, err := s.getUserData(state) - if err != nil { - return Halt(state, err, "Failed to get user_data") - } - - Say(state, "Trying to create a new instance", "") - - // config RunInstances parameters - POSTPAID_BY_HOUR := "POSTPAID_BY_HOUR" - req := cvm.NewRunInstancesRequest() - if s.ZoneId != "" { - req.Placement = &cvm.Placement{ - Zone: &s.ZoneId, - } - } - req.ImageId = source_image.ImageId - req.InstanceChargeType = &POSTPAID_BY_HOUR - req.InstanceType = &s.InstanceType - // TODO: Add check for system disk size, it should be larger than image system disk size. - req.SystemDisk = &cvm.SystemDisk{ - DiskType: &s.DiskType, - DiskSize: &s.DiskSize, - } - // System disk snapshot is mandatory, so if there are additional data disks, - // length will be larger than 1. - if source_image.SnapshotSet != nil && len(source_image.SnapshotSet) > 1 { - Message(state, "Use source image snapshot data disks, ignore user data disk settings", "") - var dataDisks []*cvm.DataDisk - for _, snapshot := range source_image.SnapshotSet { - if *snapshot.DiskUsage == "DATA_DISK" { - var dataDisk cvm.DataDisk - // FIXME: Currently we have no way to get original disk type - // from data disk snapshots, and we don't allow user to overwrite - // snapshot settings, and we cannot guarantee a certain hard-coded type - // is not sold out, so here we use system disk type as a workaround. - // - // Eventually, we need to allow user to overwrite snapshot disk - // settings. - dataDisk.DiskType = &s.DiskType - dataDisk.DiskSize = snapshot.DiskSize - dataDisk.SnapshotId = snapshot.SnapshotId - dataDisks = append(dataDisks, &dataDisk) - } - } - req.DataDisks = dataDisks - } else { - var dataDisks []*cvm.DataDisk - for _, disk := range s.DataDisks { - var dataDisk cvm.DataDisk - dataDisk.DiskType = &disk.DiskType - dataDisk.DiskSize = &disk.DiskSize - if disk.SnapshotId != "" { - dataDisk.SnapshotId = &disk.SnapshotId - } - dataDisks = append(dataDisks, &dataDisk) - } - req.DataDisks = dataDisks - } - req.VirtualPrivateCloud = &cvm.VirtualPrivateCloud{ - VpcId: &vpc_id, - SubnetId: &subnet_id, - } - TRAFFIC_POSTPAID_BY_HOUR := "TRAFFIC_POSTPAID_BY_HOUR" - if s.AssociatePublicIpAddress { - req.InternetAccessible = &cvm.InternetAccessible{ - InternetChargeType: &TRAFFIC_POSTPAID_BY_HOUR, - InternetMaxBandwidthOut: &s.InternetMaxBandwidthOut, - } - } - req.InstanceName = &s.InstanceName - loginSettings := cvm.LoginSettings{} - if password != "" { - loginSettings.Password = &password - } - if config.Comm.SSHKeyPairName != "" { - loginSettings.KeyIds = []*string{&config.Comm.SSHKeyPairName} - } - req.LoginSettings = &loginSettings - req.SecurityGroupIds = []*string{&security_group_id} - req.ClientToken = &s.InstanceName - req.HostName = &s.HostName - req.UserData = &userData - var tags []*cvm.Tag - for k, v := range s.Tags { - tags = append(tags, &cvm.Tag{ - Key: &k, - Value: &v, - }) - } - resourceType := "instance" - if len(tags) > 0 { - req.TagSpecification = []*cvm.TagSpecification{ - { - ResourceType: &resourceType, - Tags: tags, - }, - } - } - - var resp *cvm.RunInstancesResponse - err = Retry(ctx, func(ctx context.Context) error { - var e error - resp, e = client.RunInstances(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to run instance") - } - - if len(resp.Response.InstanceIdSet) != 1 { - return Halt(state, fmt.Errorf("No instance return"), "Failed to run instance") - } - - s.instanceId = *resp.Response.InstanceIdSet[0] - Message(state, "Waiting for instance ready", "") - - err = WaitForInstance(ctx, client, s.instanceId, "RUNNING", 1800) - if err != nil { - return Halt(state, err, "Failed to wait for instance ready") - } - - describeReq := cvm.NewDescribeInstancesRequest() - describeReq.InstanceIds = []*string{&s.instanceId} - var describeResp *cvm.DescribeInstancesResponse - err = Retry(ctx, func(ctx context.Context) error { - var e error - describeResp, e = client.DescribeInstances(describeReq) - return e - }) - if err != nil { - return Halt(state, err, "Failed to wait for instance ready") - } - - state.Put("instance", describeResp.Response.InstanceSet[0]) - // instance_id is the generic term used so that users can have access to the - // instance id inside of the provisioners, used in step_provision. - state.Put("instance_id", s.instanceId) - Message(state, s.instanceId, "Instance created") - - return multistep.ActionContinue -} - -func (s *stepRunInstance) getUserData(state multistep.StateBag) (string, error) { - userData := s.UserData - - if userData == "" && s.UserDataFile != "" { - data, err := ioutil.ReadFile(s.UserDataFile) - if err != nil { - return "", err - } - userData = string(data) - } - - userData = base64.StdEncoding.EncodeToString([]byte(userData)) - log.Printf(fmt.Sprintf("[DEBUG]getUserData: user_data: %s", userData)) - - return userData, nil -} - -func (s *stepRunInstance) Cleanup(state multistep.StateBag) { - if s.instanceId == "" { - return - } - - ctx := context.TODO() - client := state.Get("cvm_client").(*cvm.Client) - - SayClean(state, "instance") - - req := cvm.NewTerminateInstancesRequest() - req.InstanceIds = []*string{&s.instanceId} - err := Retry(ctx, func(ctx context.Context) error { - _, e := client.TerminateInstances(req) - return e - }) - if err != nil { - Error(state, err, fmt.Sprintf("Failed to terminate instance(%s), please delete it manually", s.instanceId)) - } -} diff --git a/builder/tencentcloud/cvm/step_share_image.go b/builder/tencentcloud/cvm/step_share_image.go deleted file mode 100644 index a6eec0202..000000000 --- a/builder/tencentcloud/cvm/step_share_image.go +++ /dev/null @@ -1,76 +0,0 @@ -package cvm - -import ( - "context" - "fmt" - "strings" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" -) - -type stepShareImage struct { - ShareAccounts []string -} - -func (s *stepShareImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - if len(s.ShareAccounts) == 0 { - return multistep.ActionContinue - } - - client := state.Get("cvm_client").(*cvm.Client) - - imageId := state.Get("image").(*cvm.Image).ImageId - Say(state, strings.Join(s.ShareAccounts, ","), "Trying to share image to") - - req := cvm.NewModifyImageSharePermissionRequest() - req.ImageId = imageId - req.Permission = common.StringPtr("SHARE") - accounts := make([]*string, 0, len(s.ShareAccounts)) - for _, account := range s.ShareAccounts { - accounts = append(accounts, common.StringPtr(account)) - } - req.AccountIds = accounts - err := Retry(ctx, func(ctx context.Context) error { - _, e := client.ModifyImageSharePermission(req) - return e - }) - if err != nil { - return Halt(state, err, "Failed to share image") - } - - Message(state, "Image shared", "") - - return multistep.ActionContinue -} - -func (s *stepShareImage) Cleanup(state multistep.StateBag) { - _, cancelled := state.GetOk(multistep.StateCancelled) - _, halted := state.GetOk(multistep.StateHalted) - if !cancelled && !halted { - return - } - - ctx := context.TODO() - client := state.Get("cvm_client").(*cvm.Client) - - imageId := state.Get("image").(*cvm.Image).ImageId - SayClean(state, "image share") - - req := cvm.NewModifyImageSharePermissionRequest() - req.ImageId = imageId - req.Permission = common.StringPtr("CANCEL") - accounts := make([]*string, 0, len(s.ShareAccounts)) - for _, account := range s.ShareAccounts { - accounts = append(accounts, &account) - } - req.AccountIds = accounts - err := Retry(ctx, func(ctx context.Context) error { - _, e := client.ModifyImageSharePermission(req) - return e - }) - if err != nil { - Error(state, err, fmt.Sprintf("Failed to cancel share image(%s), please delete it manually", *imageId)) - } -} diff --git a/builder/tencentcloud/examples/basic-with-data-disk.json b/builder/tencentcloud/examples/basic-with-data-disk.json deleted file mode 100644 index 9f78afdbe..000000000 --- a/builder/tencentcloud/examples/basic-with-data-disk.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "variables": { - "secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}", - "secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}" - }, - "builders": [ - { - "type": "tencentcloud-cvm", - "secret_id": "{{user `secret_id`}}", - "secret_key": "{{user `secret_key`}}", - "region": "ap-guangzhou", - "zone": "ap-guangzhou-4", - "instance_type": "S4.SMALL1", - "source_image_id": "img-oikl1tzv", - "ssh_username": "root", - "image_name": "PackerTest", - "disk_type": "CLOUD_PREMIUM", - "packer_debug": true, - "associate_public_ip_address": true, - "data_disks": [ - { - "disk_type": "CLOUD_PREMIUM", - "disk_size": 50 - } - ], - "run_tags": { - "good": "luck" - } - } - ], - "provisioners": [ - { - "type": "shell", - "inline": [ - "sleep 30", - "yum install redis.x86_64 -y" - ] - } - ] -} \ No newline at end of file diff --git a/builder/tencentcloud/examples/basic.json b/builder/tencentcloud/examples/basic.json deleted file mode 100644 index 09663ebbc..000000000 --- a/builder/tencentcloud/examples/basic.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "variables": { - "secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}", - "secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}" - }, - "builders": [ - { - "type": "tencentcloud-cvm", - "secret_id": "{{user `secret_id`}}", - "secret_key": "{{user `secret_key`}}", - "region": "ap-guangzhou", - "zone": "ap-guangzhou-4", - "instance_type": "S4.SMALL1", - "source_image_id": "img-oikl1tzv", - "ssh_username": "root", - "image_name": "PackerTest", - "disk_type": "CLOUD_PREMIUM", - "packer_debug": true, - "associate_public_ip_address": true, - "run_tags": { - "good": "luck" - } - } - ], - "provisioners": [ - { - "type": "shell", - "inline": [ - "sleep 30", - "yum install redis.x86_64 -y" - ] - } - ] -} \ No newline at end of file diff --git a/builder/tencentcloud/examples/centos.json b/builder/tencentcloud/examples/centos.json deleted file mode 100644 index 1d55f3fe7..000000000 --- a/builder/tencentcloud/examples/centos.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "variables": { - "secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}", - "secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}" - }, - "builders": [ - { - "type": "tencentcloud-cvm", - "secret_id": "{{user `secret_id`}}", - "secret_key": "{{user `secret_key`}}", - "region": "ap-guangzhou", - "zone": "ap-guangzhou-3", - "instance_type": "S3.SMALL1", - "source_image_id": "img-oikl1tzv", - "disk_type": "CLOUD_PREMIUM", - "vpc_id": "vpc-h70b6b49", - "subnet_id": "subnet-1uwh63so", - "internet_max_bandwidth_out": 2, - "security_group_id": "sg-nltpbqg1", - "ssh_username": "root", - "image_name": "packerTest", - "host_name": "packerTest", - "associate_public_ip_address": true, - "image_description": "centosPacker", - "image_copy_regions": [ - "ap-beijing" - ] - } - ], - "provisioners": [ - { - "execute_command": "echo '{{user `ssh_pass`}}' | {{ .Vars }} sudo -S -E sh '{{ .Path }}'", - "inline": [ - "yum update -y", - "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" - ], - "inline_shebang": "/bin/sh -x", - "type": "shell", - "skip_clean": true - } - ] -} \ No newline at end of file diff --git a/builder/tencentcloud/version/version.go b/builder/tencentcloud/version/version.go deleted file mode 100644 index b029ef780..000000000 --- a/builder/tencentcloud/version/version.go +++ /dev/null @@ -1,13 +0,0 @@ -package version - -import ( - "github.com/hashicorp/packer-plugin-sdk/version" - packerVersion "github.com/hashicorp/packer/version" -) - -var TencentPluginVersion *version.PluginVersion - -func init() { - TencentPluginVersion = version.InitializePluginVersion( - packerVersion.Version, packerVersion.VersionPrerelease) -} diff --git a/command/plugin.go b/command/plugin.go index a31cf391b..ff8289d18 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -20,7 +20,6 @@ import ( nullbuilder "github.com/hashicorp/packer/builder/null" oneandonebuilder "github.com/hashicorp/packer/builder/oneandone" profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" - tencentcloudcvmbuilder "github.com/hashicorp/packer/builder/tencentcloud/cvm" yandexbuilder "github.com/hashicorp/packer/builder/yandex" artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice" checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum" @@ -47,15 +46,14 @@ type PluginCommand struct { } var Builders = map[string]packersdk.Builder{ - "azure-arm": new(azurearmbuilder.Builder), - "azure-chroot": new(azurechrootbuilder.Builder), - "azure-dtl": new(azuredtlbuilder.Builder), - "file": new(filebuilder.Builder), - "null": new(nullbuilder.Builder), - "oneandone": new(oneandonebuilder.Builder), - "profitbricks": new(profitbricksbuilder.Builder), - "tencentcloud-cvm": new(tencentcloudcvmbuilder.Builder), - "yandex": new(yandexbuilder.Builder), + "azure-arm": new(azurearmbuilder.Builder), + "azure-chroot": new(azurechrootbuilder.Builder), + "azure-dtl": new(azuredtlbuilder.Builder), + "file": new(filebuilder.Builder), + "null": new(nullbuilder.Builder), + "oneandone": new(oneandonebuilder.Builder), + "profitbricks": new(profitbricksbuilder.Builder), + "yandex": new(yandexbuilder.Builder), } var Provisioners = map[string]packersdk.Provisioner{ diff --git a/command/vendored_plugins.go b/command/vendored_plugins.go index 09f1b9a61..bb7bd351d 100644 --- a/command/vendored_plugins.go +++ b/command/vendored_plugins.go @@ -57,6 +57,7 @@ import ( puppetserverprovisioner "github.com/hashicorp/packer-plugin-puppet/provisioner/puppet-server" qemubuilder "github.com/hashicorp/packer-plugin-qemu/builder/qemu" scalewaybuilder "github.com/hashicorp/packer-plugin-scaleway/builder/scaleway" + tencentcloudcvmbuilder "github.com/hashicorp/packer-plugin-tencentcloud/builder/tencentcloud/cvm" tritonbuilder "github.com/hashicorp/packer-plugin-triton/builder/triton" uclouduhostbuilder "github.com/hashicorp/packer-plugin-ucloud/builder/ucloud/uhost" ucloudimportpostprocessor "github.com/hashicorp/packer-plugin-ucloud/post-processor/ucloud-import" @@ -113,6 +114,7 @@ var VendoredBuilders = map[string]packersdk.Builder{ "parallels-pvm": new(parallelspvmbuilder.Builder), "qemu": new(qemubuilder.Builder), "scaleway": new(scalewaybuilder.Builder), + "tencentcloud-cvm": new(tencentcloudcvmbuilder.Builder), "triton": new(tritonbuilder.Builder), "ucloud-uhost": new(uclouduhostbuilder.Builder), "vagrant": new(vagrantbuilder.Builder), diff --git a/go.mod b/go.mod index e1ce0fb35..200abf842 100644 --- a/go.mod +++ b/go.mod @@ -58,6 +58,7 @@ require ( github.com/hashicorp/packer-plugin-qemu v0.0.1 github.com/hashicorp/packer-plugin-scaleway v0.0.1 github.com/hashicorp/packer-plugin-sdk v0.2.0 + github.com/hashicorp/packer-plugin-tencentcloud v0.0.1 github.com/hashicorp/packer-plugin-triton v0.0.0-20210421085122-768dd7c764d9 github.com/hashicorp/packer-plugin-ucloud v0.0.1 github.com/hashicorp/packer-plugin-vagrant v0.0.3 @@ -74,12 +75,10 @@ require ( github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784 github.com/mitchellh/reflectwalk v1.0.0 github.com/pierrec/lz4 v2.0.5+incompatible - github.com/pkg/errors v0.9.1 github.com/posener/complete v1.2.3 github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible github.com/shirou/gopsutil v3.21.1+incompatible github.com/stretchr/testify v1.7.0 - github.com/tencentcloud/tencentcloud-sdk-go v3.0.222+incompatible github.com/ulikunitz/xz v0.5.6 github.com/yandex-cloud/go-genproto v0.0.0-20200915125933-33de72a328bd github.com/yandex-cloud/go-sdk v0.0.0-20200921111412-ef15ded2014c diff --git a/go.sum b/go.sum index df1b6c8c9..43ee48820 100644 --- a/go.sum +++ b/go.sum @@ -584,6 +584,8 @@ github.com/hashicorp/packer-plugin-sdk v0.1.3/go.mod h1:xePpgQgQYv/bamiypx3hH9uk github.com/hashicorp/packer-plugin-sdk v0.1.4/go.mod h1:xePpgQgQYv/bamiypx3hH9ukidxDdcN8q0R0wLi8IEQ= github.com/hashicorp/packer-plugin-sdk v0.2.0 h1:A4Dq7p4y1vscY4gMzp7GQaXyDJYYhP4ukp4fapPSOY4= github.com/hashicorp/packer-plugin-sdk v0.2.0/go.mod h1:0DiOMEBldmB0HEhp0npFSSygC8bIvW43pphEgWkp2WU= +github.com/hashicorp/packer-plugin-tencentcloud v0.0.1 h1:DR7GETCzrK/DPFMUPbULIklCxwGhstbbz6pl+2S+UnM= +github.com/hashicorp/packer-plugin-tencentcloud v0.0.1/go.mod h1:FmdacMLvDKiT6OdMAc2x4LXtqu/soLApH3jF57SWOik= github.com/hashicorp/packer-plugin-triton v0.0.0-20210421085122-768dd7c764d9 h1:No5oPI9Wa7FhTKkFJwI3hcfUVvEpgPC8QMcG9l/Vxzo= github.com/hashicorp/packer-plugin-triton v0.0.0-20210421085122-768dd7c764d9/go.mod h1:XOAIiWYLbctBOsu41it/cL/ZjULAZ05YBhFm4H4M/lA= github.com/hashicorp/packer-plugin-ucloud v0.0.1 h1:SC2F1BuXb6dKhY6fRdmAqTkuc17jlBIu/Ut0URJy8TU= @@ -886,6 +888,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tencentcloud/tencentcloud-sdk-go v1.0.140/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI= github.com/tencentcloud/tencentcloud-sdk-go v3.0.222+incompatible h1:bs+0lcG4RELNbE8PsBC9oaPP0/qExr0DuEGnZyocm84= github.com/tencentcloud/tencentcloud-sdk-go v3.0.222+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= diff --git a/website/content/docs/builders/cloudstack.mdx b/website/content/docs/builders/cloudstack.mdx deleted file mode 100644 index cd7138d00..000000000 --- a/website/content/docs/builders/cloudstack.mdx +++ /dev/null @@ -1,235 +0,0 @@ ---- -description: | - The cloudstack Packer builder is able to create new templates for use with - CloudStack. The builder takes either an ISO or an existing template as it's - source, runs any provisioning necessary on the instance after launching it and - then creates a new template from that instance. -page_title: CloudStack - Builders ---- - -# CloudStack Builder - -Type: `cloudstack` -Artifact BuilderId: `packer.cloudstack` - -The `cloudstack` Packer builder is able to create new templates for use with -[CloudStack](https://cloudstack.apache.org/). The builder takes either an ISO -or an existing template as it's source, runs any provisioning necessary on the -instance after launching it and then creates a new template from that instance. - -The builder does _not_ manage templates. Once a template is created, it is up -to you to use it or delete it. - -## Configuration Reference - -There are many configuration options available for the builder. They are -segmented below into two categories: required and optional parameters. Within -each category, the available configuration keys are alphabetized. - -In addition to the options listed here, a -[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this -builder. - -### Required: - -- `api_url` (string) - The CloudStack API endpoint we will connect to. It can - also be specified via environment variable `CLOUDSTACK_API_URL`, if set. - -- `api_key` (string) - The API key used to sign all API requests. It can also - be specified via environment variable `CLOUDSTACK_API_KEY`, if set. - -- `network` (string) - The name or ID of the network to connect the instance - to. - -- `secret_key` (string) - The secret key used to sign all API requests. It - can also be specified via environment variable `CLOUDSTACK_SECRET_KEY`, if - set. - -- `service_offering` (string) - The name or ID of the service offering used - for the instance. - -- `source_iso` (string) - The name or ID of an ISO that will be mounted - before booting the instance. This option is mutually exclusive with - `source_template`. When using `source_iso`, both `disk_offering` and - `hypervisor` are required. - -- `source_template` (string) - The name or ID of the template used as base - template for the instance. This option is mutually exclusive with - `source_iso`. - -- `template_os` (string) - The name or ID of the template OS for the new - template that will be created. - -- `zone` (string) - The name or ID of the zone where the instance will be - created. - -### Optional: - -- `async_timeout` (number) - The time duration to wait for async calls to - finish. Defaults to 30m. - -- `cidr_list` (array) - List of CIDR's that will have access to the new - instance. This is needed in order for any provisioners to be able to - connect to the instance. Defaults to `[ "0.0.0.0/0" ]`. Only required when - `use_local_ip_address` is `false`. - -- `create_security_group` (boolean) - If `true` a temporary security group - will be created which allows traffic towards the instance from the - `cidr_list`. This option will be ignored if `security_groups` is also - defined. Requires `expunge` set to `true`. Defaults to `false`. - -- `disk_offering` (string) - The name or ID of the disk offering used for the - instance. This option is only available (and also required) when using - `source_iso`. - -- `disk_size` (number) - The size (in GB) of the root disk of the new - instance. This option is only available when using `source_template`. - -- `expunge` (boolean) - Set to `true` to expunge the instance when it is - destroyed. Defaults to `false`. - -- `http_get_only` (boolean) - Some cloud providers only allow HTTP GET calls - to their CloudStack API. If using such a provider, you need to set this to - `true` in order for the provider to only make GET calls and no POST calls. - -- `hypervisor` (string) - The target hypervisor (e.g. `XenServer`, `KVM`) for - the new template. This option is required when using `source_iso`. - -- `eject_iso` (boolean) - If `true` make a call to the CloudStack API, after - loading image to cache, requesting to check and detach ISO file (if any) - currently attached to a virtual machine. Defaults to `false`. This option - is only available when using `source_iso`. - -- `eject_iso_delay` (time.Duration) - Configure the duration time to wait, making - sure virtual machine is able to finish installing OS before it ejects safely. - Requires `eject_iso` set to `true` and this option is only available when - using `source_iso`. - -- `keypair` (string) - The name of the SSH key pair that will be used to - access the instance. The SSH key pair is assumed to be already available - within CloudStack. - -- `instance_name` (string) - The name of the instance. Defaults to - "packer-UUID" where UUID is dynamically generated. - -- `prevent_firewall_changes` (boolean) - Set to `true` to prevent network - ACLs or firewall rules creation. Defaults to `false`. - -- `project` (string) - The name or ID of the project to deploy the instance - to. - -- `public_ip_address` (string) - The public IP address or it's ID used for - connecting any provisioners to. If not provided, a temporary public IP - address will be associated and released during the Packer run. - -- `public_port` (number) - The fixed port you want to configure in the port - forwarding rule. Set this attribute if you do not want to use the a random - public port. - -- `security_groups` (array of strings) - A list of security group IDs or - names to associate the instance with. - -- `ssl_no_verify` (boolean) - Set to `true` to skip SSL verification. - Defaults to `false`. - -- `template_display_text` (string) - The display text of the new template. - Defaults to the `template_name`. - -- `template_featured` (boolean) - Set to `true` to indicate that the template - is featured. Defaults to `false`. - -- `template_name` (string) - The name of the new template. Defaults to - `packer-{{timestamp}}` where timestamp will be the current time. - -- `template_public` (boolean) - Set to `true` to indicate that the template - is available for all accounts. Defaults to `false`. - -- `template_password_enabled` (boolean) - Set to `true` to indicate the - template should be password enabled. Defaults to `false`. - -- `template_requires_hvm` (boolean) - Set to `true` to indicate the template - requires hardware-assisted virtualization. Defaults to `false`. - -- `template_scalable` (boolean) - Set to `true` to indicate that the template - contains tools to support dynamic scaling of VM cpu/memory. Defaults to - `false`. - -- `temporary_keypair_name` (string) - The name of the temporary SSH key pair - to generate. By default, Packer generates a name that looks like - `packer_`, where <UUID> is a 36 character unique identifier. - -- `user_data` (string) - User data to launch with the instance. This is a - [template engine](/docs/templates/legacy_json_templates/engine) see _User - Data_ below for more details. Packer will not automatically wait for a user - script to finish before shutting down the instance this must be handled in a - provisioner. - -- `user_data_file` (string) - Path to a file that will be used for the user - data when launching the instance. This file will be parsed as a [template - engine](/docs/templates/legacy_json_templates/engine) see _User Data_ below - for more details. - -- `use_local_ip_address` (boolean) - Set to `true` to indicate that the - provisioners should connect to the local IP address of the instance. - -## User Data - -The available variables are: - -- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server - that is started serving the directory specified by the `http_directory` - configuration parameter. If `http_directory` isn't specified, these will be - blank. Example: `{{.HTTPIP}}:{{.HTTPPort}}/path/to/a/file/in/http_directory` - -### Communicator Configuration - -#### Optional: - -@include 'packer-plugin-sdk/communicator/Config-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSH-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSHTemporaryKeyPair-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSH-Key-Pair-Name-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSH-Private-Key-File-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSH-Agent-Auth-not-required.mdx' - -## Http directory configuration - -@include 'packer-plugin-sdk/multistep/commonsteps/HTTPConfig.mdx' - -### Optional: - -@include 'packer-plugin-sdk/multistep/commonsteps/HTTPConfig-not-required.mdx' - -## Basic Example - -Here is a basic example. - -```json -{ - "type": "cloudstack", - "api_url": "https://cloudstack.company.com/client/api", - "api_key": "YOUR_API_KEY", - "secret_key": "YOUR_SECRET_KEY", - - "disk_offering": "Small - 20GB", - "hypervisor": "KVM", - "network": "management", - "service_offering": "small", - "source_iso": "CentOS-7.0-1406-x86_64-Minimal", - "zone": "NL1", - - "ssh_username": "root", - - "template_name": "Centos7-x86_64-KVM-Packer", - "template_display_text": "Centos7-x86_64 KVM Packer", - "template_featured": true, - "template_password_enabled": true, - "template_scalable": true, - "template_os": "Other PV (64-bit)" -} -``` diff --git a/website/content/docs/builders/tencentcloud-cvm.mdx b/website/content/docs/builders/tencentcloud-cvm.mdx deleted file mode 100644 index ca4aa2e7c..000000000 --- a/website/content/docs/builders/tencentcloud-cvm.mdx +++ /dev/null @@ -1,186 +0,0 @@ ---- -description: | - The `tencentcloud-cvm` Packer builder plugin provide the capability to build - customized images based on an existing base images. -page_title: Tencentcloud Image Builder ---- - -# Tencentcloud Image Builder - -Type: `tencentcloud-cvm` -Artifact BuilderId: `tencent.cloud` - -The `tencentcloud-cvm` Packer builder plugin provide the capability to build -customized images based on an existing base images. - -## Configuration Reference - -The following configuration options are available for building Tencentcloud images. -In addition to the options listed here, -a [communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this builder. - -### Required: - -- `secret_id` (string) - Tencentcloud secret id. You should set it directly, - or set the `TENCENTCLOUD_ACCESS_KEY` environment variable. - -- `secret_key` (string) - Tencentcloud secret key. You should set it directly, - or set the `TENCENTCLOUD_SECRET_KEY` environment variable. - -- `region` (string) - The region where your cvm will be launch. You should - reference [Region and Zone](https://intl.cloud.tencent.com/document/product/213/6091) - for parameter taking. - -- `zone` (string) - The zone where your cvm will be launch. You should - reference [Region and Zone](https://intl.cloud.tencent.com/document/product/213/6091) - for parameter taking. - -- `instance_type` (string) - The instance type your cvm will be launched by. - You should reference [Instace Type](https://intl.cloud.tencent.com/document/product/213/11518) - for parameter taking. - -- `source_image_id` (string) - The base image id of Image you want to create - your customized image from. - -- `image_name` (string) - The name you want to create your customize image, - it should be composed of no more than 60 characters, of letters, numbers - or minus sign. - -### Optional: - -- `force_poweroff` (boolean) - Indicates whether to perform a forced shutdown to - create an image when soft shutdown fails. Default value is `false`. - -- `image_description` (string) - Image description. It should no more than 60 characters. - -- `reboot` (boolean, **deprecated**) - Whether shutdown cvm to create Image. - Please refer to parameter `force_poweroff`. - -- `sysprep` (boolean) - Whether enable Sysprep during creating windows image. - -- `image_copy_regions` (array of strings) - Regions that will be copied to after - your image created. - -- `image_share_accounts` (array of strings) - Accounts that will be shared to - after your image created. - -- `skip_region_validation` (boolean) - Do not check region and zone when validate. - -- `associate_public_ip_address` (boolean) - Whether allocate public ip to your cvm. - Default value is `false`. - - If not set, you could access your cvm from the same vpc. - -- `internet_max_bandwidth_out` (number) - Max bandwidth out your cvm will be launched by(in MB). - values can be set between 1 ~ 100. - -- `instance_name` (string) - Instance name. - -- `disk_type` (string) - Root disk type your cvm will be launched by, default is `CLOUD_PREMIUM`. you could - reference [Disk Type](https://intl.cloud.tencent.com/document/product/213/15753#SystemDisk) - for parameter taking. - -- `disk_size` (number) - Root disk size your cvm will be launched by. values range(in GB): - - - LOCAL_BASIC: 50 - - Other: 50 ~ 1000 (need whitelist if > 50) - -- `data_disks` (array of data disks) - Add one or more data disks to the instance before creating the - image. Note that if the source image has data disk snapshots, this argument will be ignored, and - the running instance will use source image data disk settings, in such case, `disk_type` - argument will be used as disk type for all data disks, and each data disk size will use the - origin value in source image. - The data disks allow for the following argument: - - - `disk_type` - Type of the data disk. Valid choices: `CLOUD_BASIC`, `CLOUD_PREMIUM` and `CLOUD_SSD`. - - `disk_size` - Size of the data disk. - - `disk_snapshot_id` - Id of the snapshot for a data disk. - -- `vpc_id` (string) - Specify vpc your cvm will be launched by. - -- `vpc_name` (string) - Specify vpc name you will create. if `vpc_id` is not set, Packer will - create a vpc for you named this parameter. - -- `cidr_block` (boolean) - Specify cider block of the vpc you will create if `vpc_id` is not set. - -- `subnet_id` (string) - Specify subnet your cvm will be launched by. - -- `subnet_name` (string) - Specify subnet name you will create. if `subnet_id` is not set, Packer will - create a subnet for you named this parameter. - -- `subnect_cidr_block` (boolean) - Specify cider block of the subnet you will create if - `subnet_id` is not set. - -- `security_group_id` (string) - Specify security group your cvm will be launched by. - -- `security_group_name` (string) - Specify security name you will create if `security_group_id` is not set. - -- `user_data` (string) - userdata. - -- `user_data_file` (string) - userdata file. - -- `host_name` (string) - host name. - -- `run_tags` (map of strings) - Tags to apply to the instance that is _launched_ to create the image. - These tags are _not_ applied to the resulting image. - -### Communicator Configuration - -In addition to the above options, a communicator can be configured -for this builder. - -#### Optional: - -@include 'packer-plugin-sdk/communicator/Config-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSH-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSHTemporaryKeyPair-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSH-Key-Pair-Name-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSH-Private-Key-File-not-required.mdx' - -@include 'packer-plugin-sdk/communicator/SSH-Agent-Auth-not-required.mdx' - -## Basic Example - -Here is a basic example for Tencentcloud. - -```json -{ - "variables": { - "secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}", - "secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}" - }, - "builders": [ - { - "type": "tencentcloud-cvm", - "secret_id": "{{user `secret_id`}}", - "secret_key": "{{user `secret_key`}}", - "region": "ap-guangzhou", - "zone": "ap-guangzhou-4", - "instance_type": "S4.SMALL1", - "source_image_id": "img-oikl1tzv", - "ssh_username": "root", - "image_name": "PackerTest", - "disk_type": "CLOUD_PREMIUM", - "packer_debug": true, - "associate_public_ip_address": true, - "run_tags": { - "good": "luck" - } - } - ], - "provisioners": [ - { - "type": "shell", - "inline": ["sleep 30", "yum install redis.x86_64 -y"] - } - ] -} -``` - -See the -[examples/tencentcloud](https://github.com/hashicorp/packer/tree/master/builder/tencentcloud/examples) -folder in the Packer project for more examples. diff --git a/website/content/docs/builders/vagrant.mdx b/website/content/docs/builders/vagrant.mdx deleted file mode 100644 index 39f25d088..000000000 --- a/website/content/docs/builders/vagrant.mdx +++ /dev/null @@ -1,217 +0,0 @@ ---- -description: | - The Vagrant Packer builder is able to launch Vagrant boxes and - re-package them into .box files -page_title: Vagrant - Builders ---- - -# Vagrant Builder - -Type: `vagrant` -Artifact BuilderId: `vagrant` - -The Vagrant builder is intended for building new boxes from already-existing -boxes. Your source should be a URL or path to a .box file or a Vagrant Cloud -box name such as `hashicorp/precise64`. - -Packer will not install vagrant, nor will it install the underlying -virtualization platforms or extra providers; We expect when you run this -builder that you have already installed what you need. - -By default, this builder will initialize a new Vagrant workspace, launch your -box from that workspace, provision it, call `vagrant package` to package it -into a new box, and then destroy the original box. Please note that vagrant -will _not_ remove the box file from your system (we don't call -`vagrant box remove`). - -You can change the behavior so that the builder doesn't destroy the box by -setting the `teardown_method` option. You can change the behavior so the builder -doesn't package it (not all provisioners support the `vagrant package` command) -by setting the `skip package` option. You can also change the behavior so that -rather than initializing a new Vagrant workspace, you use an already defined -one, by using `global_id` instead of `source_box`. - -Please note that if you are using the Vagrant builder, then the Vagrant -post-processor is unnecesary because the output of the Vagrant builder is -already a Vagrant box; using that post-processor with the Vagrant builder will -cause your build to fail. Similarly, since Vagrant boxes are already compressed, -the Compress post-processor will not work with this builder. - -## Configuration Reference - -### Required: - -- `source_path` (string) - URL of the vagrant box to use, or the name of the - vagrant box. `hashicorp/precise64`, `./mylocalbox.box` and - `https://example.com/my-box.box` are all valid source boxes. If your - source is a .box file, whether locally or from a URL like the latter example - above, you will also need to provide a `box_name`. This option is required, - unless you set `global_id`. You may only set one or the other, not both. - - or - -- `global_id` (string) - the global id of a Vagrant box already added to Vagrant - on your system. You can find the global id of your Vagrant boxes using the - command `vagrant global-status`; your global_id will be a 7-digit number and - letter combination that you'll find in the leftmost column of the - global-status output. If you choose to use `global_id` instead of - `source_box`, Packer will skip the Vagrant initialize and add steps, and - simply launch the box directly using the global id. - -### Optional: - -- `output_dir` (string) - The directory to create that will contain - your output box. We always create this directory and run from inside of it to - prevent Vagrant init collisions. If unset, it will be set to `output-` plus - your buildname. - -- `box_name` (string) - if your source_box is a boxfile that we need to add - to Vagrant, this is the name to give it. If left blank, will default to - "packer\_" plus your buildname. - -- `provider` (string) - The vagrant [provider](/docs/post-processors/vagrant). - This parameter is required when `source_path` have more than one provider, - or when using `vagrant-cloud` post-processor. Defaults to unset. - -- `checksum` (string) - The checksum for the .box file. The type of the - checksum is specified with `checksum_type`, documented below. - -- `checksum_type` (string) - The type of the checksum specified in `checksum`. - Valid values are `none`, `md5`, `sha1`, `sha256`, or `sha512`. Although the - checksum will not be verified when `checksum_type` is set to "none", this is - not recommended since OVA files can be very large and corruption does happen - from time to time. - -- `template` (string) - a path to a golang template for a - vagrantfile. Our default template can be found - [here](https://github.com/hashicorp/packer/blob/master/builder/vagrant/step_create_vagrantfile.go#L23-L37). So far the only template variables available to you are `{{ .BoxName }}` and - `{{ .SyncedFolder }}`, which correspond to the Packer options `box_name` and - `synced_folder`. - - You must provide a template if your default vagrant provider is Hyper-V. - Below is a Hyper-V compatible template. - - ```ruby - Vagrant.configure("2") do |config| - config.vm.box = "{{ .BoxName }}" - config.vm.network 'public_network', bridge: 'Default Switch' - end - ``` - -- `skip_add` (bool) - Don't call "vagrant add" to add the box to your local - environment; this is necessary if you want to launch a box that is already - added to your vagrant environment. - -- `teardown_method` (string) - Whether to halt, suspend, or destroy the box when - the build has completed. Defaults to "halt" - -- `box_version` (string) - What box version to use when initializing Vagrant. - -- `add_cacert` (string) - Equivalent to setting the - [`--cacert`](https://www.vagrantup.com/docs/cli/box.html#cacert-certfile) - option in `vagrant add`; defaults to unset. - -- `add_capath` (string) - Equivalent to setting the - [`--capath`](https://www.vagrantup.com/docs/cli/box.html#capath-certdir) option - in `vagrant add`; defaults to unset. - -- `add_cert` (string) - Equivalent to setting the - [`--cert`](https://www.vagrantup.com/docs/cli/box.html#cert-certfile) option in - `vagrant add`; defaults to unset. - -- `add_clean` (bool) - Equivalent to setting the - [`--clean`](https://www.vagrantup.com/docs/cli/box.html#clean) flag in - `vagrant add`; defaults to unset. - -- `add_force` (bool) - Equivalent to setting the - [`--force`](https://www.vagrantup.com/docs/cli/box.html#force) flag in - `vagrant add`; defaults to unset. - -- `add_insecure` (bool) - Equivalent to setting the - [`--insecure`](https://www.vagrantup.com/docs/cli/box.html#insecure) flag in - `vagrant add`; defaults to unset. - -- `skip_package` (bool) - if true, Packer will not call `vagrant package` to - package your base box into its own standalone .box file. - -- `output_vagrantfile` (string) - Equivalent to setting the - [`--vagrantfile`](https://www.vagrantup.com/docs/cli/package.html#vagrantfile-file) option - in `vagrant package`; defaults to unset - -- `package_include` (string) - Equivalent to setting the - [`--include`](https://www.vagrantup.com/docs/cli/package.html#include-x-y-z) option - in `vagrant package`; defaults to unset - -## Example - -Sample for `hashicorp/precise64` with virtualbox provider. - - - - -```json -{ - "builders": [ - { - "communicator": "ssh", - "source_path": "hashicorp/precise64", - "provider": "virtualbox", - "add_force": true, - "type": "vagrant" - } - ] -} -``` - - - - -```hcl -source "vagrant" "example" { - communicator = "ssh" - source_path = "hashicorp/precise64" - provider = "virtualbox" - add_force = true -} - -build { - sources = ["source.vagrant.example"] -} -``` - - - - -## Regarding output directory and new box - -After Packer completes building and provisioning a new Vagrant Box file, it is worth -noting that the new box file will need to be added to Vagrant. For a beginner to Packer -and Vagrant, it may seem as if a simple 'vagrant up' in the output directory will run the -the newly created Box. This is not the case. - -Rather, create a new directory (to avoid Vagarant init collisions), add the new -package.box to Vagrant and init. Then run vagrant up to bring up the new box created -by Packer. You will now be able to connect to the new box with provisioned changes. - -``` -'mkdir output2' -'cp package.box ./output2' -'vagrant box add new-box name-of-the-packer-box.box' -'vagrant init new-box' -'vagrant up' -``` - -## A note on SSH connections - -Currently this builder only works for SSH connections, and automatically fills -in all information needed for the SSH communicator using vagrant's ssh-config. - -If you would like to connect via a different username or authentication method -than is produced when you call `vagrant ssh-config`, then you must provide the - -`ssh_username` and all other relevant authentication information (e.g. -`ssh_password` or `ssh_private_key_file`) - -By providing the `ssh_username`, you're telling Packer not to use the vagrant -ssh config, except for determining the host and port for the virtual machine to -connect to. diff --git a/website/content/partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-not-required.mdx b/website/content/partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-not-required.mdx deleted file mode 100644 index 7db360097..000000000 --- a/website/content/partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-not-required.mdx +++ /dev/null @@ -1,5 +0,0 @@ - - -- `skip_region_validation` (bool) - Do not check region and zone when validate. - - diff --git a/website/content/partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-required.mdx b/website/content/partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-required.mdx deleted file mode 100644 index ae3fc0b61..000000000 --- a/website/content/partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-required.mdx +++ /dev/null @@ -1,17 +0,0 @@ - - -- `secret_id` (string) - Tencentcloud secret id. You should set it directly, - or set the TENCENTCLOUD_ACCESS_KEY environment variable. - -- `secret_key` (string) - Tencentcloud secret key. You should set it directly, - or set the TENCENTCLOUD_SECRET_KEY environment variable. - -- `region` (string) - The region where your cvm will be launch. You should - reference Region and Zone - for parameter taking. - -- `zone` (string) - The zone where your cvm will be launch. You should - reference Region and Zone - for parameter taking. - - diff --git a/website/content/partials/builder/tencentcloud/cvm/TencentCloudImageConfig-not-required.mdx b/website/content/partials/builder/tencentcloud/cvm/TencentCloudImageConfig-not-required.mdx deleted file mode 100644 index 077fbb778..000000000 --- a/website/content/partials/builder/tencentcloud/cvm/TencentCloudImageConfig-not-required.mdx +++ /dev/null @@ -1,23 +0,0 @@ - - -- `image_description` (string) - Image description. - -- `reboot` (bool) - Whether shutdown cvm to create Image. Default value is - false. - -- `force_poweroff` (bool) - Whether to force power off cvm when create image. - Default value is false. - -- `sysprep` (bool) - Whether enable Sysprep during creating windows image. - -- `image_force_delete` (bool) - Image Force Delete - -- `image_copy_regions` ([]string) - regions that will be copied to after - your image created. - -- `image_share_accounts` ([]string) - accounts that will be shared to - after your image created. - -- `skip_region_validation` (bool) - Do not check region and zone when validate. - - diff --git a/website/content/partials/builder/tencentcloud/cvm/TencentCloudImageConfig-required.mdx b/website/content/partials/builder/tencentcloud/cvm/TencentCloudImageConfig-required.mdx deleted file mode 100644 index 2996e1a37..000000000 --- a/website/content/partials/builder/tencentcloud/cvm/TencentCloudImageConfig-required.mdx +++ /dev/null @@ -1,7 +0,0 @@ - - -- `image_name` (string) - The name you want to create your customize image, - it should be composed of no more than 60 characters, of letters, numbers - or minus sign. - - diff --git a/website/content/partials/builder/tencentcloud/cvm/TencentCloudRunConfig-not-required.mdx b/website/content/partials/builder/tencentcloud/cvm/TencentCloudRunConfig-not-required.mdx deleted file mode 100644 index c71bafbc8..000000000 --- a/website/content/partials/builder/tencentcloud/cvm/TencentCloudRunConfig-not-required.mdx +++ /dev/null @@ -1,73 +0,0 @@ - - -- `associate_public_ip_address` (bool) - Whether allocate public ip to your cvm. - Default value is false. - -- `source_image_id` (string) - The base image id of Image you want to create - your customized image from. - -- `source_image_name` (string) - The base image name of Image you want to create your - customized image from.Conflict with SourceImageId. - -- `instance_name` (string) - Instance name. - -- `disk_type` (string) - Root disk type your cvm will be launched by, default is `CLOUD_PREMIUM`. you could - reference Disk Type - for parameter taking. - -- `disk_size` (int64) - Root disk size your cvm will be launched by. values range(in GB): - -- `data_disks` ([]tencentCloudDataDisk) - Add one or more data disks to the instance before creating the image. - Note that if the source image has data disk snapshots, this argument - will be ignored, and the running instance will use source image data - disk settings, in such case, `disk_type` argument will be used as disk - type for all data disks, and each data disk size will use the origin - value in source image. - The data disks allow for the following argument: - - `disk_type` - Type of the data disk. Valid choices: `CLOUD_BASIC`, `CLOUD_PREMIUM` and `CLOUD_SSD`. - - `disk_size` - Size of the data disk. - - `disk_snapshot_id` - Id of the snapshot for a data disk. - -- `vpc_id` (string) - Specify vpc your cvm will be launched by. - -- `vpc_name` (string) - Specify vpc name you will create. if vpc_id is not set, packer will - create a vpc for you named this parameter. - -- `vpc_ip` (string) - Vpc Ip - -- `subnet_id` (string) - Specify subnet your cvm will be launched by. - -- `subnet_name` (string) - Specify subnet name you will create. if subnet_id is not set, packer will - create a subnet for you named this parameter. - -- `cidr_block` (string) - Specify cider block of the vpc you will create if vpc_id not set - -- `subnect_cidr_block` (string) - Specify cider block of the subnet you will create if - subnet_id not set - -- `internet_charge_type` (string) - Internet Charge Type - -- `internet_max_bandwidth_out` (int64) - Max bandwidth out your cvm will be launched by(in MB). - values can be set between 1 ~ 100. - -- `security_group_id` (string) - Specify securitygroup your cvm will be launched by. - -- `security_group_name` (string) - Specify security name you will create if security_group_id not set. - -- `user_data` (string) - userdata. - -- `user_data_file` (string) - userdata file. - -- `host_name` (string) - host name. - -- `run_tags` (map[string]string) - Key/value pair tags to apply to the instance that is *launched* to - create the image. These tags are *not* applied to the resulting image. - -- `run_tag` ([]{key string, value string}) - Same as [`run_tags`](#run_tags) but defined as a singular repeatable - block containing a `key` and a `value` field. In HCL2 mode the - [`dynamic_block`](/docs/templates/hcl_templates/expressions#dynamic-blocks) - will allow you to create those programatically. - -- `ssh_private_ip` (bool) - SSH Private Ip - - diff --git a/website/content/partials/builder/tencentcloud/cvm/TencentCloudRunConfig-required.mdx b/website/content/partials/builder/tencentcloud/cvm/TencentCloudRunConfig-required.mdx deleted file mode 100644 index b3cb818de..000000000 --- a/website/content/partials/builder/tencentcloud/cvm/TencentCloudRunConfig-required.mdx +++ /dev/null @@ -1,7 +0,0 @@ - - -- `instance_type` (string) - The instance type your cvm will be launched by. - You should reference Instace Type - for parameter taking. - - diff --git a/website/content/partials/builder/tencentcloud/cvm/tencentCloudDataDisk-not-required.mdx b/website/content/partials/builder/tencentcloud/cvm/tencentCloudDataDisk-not-required.mdx deleted file mode 100644 index 8cdd05455..000000000 --- a/website/content/partials/builder/tencentcloud/cvm/tencentCloudDataDisk-not-required.mdx +++ /dev/null @@ -1,9 +0,0 @@ - - -- `disk_type` (string) - Disk Type - -- `disk_size` (int64) - Disk Size - -- `disk_snapshot_id` (string) - Snapshot Id - - diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 212c611d1..25bfe298c 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -712,10 +712,6 @@ "title": "ProfitBricks", "path": "builders/profitbricks" }, - { - "title": "Tencent Cloud", - "path": "builders/tencentcloud-cvm" - }, { "title": "Yandex.Cloud", "path": "builders/yandex" diff --git a/website/data/docs-remote-plugins.json b/website/data/docs-remote-plugins.json index 3e5d9fcab..fe29cd7fe 100644 --- a/website/data/docs-remote-plugins.json +++ b/website/data/docs-remote-plugins.json @@ -167,6 +167,12 @@ "pluginTier": "community", "version": "latest" }, + { + "title": "Tencent Cloud", + "path": "tencentcloud", + "repo": "hashicorp/packer-plugin-tencentcloud", + "version": "latest" + }, { "title": "Triton", "path": "triton",