Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Controller] parse kvm support run.xml #6022

Merged
merged 1 commit into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 43 additions & 10 deletions server/controller/genesis/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,22 @@ type KVMDomain struct {
Type string `xml:"type,attr"`
UUID string `xml:"uuid"`
Name string `xml:"name"`
Label string `xml:"label"`
Title string `xml:"title"`
MetaData KVMMetaData `xml:"metadata"`
Devices KVMDevices `xml:"devices"`
}
type KVMDomains struct {
type ETCDomains struct {
Domains []KVMDomain `xml:"domain"`
}

type DomStatus struct {
Domains KVMDomain `xml:"domain"`
}

type RUNDomains struct {
DomStatus []DomStatus `xml:"domstatus"`
}

type XMLVPC struct {
UUID string
Name string
Expand Down Expand Up @@ -367,32 +375,57 @@ func ParseVMStates(s string) (map[string]int, error) {
return vmToState, nil
}

func ParseVMXml(s string) ([]XMLVM, error) {
func ParseVMXml(s, nameField string) ([]XMLVM, error) {
var vms []XMLVM
if s == "" {
return vms, nil
}

// ns := "http://openstack.org/xmlns/libvirt/nova/1.0"

var domains KVMDomains
err := xml.Unmarshal([]byte(s), &domains)
var domains []KVMDomain
var etcDomains ETCDomains
err := xml.Unmarshal([]byte(s), &etcDomains)
if err != nil {
return vms, err
}
for _, domain := range domains.Domains {
if len(etcDomains.Domains) != 0 {
domains = etcDomains.Domains
} else {
var runDomains RUNDomains
err := xml.Unmarshal([]byte(s), &runDomains)
if err != nil {
return vms, err
}
for _, d := range runDomains.DomStatus {
domains = append(domains, d.Domains)
}
}
for _, domain := range domains {
var vm XMLVM
if domain.UUID == "" {
log.Warning("vm uuid not found in xml")
continue
}
vm.UUID = domain.UUID
if domain.Name == "" {
log.Warning("vm uuid not found in xml")
continue
}
vm.UUID = domain.UUID
vm.Label = domain.Name
vm.Name = domain.MetaData.Instance.Name
switch nameField {
case "metadata":
vm.Name = domain.MetaData.Instance.Name
case "uuid":
vm.Name = domain.UUID
case "name":
vm.Name = domain.Name
case "title":
vm.Name = domain.Title
default:
log.Warningf("invalid config vm_name_field: (%s)", nameField)
}
if vm.Name == "" {
vm.Name = vm.Label
vm.Name = domain.Name
}
if domain.MetaData.Instance.Owner.Project.UUID != "" {
uuid := domain.MetaData.Instance.Owner.Project.UUID
Expand Down
2 changes: 1 addition & 1 deletion server/controller/genesis/common/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func TestParseVMStates(t *testing.T) {
func TestParseVMXml(t *testing.T) {
XMLStr := `<domains>\n<domain type='kvm'>\n <name>instance-00000064</name>\n <uuid>a51e6527-bd5e-42c2-81be-fee17d814706</uuid>\n <metadata>\n <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0">\n <nova:name>test-vm-liqian</nova:name>\n <nova:owner>\n <nova:user uuid="417a8402bfc64f4abb67f68a8a0fdcff">bangongfuwu</nova:user>\n <nova:project uuid="7e39057dbe2042e4b3b188678f22648e">NSLS</nova:project>\n </nova:owner>\n </nova:instance>\n </metadata>\n <devices>\n <interface type='bridge'>\n <mac address='fa:16:3e:59:b5:10'/>\n <source bridge='qbr155abd89-91'/>\n <target dev='tap155abd89-91'/>\n <model type='virtio'/>\n <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n </interface>\n </devices>\n</domain>\n<!--\nWARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE\nOVERWRITTEN AND LOST. Changes to this xml configuration should be made using:\n virsh edit instance-00000065\nor other application using the libvirt API.\n-->\n<domain type='kvm'>\n <name>instance-00000065</name>\n <uuid>75e9bb32-09c8-48e9-93bc-0330686702f3</uuid>\n <metadata>\n <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0">\n <nova:name>lbq-vm-vxlan-1</nova:name>\n <nova:owner>\n <nova:user uuid="417a8402bfc64f4abb67f68a8a0fdcff">bangongfuwu</nova:user>\n <nova:project uuid="7e39057dbe2042e4b3b188678f22648e">NSLS</nova:project>\n </nova:owner>\n </nova:instance>\n </metadata>\n <devices>\n <interface type='bridge'>\n <mac address='fa:16:3e:38:a5:48'/>\n <source bridge='qbr717a30a1-db'/>\n <target dev='tap717a30a1-db'/>\n <model type='virtio'/>\n <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n </interface>\n <interface type='bridge'>\n <mac address='fa:16:3e:8f:78:2b'/>\n <source bridge='qbr27e9b93c-93'/>\n <target dev='tap27e9b93c-93'/>\n <model type='virtio'/>\n <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>\n </interface>\n </devices>\n</domain>\n</domains>\n`
Convey("TestParseVMXml", t, func() {
xmls, _ := ParseVMXml(XMLStr)
xmls, _ := ParseVMXml(XMLStr, "metadata")
Convey("ParseVMXml items should be equal", func() {
So(len(xmls), ShouldEqual, 2)
So(xmls[0].UUID, ShouldEqual, "a51e6527-bd5e-42c2-81be-fee17d814706")
Expand Down
1 change: 1 addition & 0 deletions server/controller/genesis/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ type GenesisConfig struct {
MultiNSMode bool `default:"false" yaml:"multi_ns_mode"`
SingleVPCMode bool `default:"false" yaml:"single_vpc_mode"`
IgnoreNICRegex string `default:"^(kube-ipvs)" yaml:"ignore_nic_regex"`
VMNameField string `default:"metadata" yaml:"vm_name_field"`
}
4 changes: 3 additions & 1 deletion server/controller/genesis/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type GenesisSyncRpcUpdater struct {
excludeIPRanges []netaddr.IPPrefix
multiNSMode bool
singleVPCMode bool
vmNameField string
ignoreNICRegex *regexp.Regexp
genesisSyncDataByVtap map[string]GenesisSyncDataOperation
}
Expand Down Expand Up @@ -141,6 +142,7 @@ func NewGenesisSyncRpcUpdater(storage *SyncStorage, queue queue.QueueReader, cfg
excludeIPRanges: excludeIPRanges,
multiNSMode: cfg.MultiNSMode,
singleVPCMode: cfg.SingleVPCMode,
vmNameField: cfg.VMNameField,
ignoreNICRegex: ignoreNICRegex,
genesisSyncDataByVtap: map[string]GenesisSyncDataOperation{},
}
Expand Down Expand Up @@ -666,7 +668,7 @@ func (v *GenesisSyncRpcUpdater) ParseKVMPlatformInfo(info VIFRPCMessage, peer st
if err != nil {
log.Warning("parse vm states failed: " + err.Error())
}
xmlVMs, err := genesiscommon.ParseVMXml(rawVM)
xmlVMs, err := genesiscommon.ParseVMXml(rawVM, v.vmNameField)
if err != nil {
log.Warning("parse vm xml failed: " + err.Error())
}
Expand Down
6 changes: 6 additions & 0 deletions server/server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,12 @@ controller:
# 忽略网卡正则表达式配置,匹配到会忽略该网卡,默认为 ^(kube-ipvs) ,增加其他的网卡名称需要在此基础上新增
ignore_nic_regex:

## 采集器同步 KVM ,解析虚拟机的 XML 时,默认为 metadata 即使用 domian.metadata.instance.name 字段作为虚拟机的名称
## 可通过此配置将虚拟机名称指定为 domain.name、domain.title、domain.uuid 之一,默认为空
askyrie marked this conversation as resolved.
Show resolved Hide resolved
## 当使用此配置指定的字段取不到虚拟机名称或虚拟机名称为空时,则将使用 domain.name 的值作为虚拟机名称
## 例:vm_name_field: title ,指定 domain.title 作为虚拟机的名称
#vm_name_field: metadata

prometheus:
# synchronizer cache refresh interval, unit: second
synchronizer_cache_refresh_interval: 60
Expand Down