github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/alicloud/ecs/image_config.go (about) 1 package ecs 2 3 import ( 4 "fmt" 5 6 "github.com/denverdino/aliyungo/common" 7 "github.com/hashicorp/packer/template/interpolate" 8 "regexp" 9 "strings" 10 ) 11 12 type AlicloudDiskDevice struct { 13 DiskName string `mapstructure:"disk_name"` 14 DiskCategory string `mapstructure:"disk_category"` 15 DiskSize int `mapstructure:"disk_size"` 16 SnapshotId string `mapstructure:"disk_snapshot_id"` 17 Description string `mapstructure:"disk_description"` 18 DeleteWithInstance bool `mapstructure:"disk_delete_with_instance"` 19 Device string `mapstructure:"disk_device"` 20 } 21 22 type AlicloudDiskDevices struct { 23 ECSImagesDiskMappings []AlicloudDiskDevice `mapstructure:"image_disk_mappings"` 24 } 25 26 type AlicloudImageConfig struct { 27 AlicloudImageName string `mapstructure:"image_name"` 28 AlicloudImageVersion string `mapstructure:"image_version"` 29 AlicloudImageDescription string `mapstructure:"image_description"` 30 AlicloudImageShareAccounts []string `mapstructure:"image_share_account"` 31 AlicloudImageUNShareAccounts []string `mapstructure:"image_unshare_account"` 32 AlicloudImageDestinationRegions []string `mapstructure:"image_copy_regions"` 33 AlicloudImageDestinationNames []string `mapstructure:"image_copy_names"` 34 AlicloudImageForceDetele bool `mapstructure:"image_force_delete"` 35 AlicloudImageForceDeteleSnapshots bool `mapstructure:"image_force_delete_snapshots"` 36 AlicloudImageForceDeleteInstances bool `mapstructure:"image_force_delete_instances"` 37 AlicloudImageSkipRegionValidation bool `mapstructure:"skip_region_validation"` 38 AlicloudDiskDevices `mapstructure:",squash"` 39 } 40 41 func (c *AlicloudImageConfig) Prepare(ctx *interpolate.Context) []error { 42 var errs []error 43 if c.AlicloudImageName == "" { 44 errs = append(errs, fmt.Errorf("image_name must be specified")) 45 } else if len(c.AlicloudImageName) < 2 || len(c.AlicloudImageName) > 128 { 46 errs = append(errs, fmt.Errorf("image_name must less than 128 letters and more than 1 letters")) 47 } else if strings.HasPrefix(c.AlicloudImageName, "http://") || 48 strings.HasPrefix(c.AlicloudImageName, "https://") { 49 errs = append(errs, fmt.Errorf("image_name can't start with 'http://' or 'https://'")) 50 } 51 reg := regexp.MustCompile("\\s+") 52 if reg.FindString(c.AlicloudImageName) != "" { 53 errs = append(errs, fmt.Errorf("image_name can't include spaces")) 54 } 55 56 if len(c.AlicloudImageDestinationRegions) > 0 { 57 regionSet := make(map[string]struct{}) 58 regions := make([]string, 0, len(c.AlicloudImageDestinationRegions)) 59 60 for _, region := range c.AlicloudImageDestinationRegions { 61 // If we already saw the region, then don't look again 62 if _, ok := regionSet[region]; ok { 63 continue 64 } 65 66 // Mark that we saw the region 67 regionSet[region] = struct{}{} 68 69 if !c.AlicloudImageSkipRegionValidation { 70 // Verify the region is real 71 if valid := validateRegion(region); valid != nil { 72 errs = append(errs, fmt.Errorf("Unknown region: %s", region)) 73 continue 74 } 75 } 76 77 regions = append(regions, region) 78 } 79 80 c.AlicloudImageDestinationRegions = regions 81 } 82 83 if len(errs) > 0 { 84 return errs 85 } 86 87 return nil 88 } 89 90 func validateRegion(region string) error { 91 92 for _, valid := range common.ValidRegions { 93 if region == string(valid) { 94 return nil 95 } 96 } 97 98 return fmt.Errorf("Not a valid alicloud region: %s", region) 99 }