Merge pull request #7787 from zqfan/tencent-fix-tmp-keypair

fix: correctly remove tencentcloud temporary keypair
This commit is contained in:
Megan Marsh 2019-06-24 11:21:30 -07:00 committed by GitHub
commit 6ead0493d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 103 additions and 13 deletions

View File

@ -115,9 +115,15 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&common.StepProvision{},
&common.StepCleanupTempKeys{
Comm: &b.config.TencentCloudRunConfig.Comm},
Comm: &b.config.TencentCloudRunConfig.Comm,
},
// We need this step to detach temporary key from instance, otherwise
// it always fails to delete the key.
&stepDetachTempKeyPair{},
&stepCreateImage{},
&stepShareImage{b.config.ImageShareAccounts},
&stepShareImage{
b.config.ImageShareAccounts,
},
&stepCopyImage{
DesinationRegions: b.config.ImageCopyRegions,
SourceRegion: b.config.Region,

View File

@ -70,6 +70,7 @@ func (s *stepConfigKeyPair) Run(ctx context.Context, state multistep.StateBag) m
// set keyId to delete when Cleanup
s.keyID = *resp.Response.KeyPair.KeyId
state.Put("temporary_key_pair_id", resp.Response.KeyPair.KeyId)
s.Comm.SSHKeyPairName = *resp.Response.KeyPair.KeyId
s.Comm.SSHPrivateKey = []byte(*resp.Response.KeyPair.PrivateKey)

View File

@ -106,7 +106,7 @@ func (s *stepConfigSecurityGroup) Cleanup(state multistep.StateBag) {
vpcClient := state.Get("vpc_client").(*vpc.Client)
ui := state.Get("ui").(packer.Ui)
MessageClean(state, "VPC")
MessageClean(state, "Security Group")
req := vpc.NewDeleteSecurityGroupRequest()
req.SecurityGroupId = &s.SecurityGroupId
err := retry.Config{

View File

@ -3,9 +3,12 @@ package cvm
import (
"context"
"fmt"
"time"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
)
@ -46,7 +49,26 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
req.Sysprep = &False
}
_, err := client.CreateImage(req)
err := retry.Config{
Tries: 60,
RetryDelay: (&retry.Backoff{
InitialBackoff: 5 * time.Second,
MaxBackoff: 5 * time.Second,
Multiplier: 2,
}).Linear,
ShouldRetry: func(err error) bool {
if e, ok := err.(*errors.TencentCloudSDKError); ok {
if e.Code == "InvalidImageName.Duplicate" {
return false
}
}
return true
},
}.Run(ctx, func(ctx context.Context) error {
_, err := client.CreateImage(req)
return err
})
if err != nil {
err := fmt.Errorf("create image failed: %s", err.Error())
state.Put("error", err)

View File

@ -0,0 +1,51 @@
package cvm
import (
"context"
"fmt"
"time"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"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)
instance := state.Get("instance").(*cvm.Instance)
if _, ok := state.GetOk("temporary_key_pair_id"); !ok {
return multistep.ActionContinue
}
keyId := state.Get("temporary_key_pair_id").(*string)
ui := state.Get("ui").(packer.Ui)
ui.Say(fmt.Sprintf("Detaching temporary key pair %s...", *keyId))
req := cvm.NewDisassociateInstancesKeyPairsRequest()
req.KeyIds = []*string{keyId}
req.InstanceIds = []*string{instance.InstanceId}
req.ForceStop = common.BoolPtr(true)
err := retry.Config{
Tries: 60,
RetryDelay: (&retry.Backoff{
InitialBackoff: 5 * time.Second,
MaxBackoff: 5 * time.Second,
Multiplier: 2,
}).Linear,
}.Run(ctx, func(ctx context.Context) error {
_, err := client.DisassociateInstancesKeyPairs(req)
return err
})
if err != nil {
ui.Error(fmt.Sprintf("Fail to detach temporary key pair from instance! Error: %s", err))
state.Put("error", err)
return multistep.ActionHalt
}
return multistep.ActionContinue
}
func (s *stepDetachTempKeyPair) Cleanup(state multistep.StateBag) {
}

View File

@ -8,6 +8,7 @@ import (
"log"
"time"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
@ -143,15 +144,23 @@ func (s *stepRunInstance) Cleanup(state multistep.StateBag) {
if s.instanceId == "" {
return
}
MessageClean(state, "instance")
MessageClean(state, "Instance")
client := state.Get("cvm_client").(*cvm.Client)
ui := state.Get("ui").(packer.Ui)
req := cvm.NewTerminateInstancesRequest()
req.InstanceIds = []*string{&s.instanceId}
_, err := client.TerminateInstances(req)
// The binding relation between instance and vpc would last few minutes after
// instance terminate, we sleep here to give more time
time.Sleep(2 * time.Minute)
ctx := context.TODO()
err := retry.Config{
Tries: 60,
RetryDelay: (&retry.Backoff{
InitialBackoff: 5 * time.Second,
MaxBackoff: 5 * time.Second,
Multiplier: 2,
}).Linear,
}.Run(ctx, func(ctx context.Context) error {
_, err := client.TerminateInstances(req)
return err
})
if err != nil {
ui.Error(fmt.Sprintf("terminate instance(%s) failed: %s", s.instanceId, err.Error()))
}

View File

@ -8,11 +8,12 @@
"secret_id": "{{user `secret_id`}}",
"secret_key": "{{user `secret_key`}}",
"region": "ap-guangzhou",
"zone": "ap-guangzhou-3",
"instance_type": "S3.SMALL1",
"zone": "ap-guangzhou-4",
"instance_type": "S4.SMALL1",
"source_image_id": "img-oikl1tzv",
"ssh_username" : "root",
"image_name": "packerTest2",
"image_name": "PackerTest",
"disk_type": "CLOUD_PREMIUM",
"packer_debug": true,
"associate_public_ip_address": true
}],
@ -23,4 +24,4 @@
"yum install redis.x86_64 -y"
]
}]
}
}