From 17d3e9f0fbd6c45da6f80ce159ce37682092de91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Thu, 19 Mar 2026 10:27:47 +0800 Subject: [PATCH] fix(region): allow set disk auto-delete attribute (#24486) --- cmd/climc/shell/compute/disks.go | 4 ++-- pkg/apis/compute/api.go | 5 +++++ pkg/apis/compute/disk.go | 5 +++++ pkg/cloudcommon/cmdline/parser.go | 6 ++++++ pkg/compute/models/disks.go | 6 ++++++ pkg/compute/models/guest_actions.go | 6 +++--- pkg/compute/models/guests.go | 4 ++++ pkg/mcclient/options/compute/servers.go | 3 ++- pkg/monitor/dbinit/measurements/metrics.csv | 13 ++++++++++++- 9 files changed, 45 insertions(+), 7 deletions(-) diff --git a/cmd/climc/shell/compute/disks.go b/cmd/climc/shell/compute/disks.go index 80af9af19f..3235341dda 100644 --- a/cmd/climc/shell/compute/disks.go +++ b/cmd/climc/shell/compute/disks.go @@ -96,7 +96,7 @@ func init() { ID string `help:"ID or name of disk"` Name string `help:"New name of disk"` Desc string `help:"Description" metavar:"DESCRIPTION"` - AutoDelete string `help:"enable/disable auto delete of disk" choices:"enable|disable"` + AutoDelete string `help:"Set disk auto_delete (true/false or enable/disable)" choices:"true|false|enable|disable"` AutoSnapshot string `help:"enable/disable auto snapshot of disk" choices:"enable|disable"` DiskType string `help:"Disk type" choices:"data|volume|sys"` IsSsd *bool `help:"mark disk as ssd" negative:"no-is-ssd"` @@ -111,7 +111,7 @@ func init() { params.Add(jsonutils.NewString(args.Desc), "description") } if len(args.AutoDelete) > 0 { - if args.AutoDelete == "enable" { + if args.AutoDelete == "enable" || args.AutoDelete == "true" { params.Add(jsonutils.JSONTrue, "auto_delete") } else { params.Add(jsonutils.JSONFalse, "auto_delete") diff --git a/pkg/apis/compute/api.go b/pkg/apis/compute/api.go index 74cd094df9..ce7c5cd156 100644 --- a/pkg/apis/compute/api.go +++ b/pkg/apis/compute/api.go @@ -197,6 +197,11 @@ type DiskConfig struct { // required: false AutoReset bool `json:"auto_reset"` + // 是否跟随主机删除而自动删除 + // 默认跟随主机创建的磁盘为 true + // required: false + AutoDelete *bool `json:"auto_delete,omitempty"` + // 磁盘存储格式 // enum: ["qcow2", "raw", "docker", "iso", "vmdk", "vmdkflatver1", "vmdkflatver2", "vmdkflat", "vmdksparse", "vmdksparsever1", "vmdksparsever2", "vmdksepsparse", "vhd"] // requried: false diff --git a/pkg/apis/compute/disk.go b/pkg/apis/compute/disk.go index 78f8df3399..dbe757fa86 100644 --- a/pkg/apis/compute/disk.go +++ b/pkg/apis/compute/disk.go @@ -293,6 +293,11 @@ type DiskUpdateInput struct { DiskType string `json:"disk_type"` // 关机自动重置 AutoReset *bool `json:"auto_reset"` + + // 是否跟随主机删除而自动删除 + // 默认跟随主机创建的磁盘为 true + // required: false + AutoDelete *bool `json:"auto_delete,omitempty"` } type DiskSaveInput struct { diff --git a/pkg/cloudcommon/cmdline/parser.go b/pkg/cloudcommon/cmdline/parser.go index 4ff9d7a93e..ce64592903 100644 --- a/pkg/cloudcommon/cmdline/parser.go +++ b/pkg/cloudcommon/cmdline/parser.go @@ -248,6 +248,12 @@ func ParseDiskConfig(diskStr string, idx int) (*compute.DiskConfig, error) { return nil, errors.Errorf("invalid preallocation %s, allow choices: %s", str, compute.DISK_PREALLOCATIONS) } diskConfig.Preallocation = str + case "auto_delete": + v, err := strconv.ParseBool(str) + if err != nil { + return nil, errors.Wrapf(err, "parse disk auto_delete %s", str) + } + diskConfig.AutoDelete = &v default: return nil, errors.Errorf("invalid disk description %s", p) } diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index a53fbb4358..c3079a53f4 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -2509,9 +2509,15 @@ func (self *SDisk) RealDelete(ctx context.Context, userCred mcclient.TokenCreden return err } } + SnapshotPolicyResourceManager.RemoveByResource(self.Id, api.SNAPSHOT_POLICY_TYPE_DISK) return self.SVirtualResourceBase.Delete(ctx, userCred) } +func (self *SDisk) DoPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error { + SnapshotPolicyResourceManager.RemoveByResource(self.Id, api.SNAPSHOT_POLICY_TYPE_DISK) + return self.SVirtualResourceBase.DoPendingDelete(ctx, userCred) +} + func (self *SDisk) RecordLastAttachedHost(ctx context.Context, userCred mcclient.TokenCredential, hostId string) error { storage, err := self.GetStorage() if err != nil { diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 58c62872e6..f6d5aac25b 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -3543,12 +3543,11 @@ func (self *SGuest) StartChangeConfigTask(ctx context.Context, userCred mcclient return nil } -func (self *SGuest) DoPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) { +func (self *SGuest) DoPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error { eip, _ := self.GetEipOrPublicIp() if eip != nil { eip.DoPendingDelete(ctx, userCred) } - disks, _ := self.GetDisks() for i := range disks { if !disks[i].IsDetachable() { @@ -3558,7 +3557,8 @@ func (self *SGuest) DoPendingDelete(ctx context.Context, userCred mcclient.Token self.DetachDisk(ctx, &disks[i], userCred) } } - self.SVirtualResourceBase.DoPendingDelete(ctx, userCred) + SnapshotPolicyResourceManager.RemoveByResource(self.Id, api.SNAPSHOT_POLICY_TYPE_SERVER) + return self.SVirtualResourceBase.DoPendingDelete(ctx, userCred) } // 从回收站恢复虚拟机 diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index c4bbc4762e..1afa29f811 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -4966,6 +4966,9 @@ func (self *SGuest) CreateDiskOnStorage(ctx context.Context, userCred mcclient.T if storage.IsLocal() || billingType == billing_api.BILLING_TYPE_PREPAID || isWithServerCreate { autoDelete = true } + if diskConfig.AutoDelete != nil { + autoDelete = *diskConfig.AutoDelete + } disk, err := storage.createDisk(ctx, diskName, diskConfig, userCred, self.GetOwnerId(), autoDelete, self.IsSystem, billingType, billingCycle, self.EncryptKeyId) @@ -5298,6 +5301,7 @@ func (self *SGuest) GetLoadbalancerBackends() ([]SLoadbalancerBackend, error) { } func (self *SGuest) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error { + SnapshotPolicyResourceManager.RemoveByResource(self.Id, api.SNAPSHOT_POLICY_TYPE_SERVER) return self.purge(ctx, userCred) } diff --git a/pkg/mcclient/options/compute/servers.go b/pkg/mcclient/options/compute/servers.go index 0ce1b35706..6680b1fa60 100644 --- a/pkg/mcclient/options/compute/servers.go +++ b/pkg/mcclient/options/compute/servers.go @@ -267,6 +267,7 @@ type ServerCreateCommonConfig struct { Disk []string `help:" Disk descriptions size: 500M, 10G + auto_delete: true, false fs: swap, ext2, ext3, ext4, xfs, ntfs, fat, hfsplus fs_features: casefold format: qcow2, raw, docker, iso, vmdk, vmdkflatver1, vmdkflatver2, vmdkflat, vmdksparse, vmdksparsever1, vmdksparsever2, vmdksesparse, vhd @@ -281,7 +282,7 @@ type ServerCreateCommonConfig struct { storage_id: use storage-list get storage id image_id: use image-list get image id for example: - --disk 'image_id=c2be02a4-7ff2-43e6-8a00-a489e04d2d6f,size=10G,driver=ide,storage_type=rbd' + --disk 'image_id=c2be02a4-7ff2-43e6-8a00-a489e04d2d6f,size=10G,driver=ide,storage_type=rbd,auto_delete=true' --disk 'size=500M' --disk 'snpahost_id=1ceb8c6d-6571-451d-8957-4bd3a871af85' " nargs:"+"` diff --git a/pkg/monitor/dbinit/measurements/metrics.csv b/pkg/monitor/dbinit/measurements/metrics.csv index 119fe76401..bd135c7951 100644 --- a/pkg/monitor/dbinit/measurements/metrics.csv +++ b/pkg/monitor/dbinit/measurements/metrics.csv @@ -226,6 +226,14 @@ Measurement,MeasurementNote,ResourceType,Database,Metric,MetricNote,MetricUnit "system","System load","host","telegraf","load1_pcore","Loadavg load1 per cpu core","NULL" "system","System load","host","telegraf","load5_pcore","Loadavg load5 per cpu core","NULL" "system","System load","host","telegraf","load15_pcore","Loadavg load15 per cpu core","NULL" +"system","System load","host","telegraf","uptime","System uptime","NULL" +"agent_system","System load","agent","telegraf","load1","Loadavg load1","NULL" +"agent_system","System load","agent","telegraf","load5","Loadavg load5","NULL" +"agent_system","System load","agent","telegraf","load15","Loadavg load15","NULL" +"agent_system","System load","agent","telegraf","load1_pcore","Loadavg load1 per cpu core","NULL" +"agent_system","System load","agent","telegraf","load5_pcore","Loadavg load5 per cpu core","NULL" +"agent_system","System load","agent","telegraf","load15_pcore","Loadavg load15 per cpu core","NULL" +"agent_system","System load","agent","telegraf","uptime","System uptime","NULL" "vasmi","Vasmi GPU metrics","host","telegraf","temperature_gpu","GPU temperature","" "vasmi","Vasmi GPU metrics","host","telegraf","utilization_gpu","GPU utilization","%" "vasmi","Vasmi GPU metrics","host","telegraf","utilization_memory","GPU memory utilization","%" @@ -310,7 +318,6 @@ Measurement,MeasurementNote,ResourceType,Database,Metric,MetricNote,MetricUnit "vm_netio","Guest network traffic","guest","telegraf","bps_sent","Send traffic per second","bps" "vm_netio","Guest network traffic","guest","telegraf","pps_recv","Received packets per second","pps" "vm_netio","Guest network traffic","guest","telegraf","pps_sent","Send packets per second","pps" - "vm_netio","Guest network traffic","guest","telegraf","bytes_sent","The total number of bytes sent by the network interface","byte" "vm_netio","Guest network traffic","guest","telegraf","bytes_recv","The total number of bytes received by the network interface","byte" "vm_netio","Guest network traffic","guest","telegraf","packets_sent","The total number of packets sent by the network interface","count" @@ -324,6 +331,7 @@ Measurement,MeasurementNote,ResourceType,Database,Metric,MetricNote,MetricUnit "pod_netio","Pod network traffic","container","telegraf","bytes_recv","The total number of bytes received by the network interface","byte" "pod_netio","Pod network traffic","container","telegraf","packets_sent","The total number of packets sent by the network interface","count" "pod_netio","Pod network traffic","container","telegraf","packets_recv","The total number of packets received by the network interface","count" +"pod_netio","Pod network traffic","container","telegraf","out_bandwidth_usage","Outbound bandwidth utilization","%" "cloudaccount_balance","Cloud account balance","cloudaccount","meter_db","balance","balance","NULL" "container_cpu","Container cpu","container","telegraf","usage_rate","Container cpu usage rate","%" "container_mem","Container memory","container","telegraf","usage_rate","Container memory usage rate","%" @@ -600,6 +608,7 @@ Measurement,MeasurementNote,ResourceType,Database,Metric,MetricNote,MetricUnit "redis_keyspace","redis_keyspace","ext_redis","telegraf","expires","expires","count" "sensors","Collect lm-sensors metrics","host","telegraf","temp_input","lm-sensors temperature input","" "agent_sensors","Collect lm-sensors metrics","agent","telegraf","temp_input","lm-sensors temperature input","" +"ipmi_sensor","IPMI sensor","host","telegraf","value","Sensor value","NULL" "agent_smart_device","Collect smartctl metrics","agent","telegraf","temp_c","Disk device temperature ","" "smart_device","Collect smartctl metrics","host","telegraf","temp_c","Disk device temperature ","" "storage","Storage usage","storage","telegraf","usage_active","Storage utilization rate","%" @@ -612,3 +621,5 @@ Measurement,MeasurementNote,ResourceType,Database,Metric,MetricNote,MetricUnit "swap","The swap plugin collects system swap metrics.","host","telegraf","out","(int, bytes): data swapped out since last boot calculated from page number","byte" "temp","The temp input plugin gather metrics on system temperature","host","telegraf","temp","(float, celcius)","NULL" "agent_temp","The temp input plugin gather metrics on system temperature","guest","telegraf","temp","(float, celcius)","NULL" +"host_raid","Host RAID metrics","host","telegraf","adapter","Raid controller adapter","NULL" +"host_raid","Host RAID metrics","host","telegraf","slot","Physical disk slot","NULL"