fix(region,host): server create add qemu version params (#25714)

- windows detect is virtio_net support, default use e1000 nic driver
- add server-set-iso interface
This commit is contained in:
wanyaoqi
2026-09-22 23:12:27 +08:00
committed by GitHub
parent 4820e66ad3
commit e080ebd8ef
24 changed files with 316 additions and 97 deletions
+1
View File
@@ -160,6 +160,7 @@ func init() {
cmd.Perform("add-network-secgroup", new(options.ServerNetworkSecGroupsOptions))
cmd.Perform("revoke-network-secgroup", new(options.ServerNetworkSecGroupsOptions))
cmd.Perform("change-disk-driver", new(options.ServerChangeDiskDriverOptions))
cmd.Perform("set-iso", new(options.ServerSetIsoOptions))
cmd.GetProperty(&options.ServerStatusStatisticsOptions{})
cmd.GetProperty(&options.ServerProjectStatisticsOptions{})
+4 -1
View File
@@ -413,7 +413,10 @@ type ServerConfigs struct {
// default: kvm
Hypervisor string `json:"hypervisor"`
// swagger:ignore
// specific qemu version, eg: 4.2.0, 10.0.7
QemuVersion string `json:"qemu_version"`
// swagger: ignore
Provider string `json:"provider"`
// 包年包月资源池
+2
View File
@@ -357,6 +357,8 @@ const (
VM_METADATA_ENABLE_TPM = "enable_tpm"
VM_METADATA_QEMU_VERSION = "qemu_version"
VM_METADATA_RELEASED_DEVICES = "released_devices"
VM_METADATA_CPU_NUMA_PIN = "__cpu_numa_pin"
+6
View File
@@ -1337,6 +1337,12 @@ type ServerSetPasswordInput struct {
AutoStart bool `json:"auto_start"`
}
type ServerSetIsoInput struct {
CdromOrdinal int64 `json:"cdrom_ordinal"`
ImageId string `json:"image_id"`
BootIndex *int8 `json:"boot_index"`
}
type ServerInsertVfdInput struct {
FloppyOrdinal int64 `json:"floppy_ordinal"`
ImageId string `json:"image_id"`
+1
View File
@@ -78,6 +78,7 @@ const (
IMAGE_VDI_PROTOCOL = "vdi_protocol"
IMAGE_INTERNAL_PATH_MAP = "internal_path_map"
IMAGE_USED_BY_POST_OVERLAY = "used_by_post_overlay"
IMAGE_WIN_VIRTIO_NET = "win_virtio_net"
IMAGE_STATUS_UPDATING = "updating"
)
+1
View File
@@ -89,6 +89,7 @@ type ScheduleInput struct {
CpuMode string `json:"cpu_mode"`
OsArch string `json:"os_arch"`
ResetCpuNumaPin bool `json:"reset_cpu_numa_pin"`
QemuVersion string `json:"qemu_version"`
ExtraCpuCount int `json:"extra_cpu_count"`
CpuNumaPin []SCpuNumaPin `json:"cpu_numa_pin"`
+67 -2
View File
@@ -1519,6 +1519,56 @@ func (self *SGuest) GetDetailsKickstart(ctx context.Context, userCred mcclient.T
return result, nil
}
func (self *SGuest) PerformSetIso(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.ServerSetIsoInput) (jsonutils.JSONObject, error) {
if !utils.IsInStringArray(self.Hypervisor, []string{api.HYPERVISOR_KVM, api.HYPERVISOR_BAREMETAL}) {
return nil, httperrors.NewNotAcceptableError("Not allow for hypervisor %s", self.Hypervisor)
}
if !utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_READY}) {
return nil, httperrors.NewServerStatusError("Set ISO not allowed in status %s", self.Status)
}
if input.ImageId != "" {
isoImage, err := parseIsoInfo(ctx, userCred, input.ImageId)
if err != nil {
return nil, errors.Wrap(err, "parseIsoInfo")
}
input.ImageId = isoImage.Id
}
cdrom := self.getCdrom(false, input.CdromOrdinal)
if input.BootIndex != nil {
bd8 := *input.BootIndex
if cdrom == nil || cdrom.BootIndex != bd8 {
if isDup, err := self.isBootIndexDuplicated(bd8); err != nil {
return nil, err
} else if isDup {
return nil, httperrors.NewInputParameterError("boot index %d is duplicated", bd8)
}
}
}
srcImage := ""
if cdrom != nil {
srcImage = cdrom.ImageId
}
if srcImage == "" && input.ImageId == "" {
return nil, nil
} else if srcImage != "" && input.ImageId != "" {
if srcImage == input.ImageId {
return nil, nil
}
// eject && insert
err := self.StartEjectisoTask(ctx, input.CdromOrdinal, userCred, input.BootIndex, input.ImageId, "")
return nil, err
} else if srcImage == "" && input.ImageId != "" {
// insert only
err := self.StartInsertIsoTask(ctx, input.CdromOrdinal, input.ImageId, false, input.BootIndex, self.HostId, userCred, "")
return nil, err
} else {
// eject only
err := self.StartEjectisoTask(ctx, input.CdromOrdinal, userCred, nil, "", "")
return nil, err
}
}
// 挂载ISO镜像
func (self *SGuest) PerformInsertiso(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if !utils.IsInStringArray(self.Hypervisor, []string{api.HYPERVISOR_KVM, api.HYPERVISOR_BAREMETAL}) {
@@ -1573,16 +1623,23 @@ func (self *SGuest) PerformEjectiso(ctx context.Context, userCred mcclient.Token
return nil, httperrors.NewBadRequestError("No ISO to eject")
}
if utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_READY}) {
err := self.StartEjectisoTask(ctx, cdromOrdinal, userCred, "")
err := self.StartEjectisoTask(ctx, cdromOrdinal, userCred, nil, "", "")
return nil, err
} else {
return nil, httperrors.NewServerStatusError("Eject ISO not allowed in status %s", self.Status)
}
}
func (self *SGuest) StartEjectisoTask(ctx context.Context, cdromOrdinal int64, userCred mcclient.TokenCredential, parentTaskId string) error {
func (self *SGuest) StartEjectisoTask(ctx context.Context, cdromOrdinal int64, userCred mcclient.TokenCredential, bootIndex *int8, newImageId, parentTaskId string) error {
data := jsonutils.NewDict()
data.Add(jsonutils.NewInt(cdromOrdinal), "cdrom_ordinal")
if newImageId != "" {
data.Add(jsonutils.NewString(newImageId), "new_image_id")
if bootIndex != nil {
data.Add(jsonutils.NewInt(int64(*bootIndex)), "boot_index")
}
}
task, err := taskman.TaskManager.NewTask(ctx, "GuestEjectISOTask", self, userCred, data, parentTaskId, "", nil)
if err != nil {
return err
@@ -7397,6 +7454,14 @@ func (self *SGuest) PerformEnableMemclean(ctx context.Context, userCred mcclient
return nil, self.SetMetadata(ctx, api.VM_METADATA_ENABLE_MEMCLEAN, "true", userCred)
}
func (self *SGuest) PerformSetQemuVersion(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if data.Contains(api.VM_METADATA_QEMU_VERSION) {
qemuVersion, _ := data.GetString(api.VM_METADATA_QEMU_VERSION)
return nil, self.SetMetadata(ctx, api.VM_METADATA_QEMU_VERSION, qemuVersion, userCred)
}
return nil, self.SetMetadata(ctx, api.VM_METADATA_QEMU_VERSION, "", userCred)
}
func (self *SGuest) PerformSetTpm(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
enableTpm := jsonutils.QueryBoolean(data, api.VM_METADATA_ENABLE_TPM, false)
if enableTpm {
+10
View File
@@ -2081,6 +2081,13 @@ func (manager *SGuestManager) validateCreateData(
osType = osProf.OSType
input.OsType = osType
}
if imgIsWindows {
netDriver := api.NETWORK_DRIVER_E1000
if hasVirtioNetDrvier := imgProperties[imageapi.IMAGE_WIN_VIRTIO_NET] == "true"; hasVirtioNetDrvier {
netDriver = api.NETWORK_DRIVER_VIRTIO
}
osProf.NetDriver = netDriver
}
input.OsProfile = jsonutils.Marshal(osProf)
}
@@ -2948,6 +2955,9 @@ func (guest *SGuest) PostCreate(ctx context.Context, userCred mcclient.TokenCred
if matcherJson != nil {
guest.SetMetadata(ctx, api.BAREMETAL_SERVER_METATA_ROOT_DISK_MATCHER, matcherJson, userCred)
}
if qemuVersion, _ := data.GetString(api.VM_METADATA_QEMU_VERSION); qemuVersion != "" {
guest.SetMetadata(ctx, api.VM_METADATA_QEMU_VERSION, qemuVersion, userCred)
}
userData, _ := data.GetString("user_data")
if len(userData) > 0 {
+38 -12
View File
@@ -41,25 +41,51 @@ func (self *GuestEjectISOTask) OnInit(ctx context.Context, obj db.IStandaloneMod
func (self *GuestEjectISOTask) startEjectIso(ctx context.Context, obj db.IStandaloneModel) {
guest := obj.(*models.SGuest)
cdromOrdinal, _ := self.Params.Int("cdrom_ordinal")
if guest.EjectIso(cdromOrdinal, self.UserCred) && guest.Status == api.VM_RUNNING {
self.SetStage("OnConfigSyncComplete", nil)
drv, err := guest.GetDriver()
if err != nil {
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
return
if guest.EjectIso(cdromOrdinal, self.UserCred) {
if guest.Status == api.VM_RUNNING {
self.SetStage("OnConfigSyncComplete", nil)
drv, err := guest.GetDriver()
if err != nil {
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
return
}
drv.RequestGuestHotRemoveIso(ctx, guest, self)
} else {
self.OnConfigSyncComplete(ctx, obj, nil)
}
drv.RequestGuestHotRemoveIso(ctx, guest, self)
} else {
self.OnConfigSyncCompleteFailed(ctx, obj, jsonutils.NewString("eject iso failed"))
}
}
func (self *GuestEjectISOTask) OnConfigSyncComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
logclient.AddActionLogWithContext(ctx, obj, logclient.ACT_ISO_DETACH, nil, self.UserCred, true)
if newImageId, _ := self.Params.GetString("new_image_id"); newImageId != "" {
cdromOrdinal, _ := self.Params.Int("cdrom_ordinal")
var bootIndex *int8
if data.Contains("boot_index") {
bootIndex64, _ := data.Int("boot_index")
bootIndex8 := int8(bootIndex64)
bootIndex = &bootIndex8
}
guest := obj.(*models.SGuest)
self.SetStage("OnInsertNewIsoComplete", nil)
guest.StartInsertIsoTask(ctx, cdromOrdinal, newImageId, false, bootIndex, guest.HostId, self.UserCred, self.GetTaskId())
} else {
self.SetStageComplete(ctx, nil)
}
}
func (self *GuestEjectISOTask) OnConfigSyncComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
logclient.AddActionLogWithContext(ctx, obj, logclient.ACT_ISO_DETACH, nil, self.UserCred, true)
func (self *GuestEjectISOTask) OnConfigSyncCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
logclient.AddActionLogWithContext(ctx, obj, logclient.ACT_ISO_DETACH, nil, self.UserCred, false)
self.SetStageFailed(ctx, data)
}
func (self *GuestEjectISOTask) OnInsertNewIsoComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageComplete(ctx, nil)
}
func (self *GuestEjectISOTask) OnConfigSyncCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
logclient.AddActionLogWithContext(ctx, obj, logclient.ACT_ISO_DETACH, nil, self.UserCred, false)
self.SetStageFailed(ctx, nil)
func (self *GuestEjectISOTask) OnInsertNewIsoCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageFailed(ctx, data)
}
+7 -6
View File
@@ -774,11 +774,12 @@ func ProbeImageInfo(d deploy_iface.IDeployer) (*apis.ImageInfo, error) {
}
partition := rootfs.GetPartition()
imageInfo := &apis.ImageInfo{
OsInfo: rootfs.GetReleaseInfo(partition),
OsType: rootfs.GetOs(),
IsLvmPartition: d.IsLVMPartition(),
IsReadonly: partition.IsReadonly(),
IsInstalledCloudInit: rootfs.IsCloudinitInstall(),
OsInfo: rootfs.GetReleaseInfo(partition),
OsType: rootfs.GetOs(),
IsLvmPartition: d.IsLVMPartition(),
IsReadonly: partition.IsReadonly(),
IsInstalledCloudInit: rootfs.IsCloudinitInstall(),
IsWindowsVirtioNetSupport: rootfs.IsWindowsVirtioNetSupport(partition),
}
d.UmountRootfs(rootfs)
@@ -787,6 +788,6 @@ func ProbeImageInfo(d deploy_iface.IDeployer) (*apis.ImageInfo, error) {
imageInfo.IsUefiSupport = d.DetectIsUEFISupport(rootfs)
imageInfo.PhysicalPartitionType = partition.GetPhysicalPartitionType()
imageInfo.IsBiosSupport = d.DetectIsBIOSSupport(rootfs)
log.Infof("ProbeImageInfo response %s", imageInfo)
log.Infof("ProbeImageInfo response %#v", imageInfo)
return imageInfo, nil
}
+4
View File
@@ -166,6 +166,10 @@ func (l *sGuestRootFsDriver) MountProcfs() bool {
return false
}
func (l *sGuestRootFsDriver) IsWindowsVirtioNetSupport(IDiskPartition) bool {
return false
}
const (
modeAuthorizedKeysRWX = syscall.S_IRUSR | syscall.S_IWUSR | syscall.S_IXUSR
modeAuthorizedKeysRW = syscall.S_IRUSR | syscall.S_IWUSR
@@ -96,6 +96,7 @@ type IRootFsDriver interface {
IsCloudinitInstall() bool
IsResizeFsPartitionSupport() bool
MountProcfs() bool
IsWindowsVirtioNetSupport(part IDiskPartition) bool
PrepareFsForTemplate(IDiskPartition) error
CleanNetworkScripts(rootFs IDiskPartition) error
+7
View File
@@ -691,3 +691,10 @@ func (w *SWindowsRootFs) DeployTelegraf(config string) (bool, error) {
func (w *SWindowsRootFs) ConfigSshd(loginAccount, loginPassword string, sshPort int) error {
return nil
}
func (w *SWindowsRootFs) IsWindowsVirtioNetSupport(part IDiskPartition) bool {
confPath := part.GetLocalPath("/windows/system32/config", true)
tool := winutils.NewWinRegTool(confPath)
tool.CheckPath()
return tool.IsNetKVMInstalled()
}
+3
View File
@@ -2003,6 +2003,9 @@ func (s *SKVMGuestInstance) HandleGuestStart(ctx context.Context, userCred mccli
func (s *SKVMGuestInstance) StartGuest(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict) error {
var err error
params, err = s.prepareEncryptKeyForStart(ctx, userCred, params)
if qemuVersion, ok := s.Desc.Metadata["qemu_version"]; ok && !params.Contains("qemu_version") {
params.Set("qemu_version", jsonutils.NewString(qemuVersion))
}
if err != nil {
return errors.Wrap(err, "prepareEncryptKeyForStart")
}
+87 -75
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.20.0
// protoc v3.21.5
// protoc v3.20.3
// source: deploy.proto
// protoc --version=libprotoc 3.11.3
@@ -1828,14 +1828,15 @@ type ImageInfo struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
OsInfo *ReleaseInfo `protobuf:"bytes,1,opt,name=os_info,json=osInfo,proto3" json:"os_info,omitempty"`
OsType string `protobuf:"bytes,2,opt,name=os_type,json=osType,proto3" json:"os_type,omitempty"`
IsUefiSupport bool `protobuf:"varint,3,opt,name=is_uefi_support,json=isUefiSupport,proto3" json:"is_uefi_support,omitempty"`
IsLvmPartition bool `protobuf:"varint,4,opt,name=is_lvm_partition,json=isLvmPartition,proto3" json:"is_lvm_partition,omitempty"`
IsReadonly bool `protobuf:"varint,5,opt,name=is_readonly,json=isReadonly,proto3" json:"is_readonly,omitempty"`
PhysicalPartitionType string `protobuf:"bytes,6,opt,name=physical_partition_type,json=physicalPartitionType,proto3" json:"physical_partition_type,omitempty"`
IsInstalledCloudInit bool `protobuf:"varint,7,opt,name=is_installed_cloud_init,json=isInstalledCloudInit,proto3" json:"is_installed_cloud_init,omitempty"`
IsBiosSupport bool `protobuf:"varint,8,opt,name=is_bios_support,json=isBiosSupport,proto3" json:"is_bios_support,omitempty"`
OsInfo *ReleaseInfo `protobuf:"bytes,1,opt,name=os_info,json=osInfo,proto3" json:"os_info,omitempty"`
OsType string `protobuf:"bytes,2,opt,name=os_type,json=osType,proto3" json:"os_type,omitempty"`
IsUefiSupport bool `protobuf:"varint,3,opt,name=is_uefi_support,json=isUefiSupport,proto3" json:"is_uefi_support,omitempty"`
IsLvmPartition bool `protobuf:"varint,4,opt,name=is_lvm_partition,json=isLvmPartition,proto3" json:"is_lvm_partition,omitempty"`
IsReadonly bool `protobuf:"varint,5,opt,name=is_readonly,json=isReadonly,proto3" json:"is_readonly,omitempty"`
PhysicalPartitionType string `protobuf:"bytes,6,opt,name=physical_partition_type,json=physicalPartitionType,proto3" json:"physical_partition_type,omitempty"`
IsInstalledCloudInit bool `protobuf:"varint,7,opt,name=is_installed_cloud_init,json=isInstalledCloudInit,proto3" json:"is_installed_cloud_init,omitempty"`
IsBiosSupport bool `protobuf:"varint,8,opt,name=is_bios_support,json=isBiosSupport,proto3" json:"is_bios_support,omitempty"`
IsWindowsVirtioNetSupport bool `protobuf:"varint,9,opt,name=is_windows_virtio_net_support,json=isWindowsVirtioNetSupport,proto3" json:"is_windows_virtio_net_support,omitempty"`
}
func (x *ImageInfo) Reset() {
@@ -1926,6 +1927,13 @@ func (x *ImageInfo) GetIsBiosSupport() bool {
return false
}
func (x *ImageInfo) GetIsWindowsVirtioNetSupport() bool {
if x != nil {
return x.IsWindowsVirtioNetSupport
}
return false
}
type EsxiDiskInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -2458,7 +2466,7 @@ var file_deploy_proto_rawDesc = []byte{
0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x50, 0x72, 0x61, 0x6d, 0x61, 0x73, 0x12, 0x2b, 0x0a, 0x09,
0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0e, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52,
0x08, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xda, 0x02, 0x0a, 0x09, 0x49, 0x6d,
0x08, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x9c, 0x03, 0x0a, 0x09, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2a, 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x69, 0x6e,
0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e,
0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6f, 0x73, 0x49,
@@ -2480,71 +2488,75 @@ var file_deploy_proto_rawDesc = []byte{
0x61, 0x6c, 0x6c, 0x65, 0x64, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x26,
0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x62, 0x69, 0x6f, 0x73, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72,
0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x73, 0x42, 0x69, 0x6f, 0x73, 0x53,
0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x2b, 0x0a, 0x0c, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69,
0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x70,
0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x50,
0x61, 0x74, 0x68, 0x22, 0x7d, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x73,
0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2e, 0x0a,
0x09, 0x76, 0x64, 0x64, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x56, 0x44, 0x44, 0x4b, 0x43, 0x6f, 0x6e, 0x49,
0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x64, 0x64, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a,
0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69,
0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e,
0x66, 0x6f, 0x22, 0x43, 0x0a, 0x17, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x43,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a,
0x05, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61,
0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f,
0x52, 0x05, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x22, 0x67, 0x0a, 0x0b, 0x42, 0x6f, 0x6f, 0x74, 0x44,
0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x74, 0x4f, 0x72,
0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x42, 0x6f, 0x6f, 0x74, 0x4f,
0x72, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x44, 0x65, 0x76, 0x54, 0x79, 0x70, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x44, 0x65, 0x76, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20,
0x0a, 0x0b, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0b, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x4f, 0x72, 0x64, 0x65, 0x72,
0x22, 0x60, 0x0a, 0x13, 0x4f, 0x76, 0x6d, 0x66, 0x42, 0x6f, 0x6f, 0x74, 0x4f, 0x72, 0x64, 0x65,
0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x76, 0x6d, 0x66, 0x56,
0x61, 0x72, 0x73, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4f,
0x76, 0x6d, 0x66, 0x56, 0x61, 0x72, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x25, 0x0a, 0x04, 0x64,
0x65, 0x76, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73,
0x2e, 0x42, 0x6f, 0x6f, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x04, 0x64, 0x65,
0x76, 0x73, 0x32, 0x82, 0x04, 0x0a, 0x0b, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x41, 0x67, 0x65,
0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0d, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x47, 0x75, 0x65, 0x73,
0x74, 0x46, 0x73, 0x12, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f,
0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44,
0x65, 0x70, 0x6c, 0x6f, 0x79, 0x47, 0x75, 0x65, 0x73, 0x74, 0x46, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x46, 0x73,
0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x46, 0x73,
0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x08, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x46, 0x73, 0x12,
0x14, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x46, 0x73, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x12, 0x44, 0x0a, 0x0c, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c, 0x61, 0x6e,
0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f,
0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1a, 0x2e, 0x61,
0x70, 0x69, 0x73, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x62,
0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69,
0x73, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f,
0x50, 0x72, 0x61, 0x6d, 0x61, 0x73, 0x1a, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4f, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x12, 0x1c, 0x2e, 0x61, 0x70,
0x69, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69,
0x73, 0x6b, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x73,
0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x63,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x12,
0x1d, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73,
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0b,
0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x10, 0x53,
0x65, 0x74, 0x4f, 0x76, 0x6d, 0x66, 0x42, 0x6f, 0x6f, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12,
0x19, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x4f, 0x76, 0x6d, 0x66, 0x42, 0x6f, 0x6f, 0x74, 0x4f,
0x72, 0x64, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69,
0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x34, 0x5a, 0x32, 0x79, 0x75, 0x6e, 0x69, 0x6f,
0x6e, 0x2e, 0x69, 0x6f, 0x2f, 0x78, 0x2f, 0x6f, 0x6e, 0x65, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f,
0x70, 0x6b, 0x67, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2f, 0x68, 0x6f, 0x73, 0x74,
0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x40, 0x0a, 0x1d, 0x69, 0x73, 0x5f, 0x77, 0x69, 0x6e,
0x64, 0x6f, 0x77, 0x73, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x69, 0x6f, 0x5f, 0x6e, 0x65, 0x74, 0x5f,
0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69,
0x73, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x56, 0x69, 0x72, 0x74, 0x69, 0x6f, 0x4e, 0x65,
0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x2b, 0x0a, 0x0c, 0x45, 0x73, 0x78, 0x69,
0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b,
0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x73,
0x6b, 0x50, 0x61, 0x74, 0x68, 0x22, 0x7d, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12,
0x2e, 0x0a, 0x09, 0x76, 0x64, 0x64, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x56, 0x44, 0x44, 0x4b, 0x43, 0x6f,
0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x64, 0x64, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12,
0x33, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69,
0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
0x49, 0x6e, 0x66, 0x6f, 0x22, 0x43, 0x0a, 0x17, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b,
0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12,
0x28, 0x0a, 0x05, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12,
0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e,
0x66, 0x6f, 0x52, 0x05, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x22, 0x67, 0x0a, 0x0b, 0x42, 0x6f, 0x6f,
0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x74,
0x4f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x42, 0x6f, 0x6f,
0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x44, 0x65, 0x76, 0x54, 0x79, 0x70,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x44, 0x65, 0x76, 0x54, 0x79, 0x70, 0x65,
0x12, 0x20, 0x0a, 0x0b, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x18,
0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x4f, 0x72, 0x64,
0x65, 0x72, 0x22, 0x60, 0x0a, 0x13, 0x4f, 0x76, 0x6d, 0x66, 0x42, 0x6f, 0x6f, 0x74, 0x4f, 0x72,
0x64, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x76, 0x6d,
0x66, 0x56, 0x61, 0x72, 0x73, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0c, 0x4f, 0x76, 0x6d, 0x66, 0x56, 0x61, 0x72, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x25, 0x0a,
0x04, 0x64, 0x65, 0x76, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70,
0x69, 0x73, 0x2e, 0x42, 0x6f, 0x6f, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x04,
0x64, 0x65, 0x76, 0x73, 0x32, 0x82, 0x04, 0x0a, 0x0b, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x41,
0x67, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0d, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x47, 0x75,
0x65, 0x73, 0x74, 0x46, 0x73, 0x12, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x65, 0x70,
0x6c, 0x6f, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x73,
0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x47, 0x75, 0x65, 0x73, 0x74, 0x46, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65,
0x46, 0x73, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65,
0x46, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e,
0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x08, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x46,
0x73, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x46,
0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0c, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c,
0x61, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x53, 0x61, 0x76, 0x65,
0x54, 0x6f, 0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1a,
0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c, 0x61, 0x6e,
0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x50, 0x72,
0x6f, 0x62, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x2e, 0x61,
0x70, 0x69, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e,
0x66, 0x6f, 0x50, 0x72, 0x61, 0x6d, 0x61, 0x73, 0x1a, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e,
0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4f, 0x0a, 0x10, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x12, 0x1c, 0x2e,
0x61, 0x70, 0x69, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x73, 0x78, 0x69,
0x44, 0x69, 0x73, 0x6b, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1d, 0x2e, 0x61, 0x70,
0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x6e, 0x6e,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a, 0x13, 0x44, 0x69,
0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b,
0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73,
0x6b, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f,
0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3a, 0x0a,
0x10, 0x53, 0x65, 0x74, 0x4f, 0x76, 0x6d, 0x66, 0x42, 0x6f, 0x6f, 0x74, 0x4f, 0x72, 0x64, 0x65,
0x72, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x4f, 0x76, 0x6d, 0x66, 0x42, 0x6f, 0x6f,
0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61,
0x70, 0x69, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x34, 0x5a, 0x32, 0x79, 0x75, 0x6e,
0x69, 0x6f, 0x6e, 0x2e, 0x69, 0x6f, 0x2f, 0x78, 0x2f, 0x6f, 0x6e, 0x65, 0x63, 0x6c, 0x6f, 0x75,
0x64, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2f, 0x68, 0x6f,
0x73, 0x74, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -203,6 +203,7 @@ message ImageInfo {
string physical_partition_type = 6;
bool is_installed_cloud_init = 7;
bool is_bios_support = 8;
bool is_windows_virtio_net_support = 9;
}
message EsxiDiskInfo {
+4
View File
@@ -977,6 +977,10 @@ func (h *SHostInfo) detectSyssoftwareInfo() error {
log.Errorf("detect qemu version: %s", err.Error())
h.AppendHostError(fmt.Sprintf("detect qemu version: %s", err.Error()))
}
h.sysinfo.QemuVersions = qemutils.GetUsrLocalQemuVersions()
if !utils.IsInStringArray(h.sysinfo.QemuVersion, h.sysinfo.QemuVersions) {
h.sysinfo.QemuVersions = append(h.sysinfo.QemuVersions, h.sysinfo.QemuVersion)
}
}
h.detectOvsVersion()
if err := h.detectOvsKOVersion(); err != nil {
+2
View File
@@ -424,6 +424,8 @@ type SSysInfo struct {
CpuMicrocode string `json:"cpu_microcode"`
CgroupVersion string `json:"cgroup_version"`
QemuVersions []string `json:"qemu_versions"`
StorageType string `json:"storage_type"`
HugepagesOption string `json:"hugepages_option"`
+3
View File
@@ -1850,6 +1850,9 @@ func (image *SImage) updateImageInfo(
imageProperties.Set(api.IMAGE_IS_LVM_PARTITION, jsonutils.NewBool(imageInfo.IsLvmPartition))
imageProperties.Set(api.IMAGE_IS_READONLY, jsonutils.NewBool(imageInfo.IsReadonly))
imageProperties.Set(api.IMAGE_INSTALLED_CLOUDINIT, jsonutils.NewBool(imageInfo.IsInstalledCloudInit))
if imageInfo.IsWindowsVirtioNetSupport {
imageProperties.Set(api.IMAGE_WIN_VIRTIO_NET, jsonutils.JSONTrue)
}
return ImagePropertyManager.SaveProperties(ctx, userCred, image.Id, imageProperties)
}
+14
View File
@@ -400,6 +400,7 @@ type ServerConfigs struct {
BackupHost string `help:"Preferred host where virtual backup server should be created"`
AutoSwitchToBackupOnHostDown bool `help:"Auto switch to backup server on host down"`
Daemon *bool `help:"Set as a daemon server" json:"is_daemon"`
QemuVersion string `help:"specific server guest start version" json:"qemu_version"`
RaidConfig []string `help:"Baremetal raid config" json:"-"`
RootDiskMatcher string `help:"Baremetal root disk matcher, e.g. 'device=/dev/sdb' 'size=900G' 'size_start=800G,size_end=900G'" json:"-"`
@@ -414,6 +415,7 @@ func (o ServerConfigs) Data() (*computeapi.ServerConfigs, error) {
data.PreferBackupHost = o.BackupHost
data.IsDaemon = o.Daemon
data.Hypervisor = o.Hypervisor
data.QemuVersion = o.QemuVersion
if len(o.RaidConfig) > 0 {
// if data.Hypervisor != "baremetal" {
// return nil, fmt.Errorf("RaidConfig is applicable to baremetal ONLY")
@@ -1728,6 +1730,18 @@ func (o *ServerSetNetworkNumQueues) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(o), nil
}
type ServerSetIsoOptions struct {
ServerIdOptions
CDROM_ORDINAL int64 `json:"cdrom_ordinal" help:"cdrom ordinal"`
ImageId string `help:"Iso image id, eject on image id empty"`
BootIndex *int8 `help:"Iso boot index"`
}
func (o *ServerSetIsoOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(o), nil
}
type ServerIsoOptions struct {
ServerIdOptions
Ordinal int `help:"server iso ordinal, default 0"`
@@ -46,6 +46,7 @@ const (
ErrPrepaidHostOccupied = `prepaid host occupied`
ErrHostCpuArchitectureNotMatch = `host cpu architecture not match`
ErrHostKvmVcpuMaxNotEnough = `host kvm vcpu max not enough`
ErrHostQemuVersionNotMatch = `host qemu version not match`
ErrUnknown = `unknown error`
)
@@ -18,6 +18,7 @@ import (
"context"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates"
@@ -71,7 +72,17 @@ func (f *HypervisorPredicate) Execute(ctx context.Context, u *core.Unit, c core.
hostType := c.Getter().HostType()
guestNeedType := u.SchedData().Hypervisor
if hostType == computeapi.HOST_TYPE_HYPERVISOR {
if u.SchedData().QemuVersion != "" {
host := c.Getter().Host()
qemuVersions := make([]string, 0)
host.SysInfo.Unmarshal(&qemuVersions, "qemu_versions")
if !utils.IsInStringArray(u.SchedData().QemuVersion, qemuVersions) {
h.Exclude(predicates.ErrHostQemuVersionNotMatch)
return h.GetResult()
}
}
}
if guestNeedType != hostType {
if guestNeedType == computeapi.HYPERVISOR_POD && hostAllowRunContainer(c) {
return h.GetResult()
+23
View File
@@ -47,6 +47,10 @@ func GetQemu(version string) string {
return getQemuCmd(qemuSystemCmd, version)
}
func GetUsrLocalQemuVersions() []string {
return getUsrLocalQemuVersions(qemuSystemCmd)
}
func GetQemuNbd() string {
return getQemuCmd("qemu-nbd", "")
}
@@ -108,6 +112,25 @@ func getCmdVersion(cmd string) string {
return s[1:]
}
func getUsrLocalQemuVersions(cmd string) []string {
var qemus = make([]string, 0)
if files, err := procutils.RemoteReadDir("/usr/local"); err == nil {
for i := 0; i < len(files); i++ {
if strings.HasPrefix(files[i].Name(), "qemu-") {
p := fmt.Sprintf("/usr/local/%s/bin/%s", files[i].Name(), cmd)
if _, err := procutils.RemoteStat(p); err == nil {
qemuVersion := getQemuVersion(files[i].Name())
if qemuVersion == "" {
continue
}
qemus = append(qemus, qemuVersion)
}
}
}
}
return qemus
}
func getQemuDefaultCmd(cmd string) string {
var qemus = make([]string, 0)
if files, err := procutils.RemoteReadDir("/usr/local"); err == nil {
+17
View File
@@ -774,3 +774,20 @@ func (w *SWinRegTool) ResetUSBProfile() {
key = w.GetCcsKeyPath() + `\Enum\USB`
w.DelRegistry(key)
}
func (w *SWinRegTool) IsNetKVMInstalled() bool {
key := w.GetCcsKeyPath() + `\Services\netkvm`
if !w.KeyExists(key) {
log.Errorf("key %s not exist", key)
return false
}
imagePath := w.GetRegistry(key + `\ImagePath`)
if imagePath == "" {
log.Errorf("image path is empty")
return false
}
return true
}