Automatic merge from release/2.1.0 -> release/2.2.0

* commit '5de6c10a4b3fbca206e53083ed59ae4b06f90668':
  修正:已经绑定EIP的主机不能再绑定EIP
  修正:1. 阿里云主机镜像正确设置Platform后,可以正确初始化密码和蜜钥 2. 系统启动默认创建default安全组,主机默认安全组设置为default。defalt安全组默认出入都开放
This commit is contained in:
邱剑
2018-09-09 09:06:10 +08:00
14 changed files with 259 additions and 62 deletions
+1 -1
View File
@@ -160,7 +160,7 @@ func init() {
ID string `help:"ID or name of EIP"`
}
R(&EipShowOptions{}, "eip-show", "show details of an EIP", func(s *mcclient.ClientSession, args *EipShowOptions) error {
result, err := modules.Servers.Get(s, args.ID, nil)
result, err := modules.Elasticips.Get(s, args.ID, nil)
if err != nil {
return err
}
+1
View File
@@ -41,6 +41,7 @@ type IModelManager interface {
GetOwnerId(userCred mcclient.TokenCredential) string
// RawFetchById(idStr string) (IModel, error)
FetchById(idStr string) (IModel, error)
FetchByName(ownerProjId string, idStr string) (IModel, error)
FetchByIdOrName(ownerProjId string, idStr string) (IModel, error)
+2 -1
View File
@@ -75,7 +75,8 @@ type ICloudStoragecache interface {
CreateIImage(snapshotId, imageName, imageDesc string) (ICloudImage, error)
DownloadImage(userCred mcclient.TokenCredential, imageId string, extId string) (jsonutils.JSONObject, error)
UploadImage(userCred mcclient.TokenCredential, imageId string, extId string, isForce bool) (string, error)
UploadImage(userCred mcclient.TokenCredential, imageId string, osArch, osType, osDist string, extId string, isForce bool) (string, error)
}
type ICloudStorage interface {
+6 -1
View File
@@ -30,6 +30,11 @@ func (self *SAliyunHostDriver) CheckAndSetCacheImage(ctx context.Context, host *
if err != nil {
return err
}
osArch, _ := params.GetString("os_arch")
osType, _ := params.GetString("os_type")
osDist, _ := params.GetString("os_distribution")
isForce := jsonutils.QueryBoolean(params, "is_force", false)
userCred := task.GetUserCred()
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
@@ -38,7 +43,7 @@ func (self *SAliyunHostDriver) CheckAndSetCacheImage(ctx context.Context, host *
return nil, err
}
extImgId, err := iStorageCache.UploadImage(userCred, imageId, scimg.ExternalId, isForce)
extImgId, err := iStorageCache.UploadImage(userCred, imageId, osArch, osType, osDist, scimg.ExternalId, isForce)
if err != nil {
return nil, err
+41 -33
View File
@@ -5,41 +5,42 @@ import (
"database/sql"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/utils"
"yunion.io/x/pkg/tristate"
"yunion.io/x/log"
"yunion.io/x/jsonutils"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/mcclient"
"strings"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/mcclient"
)
const (
EIP_MODE_INSTANCE_PUBLICIP = "public_ip"
EIP_MODE_STANDALONE_EIP = "elastic_ip"
EIP_MODE_STANDALONE_EIP = "elastic_ip"
EIP_ASSOCIATE_TYPE_SERVER = "server"
EIP_STATUS_READY = "ready"
EIP_STATUS_UNKNOWN = "unknown"
EIP_STATUS_ALLOCATE = "allocate"
EIP_STATUS_ALLOCATE_FAIL = "allocate_fail"
EIP_STATUS_DEALLOCATE = "deallocate"
EIP_STATUS_READY = "ready"
EIP_STATUS_UNKNOWN = "unknown"
EIP_STATUS_ALLOCATE = "allocate"
EIP_STATUS_ALLOCATE_FAIL = "allocate_fail"
EIP_STATUS_DEALLOCATE = "deallocate"
EIP_STATUS_DEALLOCATE_FAIL = "deallocate_fail"
EIP_STATUS_ASSOCIATE = "associate"
EIP_STATUS_ASSOCIATE_FAIL = "associate_fail"
EIP_STATUS_DISSOCIATE = "dissociate"
EIP_STATUS_ASSOCIATE = "associate"
EIP_STATUS_ASSOCIATE_FAIL = "associate_fail"
EIP_STATUS_DISSOCIATE = "dissociate"
EIP_STATUS_DISSOCIATE_FAIL = "dissociate_fail"
EIP_CHARGE_TYPE_BY_TRAFFIC = "traffic"
EIP_CHARGE_TYPE_BY_TRAFFIC = "traffic"
EIP_CHARGE_TYPE_BY_BANDWIDTH = "bandwidth"
EIP_CHARGE_TYPE_DEFAULT = EIP_CHARGE_TYPE_BY_TRAFFIC
EIP_CHARGE_TYPE_DEFAULT = EIP_CHARGE_TYPE_BY_TRAFFIC
)
type SElasticipManager struct {
@@ -62,7 +63,7 @@ type SElasticip struct {
IpAddr string `width:"17" charset:"ascii" list:"user"`
AssociateType string `width:"32" charset:"ascii" list:"user"`
AssociateId string `width:"128" charset:"ascii" list:"user"`
AssociateId string `width:"128" charset:"ascii" list:"user"`
Bandwidth int `list:"user" create:"required"`
@@ -73,7 +74,6 @@ type SElasticip struct {
CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required"`
}
func (manager *SElasticipManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
q, err := manager.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
if err != nil {
@@ -126,7 +126,7 @@ func (self *SElasticip) GetRegion() *SCloudregion {
return CloudregionManager.FetchRegionById(self.CloudregionId)
}
func (manager *SElasticipManager) SyncEips(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, region *SCloudregion, eips []cloudprovider.ICloudEIP) (compare.SyncResult) {
func (manager *SElasticipManager) SyncEips(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, region *SCloudregion, eips []cloudprovider.ICloudEIP) compare.SyncResult {
// localEips := make([]SElasticip, 0)
// remoteEips := make([]cloudprovider.ICloudEIP, 0)
syncResult := compare.SyncResult{}
@@ -342,7 +342,7 @@ func (manager *SElasticipManager) getEipByExtEip(userCred mcclient.TokenCredenti
}
func (manager *SElasticipManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
regionStr := jsonutils.GetAnyString(data, []string {"region", "region_id"})
regionStr := jsonutils.GetAnyString(data, []string{"region", "region_id"})
if len(regionStr) == 0 {
return nil, httperrors.NewInputParameterError("Missing region/region_id")
}
@@ -376,7 +376,7 @@ func (manager *SElasticipManager) ValidateCreateData(ctx context.Context, userCr
chargeType = EIP_CHARGE_TYPE_DEFAULT
}
if ! utils.IsInStringArray(chargeType, []string{EIP_CHARGE_TYPE_BY_BANDWIDTH, EIP_CHARGE_TYPE_BY_TRAFFIC}) {
if !utils.IsInStringArray(chargeType, []string{EIP_CHARGE_TYPE_BY_BANDWIDTH, EIP_CHARGE_TYPE_BY_TRAFFIC}) {
return nil, httperrors.NewInputParameterError("charge type %s not supported", chargeType)
}
@@ -403,12 +403,6 @@ func (self *SElasticip) PostCreate(ctx context.Context, userCred mcclient.TokenC
}
func (self *SElasticip) startEipAllocateTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, pendingUsage quotas.IQuota) error {
/*params := jsonutils.NewDict()
params.Add(jsonutils.NewString(instanceExtId), "instance_external_id")
params.Add(jsonutils.NewString(instanceId), "instance_id")
params.Add(jsonutils.NewString(instanceType), "instance_type")
*/
task, err := taskman.TaskManager.NewTask(ctx, "EipAllocateTask", self, userCred, params, "", "", pendingUsage)
if err != nil {
log.Errorf("newtask EipAllocateTask fail %s", err)
@@ -491,6 +485,15 @@ func (self *SElasticip) PerformAssociate(ctx context.Context, userCred mcclient.
server := vmObj.(*SGuest)
if server.PendingDeleted {
return nil, httperrors.NewInvalidStatusError("cannot associate pending delete server")
}
seip, _ := server.GetEip()
if seip != nil {
return nil, httperrors.NewInvalidStatusError("instance is already associated with eip")
}
if ok, _ := utils.InStringArray(server.Status, []string{VM_READY, VM_RUNNING}); !ok {
return nil, httperrors.NewInvalidStatusError("cannot associate server in status %s", server.Status)
}
@@ -597,9 +600,9 @@ func (self *SElasticip) AllowPerformSync(ctx context.Context, userCred mcclient.
}
func (self *SElasticip) PerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
/*if self.Status != EIP_STATUS_READY && ! strings.HasSuffix(self.Status, "_fail") {
if self.Status != EIP_STATUS_READY && !strings.HasSuffix(self.Status, "_fail") {
return nil, httperrors.NewInvalidStatusError("eip cannot syncstatus in status %s", self.Status)
}*/
}
if self.Mode == EIP_MODE_INSTANCE_PUBLICIP {
return nil, httperrors.NewUnsupportOperationError("fixed eip cannot be dissociated")
@@ -635,6 +638,11 @@ func (self *SElasticip) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSO
if vm != nil {
extra.Add(jsonutils.NewString(vm.GetName()), "associate_name")
}
region := self.GetRegion()
if region != nil {
extra.Add(jsonutils.NewString(region.GetName()), "cloudregion")
extra.Add(jsonutils.NewString(region.GetName()), "region")
}
return extra
}
@@ -725,8 +733,8 @@ func (self *SElasticip) DoChangeBandwidth(userCred mcclient.TokenCredential, ban
type EipUsage struct {
PublicIPCount int
EIPCount int
EIPUsedCount int
EIPCount int
EIPUsedCount int
}
func (u EipUsage) Total() int {
@@ -747,4 +755,4 @@ func (manager *SElasticipManager) TotalCount(projectId string) EipUsage {
usage.EIPCount = q2.Count()
usage.EIPUsedCount = q3.Count()
return usage
}
}
+5 -3
View File
@@ -764,6 +764,8 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m
return nil, httperrors.NewResourceNotFoundError("Secgroup %s not found", secGrpId)
}
data.Add(jsonutils.NewString(secGrpObj.GetId()), "secgrp_id")
} else {
data.Add(jsonutils.NewString("default"), "secgrp_id")
}
/*
@@ -1146,10 +1148,10 @@ func (self *SGuest) getIPs() []string {
ips := self.getRealIPs()
vips := self.getVirtualIPs()
ips = append(ips, vips...)
eip, _ := self.GetEip()
/*eip, _ := self.GetEip()
if eip != nil {
ips = append(ips, eip.IpAddr)
}
}*/
return ips
}
@@ -2321,7 +2323,7 @@ func (self *SGuest) PerformRevokeSecgroup(ctx context.Context, userCred mcclient
return nil, httperrors.NewInputParameterError("Cannot revoke security rules in status %s", self.Status)
} else {
if _, err := self.GetModelManager().TableSpec().Update(self, func() error {
self.SecgrpId = ""
self.SecgrpId = "default"
return nil
}); err != nil {
return nil, err
+59 -3
View File
@@ -4,17 +4,20 @@ import (
"context"
"strings"
"time"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/mcclient/auth"
)
type SSecurityGroupManager struct {
@@ -297,3 +300,56 @@ func (self *SSecurityGroup) DoSync(ctx context.Context, userCred mcclient.TokenC
SecurityGroupManager.DelaySync(ctx, userCred, self.Id)
})
}
func (manager *SSecurityGroupManager) InitializeData() error {
_, err := manager.FetchById("default")
if err != nil && err != sql.ErrNoRows {
log.Errorf("find default secgroup fail %s", err)
return err
}
if err == sql.ErrNoRows {
var secGrp *SSecurityGroup
secGrp = &SSecurityGroup{}
secGrp.SetModelManager(manager)
secGrp.Id = "default"
secGrp.Name = "Default"
secGrp.ProjectId = auth.AdminCredential().GetProjectId()
secGrp.IsEmulated = false
secGrp.IsPublic = true
err = manager.TableSpec().Insert(secGrp)
if err != nil {
log.Errorf("Insert default secgroup failed!!! %s", err)
return err
}
defRule := SSecurityGroupRule{}
defRule.SetModelManager(SecurityGroupRuleManager)
defRule.Direction = secrules.DIR_IN
defRule.Protocol = secrules.PROTO_ANY
defRule.Priority = 1
defRule.CIDR = "0.0.0.0/0"
defRule.Action = string(secrules.SecurityRuleAllow)
defRule.SecgroupID = "default"
err = SecurityGroupRuleManager.TableSpec().Insert(&defRule)
if err != nil {
log.Errorf("Insert default secgroup rule fail %s", err)
return err
}
}
guests := make([]SGuest, 0)
q := GuestManager.Query()
q = q.Filter(sqlchemy.OR(sqlchemy.IsEmpty(q.Field("secgrp_id")), sqlchemy.IsNull(q.Field("secgrp_id"))))
err = db.FetchModelObjects(GuestManager, q, &guests)
if err != nil {
log.Errorf("fetch guests without secgroup fail %s", err)
return err
}
for i := 0; i < len(guests); i += 1 {
GuestManager.TableSpec().Update(&guests[i], func() error {
guests[i].SecgrpId = "default"
return nil
})
}
return nil
}
+17 -1
View File
@@ -14,6 +14,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/imagetools"
)
type SStoragecacheManager struct {
@@ -24,7 +25,11 @@ type SStoragecacheManager struct {
var StoragecacheManager *SStoragecacheManager
func init() {
StoragecacheManager = &SStoragecacheManager{SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(SStoragecache{}, "storagecaches_tbl", "storagecache", "storagecaches")}
StoragecacheManager = &SStoragecacheManager{
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(SStoragecache{},
"storagecaches_tbl",
"storagecache",
"storagecaches")}
}
type SStoragecache struct {
@@ -205,6 +210,17 @@ func (self *SStoragecache) StartImageCacheTask(ctx context.Context, userCred mcc
StoragecachedimageManager.Register(ctx, userCred, self.Id, imageId)
data := jsonutils.NewDict()
data.Add(jsonutils.NewString(imageId), "image_id")
image, _ := CachedimageManager.GetImageById(ctx, userCred, imageId, false)
if image != nil {
imgInfo := imagetools.NormalizeImageInfo(image.Name, image.Properties["os_arch"], image.Properties["os_type"],
image.Properties["os_distribution"])
data.Add(jsonutils.NewString(imgInfo.OsType), "os_type")
data.Add(jsonutils.NewString(imgInfo.OsArch), "os_arch")
data.Add(jsonutils.NewString(imgInfo.OsDistro), "os_distribution")
}
if isForce {
data.Add(jsonutils.JSONTrue, "is_force")
}
+3 -9
View File
@@ -51,15 +51,9 @@ func (self *EipDissociateTask) OnInit(ctx context.Context, obj db.IStandaloneMod
eip.SetStatus(self.UserCred, models.EIP_STATUS_READY, "dissociate")
self.SetStageComplete(ctx, nil)
if eip.AutoDellocate.IsTrue() {
self.SetStage("on_auto_dellocate_complete", nil)
eip.StartEipDeallocateTask(ctx, self.UserCred, self.Id)
} else {
self.SetStageComplete(ctx, nil)
eip.StartEipDeallocateTask(ctx, self.UserCred, "")
}
}
func (self *EipDissociateTask) OnAutoDellocateComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageComplete(ctx, nil)
}
+12 -2
View File
@@ -42,6 +42,11 @@ func (self *GuestDeleteTask) OnGuestStopComplete(ctx context.Context, obj db.ISt
}
}
func (self *GuestDeleteTask) OnEipDissociateCompleteFailed(ctx context.Context, obj db.IStandaloneModel, err jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
self.OnFailed(ctx, guest, err)
}
func (self *GuestDeleteTask) OnEipDissociateComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
@@ -104,11 +109,16 @@ func (self *GuestDeleteTask) DoDeleteGuest(ctx context.Context, guest *models.SG
}
}
func (self *GuestDeleteTask) OnGuestDeleteCompleteFailed(ctx context.Context, obj db.IStandaloneModel, err jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
func (self *GuestDeleteTask) OnFailed(ctx context.Context, guest *models.SGuest, err jsonutils.JSONObject) {
guest.SetStatus(self.UserCred, models.VM_DELETE_FAIL, err.String())
db.OpsLog.LogEvent(guest, db.ACT_DELOCATE_FAIL, err, self.UserCred)
logclient.AddActionLog(guest, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, err.String())
}
func (self *GuestDeleteTask) OnGuestDeleteCompleteFailed(ctx context.Context, obj db.IStandaloneModel, err jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
self.OnFailed(ctx, guest, err)
}
func (self *GuestDeleteTask) OnGuestDeleteComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
+7 -4
View File
@@ -142,16 +142,19 @@ type ImageImportTask struct {
TaskId string
}
func (self *SRegion) ImportImage(name string, bucket string, key string) (*ImageImportTask, error) {
func (self *SRegion) ImportImage(name string, osArch string, osType string, osDist string, bucket string, key string) (*ImageImportTask, error) {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["ImageName"] = name
params["Architecture"] = "x86_64"
params["OSType"] = "linux"
params["Platform"] = "Others Linux"
params["Platform"] = osDist // "Others Linux"
params["OSType"] = osType // "linux"
params["Architecture"] = osArch // "x86_64"
params["DiskDeviceMapping.1.OSSBucket"] = bucket
params["DiskDeviceMapping.1.OSSObject"] = key
log.Debugf("Upload image with params %#v", params)
body, err := self.ecsRequest("ImportImage", params)
if err != nil {
log.Errorf("ImportImage fail %s", err)
+4 -4
View File
@@ -86,17 +86,17 @@ func (self *SStoragecache) GetIImages() ([]cloudprovider.ICloudImage, error) {
return self.iimages, nil
}
func (self *SStoragecache) UploadImage(userCred mcclient.TokenCredential, imageId string, extId string, isForce bool) (string, error) {
func (self *SStoragecache) UploadImage(userCred mcclient.TokenCredential, imageId string, osArch, osType, osDist string, extId string, isForce bool) (string, error) {
if len(extId) > 0 {
status, _ := self.region.GetImageStatus(extId)
if status == ImageStatusAvailable && !isForce {
return extId, nil
}
}
return self.uploadImage(userCred, imageId, isForce)
return self.uploadImage(userCred, imageId, osArch, osType, osDist, isForce)
}
func (self *SStoragecache) uploadImage(userCred mcclient.TokenCredential, imageId string, isForce bool) (string, error) {
func (self *SStoragecache) uploadImage(userCred mcclient.TokenCredential, imageId string, osArch, osType, osDist string, isForce bool) (string, error) {
// first upload image to oss
s := auth.GetAdminSession(options.Options.Region, "")
@@ -161,7 +161,7 @@ func (self *SStoragecache) uploadImage(userCred mcclient.TokenCredential, imageI
log.Debugf("Import image %s", imageName)
task, err := self.region.ImportImage(imageName, bucketName, imageId)
task, err := self.region.ImportImage(imageName, osArch, osType, osDist, bucketName, imageId)
if err != nil {
log.Errorf("ImportImage error %s %s %s", imageId, bucketName, err)
+14
View File
@@ -0,0 +1,14 @@
package imagetools
import "testing"
func TestNormalizeImageInfo(t *testing.T) {
info := NormalizeImageInfo("rhel67_20180816.qcow2", "", "", "")
t.Logf("%#v", info)
info = NormalizeImageInfo("Ubuntu_16.04.3_amd64_qingcloud_20180817.qcow2", "", "", "")
t.Logf("%#v", info)
info = NormalizeImageInfo("windows-server-2008-dc-cn-20180717", "", "", "")
t.Logf("%#v", info)
}
+87
View File
@@ -0,0 +1,87 @@
package imagetools
import "strings"
func normalizeOsArch(osArch string, osType string, osDist string) string {
if len(osArch) > 0 {
if strings.ToLower(osArch) == "x86_64" {
return "x86_64"
} else {
return "i386"
}
} else {
if osType == "linux" {
return "x86_64"
} else if osDist == "Windows Server 2003" {
return "i386"
} else {
return "x86_64"
}
}
}
func normalizeOsType(osType string, osDist string) string {
osType = strings.ToLower(osType)
if osType == "linux" {
return "linux"
} else if osType == "windows" {
return "windows"
} else if strings.HasPrefix(osDist, "Windows") {
return "windows"
} else {
return "linux"
}
}
func normalizeOsDistribution(osDist string, imageName string) string {
if len(osDist) == 0 {
osDist = imageName
}
osDist = strings.ToLower(osDist)
if strings.HasPrefix(osDist, "centos") || strings.HasPrefix(osDist, "redhat") || strings.HasPrefix(osDist, "rhel") {
return "CentOS"
} else if strings.HasPrefix(osDist, "ubuntu") {
return "Ubuntu"
} else if strings.HasPrefix(osDist, "suse") {
return "SUSE"
} else if strings.HasPrefix(osDist, "opensuse") {
return "OpenSUSE"
} else if strings.HasPrefix(osDist, "debian") {
return "Debian"
} else if strings.HasPrefix(osDist, "coreos") {
return "CoreOS"
} else if strings.HasPrefix(osDist, "aliyun") {
return "Aliyun"
} else if strings.HasPrefix(osDist, "windows") {
if strings.Contains(osDist, "2003") {
return "Windows Server 2003"
} else if strings.Contains(osDist, "2008") {
return "Windows Server 2008"
} else if strings.Contains(osDist, "2012") {
return "Windows Server 2012"
} else if strings.Contains(osDist, "2016") {
return "Windows Server 2016"
} else {
return "Windows Server 2008"
}
} else {
return "Others Linux"
}
}
type ImageInfo struct {
Name string
OsArch string
OsType string
OsDistro string
}
func NormalizeImageInfo(imageName, osArch, osType, osDist string) ImageInfo {
info := ImageInfo{}
info.Name = imageName
info.OsDistro = normalizeOsDistribution(osDist, imageName)
info.OsType = normalizeOsType(osType, info.OsDistro)
info.OsArch = normalizeOsArch(osArch, info.OsType, info.OsDistro)
return info
}