ucloud packer review
This commit is contained in:
parent
b0500f97b8
commit
7804a52dd2
|
@ -86,7 +86,6 @@ func (c *AccessConfig) Config() error {
|
|||
}
|
||||
|
||||
func (c *AccessConfig) ValidateProjectId(projectId string) error {
|
||||
|
||||
supportedProjectIds, err := c.getSupportedProjectIds()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -102,7 +101,6 @@ func (c *AccessConfig) ValidateProjectId(projectId string) error {
|
|||
}
|
||||
|
||||
func (c *AccessConfig) ValidateRegion(region string) error {
|
||||
|
||||
supportedRegions, err := c.getSupportedRegions()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -118,7 +116,6 @@ func (c *AccessConfig) ValidateRegion(region string) error {
|
|||
}
|
||||
|
||||
func (c *AccessConfig) ValidateZone(region, zone string) error {
|
||||
|
||||
supportedZones, err := c.getSupportedZones(region)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -27,7 +27,6 @@ func (c *UCloudClient) describeFirewallById(sgId string) (*unet.FirewallDataSet,
|
|||
|
||||
resp, err := conn.DescribeFirewall(req)
|
||||
|
||||
// [API-STYLE] Fire wall api has not found err code, but others don't have
|
||||
if err != nil {
|
||||
if uErr, ok := err.(uerr.Error); ok && uErr.Code() == 54002 {
|
||||
return nil, newNotFoundError("security group", sgId)
|
||||
|
@ -93,9 +92,6 @@ func (c *UCloudClient) DescribeImageById(imageId string) (*uhost.UHostImageSet,
|
|||
|
||||
resp, err := c.uhostconn.DescribeImage(req)
|
||||
if err != nil {
|
||||
//if uErr, ok := err.(uerr.Error); ok && uErr.Code() == 8889 {
|
||||
// return nil, newNotFoundError("image", imageId)
|
||||
//}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -132,9 +128,6 @@ func (c *UCloudClient) describeImageByInfo(projectId, regionId, imageId string)
|
|||
|
||||
resp, err := c.uhostconn.DescribeImage(req)
|
||||
if err != nil {
|
||||
//if uErr, ok := err.(uerr.Error); ok && uErr.Code() == 8889 {
|
||||
// return nil, newNotFoundError("image", imageId)
|
||||
//}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -8,13 +8,13 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
osTypeWindows = "Windows"
|
||||
securityGroupNonWeb = "recommend non web"
|
||||
instanceStateRunning = "Running"
|
||||
instanceStateStopped = "Stopped"
|
||||
bootDiskStateInitializing = "Initializing"
|
||||
bootDiskStateNormal = "Normal"
|
||||
imageStateAvailable = "Available"
|
||||
osTypeWindows = "Windows"
|
||||
securityGroupNonWeb = "recommend non web"
|
||||
instanceStateRunning = "Running"
|
||||
instanceStateStopped = "Stopped"
|
||||
bootDiskStateNormal = "Normal"
|
||||
imageStateAvailable = "Available"
|
||||
ipTypePrivate = "Private"
|
||||
)
|
||||
|
||||
var bootDiskTypeMap = map[string]string{
|
||||
|
|
|
@ -35,6 +35,7 @@ func (c *ImageConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
if imageDestination.Name == "" {
|
||||
imageDestination.Name = imageName
|
||||
}
|
||||
|
||||
errs = append(errs, imageDestination.validate()...)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
if c.BootDiskType == "" {
|
||||
c.BootDiskType = "cloud_ssd"
|
||||
} else if err := checkStringIn(c.BootDiskType,
|
||||
[]string{"local_normal", "local_ssd", "cloud_normal", "cloud_ssd"}); err != nil {
|
||||
[]string{"local_normal", "local_ssd", "cloud_ssd"}); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
|
@ -63,9 +63,50 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
errs = append(errs, fmt.Errorf("%q must be set when use_ssh_private_ip is true", "vpc_id"))
|
||||
}
|
||||
|
||||
if c.Comm.SSHPassword != "" && len(validateInstancePassword(c.Comm.SSHPassword)) != 0 {
|
||||
for _, v := range validateInstancePassword(c.Comm.SSHPassword) {
|
||||
errs = append(errs, v)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var instancePasswordUpperPattern = regexp.MustCompile(`[A-Z]`)
|
||||
var instancePasswordLowerPattern = regexp.MustCompile(`[a-z]`)
|
||||
var instancePasswordNumPattern = regexp.MustCompile(`[0-9]`)
|
||||
var instancePasswordSpecialPattern = regexp.MustCompile(`[` + "`" + `()~!@#$%^&*-+=_|{}\[\]:;'<>,.?/]`)
|
||||
var instancePasswordPattern = regexp.MustCompile(`^[A-Za-z0-9` + "`" + `()~!@#$%^&*-+=_|{}\[\]:;'<>,.?/]{8,30}$`)
|
||||
|
||||
func validateInstancePassword(password string) (errors []error) {
|
||||
if !instancePasswordPattern.MatchString(password) {
|
||||
errors = append(errors, fmt.Errorf("%q is invalid, should have between 8-30 characters and any characters must be legal, got %q", "ssh_password", password))
|
||||
}
|
||||
|
||||
categoryCount := 0
|
||||
if instancePasswordUpperPattern.MatchString(password) {
|
||||
categoryCount++
|
||||
}
|
||||
|
||||
if instancePasswordLowerPattern.MatchString(password) {
|
||||
categoryCount++
|
||||
}
|
||||
|
||||
if instancePasswordNumPattern.MatchString(password) {
|
||||
categoryCount++
|
||||
}
|
||||
|
||||
if instancePasswordSpecialPattern.MatchString(password) {
|
||||
categoryCount++
|
||||
}
|
||||
|
||||
if categoryCount < 2 {
|
||||
errors = append(errors, fmt.Errorf("%q is invalid, should have least 2 items of capital letters, lower case letters, numbers and special characters, got %q", "ssh_password", password))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package uhost
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
@ -21,7 +22,7 @@ func (s *stepCheckSourceImageId) Run(ctx context.Context, state multistep.StateB
|
|||
if isNotFoundError(err) {
|
||||
return halt(state, err, "")
|
||||
}
|
||||
return halt(state, err, "Error on querying source_image_id")
|
||||
return halt(state, err, fmt.Sprintf("Error on querying specified source_image_id %q", s.SourceUHostImageId))
|
||||
}
|
||||
|
||||
if imageSet.OsType == osTypeWindows {
|
||||
|
|
|
@ -25,7 +25,7 @@ func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.State
|
|||
err = fmt.Errorf("the specified security group %q not exist", s.SecurityGroupId)
|
||||
return halt(state, err, "")
|
||||
}
|
||||
return halt(state, err, "Error on querying security group")
|
||||
return halt(state, err, fmt.Sprintf("Error on querying specified security group %q", s.SecurityGroupId))
|
||||
}
|
||||
|
||||
state.Put("security_group_id", securityGroupSet.FWId)
|
||||
|
@ -44,7 +44,7 @@ func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.State
|
|||
|
||||
resp, err := conn.DescribeFirewall(req)
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on querying security group")
|
||||
return halt(state, err, "Error on querying default security group")
|
||||
}
|
||||
|
||||
if resp == nil || len(resp.DataSet) < 1 {
|
||||
|
@ -65,10 +65,11 @@ func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.State
|
|||
offset = offset + limit
|
||||
}
|
||||
|
||||
if securityGroupId != "" {
|
||||
state.Put("security_group_id", securityGroupId)
|
||||
return multistep.ActionContinue
|
||||
if securityGroupId == "" {
|
||||
return halt(state, fmt.Errorf("the default security group not exist"), "")
|
||||
}
|
||||
|
||||
state.Put("security_group_id", securityGroupId)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ func (s *stepConfigSubnet) Run(ctx context.Context, state multistep.StateBag) mu
|
|||
err = fmt.Errorf("the specified subnet %q not exist", s.SubnetId)
|
||||
return halt(state, err, "")
|
||||
}
|
||||
return halt(state, err, "Error on querying subnet")
|
||||
return halt(state, err, fmt.Sprintf("Error on querying specified subnet %q", s.SubnetId))
|
||||
}
|
||||
|
||||
state.Put("subnet_id", subnetSet.SubnetId)
|
||||
|
|
|
@ -25,7 +25,7 @@ func (s *stepConfigVPC) Run(ctx context.Context, state multistep.StateBag) multi
|
|||
err = fmt.Errorf("the specified vpc %q not exist", s.VPCId)
|
||||
return halt(state, err, "")
|
||||
}
|
||||
return halt(state, err, "Error on querying vpc")
|
||||
return halt(state, err, fmt.Sprintf("Error on querying specified vpc %q", s.VPCId))
|
||||
}
|
||||
|
||||
state.Put("vpc_id", vpcSet.VPCId)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
|
@ -29,34 +30,34 @@ func (s *stepCopyUCloudImage) Run(ctx context.Context, state multistep.StateBag)
|
|||
srcImageId := state.Get("image_id").(string)
|
||||
artifactImages := state.Get("ucloud_images").(*imageInfoSet)
|
||||
expectedImages := newImageInfoSet(nil)
|
||||
|
||||
ui.Say(fmt.Sprintf("Copying image with %q...", srcImageId))
|
||||
for _, imageDestination := range s.ImageDestinations {
|
||||
if imageDestination.ProjectId == s.ProjectId && imageDestination.Region == s.RegionId {
|
||||
for _, v := range s.ImageDestinations {
|
||||
if v.ProjectId == s.ProjectId && v.Region == s.RegionId {
|
||||
continue
|
||||
}
|
||||
|
||||
req := conn.NewCopyCustomImageRequest()
|
||||
req.TargetProjectId = ucloud.String(imageDestination.ProjectId)
|
||||
req.TargetRegion = ucloud.String(imageDestination.Region)
|
||||
req.TargetProjectId = ucloud.String(v.ProjectId)
|
||||
req.TargetRegion = ucloud.String(v.Region)
|
||||
req.SourceImageId = ucloud.String(srcImageId)
|
||||
req.TargetImageName = ucloud.String(imageDestination.Name)
|
||||
req.TargetImageName = ucloud.String(v.Name)
|
||||
req.TargetImageDescription = ucloud.String(v.Description)
|
||||
|
||||
resp, err := conn.CopyCustomImage(req)
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on copying images")
|
||||
return halt(state, err, fmt.Sprintf("Error on copying image %q to %s:%s", srcImageId, v.ProjectId, v.Region))
|
||||
}
|
||||
|
||||
image := imageInfo{
|
||||
Region: imageDestination.Region,
|
||||
ProjectId: imageDestination.ProjectId,
|
||||
Region: v.Region,
|
||||
ProjectId: v.ProjectId,
|
||||
ImageId: resp.TargetImageId,
|
||||
}
|
||||
expectedImages.Set(image)
|
||||
artifactImages.Set(image)
|
||||
|
||||
ui.Message(fmt.Sprintf("Copying image from %s:%s:%s to %s:%s:%s)",
|
||||
s.ProjectId, s.RegionId, srcImageId, imageDestination.ProjectId, imageDestination.Region, resp.TargetImageId))
|
||||
s.ProjectId, s.RegionId, srcImageId, v.ProjectId, v.Region, resp.TargetImageId))
|
||||
}
|
||||
|
||||
err := retry.Config{
|
||||
|
@ -67,7 +68,7 @@ func (s *stepCopyUCloudImage) Run(ctx context.Context, state multistep.StateBag)
|
|||
for _, v := range expectedImages.GetAll() {
|
||||
imageSet, err := client.describeImageByInfo(v.ProjectId, v.Region, v.ImageId)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("reading %s:%s:%s failed, %s", v.ProjectId, v.Region, v.ImageId, err)
|
||||
}
|
||||
|
||||
if imageSet.State == imageStateAvailable {
|
||||
|
@ -84,10 +85,15 @@ func (s *stepCopyUCloudImage) Run(ctx context.Context, state multistep.StateBag)
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, fmt.Sprintf("Error on waiting for copying image finished"))
|
||||
var s []string
|
||||
for _, v := range expectedImages.GetAll() {
|
||||
s = append(s, fmt.Sprintf("%s:%s:%s", v.ProjectId, v.Region, v.ImageId))
|
||||
}
|
||||
|
||||
return halt(state, err, fmt.Sprintf("Error on waiting for copying images %q available", strings.Join(s, ",")))
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Copy image complete"))
|
||||
ui.Message(fmt.Sprintf("Copying image complete"))
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
@ -128,5 +134,5 @@ func (s *stepCopyUCloudImage) Cleanup(state multistep.StateBag) {
|
|||
}
|
||||
}
|
||||
|
||||
ui.Message("Delete copied image complete")
|
||||
ui.Message("Deleting copied image complete")
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
|
||||
resp, err := conn.CreateCustomImage(req)
|
||||
if err != nil {
|
||||
return halt(state, err, "")
|
||||
return halt(state, err, "Error on creating image")
|
||||
}
|
||||
|
||||
err = retry.Config{
|
||||
|
@ -54,12 +54,12 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on waiting for image to available")
|
||||
return halt(state, err, fmt.Sprintf("Error on waiting for image %q available", resp.ImageId))
|
||||
}
|
||||
|
||||
imageSet, err := client.DescribeImageById(resp.ImageId)
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on reading image")
|
||||
return halt(state, err, fmt.Sprintf("Error on reading image when creating %q", resp.ImageId))
|
||||
}
|
||||
|
||||
s.image = imageSet
|
||||
|
@ -74,7 +74,7 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
}
|
||||
|
||||
state.Put("ucloud_images", newImageInfoSet(images))
|
||||
ui.Message(fmt.Sprintf("Create image %q complete", imageSet.ImageId))
|
||||
ui.Message(fmt.Sprintf("Creating image %q complete", imageSet.ImageId))
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
@ -99,5 +99,5 @@ func (s *stepCreateImage) Cleanup(state multistep.StateBag) {
|
|||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on deleting image %q", s.image.ImageId))
|
||||
}
|
||||
ui.Message(fmt.Sprintf("Delete image %q complete", s.image.ImageId))
|
||||
ui.Message(fmt.Sprintf("Deleting image %q complete", s.image.ImageId))
|
||||
}
|
||||
|
|
|
@ -31,12 +31,7 @@ func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
|
|||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Creating Instance...")
|
||||
req, err := s.buildCreateInstanceRequest(state)
|
||||
if err != nil {
|
||||
return halt(state, err, "")
|
||||
}
|
||||
|
||||
resp, err := conn.CreateUHostInstance(req)
|
||||
resp, err := conn.CreateUHostInstance(s.buildCreateInstanceRequest(state))
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on creating instance")
|
||||
}
|
||||
|
@ -53,6 +48,15 @@ func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if inst.State == "ResizeFail" {
|
||||
return fmt.Errorf("resizing instance failed")
|
||||
}
|
||||
|
||||
if inst.State == "Install Fail" {
|
||||
return fmt.Errorf("install failed")
|
||||
}
|
||||
|
||||
if inst == nil || inst.State != instanceStateRunning {
|
||||
return newExpectedStateError("instance", instanceId)
|
||||
}
|
||||
|
@ -61,20 +65,23 @@ func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on waiting for instance to available")
|
||||
return halt(state, err, fmt.Sprintf("Error on waiting for instance %q available", instanceId))
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Create instance %q complete", instanceId))
|
||||
ui.Message(fmt.Sprintf("Creating instance %q complete", instanceId))
|
||||
instance, err := client.describeUHostById(instanceId)
|
||||
if err != nil {
|
||||
return halt(state, err, "")
|
||||
return halt(state, err, fmt.Sprintf("Error on reading instance when creating %q", instanceId))
|
||||
}
|
||||
|
||||
s.instanceId = instanceId
|
||||
state.Put("instance", instance)
|
||||
|
||||
if instance.BootDiskState == bootDiskStateInitializing {
|
||||
ui.Say(fmt.Sprintf("Waiting for boot disk of instance initialized when boot_disk_type is %q", s.BootDiskType))
|
||||
if instance.BootDiskState != bootDiskStateNormal {
|
||||
ui.Say("Waiting for boot disk of instance initialized")
|
||||
if s.BootDiskType == "local_normal" || s.BootDiskType == "local_ssd" {
|
||||
ui.Message(fmt.Sprintf("Warning: It takes around 10 mins for boot disk initialization when `boot_disk_type` is %q", s.BootDiskType))
|
||||
}
|
||||
|
||||
err = retry.Config{
|
||||
Tries: 200,
|
||||
|
@ -95,10 +102,10 @@ func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on waiting for boot disk of instance initialized")
|
||||
return halt(state, err, fmt.Sprintf("Error on waiting for boot disk of instance %q initialized", instanceId))
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Waite for boot disk of instance %q initialized complete", instanceId))
|
||||
ui.Message(fmt.Sprintf("Waiting for boot disk of instance %q initialized complete", instanceId))
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
|
@ -123,35 +130,21 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
|
|||
client := state.Get("client").(*UCloudClient)
|
||||
conn := client.uhostconn
|
||||
|
||||
stopReq := conn.NewPoweroffUHostInstanceRequest()
|
||||
stopReq.UHostId = ucloud.String(s.instanceId)
|
||||
|
||||
instance, err := client.describeUHostById(s.instanceId)
|
||||
if err != nil {
|
||||
if isNotFoundError(err) {
|
||||
return
|
||||
}
|
||||
ui.Error(fmt.Sprintf("Error on reading instance when delete %q, %s",
|
||||
ui.Error(fmt.Sprintf("Error on reading instance when deleting %q, %s",
|
||||
s.instanceId, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if instance.State != instanceStateStopped {
|
||||
err = retry.Config{
|
||||
Tries: 5,
|
||||
ShouldRetry: func(err error) bool {
|
||||
return err != nil
|
||||
},
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 6 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
if _, err = conn.PoweroffUHostInstance(stopReq); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on stopping instance when delete %q, %s",
|
||||
stopReq := conn.NewPoweroffUHostInstanceRequest()
|
||||
stopReq.UHostId = ucloud.String(s.instanceId)
|
||||
if _, err = conn.PoweroffUHostInstance(stopReq); err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on stopping instance when deleting %q, %s",
|
||||
s.instanceId, err.Error()))
|
||||
return
|
||||
}
|
||||
|
@ -176,7 +169,7 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on waiting for instance %q to stopped, %s",
|
||||
ui.Error(fmt.Sprintf("Error on waiting for stopping instance when deleting %q, %s",
|
||||
s.instanceId, err.Error()))
|
||||
return
|
||||
}
|
||||
|
@ -187,20 +180,7 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
|
|||
deleteReq.ReleaseUDisk = ucloud.Bool(true)
|
||||
deleteReq.ReleaseEIP = ucloud.Bool(true)
|
||||
|
||||
err = retry.Config{
|
||||
Tries: 5,
|
||||
ShouldRetry: func(err error) bool {
|
||||
return err != nil
|
||||
},
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 6 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
if _, err = conn.TerminateUHostInstance(deleteReq); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if _, err = conn.TerminateUHostInstance(deleteReq); err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on deleting instance %q, %s",
|
||||
s.instanceId, err.Error()))
|
||||
return
|
||||
|
@ -221,10 +201,10 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
|
|||
return
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Delete instance %q complete", s.instanceId))
|
||||
ui.Message(fmt.Sprintf("Deleting instance %q complete", s.instanceId))
|
||||
}
|
||||
|
||||
func (s *stepCreateInstance) buildCreateInstanceRequest(state multistep.StateBag) (*uhost.CreateUHostInstanceRequest, error) {
|
||||
func (s *stepCreateInstance) buildCreateInstanceRequest(state multistep.StateBag) *uhost.CreateUHostInstanceRequest {
|
||||
client := state.Get("client").(*UCloudClient)
|
||||
conn := client.uhostconn
|
||||
srcImage := state.Get("source_image").(*uhost.UHostImageSet)
|
||||
|
@ -292,7 +272,7 @@ func (s *stepCreateInstance) buildCreateInstanceRequest(state multistep.StateBag
|
|||
|
||||
req.NetworkInterface = append(req.NetworkInterface, networkInterface)
|
||||
}
|
||||
return req, nil
|
||||
return req
|
||||
}
|
||||
|
||||
func (s *stepCreateInstance) randStringFromCharSet(strlen int, charSet string) string {
|
||||
|
|
|
@ -23,7 +23,7 @@ func (s *stepStopInstance) Run(ctx context.Context, state multistep.StateBag) mu
|
|||
|
||||
instance, err := client.describeUHostById(instance.UHostId)
|
||||
if err != nil {
|
||||
return halt(state, err, fmt.Sprintf("Error on reading instance when stop %q", instance.UHostId))
|
||||
return halt(state, err, fmt.Sprintf("Error on reading instance when stopping %q", instance.UHostId))
|
||||
}
|
||||
|
||||
if instance.State != instanceStateStopped {
|
||||
|
@ -67,10 +67,10 @@ func (s *stepStopInstance) Run(ctx context.Context, state multistep.StateBag) mu
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, fmt.Sprintf("Error on waiting for instance %q to stopped", instance.UHostId))
|
||||
return halt(state, err, fmt.Sprintf("Error on waiting for stopping instance when stopping %q", instance.UHostId))
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Stop instance %q complete", instance.UHostId))
|
||||
ui.Message(fmt.Sprintf("Stopping instance %q complete", instance.UHostId))
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
|
|
|
@ -46,17 +46,18 @@ func SSHHost(usePrivateIp bool) func(multistep.StateBag) (string, error) {
|
|||
var privateIp, publicIp string
|
||||
|
||||
for _, v := range instance.IPSet {
|
||||
if v.Type == "Private" {
|
||||
if v.Type == ipTypePrivate {
|
||||
privateIp = v.IP
|
||||
} else {
|
||||
publicIp = v.IP
|
||||
}
|
||||
}
|
||||
|
||||
if usePrivateIp {
|
||||
return privateIp, nil
|
||||
} else {
|
||||
return publicIp, nil
|
||||
}
|
||||
|
||||
return publicIp, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"variables": {
|
||||
"ucloud_public_key": "{{env `UCLOUD_PUBLIC_KEY`}}",
|
||||
"ucloud_private_key": "{{env `UCLOUD_PRIVATE_KEY`}}",
|
||||
"ucloud_project_id": "{{env `UCLOUD_PROJECT_ID`}}"
|
||||
},
|
||||
|
||||
"builders": [{
|
||||
"type": "ucloud-uhost",
|
||||
"public_key":"{{user `ucloud_public_key`}}",
|
||||
"private_key":"{{user `ucloud_private_key`}}",
|
||||
"project_id": "{{user `ucloud_project_id`}}",
|
||||
"region": "cn-bj2",
|
||||
"availability_zone": "cn-bj2-02",
|
||||
"instance_type": "n-basic-2",
|
||||
"source_image_id":"uimage-irofn4",
|
||||
"ssh_username":"ubuntu",
|
||||
"image_name": "packer-test-ubuntu-bj"
|
||||
}],
|
||||
"provisioners": [{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"sudo visudo",
|
||||
"ubuntu ALL = NOPASSWD: /usr/local/sbin/apt-get",
|
||||
"sudo apt-get update",
|
||||
"sudo apt-get install -y mysql"
|
||||
]
|
||||
}]
|
||||
}
|
|
@ -26,7 +26,7 @@ In addition to the options listed here, a
|
|||
[communicator](../templates/communicator.html) can be configured for this
|
||||
builder.
|
||||
|
||||
\~> **Note:** This builder only support ssh authenticating with username and given password.
|
||||
\~> **Note:** This builder not support build Windows image yet and only support ssh authenticating with `ssh_user_name` (Required) and `ssh_password` (Optional). There into, `ssh_user_name` can be set `root` for CentoOS image, `ubuntu` for Ubuntu image. `ssh_password` contains 8-30 characters, and at least 2 items of capital letters, lower case letters, numbers and special characters. The special characters include <code>`()~!@#$%^&*-+=_|{}\[]:;'<>,.?/</code>.
|
||||
|
||||
### Required:
|
||||
|
||||
|
|
Loading…
Reference in New Issue