From d913be0312dde2fcb2f8624b6edcdeb535a9d0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Mon, 13 Oct 2025 18:51:12 +0800 Subject: [PATCH] fix(region): healt status (#23526) --- go.mod | 2 +- go.sum | 4 +- pkg/compute/models/guests.go | 5 ++ .../klauspost/cpuid/v2/CONTRIBUTING.txt | 70 +++++++++---------- vendor/modules.txt | 2 +- .../x/cloudmux/pkg/cloudprovider/resources.go | 1 + .../pkg/multicloud/aliyun/instance.go | 40 +++++++++++ .../cloudmux/pkg/multicloud/instance_base.go | 4 ++ .../cloudmux/pkg/multicloud/ksyun/snapshot.go | 6 +- .../cloudmux/pkg/multicloud/ksyun/storages.go | 6 +- .../x/cloudmux/pkg/multicloud/ksyun/zone.go | 48 ++++++++----- .../pkg/multicloud/remotefile/instance.go | 4 ++ 12 files changed, 132 insertions(+), 60 deletions(-) diff --git a/go.mod b/go.mod index e24dc2e8d1..b886649978 100644 --- a/go.mod +++ b/go.mod @@ -88,7 +88,7 @@ require ( k8s.io/client-go v0.19.3 k8s.io/cluster-bootstrap v0.19.3 moul.io/http2curl/v2 v2.3.0 - yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250930065042-7d3c7efa5758 + yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20251013100819-3cfce351f66b yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0 yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1 yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91 diff --git a/go.sum b/go.sum index 720d3c1e4e..e22f580603 100644 --- a/go.sum +++ b/go.sum @@ -1279,8 +1279,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250930065042-7d3c7efa5758 h1:4h+YVyHN16fn6Tt4dO2KFgHn1m4ToHG4kVo5Pxx1Xhc= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250930065042-7d3c7efa5758/go.mod h1:S9o/TRZsnYWGaGe7o3PpeOv6CgMY8ZJwITYsEnGfOgQ= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20251013100819-3cfce351f66b h1:HxowEB3tVS1bV32hQiKyBi6V4PwzVu0GCbwD4Fl+m54= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20251013100819-3cfce351f66b/go.mod h1:S9o/TRZsnYWGaGe7o3PpeOv6CgMY8ZJwITYsEnGfOgQ= yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0 h1:msG4SiDSVU7CrXH06WuHlNEZXIooTcmNbfrIGHuIHBU= yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws= yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634= diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 0212deb54f..be95dc47f4 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -188,6 +188,8 @@ type SGuest struct { QgaStatus string `width:"36" charset:"ascii" nullable:"false" default:"unknown" list:"user" create:"optional"` // power_states limit in [on, off, unknown] PowerStates string `width:"36" charset:"ascii" nullable:"false" default:"unknown" list:"user" create:"optional"` + // 健康状态, 仅开机中火运行中有效, 目前只支持阿里云 + HealthStatus string `width:"36" charset:"ascii" nullable:"true" default:"ok" list:"user"` // Used for guest rescue RescueMode bool `nullable:"false" default:"false" list:"user" create:"optional"` } @@ -3158,6 +3160,9 @@ func (g *SGuest) syncWithCloudVM(ctx context.Context, userCred mcclient.TokenCre if !g.IsFailureStatus() && syncStatus { g.Status = extVM.GetStatus() + if g.Status == api.VM_RUNNING || g.Status == api.VM_STARTING { + g.HealthStatus = extVM.GetHealthStatus() + } g.PowerStates = extVM.GetPowerStates() g.InferPowerStates() } diff --git a/vendor/github.com/klauspost/cpuid/v2/CONTRIBUTING.txt b/vendor/github.com/klauspost/cpuid/v2/CONTRIBUTING.txt index 452d28eda8..2ef4714f71 100644 --- a/vendor/github.com/klauspost/cpuid/v2/CONTRIBUTING.txt +++ b/vendor/github.com/klauspost/cpuid/v2/CONTRIBUTING.txt @@ -1,35 +1,35 @@ -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2015- Klaus Post & Contributors. -Email: klauspost@gmail.com - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2015- Klaus Post & Contributors. +Email: klauspost@gmail.com + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. diff --git a/vendor/modules.txt b/vendor/modules.txt index 279d47823f..7c78e4c312 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1605,7 +1605,7 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250930065042-7d3c7efa5758 +# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20251013100819-3cfce351f66b ## explicit; go 1.21 yunion.io/x/cloudmux/pkg/apis yunion.io/x/cloudmux/pkg/apis/billing diff --git a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go index d090ccfadc..6d8d0fa741 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go +++ b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go @@ -403,6 +403,7 @@ type ICloudVM interface { AllocatePublicIpAddress() (string, error) GetPowerStates() string + GetHealthStatus() string } type ICloudNic interface { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/instance.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/instance.go index c0d6ca540d..b7a38d172b 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/instance.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/instance.go @@ -375,6 +375,46 @@ func (self *SInstance) GetStatus() string { } } +type SInstanceStatus struct { + InstanceId string + HealthStatus struct { + Name string + } +} + +func (region *SRegion) DescribeInstancesFullStatus(vmId string) (*SInstanceStatus, error) { + params := map[string]string{ + "InstanceId": vmId, + } + resp, err := region.ecsRequest("DescribeInstancesFullStatus", params) + if err != nil { + return nil, err + } + ret := struct { + InstanceFullStatusSet struct { + InstanceFullStatusType []SInstanceStatus + } + }{} + err = resp.Unmarshal(&ret) + if err != nil { + return nil, errors.Wrapf(err, "Unmarshal") + } + for i := range ret.InstanceFullStatusSet.InstanceFullStatusType { + if ret.InstanceFullStatusSet.InstanceFullStatusType[i].InstanceId == vmId { + return &ret.InstanceFullStatusSet.InstanceFullStatusType[i], nil + } + } + return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", vmId) +} + +func (self *SInstance) GetHealthStatus() string { + status, err := self.host.zone.region.DescribeInstancesFullStatus(self.InstanceId) + if err != nil { + return "" + } + return strings.ToLower(status.HealthStatus.Name) +} + func (self *SInstance) Refresh() error { ins, err := self.host.zone.region.GetInstance(self.InstanceId) if err != nil { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/instance_base.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/instance_base.go index 570cedd29d..b3bc8e4ffe 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/instance_base.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/instance_base.go @@ -91,6 +91,10 @@ func (ins *SInstanceBase) GetPowerStates() string { return "" } +func (ins *SInstanceBase) GetHealthStatus() string { + return "" +} + func (instance *SInstanceBase) GetError() error { return nil } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/snapshot.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/snapshot.go index 1eeca52814..fd3784f45c 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/snapshot.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/snapshot.go @@ -142,13 +142,13 @@ func (region *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) { ret := []cloudprovider.ICloudSnapshot{} for i := 0; i < len(snapshots); i += 1 { snapshots[i].region = region - ret[i] = &snapshots[i] + ret = append(ret, &snapshots[i]) } return ret, nil } -func (self *SSnapshot) Delete() error { - return self.region.DeleteSnapshot(self.SnapshotId) +func (snap *SSnapshot) Delete() error { + return snap.region.DeleteSnapshot(snap.SnapshotId) } func (region *SRegion) CreateSnapshot(diskId, name, desc string) (*SSnapshot, error) { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/storages.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/storages.go index a10c861dc4..75031aedf0 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/storages.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/storages.go @@ -31,6 +31,7 @@ type SStorage struct { zone *SZone StorageType string + available bool } func (storage *SStorage) GetId() string { @@ -91,7 +92,7 @@ func (storage *SStorage) GetStorageConf() jsonutils.JSONObject { } func (storage *SStorage) GetEnabled() bool { - return true + return storage.available } func (storage *SStorage) CreateIDisk(opts *cloudprovider.DiskCreateConfig) (cloudprovider.ICloudDisk, error) { @@ -138,5 +139,8 @@ func (storage *SStorage) GetIStoragecache() cloudprovider.ICloudStoragecache { } func (storage *SStorage) GetStatus() string { + if !storage.available { + return api.STORAGE_OFFLINE + } return api.STORAGE_ONLINE } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/zone.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/zone.go index 76c8e75ba2..2760331a32 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/zone.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/zone.go @@ -147,31 +147,45 @@ func (zone *SZone) GetDescription() string { } func (zone *SZone) GetStorages() ([]SStorage, error) { - zoneDiskType := []string{} - for i := range api.KSYUN_STORAGES { - if api.KSYUN_STORAGES[i] == api.STORAGE_KSYUN_LOCAL_SSD { - zoneDiskType = append(zoneDiskType, api.KSYUN_STORAGES[i]) + zoneDiskType := map[string]bool{} + for _, storageType := range api.KSYUN_STORAGES { + if storageType == api.STORAGE_KSYUN_LOCAL_SSD { + zoneDiskType[storageType] = true continue } - params := map[string]interface{}{ - "VolumeType": api.KSYUN_STORAGES[i], - } - resp, err := zone.region.ebsRequest("DescribeAvailabilityZones", params) + zoneList, err := zone.region.GetZonesByDiskType(storageType) if err != nil { - return nil, errors.Wrapf(err, "%s:ValidateAttachInstance", api.KSYUN_STORAGES[i]) - } - zoneList := []string{} - err = resp.Unmarshal(&zoneList, "AvailabilityZones") - if err != nil { - return nil, errors.Wrap(err, "unmarshal zoneList") + return nil, errors.Wrapf(err, "GetZonesByDiskType: %s", storageType) } + if utils.IsInStringArray(zone.GetName(), zoneList) { - zoneDiskType = append(zoneDiskType, api.KSYUN_STORAGES[i]) + zoneDiskType[storageType] = true + } else { + zoneDiskType[storageType] = false } } storages := []SStorage{} - for i := range zoneDiskType { - storages = append(storages, SStorage{zone: zone, StorageType: zoneDiskType[i]}) + for storageType, available := range zoneDiskType { + storage := SStorage{zone: zone, StorageType: storageType, available: available} + storages = append(storages, storage) } return storages, nil } + +func (region *SRegion) GetZonesByDiskType(diskType string) ([]string, error) { + params := map[string]interface{}{ + "VolumeType": diskType, + } + resp, err := region.ebsRequest("DescribeAvailabilityZones", params) + if err != nil { + return nil, errors.Wrap(err, "DescribeAvailabilityZones") + } + ret := struct { + AvailabilityZones []string `json:"AvailabilityZones"` + }{} + err = resp.Unmarshal(&ret) + if err != nil { + return nil, errors.Wrap(err, "unmarshal zoneList") + } + return ret.AvailabilityZones, nil +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/remotefile/instance.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/remotefile/instance.go index 3998de4bc3..588d539aba 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/remotefile/instance.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/remotefile/instance.go @@ -284,3 +284,7 @@ func (self *SInstance) GetPowerStates() string { } return api.VM_POWER_STATES_OFF } + +func (self *SInstance) GetHealthStatus() string { + return "" +}