From 7c795f7975effe553f8ce7194a8154e19717c72b Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Thu, 6 Sep 2018 15:10:55 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=EF=BC=9A1.=20=E9=98=BF?= =?UTF-8?q?=E9=87=8C=E4=BA=91=E4=B8=BB=E6=9C=BA=E9=95=9C=E5=83=8F=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E8=AE=BE=E7=BD=AEPlatform=E5=90=8E=EF=BC=8C=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E6=AD=A3=E7=A1=AE=E5=88=9D=E5=A7=8B=E5=8C=96=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E5=92=8C=E8=9C=9C=E9=92=A5=202.=20=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E9=BB=98=E8=AE=A4=E5=88=9B=E5=BB=BAdefault?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E7=BB=84=EF=BC=8C=E4=B8=BB=E6=9C=BA=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=AE=89=E5=85=A8=E7=BB=84=E8=AE=BE=E7=BD=AE=E4=B8=BA?= =?UTF-8?q?default=E3=80=82defalt=E5=AE=89=E5=85=A8=E7=BB=84=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=87=BA=E5=85=A5=E9=83=BD=E5=BC=80=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/climc/shell/elasticips.go | 2 +- pkg/cloudcommon/db/interface.go | 1 + pkg/cloudprovider/resources.go | 3 +- pkg/compute/hostdrivers/aliyun.go | 7 +- pkg/compute/models/elasticips.go | 20 +++--- pkg/compute/models/guests.go | 8 ++- pkg/compute/models/secgroups.go | 62 ++++++++++++++++- pkg/compute/models/storagecaches.go | 18 ++++- pkg/compute/tasks/eip_dissociate_task.go | 12 +--- pkg/compute/tasks/guest_delete_task.go | 14 +++- pkg/util/aliyun/image.go | 11 +-- pkg/util/aliyun/storagecache.go | 8 +-- pkg/util/imagetools/image_test.go | 14 ++++ pkg/util/imagetools/imagetools.go | 87 ++++++++++++++++++++++++ 14 files changed, 230 insertions(+), 37 deletions(-) create mode 100644 pkg/util/imagetools/image_test.go create mode 100644 pkg/util/imagetools/imagetools.go diff --git a/cmd/climc/shell/elasticips.go b/cmd/climc/shell/elasticips.go index e7a891fadd..cb5d12073f 100644 --- a/cmd/climc/shell/elasticips.go +++ b/cmd/climc/shell/elasticips.go @@ -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 } diff --git a/pkg/cloudcommon/db/interface.go b/pkg/cloudcommon/db/interface.go index a269758eeb..71097f4614 100644 --- a/pkg/cloudcommon/db/interface.go +++ b/pkg/cloudcommon/db/interface.go @@ -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) diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 55ff5d022c..e9d9322122 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -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 { diff --git a/pkg/compute/hostdrivers/aliyun.go b/pkg/compute/hostdrivers/aliyun.go index e0977b298b..55ee805015 100644 --- a/pkg/compute/hostdrivers/aliyun.go +++ b/pkg/compute/hostdrivers/aliyun.go @@ -29,6 +29,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) { @@ -37,7 +42,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 diff --git a/pkg/compute/models/elasticips.go b/pkg/compute/models/elasticips.go index cb60e4ca08..f672f25b32 100644 --- a/pkg/compute/models/elasticips.go +++ b/pkg/compute/models/elasticips.go @@ -18,6 +18,7 @@ import ( "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudcommon/db/quotas" + "strings" ) const ( @@ -403,12 +404,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 +486,10 @@ func (self *SElasticip) PerformAssociate(ctx context.Context, userCred mcclient. server := vmObj.(*SGuest) + if server.PendingDeleted { + return nil, httperrors.NewInvalidStatusError("cannot associate pending delete server") + } + 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 +596,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 +634,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 } diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index c9e40e87b4..c13790530d 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -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 diff --git a/pkg/compute/models/secgroups.go b/pkg/compute/models/secgroups.go index e2418d3ed1..a572574bb9 100644 --- a/pkg/compute/models/secgroups.go +++ b/pkg/compute/models/secgroups.go @@ -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 +} \ No newline at end of file diff --git a/pkg/compute/models/storagecaches.go b/pkg/compute/models/storagecaches.go index e0d71d9712..3d7b067e0e 100644 --- a/pkg/compute/models/storagecaches.go +++ b/pkg/compute/models/storagecaches.go @@ -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") } diff --git a/pkg/compute/tasks/eip_dissociate_task.go b/pkg/compute/tasks/eip_dissociate_task.go index cad5a98cf2..637133792b 100644 --- a/pkg/compute/tasks/eip_dissociate_task.go +++ b/pkg/compute/tasks/eip_dissociate_task.go @@ -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) -} - diff --git a/pkg/compute/tasks/guest_delete_task.go b/pkg/compute/tasks/guest_delete_task.go index 51a4e42ef0..6fc8aaf32a 100644 --- a/pkg/compute/tasks/guest_delete_task.go +++ b/pkg/compute/tasks/guest_delete_task.go @@ -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) { diff --git a/pkg/util/aliyun/image.go b/pkg/util/aliyun/image.go index dfdddbcbfd..9de2676629 100644 --- a/pkg/util/aliyun/image.go +++ b/pkg/util/aliyun/image.go @@ -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) diff --git a/pkg/util/aliyun/storagecache.go b/pkg/util/aliyun/storagecache.go index cab1cbd7ab..7b898fc28e 100644 --- a/pkg/util/aliyun/storagecache.go +++ b/pkg/util/aliyun/storagecache.go @@ -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) diff --git a/pkg/util/imagetools/image_test.go b/pkg/util/imagetools/image_test.go new file mode 100644 index 0000000000..059fe0ecb7 --- /dev/null +++ b/pkg/util/imagetools/image_test.go @@ -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) +} diff --git a/pkg/util/imagetools/imagetools.go b/pkg/util/imagetools/imagetools.go new file mode 100644 index 0000000000..3a52a949ac --- /dev/null +++ b/pkg/util/imagetools/imagetools.go @@ -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 +} + From 1aa1fba80111ad9fc4a9f80d99efeba47f947753 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Fri, 7 Sep 2018 14:32:57 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=EF=BC=9A=E5=B7=B2?= =?UTF-8?q?=E7=BB=8F=E7=BB=91=E5=AE=9AEIP=E7=9A=84=E4=B8=BB=E6=9C=BA?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E5=86=8D=E7=BB=91=E5=AE=9AEIP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/compute/models/elasticips.go | 58 +++++++++++++++++--------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/pkg/compute/models/elasticips.go b/pkg/compute/models/elasticips.go index f672f25b32..38f415cb14 100644 --- a/pkg/compute/models/elasticips.go +++ b/pkg/compute/models/elasticips.go @@ -5,42 +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" - "strings" + "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 { @@ -63,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"` @@ -74,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 { @@ -127,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{} @@ -343,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") } @@ -377,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) } @@ -490,6 +489,11 @@ func (self *SElasticip) PerformAssociate(ctx context.Context, userCred mcclient. 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) } @@ -596,7 +600,7 @@ 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) } @@ -729,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 { @@ -751,4 +755,4 @@ func (manager *SElasticipManager) TotalCount(projectId string) EipUsage { usage.EIPCount = q2.Count() usage.EIPUsedCount = q3.Count() return usage -} \ No newline at end of file +}