pax_global_header00006660000000000000000000000064140557325020014515gustar00rootroot0000000000000052 comment=77fd4843edad8d67c3326a1c5df6303434c82ecb libvirt-go-xml-7.4.0/000077500000000000000000000000001405573250200144015ustar00rootroot00000000000000libvirt-go-xml-7.4.0/.github/000077500000000000000000000000001405573250200157415ustar00rootroot00000000000000libvirt-go-xml-7.4.0/.github/lockdown.yml000066400000000000000000000022271405573250200203070ustar00rootroot00000000000000# Configuration for Repo Lockdown - https://github.com/dessant/repo-lockdown skipCreatedBefore: 2020-01-01 # Close issues and pull requests close: true # Lock issues and pull requests lock: true # Optionally, specify configuration settings just for `issues` or `pulls` issues: comment: | Thank you for your interest in the libvirt project. Since this repository is a read-only mirror of the project's master repostory hosted on GitLab, issues opened here are not processed. We kindly request that new issues are reported to https://gitlab.com/libvirt/libvirt-go-xml/-/issues/new Thank you for your time and understanding. pulls: comment: | Thank you for your interest in the libvirt project. Since this repository is a read-only mirror of the project's master repostory hosted on GitLab, merge requests opened here are not processed. We kindly request that contributors fork the project at https://gitlab.com/libvirt/libvirt-go-xml/ push changes to the fork, and then open a new merge request at https://gitlab.com/libvirt/libvirt-go-xml/-/merge_requests/new Thank you for your time and understanding. libvirt-go-xml-7.4.0/.gitignore000066400000000000000000000000301405573250200163620ustar00rootroot00000000000000*~ *.bak .\#* testdata/ libvirt-go-xml-7.4.0/.gitlab-ci.yml000066400000000000000000000016651405573250200170450ustar00rootroot00000000000000 stages: - prebuild - build # Check that all commits are signed-off for the DCO. # Skip on "libvirt" namespace, since we only need to run # this test on developer's personal forks from which # merge requests are submitted check-dco: stage: prebuild image: registry.gitlab.com/libvirt/libvirt-ci/check-dco:master script: - /check-dco except: variables: - $CI_PROJECT_NAMESPACE == 'libvirt' go-fmt: stage: prebuild image: registry.gitlab.com/libvirt/libvirt-ci/go-fmt:master script: - /go-fmt artifacts: paths: - go-fmt.patch expire_in: 1 week when: on_failure .go_build: &go_build stage: build script: - go test -timeout 10m -tags xmlroundtrip -v go_1_10: <<: *go_build image: golang:1.10 go_1_11: <<: *go_build image: golang:1.11 go_1_12: <<: *go_build image: golang:1.12 go_1_13: <<: *go_build image: golang:1.13 go_1_14: <<: *go_build image: golang:1.14 libvirt-go-xml-7.4.0/.gitmodules000066400000000000000000000000001405573250200165440ustar00rootroot00000000000000libvirt-go-xml-7.4.0/CONTRIBUTING.rst000066400000000000000000000017731405573250200170520ustar00rootroot00000000000000============================== Contributing to libvirt-go-xml ============================== The libvirt Go API binding accepts code contributions via merge requests on the GitLab project: https://gitlab.com/libvirt/libvirt-go-xml/-/merge_requests It is required that automated CI pipelines succeed before a merge request will be accepted. The global pipeline status for the ``master`` branch is visible at: https://gitlab.com/libvirt/libvirt-go-xml/pipelines CI pipeline results for merge requests will be visible via the contributors' own private repository fork: https://gitlab.com/yourusername/libvirt-go-xml/pipelines Contributions submitted to the project must be in compliance with the Developer Certificate of Origin Version 1.1. This is documented at: https://developercertificate.org/ To indicate compliance, each commit in a series must have a "Signed-off-by" tag with the submitter's name and email address. This can be added by passing the ``-s`` flag to ``git commit`` when creating the patches. libvirt-go-xml-7.4.0/LICENSE000066400000000000000000000020171405573250200154060ustar00rootroot00000000000000The MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.libvirt-go-xml-7.4.0/README.rst000066400000000000000000000036761405573250200161040ustar00rootroot00000000000000============== libvirt-go-xml ============== .. image:: https://gitlab.com/libvirt/libvirt-go-xml/badges/master/pipeline.svg :target: https://gitlab.com/libvirt/libvirt-go-xml/pipelines :alt: Build Status .. image:: https://img.shields.io/static/v1?label=godev&message=reference&color=00add8 :target: https://pkg.go.dev/libvirt.org/libvirt-go-xml :alt: API Documentation Go API for manipulating libvirt XML documents This package provides a Go API that defines a set of structs, annotated for use with "encoding/xml", that can represent libvirt XML documents. There is no dependency on the libvirt library itself, so this can be used regardless of the way in which the application talks to libvirt. Documentation ============= * `API documentation for the bindings `_ * `Libvirt XML schema documentation `_ * `capabilities `_ * `domain `_ * `domain capabilities `_ * `domain snapshot `_ * `network `_ * `node device `_ * `nwfilter `_ * `secret `_ * `storage `_ * `storage encryption `_ Contributing ============ The libvirt project aims to add support for new XML elements to libvirt-go-xml as soon as they are added to the main libvirt C library. If you are submitting changes to the libvirt C library that introduce new XML elements, please submit a libvirt-go-xml change at the same time. Bug fixes and other improvements to the libvirt-go-xml library are welcome at any time. For more information, see the `CONTRIBUTING `_ file. libvirt-go-xml-7.4.0/capabilities.go000066400000000000000000000230071405573250200173630ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2016 Red Hat, Inc. * */ package libvirtxml import ( "encoding/xml" ) type CapsHostCPUTopology struct { Sockets int `xml:"sockets,attr"` Cores int `xml:"cores,attr"` Threads int `xml:"threads,attr"` } type CapsHostCPUFeatureFlag struct { Name string `xml:"name,attr"` } type CapsHostCPUPageSize struct { Size int `xml:"size,attr"` Unit string `xml:"unit,attr"` } type CapsHostCPUMicrocode struct { Version int `xml:"version,attr"` } type CapsHostCPU struct { XMLName xml.Name `xml:"cpu"` Arch string `xml:"arch,omitempty"` Model string `xml:"model,omitempty"` Vendor string `xml:"vendor,omitempty"` Topology *CapsHostCPUTopology `xml:"topology"` FeatureFlags []CapsHostCPUFeatureFlag `xml:"feature"` Features *CapsHostCPUFeatures `xml:"features"` PageSizes []CapsHostCPUPageSize `xml:"pages"` Microcode *CapsHostCPUMicrocode `xml:"microcode"` } type CapsHostCPUFeature struct { } type CapsHostCPUFeatures struct { PAE *CapsHostCPUFeature `xml:"pae"` NonPAE *CapsHostCPUFeature `xml:"nonpae"` SVM *CapsHostCPUFeature `xml:"svm"` VMX *CapsHostCPUFeature `xml:"vmx"` } type CapsHostNUMAMemory struct { Size uint64 `xml:",chardata"` Unit string `xml:"unit,attr"` } type CapsHostNUMAPageInfo struct { Size int `xml:"size,attr"` Unit string `xml:"unit,attr"` Count uint64 `xml:",chardata"` } type CapsHostNUMACPU struct { ID int `xml:"id,attr"` SocketID *int `xml:"socket_id,attr"` DieID *int `xml:"die_id,attr"` CoreID *int `xml:"core_id,attr"` Siblings string `xml:"siblings,attr,omitempty"` } type CapsHostNUMASibling struct { ID int `xml:"id,attr"` Value int `xml:"value,attr"` } type CapsHostNUMACell struct { ID int `xml:"id,attr"` Memory *CapsHostNUMAMemory `xml:"memory"` PageInfo []CapsHostNUMAPageInfo `xml:"pages"` Distances *CapsHostNUMADistances `xml:"distances"` CPUS *CapsHostNUMACPUs `xml:"cpus"` } type CapsHostNUMADistances struct { Siblings []CapsHostNUMASibling `xml:"sibling"` } type CapsHostNUMACPUs struct { Num uint `xml:"num,attr,omitempty"` CPUs []CapsHostNUMACPU `xml:"cpu"` } type CapsHostNUMATopology struct { Cells *CapsHostNUMACells `xml:"cells"` } type CapsHostNUMACells struct { Num uint `xml:"num,attr,omitempty"` Cells []CapsHostNUMACell `xml:"cell"` } type CapsHostSecModelLabel struct { Type string `xml:"type,attr"` Value string `xml:",chardata"` } type CapsHostSecModel struct { Name string `xml:"model"` DOI string `xml:"doi"` Labels []CapsHostSecModelLabel `xml:"baselabel"` } type CapsHostMigrationFeatures struct { Live *CapsHostMigrationLive `xml:"live"` URITransports *CapsHostMigrationURITransports `xml:"uri_transports"` } type CapsHostMigrationLive struct { } type CapsHostMigrationURITransports struct { URI []string `xml:"uri_transport"` } type CapsHost struct { UUID string `xml:"uuid,omitempty"` CPU *CapsHostCPU `xml:"cpu"` PowerManagement *CapsHostPowerManagement `xml:"power_management"` IOMMU *CapsHostIOMMU `xml:"iommu"` MigrationFeatures *CapsHostMigrationFeatures `xml:"migration_features"` NUMA *CapsHostNUMATopology `xml:"topology"` Cache *CapsHostCache `xml:"cache"` MemoryBandwidth *CapsHostMemoryBandwidth `xml:"memory_bandwidth"` SecModel []CapsHostSecModel `xml:"secmodel"` } type CapsHostPowerManagement struct { SuspendMem *CapsHostPowerManagementMode `xml:"suspend_mem"` SuspendDisk *CapsHostPowerManagementMode `xml:"suspend_disk"` SuspendHybrid *CapsHostPowerManagementMode `xml:"suspend_hybrid"` } type CapsHostPowerManagementMode struct { } type CapsHostIOMMU struct { Support string `xml:"support,attr"` } type CapsHostCache struct { Banks []CapsHostCacheBank `xml:"bank"` Monitor *CapsHostCacheMonitor `xml:"monitor"` } type CapsHostCacheBank struct { ID uint `xml:"id,attr"` Level uint `xml:"level,attr"` Type string `xml:"type,attr"` Size uint `xml:"size,attr"` Unit string `xml:"unit,attr"` CPUs string `xml:"cpus,attr"` Control []CapsHostCacheControl `xml:"control"` } type CapsHostCacheMonitor struct { Level uint `xml:"level,attr,omitempty"` ResueThreshold uint `xml:"reuseThreshold,attr,omitempty"` MaxMonitors uint `xml:"maxMonitors,attr"` Features []CapsHostCacheMonitorFeature `xml:"feature"` } type CapsHostCacheMonitorFeature struct { Name string `xml:"name,attr"` } type CapsHostCacheControl struct { Granularity uint `xml:"granularity,attr"` Min uint `xml:"min,attr,omitempty"` Unit string `xml:"unit,attr"` Type string `xml:"type,attr"` MaxAllows uint `xml:"maxAllocs,attr"` } type CapsHostMemoryBandwidth struct { Nodes []CapsHostMemoryBandwidthNode `xml:"node"` Monitor *CapsHostMemoryBandwidthMonitor `xml:"monitor"` } type CapsHostMemoryBandwidthNode struct { ID uint `xml:"id,attr"` CPUs string `xml:"cpus,attr"` Control *CapsHostMemoryBandwidthNodeControl `xml:"control"` } type CapsHostMemoryBandwidthNodeControl struct { Granularity uint `xml:"granularity,attr"` Min uint `xml:"min,attr"` MaxAllocs uint `xml:"maxAllocs,attr"` } type CapsHostMemoryBandwidthMonitor struct { MaxMonitors uint `xml:"maxMonitors,attr"` Features []CapsHostMemoryBandwidthMonitorFeature `xml:"feature"` } type CapsHostMemoryBandwidthMonitorFeature struct { Name string `xml:"name,attr"` } type CapsGuestMachine struct { Name string `xml:",chardata"` MaxCPUs int `xml:"maxCpus,attr,omitempty"` Canonical string `xml:"canonical,attr,omitempty"` } type CapsGuestDomain struct { Type string `xml:"type,attr"` Emulator string `xml:"emulator,omitempty"` Machines []CapsGuestMachine `xml:"machine"` } type CapsGuestArch struct { Name string `xml:"name,attr"` WordSize string `xml:"wordsize"` Emulator string `xml:"emulator"` Loader string `xml:"loader,omitempty"` Machines []CapsGuestMachine `xml:"machine"` Domains []CapsGuestDomain `xml:"domain"` } type CapsGuestFeatureCPUSelection struct { } type CapsGuestFeatureDeviceBoot struct { } type CapsGuestFeaturePAE struct { } type CapsGuestFeatureNonPAE struct { } type CapsGuestFeatureDiskSnapshot struct { Default string `xml:"default,attr,omitempty"` Toggle string `xml:"toggle,attr,omitempty"` } type CapsGuestFeatureAPIC struct { Default string `xml:"default,attr,omitempty"` Toggle string `xml:"toggle,attr,omitempty"` } type CapsGuestFeatureACPI struct { Default string `xml:"default,attr,omitempty"` Toggle string `xml:"toggle,attr,omitempty"` } type CapsGuestFeatureIA64BE struct { } type CapsGuestFeatures struct { CPUSelection *CapsGuestFeatureCPUSelection `xml:"cpuselection"` DeviceBoot *CapsGuestFeatureDeviceBoot `xml:"deviceboot"` DiskSnapshot *CapsGuestFeatureDiskSnapshot `xml:"disksnapshot"` PAE *CapsGuestFeaturePAE `xml:"pae"` NonPAE *CapsGuestFeatureNonPAE `xml:"nonpae"` APIC *CapsGuestFeatureAPIC `xml:"apic"` ACPI *CapsGuestFeatureACPI `xml:"acpi"` IA64BE *CapsGuestFeatureIA64BE `xml:"ia64_be"` } type CapsGuest struct { OSType string `xml:"os_type"` Arch CapsGuestArch `xml:"arch"` Features *CapsGuestFeatures `xml:"features"` } type Caps struct { XMLName xml.Name `xml:"capabilities"` Host CapsHost `xml:"host"` Guests []CapsGuest `xml:"guest"` } func (c *CapsHostCPU) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), c) } func (c *CapsHostCPU) Marshal() (string, error) { doc, err := xml.MarshalIndent(c, "", " ") if err != nil { return "", err } return string(doc), nil } func (c *Caps) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), c) } func (c *Caps) Marshal() (string, error) { doc, err := xml.MarshalIndent(c, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/doc.go000066400000000000000000000047261405573250200155060ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ // Package libvirt-go-xml defines structs for parsing libvirt XML schemas // // The libvirt API uses XML schemas/documents to describe the configuration // of many of its managed objects. Thus when using the libvirt-go package, // it is often neccessary to either parse or format XML documents. This // package defines a set of Go structs which have been annotated for use // with the encoding/xml API to manage libvirt XML documents. // // Example creating a domain XML document from configuration: // // package main // // import ( // "libvirt.org/libvirt-go-xml" // ) // // func main() { // domcfg := &libvirtxml.Domain{Type: "kvm", Name: "demo", // UUID: "8f99e332-06c4-463a-9099-330fb244e1b3", // ....} // xmldoc, err := domcfg.Marshal() // } // // Example parsing a domainXML document, in combination with libvirt-go // // package main // // import ( // "libvirt.org/libvirt-go" // "libvirt.org/libvirt-go-xml" // "fmt" // ) // // func main() { // conn, err := libvirt.NewConnect("qemu:///system") // dom, err := conn.LookupDomainByName("demo") // xmldoc, err := dom.GetXMLDesc(0) // // domcfg := &libvirtxml.Domain{} // err = domcfg.Unmarshal(xmldoc) // // fmt.Printf("Virt type %s\n", domcfg.Type) // } // package libvirtxml libvirt-go-xml-7.4.0/document.go000066400000000000000000000001501405573250200165420ustar00rootroot00000000000000package libvirtxml type Document interface { Unmarshal(doc string) error Marshal() (string, error) } libvirt-go-xml-7.4.0/domain.go000066400000000000000000005370201405573250200162060ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2016 Red Hat, Inc. * */ package libvirtxml import ( "encoding/xml" "fmt" "io" "strconv" "strings" ) type DomainControllerPCIHole64 struct { Size uint64 `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` } type DomainControllerPCIModel struct { Name string `xml:"name,attr"` } type DomainControllerPCITarget struct { ChassisNr *uint Chassis *uint Port *uint BusNr *uint Index *uint NUMANode *uint Hotplug string } type DomainControllerPCI struct { Model *DomainControllerPCIModel `xml:"model"` Target *DomainControllerPCITarget `xml:"target"` Hole64 *DomainControllerPCIHole64 `xml:"pcihole64"` } type DomainControllerUSBMaster struct { StartPort uint `xml:"startport,attr"` } type DomainControllerUSB struct { Port *uint `xml:"ports,attr"` Master *DomainControllerUSBMaster `xml:"master"` } type DomainControllerVirtIOSerial struct { Ports *uint `xml:"ports,attr"` Vectors *uint `xml:"vectors,attr"` } type DomainControllerXenBus struct { MaxGrantFrames uint `xml:"maxGrantFrames,attr,omitempty"` MaxEventChannels uint `xml:"maxEventChannels,attr,omitempty"` } type DomainControllerDriver struct { Queues *uint `xml:"queues,attr"` CmdPerLUN *uint `xml:"cmd_per_lun,attr"` MaxSectors *uint `xml:"max_sectors,attr"` IOEventFD string `xml:"ioeventfd,attr,omitempty"` IOThread uint `xml:"iothread,attr,omitempty"` IOMMU string `xml:"iommu,attr,omitempty"` ATS string `xml:"ats,attr,omitempty"` Packed string `xml:"packed,attr,omitempty"` } type DomainController struct { XMLName xml.Name `xml:"controller"` Type string `xml:"type,attr"` Index *uint `xml:"index,attr"` Model string `xml:"model,attr,omitempty"` Driver *DomainControllerDriver `xml:"driver"` PCI *DomainControllerPCI `xml:"-"` USB *DomainControllerUSB `xml:"-"` VirtIOSerial *DomainControllerVirtIOSerial `xml:"-"` XenBus *DomainControllerXenBus `xml:"-"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainDiskSecret struct { Type string `xml:"type,attr,omitempty"` Usage string `xml:"usage,attr,omitempty"` UUID string `xml:"uuid,attr,omitempty"` } type DomainDiskAuth struct { Username string `xml:"username,attr,omitempty"` Secret *DomainDiskSecret `xml:"secret"` } type DomainDiskSourceHost struct { Transport string `xml:"transport,attr,omitempty"` Name string `xml:"name,attr,omitempty"` Port string `xml:"port,attr,omitempty"` Socket string `xml:"socket,attr,omitempty"` } type DomainDiskSourceSSL struct { Verify string `xml:"verify,attr"` } type DomainDiskCookie struct { Name string `xml:"name,attr"` Value string `xml:",chardata"` } type DomainDiskCookies struct { Cookies []DomainDiskCookie `xml:"cookie"` } type DomainDiskSourceReadahead struct { Size string `xml:"size,attr"` } type DomainDiskSourceTimeout struct { Seconds string `xml:"seconds,attr"` } type DomainDiskReservationsSource DomainChardevSource type DomainDiskReservations struct { Enabled string `xml:"enabled,attr,omitempty"` Managed string `xml:"managed,attr,omitempty"` Source *DomainDiskReservationsSource `xml:"source"` } type DomainDiskSource struct { File *DomainDiskSourceFile `xml:"-"` Block *DomainDiskSourceBlock `xml:"-"` Dir *DomainDiskSourceDir `xml:"-"` Network *DomainDiskSourceNetwork `xml:"-"` Volume *DomainDiskSourceVolume `xml:"-"` NVME *DomainDiskSourceNVME `xml:"-"` VHostUser *DomainDiskSourceVHostUser `xml:"-"` StartupPolicy string `xml:"startupPolicy,attr,omitempty"` Index uint `xml:"index,attr,omitempty"` Encryption *DomainDiskEncryption `xml:"encryption"` Reservations *DomainDiskReservations `xml:"reservations"` Slices *DomainDiskSlices `xml:"slices"` SSL *DomainDiskSourceSSL `xml:"ssl"` Cookies *DomainDiskCookies `xml:"cookies"` Readahead *DomainDiskSourceReadahead `xml:"readahead"` Timeout *DomainDiskSourceTimeout `xml:"timeout"` } type DomainDiskSlices struct { Slices []DomainDiskSlice `xml:"slice"` } type DomainDiskSlice struct { Type string `xml:"type,attr"` Offset uint `xml:"offset,attr"` Size uint `xml:"size,attr"` } type DomainDiskSourceFile struct { File string `xml:"file,attr,omitempty"` SecLabel []DomainDeviceSecLabel `xml:"seclabel"` } type DomainDiskSourceNVME struct { PCI *DomainDiskSourceNVMEPCI } type DomainDiskSourceNVMEPCI struct { Managed string `xml:"managed,attr,omitempty"` Namespace uint64 `xml:"namespace,attr,omitempty"` Address *DomainAddressPCI `xml:"address"` } type DomainDiskSourceBlock struct { Dev string `xml:"dev,attr,omitempty"` SecLabel []DomainDeviceSecLabel `xml:"seclabel"` } type DomainDiskSourceDir struct { Dir string `xml:"dir,attr,omitempty"` } type DomainDiskSourceNetwork struct { Protocol string `xml:"protocol,attr,omitempty"` Name string `xml:"name,attr,omitempty"` Query string `xml:"query,attr,omitempty"` TLS string `xml:"tls,attr,omitempty"` Hosts []DomainDiskSourceHost `xml:"host"` Identity *DomainDiskSourceNetworkIdentity `xml:"identity"` Initiator *DomainDiskSourceNetworkInitiator `xml:"initiator"` Snapshot *DomainDiskSourceNetworkSnapshot `xml:"snapshot"` Config *DomainDiskSourceNetworkConfig `xml:"config"` Auth *DomainDiskAuth `xml:"auth"` } type DomainDiskSourceNetworkIdentity struct { User string `xml:"user,attr"` Group string `xml:"group,attr"` } type DomainDiskSourceNetworkInitiator struct { IQN *DomainDiskSourceNetworkIQN `xml:"iqn"` } type DomainDiskSourceNetworkIQN struct { Name string `xml:"name,attr,omitempty"` } type DomainDiskSourceNetworkSnapshot struct { Name string `xml:"name,attr"` } type DomainDiskSourceNetworkConfig struct { File string `xml:"file,attr"` } type DomainDiskSourceVolume struct { Pool string `xml:"pool,attr,omitempty"` Volume string `xml:"volume,attr,omitempty"` Mode string `xml:"mode,attr,omitempty"` SecLabel []DomainDeviceSecLabel `xml:"seclabel"` } type DomainDiskSourceVHostUser DomainChardevSource type DomainDiskMetadataCache struct { MaxSize *DomainDiskMetadataCacheSize `xml:"max_size"` } type DomainDiskMetadataCacheSize struct { Unit string `xml:"unit,attr,omitempty"` Value int `xml:",cdata"` } type DomainDiskDriver struct { Name string `xml:"name,attr,omitempty"` Type string `xml:"type,attr,omitempty"` Cache string `xml:"cache,attr,omitempty"` ErrorPolicy string `xml:"error_policy,attr,omitempty"` RErrorPolicy string `xml:"rerror_policy,attr,omitempty"` IO string `xml:"io,attr,omitempty"` IOEventFD string `xml:"ioeventfd,attr,omitempty"` EventIDX string `xml:"event_idx,attr,omitempty"` CopyOnRead string `xml:"copy_on_read,attr,omitempty"` Discard string `xml:"discard,attr,omitempty"` IOThread *uint `xml:"iothread,attr"` DetectZeros string `xml:"detect_zeroes,attr,omitempty"` Queues *uint `xml:"queues,attr"` IOMMU string `xml:"iommu,attr,omitempty"` ATS string `xml:"ats,attr,omitempty"` Packed string `xml:"packed,attr,omitempty"` MetadataCache *DomainDiskMetadataCache `xml:"metadata_cache"` } type DomainDiskTarget struct { Dev string `xml:"dev,attr,omitempty"` Bus string `xml:"bus,attr,omitempty"` Tray string `xml:"tray,attr,omitempty"` Removable string `xml:"removable,attr,omitempty"` RotationRate uint `xml:"rotation_rate,attr,omitempty"` } type DomainDiskEncryption struct { Format string `xml:"format,attr,omitempty"` Secret *DomainDiskSecret `xml:"secret"` } type DomainDiskReadOnly struct { } type DomainDiskShareable struct { } type DomainDiskTransient struct { ShareBacking string `xml:"shareBacking,attr,omitempty"` } type DomainDiskIOTune struct { TotalBytesSec uint64 `xml:"total_bytes_sec,omitempty"` ReadBytesSec uint64 `xml:"read_bytes_sec,omitempty"` WriteBytesSec uint64 `xml:"write_bytes_sec,omitempty"` TotalIopsSec uint64 `xml:"total_iops_sec,omitempty"` ReadIopsSec uint64 `xml:"read_iops_sec,omitempty"` WriteIopsSec uint64 `xml:"write_iops_sec,omitempty"` TotalBytesSecMax uint64 `xml:"total_bytes_sec_max,omitempty"` ReadBytesSecMax uint64 `xml:"read_bytes_sec_max,omitempty"` WriteBytesSecMax uint64 `xml:"write_bytes_sec_max,omitempty"` TotalIopsSecMax uint64 `xml:"total_iops_sec_max,omitempty"` ReadIopsSecMax uint64 `xml:"read_iops_sec_max,omitempty"` WriteIopsSecMax uint64 `xml:"write_iops_sec_max,omitempty"` TotalBytesSecMaxLength uint64 `xml:"total_bytes_sec_max_length,omitempty"` ReadBytesSecMaxLength uint64 `xml:"read_bytes_sec_max_length,omitempty"` WriteBytesSecMaxLength uint64 `xml:"write_bytes_sec_max_length,omitempty"` TotalIopsSecMaxLength uint64 `xml:"total_iops_sec_max_length,omitempty"` ReadIopsSecMaxLength uint64 `xml:"read_iops_sec_max_length,omitempty"` WriteIopsSecMaxLength uint64 `xml:"write_iops_sec_max_length,omitempty"` SizeIopsSec uint64 `xml:"size_iops_sec,omitempty"` GroupName string `xml:"group_name,omitempty"` } type DomainDiskGeometry struct { Cylinders uint `xml:"cyls,attr"` Headers uint `xml:"heads,attr"` Sectors uint `xml:"secs,attr"` Trans string `xml:"trans,attr,omitempty"` } type DomainDiskBlockIO struct { LogicalBlockSize uint `xml:"logical_block_size,attr,omitempty"` PhysicalBlockSize uint `xml:"physical_block_size,attr,omitempty"` } type DomainDiskFormat struct { Type string `xml:"type,attr"` MetadataCache *DomainDiskMetadataCache `xml:"metadata_cache"` } type DomainDiskBackingStore struct { Index uint `xml:"index,attr,omitempty"` Format *DomainDiskFormat `xml:"format"` Source *DomainDiskSource `xml:"source"` BackingStore *DomainDiskBackingStore `xml:"backingStore"` } type DomainDiskMirror struct { Job string `xml:"job,attr,omitempty"` Ready string `xml:"ready,attr,omitempty"` Format *DomainDiskFormat `xml:"format"` Source *DomainDiskSource `xml:"source"` BackingStore *DomainDiskBackingStore `xml:"backingStore"` } type DomainBackendDomain struct { Name string `xml:"name,attr"` } type DomainDisk struct { XMLName xml.Name `xml:"disk"` Device string `xml:"device,attr,omitempty"` RawIO string `xml:"rawio,attr,omitempty"` SGIO string `xml:"sgio,attr,omitempty"` Snapshot string `xml:"snapshot,attr,omitempty"` Model string `xml:"model,attr,omitempty"` Driver *DomainDiskDriver `xml:"driver"` Auth *DomainDiskAuth `xml:"auth"` Source *DomainDiskSource `xml:"source"` BackingStore *DomainDiskBackingStore `xml:"backingStore"` BackendDomain *DomainBackendDomain `xml:"backenddomain"` Geometry *DomainDiskGeometry `xml:"geometry"` BlockIO *DomainDiskBlockIO `xml:"blockio"` Mirror *DomainDiskMirror `xml:"mirror"` Target *DomainDiskTarget `xml:"target"` IOTune *DomainDiskIOTune `xml:"iotune"` ReadOnly *DomainDiskReadOnly `xml:"readonly"` Shareable *DomainDiskShareable `xml:"shareable"` Transient *DomainDiskTransient `xml:"transient"` Serial string `xml:"serial,omitempty"` WWN string `xml:"wwn,omitempty"` Vendor string `xml:"vendor,omitempty"` Product string `xml:"product,omitempty"` Encryption *DomainDiskEncryption `xml:"encryption"` Boot *DomainDeviceBoot `xml:"boot"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainFilesystemDriver struct { Type string `xml:"type,attr,omitempty"` Format string `xml:"format,attr,omitempty"` Name string `xml:"name,attr,omitempty"` WRPolicy string `xml:"wrpolicy,attr,omitempty"` IOMMU string `xml:"iommu,attr,omitempty"` ATS string `xml:"ats,attr,omitempty"` Packed string `xml:"packed,attr,omitempty"` Queue uint `xml:"queue,attr,omitempty"` } type DomainFilesystemSource struct { Mount *DomainFilesystemSourceMount `xml:"-"` Block *DomainFilesystemSourceBlock `xml:"-"` File *DomainFilesystemSourceFile `xml:"-"` Template *DomainFilesystemSourceTemplate `xml:"-"` RAM *DomainFilesystemSourceRAM `xml:"-"` Bind *DomainFilesystemSourceBind `xml:"-"` Volume *DomainFilesystemSourceVolume `xml:"-"` } type DomainFilesystemSourceMount struct { Dir string `xml:"dir,attr,omitempty"` Socket string `xml:"socket,attr,omitempty"` } type DomainFilesystemSourceBlock struct { Dev string `xml:"dev,attr"` } type DomainFilesystemSourceFile struct { File string `xml:"file,attr"` } type DomainFilesystemSourceTemplate struct { Name string `xml:"name,attr"` } type DomainFilesystemSourceRAM struct { Usage uint `xml:"usage,attr"` Units string `xml:"units,attr,omitempty"` } type DomainFilesystemSourceBind struct { Dir string `xml:"dir,attr"` } type DomainFilesystemSourceVolume struct { Pool string `xml:"pool,attr"` Volume string `xml:"volume,attr"` } type DomainFilesystemTarget struct { Dir string `xml:"dir,attr"` } type DomainFilesystemReadOnly struct { } type DomainFilesystemSpaceHardLimit struct { Value uint `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` } type DomainFilesystemSpaceSoftLimit struct { Value uint `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` } type DomainFilesystemBinaryCache struct { Mode string `xml:"mode,attr"` } type DomainFilesystemBinarySandbox struct { Mode string `xml:"mode,attr"` } type DomainFilesystemBinaryLock struct { POSIX string `xml:"posix,attr,omitempty"` Flock string `xml:"flock,attr,omitempty"` } type DomainFilesystemBinary struct { Path string `xml:"path,attr,omitempty"` XAttr string `xml:"xattr,attr,omitempty"` Cache *DomainFilesystemBinaryCache `xml:"cache"` Sandbox *DomainFilesystemBinarySandbox `xml:"sandbox"` Lock *DomainFilesystemBinaryLock `xml:"lock"` } type DomainFilesystem struct { XMLName xml.Name `xml:"filesystem"` AccessMode string `xml:"accessmode,attr,omitempty"` Model string `xml:"model,attr,omitempty"` MultiDevs string `xml:"multidevs,attr,omitempty"` FMode string `xml:"fmode,attr,omitempty"` DMode string `xml:"dmode,attr,omitempty"` Driver *DomainFilesystemDriver `xml:"driver"` Binary *DomainFilesystemBinary `xml:"binary"` Source *DomainFilesystemSource `xml:"source"` Target *DomainFilesystemTarget `xml:"target"` ReadOnly *DomainFilesystemReadOnly `xml:"readonly"` SpaceHardLimit *DomainFilesystemSpaceHardLimit `xml:"space_hard_limit"` SpaceSoftLimit *DomainFilesystemSpaceSoftLimit `xml:"space_soft_limit"` Boot *DomainDeviceBoot `xml:"boot"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainInterfaceMAC struct { Address string `xml:"address,attr"` Type string `xml:"type,attr,omitempty"` Check string `xml:"check,attr,omitempty"` } type DomainInterfaceModel struct { Type string `xml:"type,attr"` } type DomainInterfaceSource struct { User *DomainInterfaceSourceUser `xml:"-"` Ethernet *DomainInterfaceSourceEthernet `xml:"-"` VHostUser *DomainChardevSource `xml:"-"` Server *DomainInterfaceSourceServer `xml:"-"` Client *DomainInterfaceSourceClient `xml:"-"` MCast *DomainInterfaceSourceMCast `xml:"-"` Network *DomainInterfaceSourceNetwork `xml:"-"` Bridge *DomainInterfaceSourceBridge `xml:"-"` Internal *DomainInterfaceSourceInternal `xml:"-"` Direct *DomainInterfaceSourceDirect `xml:"-"` Hostdev *DomainInterfaceSourceHostdev `xml:"-"` UDP *DomainInterfaceSourceUDP `xml:"-"` VDPA *DomainInterfaceSourceVDPA `xml:"-"` } type DomainInterfaceSourceUser struct { } type DomainInterfaceSourceEthernet struct { IP []DomainInterfaceIP `xml:"ip"` Route []DomainInterfaceRoute `xml:"route"` } type DomainInterfaceSourceServer struct { Address string `xml:"address,attr,omitempty"` Port uint `xml:"port,attr,omitempty"` Local *DomainInterfaceSourceLocal `xml:"local"` } type DomainInterfaceSourceClient struct { Address string `xml:"address,attr,omitempty"` Port uint `xml:"port,attr,omitempty"` Local *DomainInterfaceSourceLocal `xml:"local"` } type DomainInterfaceSourceMCast struct { Address string `xml:"address,attr,omitempty"` Port uint `xml:"port,attr,omitempty"` Local *DomainInterfaceSourceLocal `xml:"local"` } type DomainInterfaceSourceNetwork struct { Network string `xml:"network,attr,omitempty"` PortGroup string `xml:"portgroup,attr,omitempty"` Bridge string `xml:"bridge,attr,omitempty"` PortID string `xml:"portid,attr,omitempty"` } type DomainInterfaceSourceBridge struct { Bridge string `xml:"bridge,attr"` } type DomainInterfaceSourceInternal struct { Name string `xml:"name,attr,omitempty"` } type DomainInterfaceSourceDirect struct { Dev string `xml:"dev,attr,omitempty"` Mode string `xml:"mode,attr,omitempty"` } type DomainInterfaceSourceHostdev struct { PCI *DomainHostdevSubsysPCISource `xml:"-"` USB *DomainHostdevSubsysUSBSource `xml:"-"` } type DomainInterfaceSourceUDP struct { Address string `xml:"address,attr,omitempty"` Port uint `xml:"port,attr,omitempty"` Local *DomainInterfaceSourceLocal `xml:"local"` } type DomainInterfaceSourceVDPA struct { Device string `xml:"dev,attr,omitempty"` } type DomainInterfaceSourceLocal struct { Address string `xml:"address,attr,omitempty"` Port uint `xml:"port,attr,omitempty"` } type DomainInterfaceTarget struct { Dev string `xml:"dev,attr"` Managed string `xml:"managed,attr,omitempty"` } type DomainInterfaceLink struct { State string `xml:"state,attr"` } type DomainDeviceBoot struct { Order uint `xml:"order,attr"` LoadParm string `xml:"loadparm,attr,omitempty"` } type DomainInterfaceScript struct { Path string `xml:"path,attr"` } type DomainInterfaceDriver struct { Name string `xml:"name,attr,omitempty"` TXMode string `xml:"txmode,attr,omitempty"` IOEventFD string `xml:"ioeventfd,attr,omitempty"` EventIDX string `xml:"event_idx,attr,omitempty"` Queues uint `xml:"queues,attr,omitempty"` RXQueueSize uint `xml:"rx_queue_size,attr,omitempty"` TXQueueSize uint `xml:"tx_queue_size,attr,omitempty"` IOMMU string `xml:"iommu,attr,omitempty"` ATS string `xml:"ats,attr,omitempty"` Packed string `xml:"packed,attr,omitempty"` Host *DomainInterfaceDriverHost `xml:"host"` Guest *DomainInterfaceDriverGuest `xml:"guest"` } type DomainInterfaceDriverHost struct { CSum string `xml:"csum,attr,omitempty"` GSO string `xml:"gso,attr,omitempty"` TSO4 string `xml:"tso4,attr,omitempty"` TSO6 string `xml:"tso6,attr,omitempty"` ECN string `xml:"ecn,attr,omitempty"` UFO string `xml:"ufo,attr,omitempty"` MrgRXBuf string `xml:"mrg_rxbuf,attr,omitempty"` } type DomainInterfaceDriverGuest struct { CSum string `xml:"csum,attr,omitempty"` TSO4 string `xml:"tso4,attr,omitempty"` TSO6 string `xml:"tso6,attr,omitempty"` ECN string `xml:"ecn,attr,omitempty"` UFO string `xml:"ufo,attr,omitempty"` } type DomainInterfaceVirtualPort struct { Params *DomainInterfaceVirtualPortParams `xml:"parameters"` } type DomainInterfaceVirtualPortParams struct { Any *DomainInterfaceVirtualPortParamsAny `xml:"-"` VEPA8021QBG *DomainInterfaceVirtualPortParamsVEPA8021QBG `xml:"-"` VNTag8011QBH *DomainInterfaceVirtualPortParamsVNTag8021QBH `xml:"-"` OpenVSwitch *DomainInterfaceVirtualPortParamsOpenVSwitch `xml:"-"` MidoNet *DomainInterfaceVirtualPortParamsMidoNet `xml:"-"` } type DomainInterfaceVirtualPortParamsAny struct { ManagerID *uint `xml:"managerid,attr"` TypeID *uint `xml:"typeid,attr"` TypeIDVersion *uint `xml:"typeidversion,attr"` InstanceID string `xml:"instanceid,attr,omitempty"` ProfileID string `xml:"profileid,attr,omitempty"` InterfaceID string `xml:"interfaceid,attr,omitempty"` } type DomainInterfaceVirtualPortParamsVEPA8021QBG struct { ManagerID *uint `xml:"managerid,attr"` TypeID *uint `xml:"typeid,attr"` TypeIDVersion *uint `xml:"typeidversion,attr"` InstanceID string `xml:"instanceid,attr,omitempty"` } type DomainInterfaceVirtualPortParamsVNTag8021QBH struct { ProfileID string `xml:"profileid,attr,omitempty"` } type DomainInterfaceVirtualPortParamsOpenVSwitch struct { InterfaceID string `xml:"interfaceid,attr,omitempty"` ProfileID string `xml:"profileid,attr,omitempty"` } type DomainInterfaceVirtualPortParamsMidoNet struct { InterfaceID string `xml:"interfaceid,attr,omitempty"` } type DomainInterfaceBandwidthParams struct { Average *int `xml:"average,attr"` Peak *int `xml:"peak,attr"` Burst *int `xml:"burst,attr"` Floor *int `xml:"floor,attr"` } type DomainInterfaceBandwidth struct { Inbound *DomainInterfaceBandwidthParams `xml:"inbound"` Outbound *DomainInterfaceBandwidthParams `xml:"outbound"` } type DomainInterfaceVLan struct { Trunk string `xml:"trunk,attr,omitempty"` Tags []DomainInterfaceVLanTag `xml:"tag"` } type DomainInterfaceVLanTag struct { ID uint `xml:"id,attr"` NativeMode string `xml:"nativeMode,attr,omitempty"` } type DomainInterfaceGuest struct { Dev string `xml:"dev,attr,omitempty"` Actual string `xml:"actual,attr,omitempty"` } type DomainInterfaceFilterRef struct { Filter string `xml:"filter,attr"` Parameters []DomainInterfaceFilterParam `xml:"parameter"` } type DomainInterfaceFilterParam struct { Name string `xml:"name,attr"` Value string `xml:"value,attr"` } type DomainInterfaceBackend struct { Tap string `xml:"tap,attr,omitempty"` VHost string `xml:"vhost,attr,omitempty"` } type DomainInterfaceTune struct { SndBuf uint `xml:"sndbuf"` } type DomainInterfaceMTU struct { Size uint `xml:"size,attr"` } type DomainInterfaceCoalesce struct { RX *DomainInterfaceCoalesceRX `xml:"rx"` } type DomainInterfaceCoalesceRX struct { Frames *DomainInterfaceCoalesceRXFrames `xml:"frames"` } type DomainInterfaceCoalesceRXFrames struct { Max *uint `xml:"max,attr"` } type DomainROM struct { Bar string `xml:"bar,attr,omitempty"` File string `xml:"file,attr,omitempty"` Enabled string `xml:"enabled,attr,omitempty"` } type DomainInterfaceIP struct { Address string `xml:"address,attr"` Family string `xml:"family,attr,omitempty"` Prefix uint `xml:"prefix,attr,omitempty"` Peer string `xml:"peer,attr,omitempty"` } type DomainInterfaceRoute struct { Family string `xml:"family,attr,omitempty"` Address string `xml:"address,attr"` Netmask string `xml:"netmask,attr,omitempty"` Prefix uint `xml:"prefix,attr,omitempty"` Gateway string `xml:"gateway,attr"` Metric uint `xml:"metric,attr,omitempty"` } type DomainInterfaceTeaming struct { Type string `xml:"type,attr"` Persistent string `xml:"persistent,attr,omitempty"` } type DomainInterfacePortOptions struct { Isolated string `xml:"isolated,attr,omitempty"` } type DomainInterface struct { XMLName xml.Name `xml:"interface"` Managed string `xml:"managed,attr,omitempty"` TrustGuestRXFilters string `xml:"trustGuestRxFilters,attr,omitempty"` MAC *DomainInterfaceMAC `xml:"mac"` Source *DomainInterfaceSource `xml:"source"` Boot *DomainDeviceBoot `xml:"boot"` VLan *DomainInterfaceVLan `xml:"vlan"` VirtualPort *DomainInterfaceVirtualPort `xml:"virtualport"` IP []DomainInterfaceIP `xml:"ip"` Route []DomainInterfaceRoute `xml:"route"` Script *DomainInterfaceScript `xml:"script"` DownScript *DomainInterfaceScript `xml:"downscript"` BackendDomain *DomainBackendDomain `xml:"backenddomain"` Target *DomainInterfaceTarget `xml:"target"` Guest *DomainInterfaceGuest `xml:"guest"` Model *DomainInterfaceModel `xml:"model"` Driver *DomainInterfaceDriver `xml:"driver"` Backend *DomainInterfaceBackend `xml:"backend"` FilterRef *DomainInterfaceFilterRef `xml:"filterref"` Tune *DomainInterfaceTune `xml:"tune"` Teaming *DomainInterfaceTeaming `xml:"teaming"` Link *DomainInterfaceLink `xml:"link"` MTU *DomainInterfaceMTU `xml:"mtu"` Bandwidth *DomainInterfaceBandwidth `xml:"bandwidth"` PortOptions *DomainInterfacePortOptions `xml:"port"` Coalesce *DomainInterfaceCoalesce `xml:"coalesce"` ROM *DomainROM `xml:"rom"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainChardevSource struct { Null *DomainChardevSourceNull `xml:"-"` VC *DomainChardevSourceVC `xml:"-"` Pty *DomainChardevSourcePty `xml:"-"` Dev *DomainChardevSourceDev `xml:"-"` File *DomainChardevSourceFile `xml:"-"` Pipe *DomainChardevSourcePipe `xml:"-"` StdIO *DomainChardevSourceStdIO `xml:"-"` UDP *DomainChardevSourceUDP `xml:"-"` TCP *DomainChardevSourceTCP `xml:"-"` UNIX *DomainChardevSourceUNIX `xml:"-"` SpiceVMC *DomainChardevSourceSpiceVMC `xml:"-"` SpicePort *DomainChardevSourceSpicePort `xml:"-"` NMDM *DomainChardevSourceNMDM `xml:"-"` } type DomainChardevSourceNull struct { } type DomainChardevSourceVC struct { } type DomainChardevSourcePty struct { Path string `xml:"path,attr"` SecLabel []DomainDeviceSecLabel `xml:"seclabel"` } type DomainChardevSourceDev struct { Path string `xml:"path,attr"` SecLabel []DomainDeviceSecLabel `xml:"seclabel"` } type DomainChardevSourceFile struct { Path string `xml:"path,attr"` Append string `xml:"append,attr,omitempty"` SecLabel []DomainDeviceSecLabel `xml:"seclabel"` } type DomainChardevSourcePipe struct { Path string `xml:"path,attr"` SecLabel []DomainDeviceSecLabel `xml:"seclabel"` } type DomainChardevSourceStdIO struct { } type DomainChardevSourceUDP struct { BindHost string `xml:"-"` BindService string `xml:"-"` ConnectHost string `xml:"-"` ConnectService string `xml:"-"` } type DomainChardevSourceReconnect struct { Enabled string `xml:"enabled,attr"` Timeout *uint `xml:"timeout,attr"` } type DomainChardevSourceTCP struct { Mode string `xml:"mode,attr,omitempty"` Host string `xml:"host,attr,omitempty"` Service string `xml:"service,attr,omitempty"` TLS string `xml:"tls,attr,omitempty"` Reconnect *DomainChardevSourceReconnect `xml:"reconnect"` } type DomainChardevSourceUNIX struct { Mode string `xml:"mode,attr,omitempty"` Path string `xml:"path,attr,omitempty"` Reconnect *DomainChardevSourceReconnect `xml:"reconnect"` SecLabel []DomainDeviceSecLabel `xml:"seclabel"` } type DomainChardevSourceSpiceVMC struct { } type DomainChardevSourceSpicePort struct { Channel string `xml:"channel,attr"` } type DomainChardevSourceNMDM struct { Master string `xml:"master,attr"` Slave string `xml:"slave,attr"` } type DomainChardevTarget struct { Type string `xml:"type,attr,omitempty"` Name string `xml:"name,attr,omitempty"` State string `xml:"state,attr,omitempty"` // is guest agent connected? Port *uint `xml:"port,attr"` } type DomainConsoleTarget struct { Type string `xml:"type,attr,omitempty"` Port *uint `xml:"port,attr"` } type DomainSerialTarget struct { Type string `xml:"type,attr,omitempty"` Port *uint `xml:"port,attr"` Model *DomainSerialTargetModel `xml:"model"` } type DomainSerialTargetModel struct { Name string `xml:"name,attr,omitempty"` } type DomainParallelTarget struct { Type string `xml:"type,attr,omitempty"` Port *uint `xml:"port,attr"` } type DomainChannelTarget struct { VirtIO *DomainChannelTargetVirtIO `xml:"-"` Xen *DomainChannelTargetXen `xml:"-"` GuestFWD *DomainChannelTargetGuestFWD `xml:"-"` } type DomainChannelTargetVirtIO struct { Name string `xml:"name,attr,omitempty"` State string `xml:"state,attr,omitempty"` // is guest agent connected? } type DomainChannelTargetXen struct { Name string `xml:"name,attr,omitempty"` State string `xml:"state,attr,omitempty"` // is guest agent connected? } type DomainChannelTargetGuestFWD struct { Address string `xml:"address,attr,omitempty"` Port string `xml:"port,attr,omitempty"` } type DomainAlias struct { Name string `xml:"name,attr"` } type DomainDeviceACPI struct { Index uint `xml:"index,attr,omitempty"` } type DomainAddressPCI struct { Domain *uint `xml:"domain,attr"` Bus *uint `xml:"bus,attr"` Slot *uint `xml:"slot,attr"` Function *uint `xml:"function,attr"` MultiFunction string `xml:"multifunction,attr,omitempty"` ZPCI *DomainAddressZPCI `xml:"zpci"` } type DomainAddressZPCI struct { UID *uint `xml:"uid,attr,omitempty"` FID *uint `xml:"fid,attr,omitempty"` } type DomainAddressUSB struct { Bus *uint `xml:"bus,attr"` Port string `xml:"port,attr,omitempty"` Device *uint `xml:"device,attr"` } type DomainAddressDrive struct { Controller *uint `xml:"controller,attr"` Bus *uint `xml:"bus,attr"` Target *uint `xml:"target,attr"` Unit *uint `xml:"unit,attr"` } type DomainAddressDIMM struct { Slot *uint `xml:"slot,attr"` Base *uint64 `xml:"base,attr"` } type DomainAddressISA struct { IOBase *uint `xml:"iobase,attr"` IRQ *uint `xml:"irq,attr"` } type DomainAddressVirtioMMIO struct { } type DomainAddressCCW struct { CSSID *uint `xml:"cssid,attr"` SSID *uint `xml:"ssid,attr"` DevNo *uint `xml:"devno,attr"` } type DomainAddressVirtioSerial struct { Controller *uint `xml:"controller,attr"` Bus *uint `xml:"bus,attr"` Port *uint `xml:"port,attr"` } type DomainAddressSpaprVIO struct { Reg *uint64 `xml:"reg,attr"` } type DomainAddressCCID struct { Controller *uint `xml:"controller,attr"` Slot *uint `xml:"slot,attr"` } type DomainAddressVirtioS390 struct { } type DomainAddressUnassigned struct { } type DomainAddress struct { PCI *DomainAddressPCI Drive *DomainAddressDrive VirtioSerial *DomainAddressVirtioSerial CCID *DomainAddressCCID USB *DomainAddressUSB SpaprVIO *DomainAddressSpaprVIO VirtioS390 *DomainAddressVirtioS390 CCW *DomainAddressCCW VirtioMMIO *DomainAddressVirtioMMIO ISA *DomainAddressISA DIMM *DomainAddressDIMM Unassigned *DomainAddressUnassigned } type DomainChardevLog struct { File string `xml:"file,attr"` Append string `xml:"append,attr,omitempty"` } type DomainConsole struct { XMLName xml.Name `xml:"console"` TTY string `xml:"tty,attr,omitempty"` Source *DomainChardevSource `xml:"source"` Protocol *DomainChardevProtocol `xml:"protocol"` Target *DomainConsoleTarget `xml:"target"` Log *DomainChardevLog `xml:"log"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainSerial struct { XMLName xml.Name `xml:"serial"` Source *DomainChardevSource `xml:"source"` Protocol *DomainChardevProtocol `xml:"protocol"` Target *DomainSerialTarget `xml:"target"` Log *DomainChardevLog `xml:"log"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainParallel struct { XMLName xml.Name `xml:"parallel"` Source *DomainChardevSource `xml:"source"` Protocol *DomainChardevProtocol `xml:"protocol"` Target *DomainParallelTarget `xml:"target"` Log *DomainChardevLog `xml:"log"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainChardevProtocol struct { Type string `xml:"type,attr"` } type DomainChannel struct { XMLName xml.Name `xml:"channel"` Source *DomainChardevSource `xml:"source"` Protocol *DomainChardevProtocol `xml:"protocol"` Target *DomainChannelTarget `xml:"target"` Log *DomainChardevLog `xml:"log"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainRedirDev struct { XMLName xml.Name `xml:"redirdev"` Bus string `xml:"bus,attr,omitempty"` Source *DomainChardevSource `xml:"source"` Protocol *DomainChardevProtocol `xml:"protocol"` Boot *DomainDeviceBoot `xml:"boot"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainRedirFilter struct { USB []DomainRedirFilterUSB `xml:"usbdev"` } type DomainRedirFilterUSB struct { Class *uint `xml:"class,attr"` Vendor *uint `xml:"vendor,attr"` Product *uint `xml:"product,attr"` Version string `xml:"version,attr,omitempty"` Allow string `xml:"allow,attr"` } type DomainInput struct { XMLName xml.Name `xml:"input"` Type string `xml:"type,attr"` Bus string `xml:"bus,attr,omitempty"` Model string `xml:"model,attr,omitempty"` Driver *DomainInputDriver `xml:"driver"` Source *DomainInputSource `xml:"source"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainInputDriver struct { IOMMU string `xml:"iommu,attr,omitempty"` ATS string `xml:"ats,attr,omitempty"` Packed string `xml:"packed,attr,omitempty"` } type DomainInputSource struct { Passthrough *DomainInputSourcePassthrough `xml:"-"` EVDev *DomainInputSourceEVDev `xml:"-"` } type DomainInputSourcePassthrough struct { EVDev string `xml:"evdev,attr"` } type DomainInputSourceEVDev struct { Dev string `xml:"dev,attr"` Grab string `xml:"grab,attr,omitempty"` Repeat string `xml:"repeat,attr,omitempty"` } type DomainGraphicListenerAddress struct { Address string `xml:"address,attr,omitempty"` } type DomainGraphicListenerNetwork struct { Address string `xml:"address,attr,omitempty"` Network string `xml:"network,attr,omitempty"` } type DomainGraphicListenerSocket struct { Socket string `xml:"socket,attr,omitempty"` } type DomainGraphicListener struct { Address *DomainGraphicListenerAddress `xml:"-"` Network *DomainGraphicListenerNetwork `xml:"-"` Socket *DomainGraphicListenerSocket `xml:"-"` } type DomainGraphicChannel struct { Name string `xml:"name,attr,omitempty"` Mode string `xml:"mode,attr,omitempty"` } type DomainGraphicFileTransfer struct { Enable string `xml:"enable,attr,omitempty"` } type DomainGraphicsSDLGL struct { Enable string `xml:"enable,attr,omitempty"` } type DomainGraphicSDL struct { Display string `xml:"display,attr,omitempty"` XAuth string `xml:"xauth,attr,omitempty"` FullScreen string `xml:"fullscreen,attr,omitempty"` GL *DomainGraphicsSDLGL `xml:"gl"` } type DomainGraphicVNC struct { Socket string `xml:"socket,attr,omitempty"` Port int `xml:"port,attr,omitempty"` AutoPort string `xml:"autoport,attr,omitempty"` WebSocket int `xml:"websocket,attr,omitempty"` Keymap string `xml:"keymap,attr,omitempty"` SharePolicy string `xml:"sharePolicy,attr,omitempty"` Passwd string `xml:"passwd,attr,omitempty"` PasswdValidTo string `xml:"passwdValidTo,attr,omitempty"` Connected string `xml:"connected,attr,omitempty"` PowerControl string `xml:"powerControl,attr,omitempty"` Listen string `xml:"listen,attr,omitempty"` Listeners []DomainGraphicListener `xml:"listen"` } type DomainGraphicRDP struct { Port int `xml:"port,attr,omitempty"` AutoPort string `xml:"autoport,attr,omitempty"` ReplaceUser string `xml:"replaceUser,attr,omitempty"` MultiUser string `xml:"multiUser,attr,omitempty"` Listen string `xml:"listen,attr,omitempty"` Listeners []DomainGraphicListener `xml:"listen"` } type DomainGraphicDesktop struct { Display string `xml:"display,attr,omitempty"` FullScreen string `xml:"fullscreen,attr,omitempty"` } type DomainGraphicSpiceChannel struct { Name string `xml:"name,attr"` Mode string `xml:"mode,attr"` } type DomainGraphicSpiceImage struct { Compression string `xml:"compression,attr"` } type DomainGraphicSpiceJPEG struct { Compression string `xml:"compression,attr"` } type DomainGraphicSpiceZLib struct { Compression string `xml:"compression,attr"` } type DomainGraphicSpicePlayback struct { Compression string `xml:"compression,attr"` } type DomainGraphicSpiceStreaming struct { Mode string `xml:"mode,attr"` } type DomainGraphicSpiceMouse struct { Mode string `xml:"mode,attr"` } type DomainGraphicSpiceClipBoard struct { CopyPaste string `xml:"copypaste,attr"` } type DomainGraphicSpiceFileTransfer struct { Enable string `xml:"enable,attr"` } type DomainGraphicSpiceGL struct { Enable string `xml:"enable,attr,omitempty"` RenderNode string `xml:"rendernode,attr,omitempty"` } type DomainGraphicSpice struct { Port int `xml:"port,attr,omitempty"` TLSPort int `xml:"tlsPort,attr,omitempty"` AutoPort string `xml:"autoport,attr,omitempty"` Listen string `xml:"listen,attr,omitempty"` Keymap string `xml:"keymap,attr,omitempty"` DefaultMode string `xml:"defaultMode,attr,omitempty"` Passwd string `xml:"passwd,attr,omitempty"` PasswdValidTo string `xml:"passwdValidTo,attr,omitempty"` Connected string `xml:"connected,attr,omitempty"` Listeners []DomainGraphicListener `xml:"listen"` Channel []DomainGraphicSpiceChannel `xml:"channel"` Image *DomainGraphicSpiceImage `xml:"image"` JPEG *DomainGraphicSpiceJPEG `xml:"jpeg"` ZLib *DomainGraphicSpiceZLib `xml:"zlib"` Playback *DomainGraphicSpicePlayback `xml:"playback"` Streaming *DomainGraphicSpiceStreaming `xml:"streaming"` Mouse *DomainGraphicSpiceMouse `xml:"mouse"` ClipBoard *DomainGraphicSpiceClipBoard `xml:"clipboard"` FileTransfer *DomainGraphicSpiceFileTransfer `xml:"filetransfer"` GL *DomainGraphicSpiceGL `xml:"gl"` } type DomainGraphicEGLHeadlessGL struct { RenderNode string `xml:"rendernode,attr,omitempty"` } type DomainGraphicEGLHeadless struct { GL *DomainGraphicEGLHeadlessGL `xml:"gl"` } type DomainGraphicAudio struct { ID uint `xml:"id,attr,omitempty"` } type DomainGraphic struct { XMLName xml.Name `xml:"graphics"` SDL *DomainGraphicSDL `xml:"-"` VNC *DomainGraphicVNC `xml:"-"` RDP *DomainGraphicRDP `xml:"-"` Desktop *DomainGraphicDesktop `xml:"-"` Spice *DomainGraphicSpice `xml:"-"` EGLHeadless *DomainGraphicEGLHeadless `xml:"-"` Audio *DomainGraphicAudio `xml:"audio"` } type DomainVideoAccel struct { Accel3D string `xml:"accel3d,attr,omitempty"` Accel2D string `xml:"accel2d,attr,omitempty"` RenderNode string `xml:"rendernode,attr,omitempty"` } type DomainVideoResolution struct { X uint `xml:"x,attr"` Y uint `xml:"y,attr"` } type DomainVideoModel struct { Type string `xml:"type,attr"` Heads uint `xml:"heads,attr,omitempty"` Ram uint `xml:"ram,attr,omitempty"` VRam uint `xml:"vram,attr,omitempty"` VRam64 uint `xml:"vram64,attr,omitempty"` VGAMem uint `xml:"vgamem,attr,omitempty"` Primary string `xml:"primary,attr,omitempty"` Accel *DomainVideoAccel `xml:"acceleration"` Resolution *DomainVideoResolution `xml:"resolution"` } type DomainVideo struct { XMLName xml.Name `xml:"video"` Model DomainVideoModel `xml:"model"` Driver *DomainVideoDriver `xml:"driver"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainVideoDriver struct { Name string `xml:"name,attr,omitempty"` VGAConf string `xml:"vgaconf,attr,omitempty"` IOMMU string `xml:"iommu,attr,omitempty"` ATS string `xml:"ats,attr,omitempty"` Packed string `xml:"packed,attr,omitempty"` } type DomainMemBalloonStats struct { Period uint `xml:"period,attr"` } type DomainMemBalloon struct { XMLName xml.Name `xml:"memballoon"` Model string `xml:"model,attr"` AutoDeflate string `xml:"autodeflate,attr,omitempty"` FreePageReporting string `xml:"freePageReporting,attr,omitempty"` Driver *DomainMemBalloonDriver `xml:"driver"` Stats *DomainMemBalloonStats `xml:"stats"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainVSockCID struct { Auto string `xml:"auto,attr,omitempty"` Address string `xml:"address,attr,omitempty"` } type DomainVSockDriver struct { IOMMU string `xml:"iommu,attr,omitempty"` ATS string `xml:"ats,attr,omitempty"` Packed string `xml:"packed,attr,omitempty"` } type DomainVSock struct { XMLName xml.Name `xml:"vsock"` Model string `xml:"model,attr,omitempty"` CID *DomainVSockCID `xml:"cid"` Driver *DomainVSockDriver `xml:"driver"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainMemBalloonDriver struct { IOMMU string `xml:"iommu,attr,omitempty"` ATS string `xml:"ats,attr,omitempty"` Packed string `xml:"packed,attr,omitempty"` } type DomainPanic struct { XMLName xml.Name `xml:"panic"` Model string `xml:"model,attr,omitempty"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainSoundCodec struct { Type string `xml:"type,attr"` } type DomainSound struct { XMLName xml.Name `xml:"sound"` Model string `xml:"model,attr"` Codec []DomainSoundCodec `xml:"codec"` Audio *DomainSoundAudio `xml:"audio"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainSoundAudio struct { ID uint `xml:"id,attr"` } type DomainAudio struct { XMLName xml.Name `xml:"audio"` ID int `xml:"id,attr"` None *DomainAudioNone `xml:"-"` ALSA *DomainAudioALSA `xml:"-"` CoreAudio *DomainAudioCoreAudio `xml:"-"` Jack *DomainAudioJack `xml:"-"` OSS *DomainAudioOSS `xml:"-"` PulseAudio *DomainAudioPulseAudio `xml:"-"` SDL *DomainAudioSDL `xml:"-"` SPICE *DomainAudioSPICE `xml:"-"` File *DomainAudioFile `xml:"-"` } type DomainAudioChannel struct { MixingEngine string `xml:"mixingEngine,attr,omitempty"` FixedSettings string `xml:"fixedSettings,attr,omitempty"` Voices uint `xml:"voices,attr,omitempty"` Settings *DomainAudioChannelSettings `xml:"settings"` BufferLength uint `xml:"bufferLength,attr,omitempty"` } type DomainAudioChannelSettings struct { Frequency uint `xml:"frequency,attr,omitempty"` Channels uint `xml:"channels,attr,omitempty"` Format string `xml:"format,attr,omitempty"` } type DomainAudioNone struct { Input *DomainAudioNoneChannel `xml:"input"` Output *DomainAudioNoneChannel `xml:"output"` } type DomainAudioNoneChannel struct { DomainAudioChannel } type DomainAudioALSA struct { Input *DomainAudioALSAChannel `xml:"input"` Output *DomainAudioALSAChannel `xml:"output"` } type DomainAudioALSAChannel struct { DomainAudioChannel Dev string `xml:"dev,attr,omitempty"` } type DomainAudioCoreAudio struct { Input *DomainAudioCoreAudioChannel `xml:"input"` Output *DomainAudioCoreAudioChannel `xml:"output"` } type DomainAudioCoreAudioChannel struct { DomainAudioChannel BufferCount uint `xml:"bufferCount,attr,omitempty"` } type DomainAudioJack struct { Input *DomainAudioJackChannel `xml:"input"` Output *DomainAudioJackChannel `xml:"output"` } type DomainAudioJackChannel struct { DomainAudioChannel ServerName string `xml:"serverName,attr,omitempty"` ClientName string `xml:"clientName,attr,omitempty"` ConnectPorts string `xml:"connectPorts,attr,omitempty"` ExactName string `xml:"exactName,attr,omitempty"` } type DomainAudioOSS struct { TryMMap string `xml:"tryMMap,attr,omitempty"` Exclusive string `xml:"exclusive,attr,omitempty"` DSPPolicy *int `xml:"dspPolicy,attr"` Input *DomainAudioOSSChannel `xml:"input"` Output *DomainAudioOSSChannel `xml:"output"` } type DomainAudioOSSChannel struct { DomainAudioChannel Dev string `xml:"dev,attr,omitempty"` BufferCount uint `xml:"bufferCount,attr,omitempty"` TryPoll string `xml:"tryPoll,attr,omitempty"` } type DomainAudioPulseAudio struct { ServerName string `xml:"serverName,attr,omitempty"` Input *DomainAudioPulseAudioChannel `xml:"input"` Output *DomainAudioPulseAudioChannel `xml:"output"` } type DomainAudioPulseAudioChannel struct { DomainAudioChannel Name string `xml:"name,attr,omitempty"` StreamName string `xml:"streamName,attr,omitempty"` Latency uint `xml:"latency,attr,omitempty"` } type DomainAudioSDL struct { Driver string `xml:"driver,attr,omitempty"` Input *DomainAudioSDLChannel `xml:"input"` Output *DomainAudioSDLChannel `xml:"output"` } type DomainAudioSDLChannel struct { DomainAudioChannel BufferCount uint `xml:"bufferCount,attr,omitempty"` } type DomainAudioSPICE struct { Input *DomainAudioSPICEChannel `xml:"input"` Output *DomainAudioSPICEChannel `xml:"output"` } type DomainAudioSPICEChannel struct { DomainAudioChannel } type DomainAudioFile struct { Path string `xml:"path,attr,omitempty"` Input *DomainAudioFileChannel `xml:"input"` Output *DomainAudioFileChannel `xml:"output"` } type DomainAudioFileChannel struct { DomainAudioChannel } type DomainRNGRate struct { Bytes uint `xml:"bytes,attr"` Period uint `xml:"period,attr,omitempty"` } type DomainRNGBackend struct { Random *DomainRNGBackendRandom `xml:"-"` EGD *DomainRNGBackendEGD `xml:"-"` BuiltIn *DomainRNGBackendBuiltIn `xml:"-"` } type DomainRNGBackendEGD struct { Source *DomainChardevSource `xml:"source"` Protocol *DomainChardevProtocol `xml:"protocol"` } type DomainRNGBackendRandom struct { Device string `xml:",chardata"` } type DomainRNGBackendBuiltIn struct { } type DomainRNG struct { XMLName xml.Name `xml:"rng"` Model string `xml:"model,attr"` Driver *DomainRNGDriver `xml:"driver"` Rate *DomainRNGRate `xml:"rate"` Backend *DomainRNGBackend `xml:"backend"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainRNGDriver struct { IOMMU string `xml:"iommu,attr,omitempty"` ATS string `xml:"ats,attr,omitempty"` Packed string `xml:"packed,attr,omitempty"` } type DomainHostdevSubsysUSB struct { Source *DomainHostdevSubsysUSBSource `xml:"source"` } type DomainHostdevSubsysUSBSource struct { Address *DomainAddressUSB `xml:"address"` } type DomainHostdevSubsysSCSI struct { SGIO string `xml:"sgio,attr,omitempty"` RawIO string `xml:"rawio,attr,omitempty"` Source *DomainHostdevSubsysSCSISource `xml:"source"` ReadOnly *DomainDiskReadOnly `xml:"readonly"` Shareable *DomainDiskShareable `xml:"shareable"` } type DomainHostdevSubsysSCSISource struct { Host *DomainHostdevSubsysSCSISourceHost `xml:"-"` ISCSI *DomainHostdevSubsysSCSISourceISCSI `xml:"-"` } type DomainHostdevSubsysSCSIAdapter struct { Name string `xml:"name,attr"` } type DomainHostdevSubsysSCSISourceHost struct { Adapter *DomainHostdevSubsysSCSIAdapter `xml:"adapter"` Address *DomainAddressDrive `xml:"address"` } type DomainHostdevSubsysSCSISourceISCSI struct { Name string `xml:"name,attr"` Host []DomainDiskSourceHost `xml:"host"` Auth *DomainDiskAuth `xml:"auth"` Initiator *DomainHostdevSubsysSCSISourceInitiator `xml:"initiator"` } type DomainHostdevSubsysSCSISourceInitiator struct { IQN DomainHostdevSubsysSCSISourceIQN `xml:"iqn"` } type DomainHostdevSubsysSCSISourceIQN struct { Name string `xml:"name,attr"` } type DomainHostdevSubsysSCSIHost struct { Model string `xml:"model,attr,omitempty"` Source *DomainHostdevSubsysSCSIHostSource `xml:"source"` } type DomainHostdevSubsysSCSIHostSource struct { Protocol string `xml:"protocol,attr,omitempty"` WWPN string `xml:"wwpn,attr,omitempty"` } type DomainHostdevSubsysPCISource struct { WriteFiltering string `xml:"writeFiltering,attr,omitempty"` Address *DomainAddressPCI `xml:"address"` } type DomainHostdevSubsysPCIDriver struct { Name string `xml:"name,attr,omitempty"` } type DomainHostdevSubsysPCI struct { Driver *DomainHostdevSubsysPCIDriver `xml:"driver"` Source *DomainHostdevSubsysPCISource `xml:"source"` Teaming *DomainInterfaceTeaming `xml:"teaming"` } type DomainAddressMDev struct { UUID string `xml:"uuid,attr"` } type DomainHostdevSubsysMDevSource struct { Address *DomainAddressMDev `xml:"address"` } type DomainHostdevSubsysMDev struct { Model string `xml:"model,attr,omitempty"` Display string `xml:"display,attr,omitempty"` RamFB string `xml:"ramfb,attr,omitempty"` Source *DomainHostdevSubsysMDevSource `xml:"source"` } type DomainHostdevCapsStorage struct { Source *DomainHostdevCapsStorageSource `xml:"source"` } type DomainHostdevCapsStorageSource struct { Block string `xml:"block"` } type DomainHostdevCapsMisc struct { Source *DomainHostdevCapsMiscSource `xml:"source"` } type DomainHostdevCapsMiscSource struct { Char string `xml:"char"` } type DomainIP struct { Address string `xml:"address,attr,omitempty"` Family string `xml:"family,attr,omitempty"` Prefix *uint `xml:"prefix,attr"` } type DomainRoute struct { Family string `xml:"family,attr,omitempty"` Address string `xml:"address,attr,omitempty"` Gateway string `xml:"gateway,attr,omitempty"` } type DomainHostdevCapsNet struct { Source *DomainHostdevCapsNetSource `xml:"source"` IP []DomainIP `xml:"ip"` Route []DomainRoute `xml:"route"` } type DomainHostdevCapsNetSource struct { Interface string `xml:"interface"` } type DomainHostdev struct { Managed string `xml:"managed,attr,omitempty"` SubsysUSB *DomainHostdevSubsysUSB `xml:"-"` SubsysSCSI *DomainHostdevSubsysSCSI `xml:"-"` SubsysSCSIHost *DomainHostdevSubsysSCSIHost `xml:"-"` SubsysPCI *DomainHostdevSubsysPCI `xml:"-"` SubsysMDev *DomainHostdevSubsysMDev `xml:"-"` CapsStorage *DomainHostdevCapsStorage `xml:"-"` CapsMisc *DomainHostdevCapsMisc `xml:"-"` CapsNet *DomainHostdevCapsNet `xml:"-"` Boot *DomainDeviceBoot `xml:"boot"` ROM *DomainROM `xml:"rom"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainMemorydevSource struct { NodeMask string `xml:"nodemask,omitempty"` PageSize *DomainMemorydevSourcePagesize `xml:"pagesize"` Path string `xml:"path,omitempty"` AlignSize *DomainMemorydevSourceAlignsize `xml:"alignsize"` PMem *DomainMemorydevSourcePMem `xml:"pmem"` } type DomainMemorydevSourcePMem struct { } type DomainMemorydevSourcePagesize struct { Value uint64 `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` } type DomainMemorydevSourceAlignsize struct { Value uint64 `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` } type DomainMemorydevTargetNode struct { Value uint `xml:",chardata"` } type DomainMemorydevTargetReadOnly struct { } type DomainMemorydevTargetSize struct { Value uint `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` } type DomainMemorydevTargetLabel struct { Size *DomainMemorydevTargetSize `xml:"size"` } type DomainMemorydevTarget struct { Size *DomainMemorydevTargetSize `xml:"size"` Node *DomainMemorydevTargetNode `xml:"node"` Label *DomainMemorydevTargetLabel `xml:"label"` ReadOnly *DomainMemorydevTargetReadOnly `xml:"readonly"` } type DomainMemorydev struct { XMLName xml.Name `xml:"memory"` Model string `xml:"model,attr"` Access string `xml:"access,attr,omitempty"` Discard string `xml:"discard,attr,omitempty"` UUID string `xml:"uuid,omitempty"` Source *DomainMemorydevSource `xml:"source"` Target *DomainMemorydevTarget `xml:"target"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainWatchdog struct { XMLName xml.Name `xml:"watchdog"` Model string `xml:"model,attr"` Action string `xml:"action,attr,omitempty"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainHub struct { Type string `xml:"type,attr"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainIOMMU struct { Model string `xml:"model,attr"` Driver *DomainIOMMUDriver `xml:"driver"` } type DomainIOMMUDriver struct { IntRemap string `xml:"intremap,attr,omitempty"` CachingMode string `xml:"caching_mode,attr,omitempty"` EIM string `xml:"eim,attr,omitempty"` IOTLB string `xml:"iotlb,attr,omitempty"` AWBits uint `xml:"aw_bits,attr,omitempty"` } type DomainNVRAM struct { ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainLease struct { Lockspace string `xml:"lockspace"` Key string `xml:"key"` Target *DomainLeaseTarget `xml:"target"` } type DomainLeaseTarget struct { Path string `xml:"path,attr"` Offset uint64 `xml:"offset,attr,omitempty"` } type DomainSmartcard struct { XMLName xml.Name `xml:"smartcard"` Passthrough *DomainChardevSource `xml:"source"` Protocol *DomainChardevProtocol `xml:"protocol"` Host *DomainSmartcardHost `xml:"-"` HostCerts []DomainSmartcardHostCert `xml:"certificate"` Database string `xml:"database,omitempty"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainSmartcardHost struct { } type DomainSmartcardHostCert struct { File string `xml:",chardata"` } type DomainTPM struct { XMLName xml.Name `xml:"tpm"` Model string `xml:"model,attr,omitempty"` Backend *DomainTPMBackend `xml:"backend"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainTPMBackend struct { Passthrough *DomainTPMBackendPassthrough `xml:"-"` Emulator *DomainTPMBackendEmulator `xml:"-"` } type DomainTPMBackendPassthrough struct { Device *DomainTPMBackendDevice `xml:"device"` } type DomainTPMBackendEmulator struct { Version string `xml:"version,attr,omitempty"` Encryption *DomainTPMBackendEncryption `xml:"encryption"` PersistentState string `xml:"persistent_state,attr,omitempty"` } type DomainTPMBackendEncryption struct { Secret string `xml:"secret,attr"` } type DomainTPMBackendDevice struct { Path string `xml:"path,attr"` } type DomainShmem struct { XMLName xml.Name `xml:"shmem"` Name string `xml:"name,attr"` Role string `xml:"role,attr,omitempty"` Size *DomainShmemSize `xml:"size"` Model *DomainShmemModel `xml:"model"` Server *DomainShmemServer `xml:"server"` MSI *DomainShmemMSI `xml:"msi"` ACPI *DomainDeviceACPI `xml:"acpi"` Alias *DomainAlias `xml:"alias"` Address *DomainAddress `xml:"address"` } type DomainShmemSize struct { Value uint `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` } type DomainShmemModel struct { Type string `xml:"type,attr"` } type DomainShmemServer struct { Path string `xml:"path,attr,omitempty"` } type DomainShmemMSI struct { Enabled string `xml:"enabled,attr,omitempty"` Vectors uint `xml:"vectors,attr,omitempty"` IOEventFD string `xml:"ioeventfd,attr,omitempty"` } type DomainDeviceList struct { Emulator string `xml:"emulator,omitempty"` Disks []DomainDisk `xml:"disk"` Controllers []DomainController `xml:"controller"` Leases []DomainLease `xml:"lease"` Filesystems []DomainFilesystem `xml:"filesystem"` Interfaces []DomainInterface `xml:"interface"` Smartcards []DomainSmartcard `xml:"smartcard"` Serials []DomainSerial `xml:"serial"` Parallels []DomainParallel `xml:"parallel"` Consoles []DomainConsole `xml:"console"` Channels []DomainChannel `xml:"channel"` Inputs []DomainInput `xml:"input"` TPMs []DomainTPM `xml:"tpm"` Graphics []DomainGraphic `xml:"graphics"` Sounds []DomainSound `xml:"sound"` Audios []DomainAudio `xml:"audio"` Videos []DomainVideo `xml:"video"` Hostdevs []DomainHostdev `xml:"hostdev"` RedirDevs []DomainRedirDev `xml:"redirdev"` RedirFilters []DomainRedirFilter `xml:"redirfilter"` Hubs []DomainHub `xml:"hub"` Watchdog *DomainWatchdog `xml:"watchdog"` MemBalloon *DomainMemBalloon `xml:"memballoon"` RNGs []DomainRNG `xml:"rng"` NVRAM *DomainNVRAM `xml:"nvram"` Panics []DomainPanic `xml:"panic"` Shmems []DomainShmem `xml:"shmem"` Memorydevs []DomainMemorydev `xml:"memory"` IOMMU *DomainIOMMU `xml:"iommu"` VSock *DomainVSock `xml:"vsock"` } type DomainMemory struct { Value uint `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` DumpCore string `xml:"dumpCore,attr,omitempty"` } type DomainCurrentMemory struct { Value uint `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` } type DomainMaxMemory struct { Value uint `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` Slots uint `xml:"slots,attr,omitempty"` } type DomainMemoryHugepage struct { Size uint `xml:"size,attr"` Unit string `xml:"unit,attr,omitempty"` Nodeset string `xml:"nodeset,attr,omitempty"` } type DomainMemoryHugepages struct { Hugepages []DomainMemoryHugepage `xml:"page"` } type DomainMemoryNosharepages struct { } type DomainMemoryLocked struct { } type DomainMemorySource struct { Type string `xml:"type,attr,omitempty"` } type DomainMemoryAccess struct { Mode string `xml:"mode,attr,omitempty"` } type DomainMemoryAllocation struct { Mode string `xml:"mode,attr,omitempty"` } type DomainMemoryDiscard struct { } type DomainMemoryBacking struct { MemoryHugePages *DomainMemoryHugepages `xml:"hugepages"` MemoryNosharepages *DomainMemoryNosharepages `xml:"nosharepages"` MemoryLocked *DomainMemoryLocked `xml:"locked"` MemorySource *DomainMemorySource `xml:"source"` MemoryAccess *DomainMemoryAccess `xml:"access"` MemoryAllocation *DomainMemoryAllocation `xml:"allocation"` MemoryDiscard *DomainMemoryDiscard `xml:"discard"` } type DomainOSType struct { Arch string `xml:"arch,attr,omitempty"` Machine string `xml:"machine,attr,omitempty"` Type string `xml:",chardata"` } type DomainSMBios struct { Mode string `xml:"mode,attr"` } type DomainNVRam struct { NVRam string `xml:",chardata"` Template string `xml:"template,attr,omitempty"` } type DomainBootDevice struct { Dev string `xml:"dev,attr"` } type DomainBootMenu struct { Enable string `xml:"enable,attr,omitempty"` Timeout string `xml:"timeout,attr,omitempty"` } type DomainSysInfoBIOS struct { Entry []DomainSysInfoEntry `xml:"entry"` } type DomainSysInfoSystem struct { Entry []DomainSysInfoEntry `xml:"entry"` } type DomainSysInfoBaseBoard struct { Entry []DomainSysInfoEntry `xml:"entry"` } type DomainSysInfoProcessor struct { Entry []DomainSysInfoEntry `xml:"entry"` } type DomainSysInfoMemory struct { Entry []DomainSysInfoEntry `xml:"entry"` } type DomainSysInfoChassis struct { Entry []DomainSysInfoEntry `xml:"entry"` } type DomainSysInfoOEMStrings struct { Entry []string `xml:"entry"` } type DomainSysInfoSMBIOS struct { BIOS *DomainSysInfoBIOS `xml:"bios"` System *DomainSysInfoSystem `xml:"system"` BaseBoard []DomainSysInfoBaseBoard `xml:"baseBoard"` Chassis *DomainSysInfoChassis `xml:"chassis"` Processor []DomainSysInfoProcessor `xml:"processor"` Memory []DomainSysInfoMemory `xml:"memory"` OEMStrings *DomainSysInfoOEMStrings `xml:"oemStrings"` } type DomainSysInfoFWCfg struct { Entry []DomainSysInfoEntry `xml:"entry"` } type DomainSysInfo struct { SMBIOS *DomainSysInfoSMBIOS `xml:"-"` FWCfg *DomainSysInfoFWCfg `xml:"-"` } type DomainSysInfoEntry struct { Name string `xml:"name,attr"` File string `xml:"file,attr,omitempty"` Value string `xml:",chardata"` } type DomainBIOS struct { UseSerial string `xml:"useserial,attr,omitempty"` RebootTimeout *int `xml:"rebootTimeout,attr"` } type DomainLoader struct { Path string `xml:",chardata"` Readonly string `xml:"readonly,attr,omitempty"` Secure string `xml:"secure,attr,omitempty"` Type string `xml:"type,attr,omitempty"` } type DomainACPI struct { Tables []DomainACPITable `xml:"table"` } type DomainACPITable struct { Type string `xml:"type,attr"` Path string `xml:",chardata"` } type DomainOSInitEnv struct { Name string `xml:"name,attr"` Value string `xml:",chardata"` } type DomainOSFirmwareInfo struct { Features []DomainOSFirmwareFeature `xml:"feature"` } type DomainOSFirmwareFeature struct { Enabled string `xml:"enabled,attr,omitempty"` Name string `xml:"name,attr,omitempty"` } type DomainOS struct { Type *DomainOSType `xml:"type"` Firmware string `xml:"firmware,attr,omitempty"` FirmwareInfo *DomainOSFirmwareInfo `xml:"firmware"` Init string `xml:"init,omitempty"` InitArgs []string `xml:"initarg"` InitEnv []DomainOSInitEnv `xml:"initenv"` InitDir string `xml:"initdir,omitempty"` InitUser string `xml:"inituser,omitempty"` InitGroup string `xml:"initgroup,omitempty"` Loader *DomainLoader `xml:"loader"` NVRam *DomainNVRam `xml:"nvram"` Kernel string `xml:"kernel,omitempty"` Initrd string `xml:"initrd,omitempty"` Cmdline string `xml:"cmdline,omitempty"` DTB string `xml:"dtb,omitempty"` ACPI *DomainACPI `xml:"acpi"` BootDevices []DomainBootDevice `xml:"boot"` BootMenu *DomainBootMenu `xml:"bootmenu"` BIOS *DomainBIOS `xml:"bios"` SMBios *DomainSMBios `xml:"smbios"` } type DomainResource struct { Partition string `xml:"partition,omitempty"` } type DomainVCPU struct { Placement string `xml:"placement,attr,omitempty"` CPUSet string `xml:"cpuset,attr,omitempty"` Current uint `xml:"current,attr,omitempty"` Value uint `xml:",chardata"` } type DomainVCPUsVCPU struct { Id *uint `xml:"id,attr"` Enabled string `xml:"enabled,attr,omitempty"` Hotpluggable string `xml:"hotpluggable,attr,omitempty"` Order *uint `xml:"order,attr"` } type DomainVCPUs struct { VCPU []DomainVCPUsVCPU `xml:"vcpu"` } type DomainCPUModel struct { Fallback string `xml:"fallback,attr,omitempty"` Value string `xml:",chardata"` VendorID string `xml:"vendor_id,attr,omitempty"` } type DomainCPUTopology struct { Sockets int `xml:"sockets,attr,omitempty"` Dies int `xml:"dies,attr,omitempty"` Cores int `xml:"cores,attr,omitempty"` Threads int `xml:"threads,attr,omitempty"` } type DomainCPUFeature struct { Policy string `xml:"policy,attr,omitempty"` Name string `xml:"name,attr,omitempty"` } type DomainCPUCache struct { Level uint `xml:"level,attr,omitempty"` Mode string `xml:"mode,attr"` } type DomainCPU struct { XMLName xml.Name `xml:"cpu"` Match string `xml:"match,attr,omitempty"` Mode string `xml:"mode,attr,omitempty"` Check string `xml:"check,attr,omitempty"` Migratable string `xml:"migratable,attr,omitempty"` Model *DomainCPUModel `xml:"model"` Vendor string `xml:"vendor,omitempty"` Topology *DomainCPUTopology `xml:"topology"` Cache *DomainCPUCache `xml:"cache"` Features []DomainCPUFeature `xml:"feature"` Numa *DomainNuma `xml:"numa"` } type DomainNuma struct { Cell []DomainCell `xml:"cell"` Interconnects *DomainNUMAInterconnects `xml:"interconnects"` } type DomainCell struct { ID *uint `xml:"id,attr"` CPUs string `xml:"cpus,attr,omitempty"` Memory uint `xml:"memory,attr"` Unit string `xml:"unit,attr,omitempty"` MemAccess string `xml:"memAccess,attr,omitempty"` Discard string `xml:"discard,attr,omitempty"` Distances *DomainCellDistances `xml:"distances"` Caches []DomainCellCache `xml:"cache"` } type DomainCellDistances struct { Siblings []DomainCellSibling `xml:"sibling"` } type DomainCellSibling struct { ID uint `xml:"id,attr"` Value uint `xml:"value,attr"` } type DomainCellCache struct { Level uint `xml:"level,attr"` Associativity string `xml:"associativity,attr"` Policy string `xml:"policy,attr"` Size DomainCellCacheSize `xml:"size"` Line DomainCellCacheLine `xml:"line"` } type DomainCellCacheSize struct { Value string `xml:"value,attr"` Unit string `xml:"unit,attr"` } type DomainCellCacheLine struct { Value string `xml:"value,attr"` Unit string `xml:"unit,attr"` } type DomainNUMAInterconnects struct { Latencies []DomainNUMAInterconnectLatency `xml:"latency"` Bandwidths []DomainNUMAInterconnectBandwidth `xml:"bandwidth"` } type DomainNUMAInterconnectLatency struct { Initiator uint `xml:"initiator,attr"` Target uint `xml:"target,attr"` Cache uint `xml:"cache,attr,omitempty"` Type string `xml:"type,attr"` Value uint `xml:"value,attr"` } type DomainNUMAInterconnectBandwidth struct { Initiator uint `xml:"initiator,attr"` Target uint `xml:"target,attr"` Type string `xml:"type,attr"` Value uint `xml:"value,attr"` Unit string `xml:"unit,attr"` } type DomainClock struct { Offset string `xml:"offset,attr,omitempty"` Basis string `xml:"basis,attr,omitempty"` Adjustment string `xml:"adjustment,attr,omitempty"` TimeZone string `xml:"timezone,attr,omitempty"` Timer []DomainTimer `xml:"timer"` } type DomainTimer struct { Name string `xml:"name,attr"` Track string `xml:"track,attr,omitempty"` TickPolicy string `xml:"tickpolicy,attr,omitempty"` CatchUp *DomainTimerCatchUp `xml:"catchup"` Frequency uint64 `xml:"frequency,attr,omitempty"` Mode string `xml:"mode,attr,omitempty"` Present string `xml:"present,attr,omitempty"` } type DomainTimerCatchUp struct { Threshold uint `xml:"threshold,attr,omitempty"` Slew uint `xml:"slew,attr,omitempty"` Limit uint `xml:"limit,attr,omitempty"` } type DomainFeature struct { } type DomainFeatureState struct { State string `xml:"state,attr,omitempty"` } type DomainFeatureAPIC struct { EOI string `xml:"eoi,attr,omitempty"` } type DomainFeatureHyperVVendorId struct { DomainFeatureState Value string `xml:"value,attr,omitempty"` } type DomainFeatureHyperVSpinlocks struct { DomainFeatureState Retries uint `xml:"retries,attr,omitempty"` } type DomainFeatureHyperVSTimer struct { DomainFeatureState Direct *DomainFeatureState `xml:"direct"` } type DomainFeatureHyperV struct { DomainFeature Relaxed *DomainFeatureState `xml:"relaxed"` VAPIC *DomainFeatureState `xml:"vapic"` Spinlocks *DomainFeatureHyperVSpinlocks `xml:"spinlocks"` VPIndex *DomainFeatureState `xml:"vpindex"` Runtime *DomainFeatureState `xml:"runtime"` Synic *DomainFeatureState `xml:"synic"` STimer *DomainFeatureHyperVSTimer `xml:"stimer"` Reset *DomainFeatureState `xml:"reset"` VendorId *DomainFeatureHyperVVendorId `xml:"vendor_id"` Frequencies *DomainFeatureState `xml:"frequencies"` ReEnlightenment *DomainFeatureState `xml:"reenlightenment"` TLBFlush *DomainFeatureState `xml:"tlbflush"` IPI *DomainFeatureState `xml:"ipi"` EVMCS *DomainFeatureState `xml:"evmcs"` } type DomainFeatureKVM struct { Hidden *DomainFeatureState `xml:"hidden"` HintDedicated *DomainFeatureState `xml:"hint-dedicated"` PollControl *DomainFeatureState `xml:"poll-control"` } type DomainFeatureXenPassthrough struct { State string `xml:"state,attr,omitempty"` Mode string `xml:"mode,attr,omitempty"` } type DomainFeatureXenE820Host struct { State string `xml:"state,attr"` } type DomainFeatureXen struct { E820Host *DomainFeatureXenE820Host `xml:"e820_host"` Passthrough *DomainFeatureXenPassthrough `xml:"passthrough"` } type DomainFeatureGIC struct { Version string `xml:"version,attr,omitempty"` } type DomainFeatureIOAPIC struct { Driver string `xml:"driver,attr,omitempty"` } type DomainFeatureHPT struct { Resizing string `xml:"resizing,attr,omitempty"` MaxPageSize *DomainFeatureHPTPageSize `xml:"maxpagesize"` } type DomainFeatureHPTPageSize struct { Unit string `xml:"unit,attr,omitempty"` Value string `xml:",chardata"` } type DomainFeatureSMM struct { State string `xml:"state,attr,omitempty"` TSeg *DomainFeatureSMMTSeg `xml:"tseg"` } type DomainFeatureSMMTSeg struct { Unit string `xml:"unit,attr,omitempty"` Value uint `xml:",chardata"` } type DomainFeatureCapability struct { State string `xml:"state,attr,omitempty"` } type DomainLaunchSecurity struct { SEV *DomainLaunchSecuritySEV `xml:"-"` } type DomainLaunchSecuritySEV struct { CBitPos *uint `xml:"cbitpos"` ReducedPhysBits *uint `xml:"reducedPhysBits"` Policy *uint `xml:"policy"` DHCert string `xml:"dhCert"` Session string `xml:"sesion"` } type DomainFeatureCapabilities struct { Policy string `xml:"policy,attr,omitempty"` AuditControl *DomainFeatureCapability `xml:"audit_control"` AuditWrite *DomainFeatureCapability `xml:"audit_write"` BlockSuspend *DomainFeatureCapability `xml:"block_suspend"` Chown *DomainFeatureCapability `xml:"chown"` DACOverride *DomainFeatureCapability `xml:"dac_override"` DACReadSearch *DomainFeatureCapability `xml:"dac_read_Search"` FOwner *DomainFeatureCapability `xml:"fowner"` FSetID *DomainFeatureCapability `xml:"fsetid"` IPCLock *DomainFeatureCapability `xml:"ipc_lock"` IPCOwner *DomainFeatureCapability `xml:"ipc_owner"` Kill *DomainFeatureCapability `xml:"kill"` Lease *DomainFeatureCapability `xml:"lease"` LinuxImmutable *DomainFeatureCapability `xml:"linux_immutable"` MACAdmin *DomainFeatureCapability `xml:"mac_admin"` MACOverride *DomainFeatureCapability `xml:"mac_override"` MkNod *DomainFeatureCapability `xml:"mknod"` NetAdmin *DomainFeatureCapability `xml:"net_admin"` NetBindService *DomainFeatureCapability `xml:"net_bind_service"` NetBroadcast *DomainFeatureCapability `xml:"net_broadcast"` NetRaw *DomainFeatureCapability `xml:"net_raw"` SetGID *DomainFeatureCapability `xml:"setgid"` SetFCap *DomainFeatureCapability `xml:"setfcap"` SetPCap *DomainFeatureCapability `xml:"setpcap"` SetUID *DomainFeatureCapability `xml:"setuid"` SysAdmin *DomainFeatureCapability `xml:"sys_admin"` SysBoot *DomainFeatureCapability `xml:"sys_boot"` SysChRoot *DomainFeatureCapability `xml:"sys_chroot"` SysModule *DomainFeatureCapability `xml:"sys_module"` SysNice *DomainFeatureCapability `xml:"sys_nice"` SysPAcct *DomainFeatureCapability `xml:"sys_pacct"` SysPTrace *DomainFeatureCapability `xml:"sys_ptrace"` SysRawIO *DomainFeatureCapability `xml:"sys_rawio"` SysResource *DomainFeatureCapability `xml:"sys_resource"` SysTime *DomainFeatureCapability `xml:"sys_time"` SysTTYCnofig *DomainFeatureCapability `xml:"sys_tty_config"` SysLog *DomainFeatureCapability `xml:"syslog"` WakeAlarm *DomainFeatureCapability `xml:"wake_alarm"` } type DomainFeatureMSRS struct { Unknown string `xml:"unknown,attr"` } type DomainFeatureCFPC struct { Value string `xml:"value,attr"` } type DomainFeatureSBBC struct { Value string `xml:"value,attr"` } type DomainFeatureIBS struct { Value string `xml:"value,attr"` } type DomainFeatureList struct { PAE *DomainFeature `xml:"pae"` ACPI *DomainFeature `xml:"acpi"` APIC *DomainFeatureAPIC `xml:"apic"` HAP *DomainFeatureState `xml:"hap"` Viridian *DomainFeature `xml:"viridian"` PrivNet *DomainFeature `xml:"privnet"` HyperV *DomainFeatureHyperV `xml:"hyperv"` KVM *DomainFeatureKVM `xml:"kvm"` Xen *DomainFeatureXen `xml:"xen"` PVSpinlock *DomainFeatureState `xml:"pvspinlock"` PMU *DomainFeatureState `xml:"pmu"` VMPort *DomainFeatureState `xml:"vmport"` GIC *DomainFeatureGIC `xml:"gic"` SMM *DomainFeatureSMM `xml:"smm"` IOAPIC *DomainFeatureIOAPIC `xml:"ioapic"` HPT *DomainFeatureHPT `xml:"hpt"` HTM *DomainFeatureState `xml:"htm"` NestedHV *DomainFeatureState `xml:"nested-hv"` Capabilities *DomainFeatureCapabilities `xml:"capabilities"` VMCoreInfo *DomainFeatureState `xml:"vmcoreinfo"` MSRS *DomainFeatureMSRS `xml:"msrs"` CCFAssist *DomainFeatureState `xml:"ccf-assist"` CFPC *DomainFeatureCFPC `xml:"cfpc"` SBBC *DomainFeatureSBBC `xml:"sbbc"` IBS *DomainFeatureIBS `xml:"ibs"` } type DomainCPUTuneShares struct { Value uint `xml:",chardata"` } type DomainCPUTunePeriod struct { Value uint64 `xml:",chardata"` } type DomainCPUTuneQuota struct { Value int64 `xml:",chardata"` } type DomainCPUTuneVCPUPin struct { VCPU uint `xml:"vcpu,attr"` CPUSet string `xml:"cpuset,attr"` } type DomainCPUTuneEmulatorPin struct { CPUSet string `xml:"cpuset,attr"` } type DomainCPUTuneIOThreadPin struct { IOThread uint `xml:"iothread,attr"` CPUSet string `xml:"cpuset,attr"` } type DomainCPUTuneVCPUSched struct { VCPUs string `xml:"vcpus,attr"` Scheduler string `xml:"scheduler,attr,omitempty"` Priority *int `xml:"priority,attr"` } type DomainCPUTuneIOThreadSched struct { IOThreads string `xml:"iothreads,attr"` Scheduler string `xml:"scheduler,attr,omitempty"` Priority *int `xml:"priority,attr"` } type DomainCPUTuneEmulatorSched struct { Scheduler string `xml:"scheduler,attr,omitempty"` Priority *int `xml:"priority,attr"` } type DomainCPUCacheTune struct { VCPUs string `xml:"vcpus,attr,omitempty"` Cache []DomainCPUCacheTuneCache `xml:"cache"` Monitor []DomainCPUCacheTuneMonitor `xml:"monitor"` } type DomainCPUCacheTuneCache struct { ID uint `xml:"id,attr"` Level uint `xml:"level,attr"` Type string `xml:"type,attr"` Size uint `xml:"size,attr"` Unit string `xml:"unit,attr"` } type DomainCPUCacheTuneMonitor struct { Level uint `xml:"level,attr,omitempty"` VCPUs string `xml:"vcpus,attr,omitempty"` } type DomainCPUMemoryTune struct { VCPUs string `xml:"vcpus,attr"` Nodes []DomainCPUMemoryTuneNode `xml:"node"` Monitor []DomainCPUMemoryTuneMonitor `xml:"monitor"` } type DomainCPUMemoryTuneNode struct { ID uint `xml:"id,attr"` Bandwidth uint `xml:"bandwidth,attr"` } type DomainCPUMemoryTuneMonitor struct { Level uint `xml:"level,attr,omitempty"` VCPUs string `xml:"vcpus,attr,omitempty"` } type DomainCPUTune struct { Shares *DomainCPUTuneShares `xml:"shares"` Period *DomainCPUTunePeriod `xml:"period"` Quota *DomainCPUTuneQuota `xml:"quota"` GlobalPeriod *DomainCPUTunePeriod `xml:"global_period"` GlobalQuota *DomainCPUTuneQuota `xml:"global_quota"` EmulatorPeriod *DomainCPUTunePeriod `xml:"emulator_period"` EmulatorQuota *DomainCPUTuneQuota `xml:"emulator_quota"` IOThreadPeriod *DomainCPUTunePeriod `xml:"iothread_period"` IOThreadQuota *DomainCPUTuneQuota `xml:"iothread_quota"` VCPUPin []DomainCPUTuneVCPUPin `xml:"vcpupin"` EmulatorPin *DomainCPUTuneEmulatorPin `xml:"emulatorpin"` IOThreadPin []DomainCPUTuneIOThreadPin `xml:"iothreadpin"` VCPUSched []DomainCPUTuneVCPUSched `xml:"vcpusched"` EmulatorSched *DomainCPUTuneEmulatorSched `xml:"emulatorsched"` IOThreadSched []DomainCPUTuneIOThreadSched `xml:"iothreadsched"` CacheTune []DomainCPUCacheTune `xml:"cachetune"` MemoryTune []DomainCPUMemoryTune `xml:"memorytune"` } type DomainQEMUCommandlineArg struct { Value string `xml:"value,attr"` } type DomainQEMUCommandlineEnv struct { Name string `xml:"name,attr"` Value string `xml:"value,attr,omitempty"` } type DomainQEMUCommandline struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/domain/qemu/1.0 commandline"` Args []DomainQEMUCommandlineArg `xml:"arg"` Envs []DomainQEMUCommandlineEnv `xml:"env"` } type DomainQEMUCapabilitiesEntry struct { Name string `xml:"capability,attr"` } type DomainQEMUCapabilities struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/domain/qemu/1.0 capabilities"` Add []DomainQEMUCapabilitiesEntry `xml:"add"` Del []DomainQEMUCapabilitiesEntry `xml:"del"` } type DomainQEMUDeprecation struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/domain/qemu/1.0 deprecation"` Behavior string `xml:"behavior,attr,omitempty"` } type DomainLXCNamespace struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/domain/lxc/1.0 namespace"` ShareNet *DomainLXCNamespaceMap `xml:"sharenet"` ShareIPC *DomainLXCNamespaceMap `xml:"shareipc"` ShareUTS *DomainLXCNamespaceMap `xml:"shareuts"` } type DomainLXCNamespaceMap struct { Type string `xml:"type,attr"` Value string `xml:"value,attr"` } type DomainBHyveCommandlineArg struct { Value string `xml:"value,attr"` } type DomainBHyveCommandlineEnv struct { Name string `xml:"name,attr"` Value string `xml:"value,attr,omitempty"` } type DomainBHyveCommandline struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/domain/bhyve/1.0 commandline"` Args []DomainBHyveCommandlineArg `xml:"arg"` Envs []DomainBHyveCommandlineEnv `xml:"env"` } type DomainXenCommandlineArg struct { Value string `xml:"value,attr"` } type DomainXenCommandline struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/domain/xen/1.0 commandline"` Args []DomainXenCommandlineArg `xml:"arg"` } type DomainBlockIOTune struct { Weight uint `xml:"weight,omitempty"` Device []DomainBlockIOTuneDevice `xml:"device"` } type DomainBlockIOTuneDevice struct { Path string `xml:"path"` Weight uint `xml:"weight,omitempty"` ReadIopsSec uint `xml:"read_iops_sec,omitempty"` WriteIopsSec uint `xml:"write_iops_sec,omitempty"` ReadBytesSec uint `xml:"read_bytes_sec,omitempty"` WriteBytesSec uint `xml:"write_bytes_sec,omitempty"` } type DomainPM struct { SuspendToMem *DomainPMPolicy `xml:"suspend-to-mem"` SuspendToDisk *DomainPMPolicy `xml:"suspend-to-disk"` } type DomainPMPolicy struct { Enabled string `xml:"enabled,attr"` } type DomainSecLabel struct { Type string `xml:"type,attr,omitempty"` Model string `xml:"model,attr,omitempty"` Relabel string `xml:"relabel,attr,omitempty"` Label string `xml:"label,omitempty"` ImageLabel string `xml:"imagelabel,omitempty"` BaseLabel string `xml:"baselabel,omitempty"` } type DomainDeviceSecLabel struct { Model string `xml:"model,attr,omitempty"` LabelSkip string `xml:"labelskip,attr,omitempty"` Relabel string `xml:"relabel,attr,omitempty"` Label string `xml:"label,omitempty"` } type DomainNUMATune struct { Memory *DomainNUMATuneMemory `xml:"memory"` MemNodes []DomainNUMATuneMemNode `xml:"memnode"` } type DomainNUMATuneMemory struct { Mode string `xml:"mode,attr,omitempty"` Nodeset string `xml:"nodeset,attr,omitempty"` Placement string `xml:"placement,attr,omitempty"` } type DomainNUMATuneMemNode struct { CellID uint `xml:"cellid,attr"` Mode string `xml:"mode,attr"` Nodeset string `xml:"nodeset,attr"` } type DomainIOThreadIDs struct { IOThreads []DomainIOThread `xml:"iothread"` } type DomainIOThread struct { ID uint `xml:"id,attr"` } type DomainKeyWrap struct { Ciphers []DomainKeyWrapCipher `xml:"cipher"` } type DomainKeyWrapCipher struct { Name string `xml:"name,attr"` State string `xml:"state,attr"` } type DomainIDMap struct { UIDs []DomainIDMapRange `xml:"uid"` GIDs []DomainIDMapRange `xml:"gid"` } type DomainIDMapRange struct { Start uint `xml:"start,attr"` Target uint `xml:"target,attr"` Count uint `xml:"count,attr"` } type DomainMemoryTuneLimit struct { Value uint64 `xml:",chardata"` Unit string `xml:"unit,attr,omitempty"` } type DomainMemoryTune struct { HardLimit *DomainMemoryTuneLimit `xml:"hard_limit"` SoftLimit *DomainMemoryTuneLimit `xml:"soft_limit"` MinGuarantee *DomainMemoryTuneLimit `xml:"min_guarantee"` SwapHardLimit *DomainMemoryTuneLimit `xml:"swap_hard_limit"` } type DomainMetadata struct { XML string `xml:",innerxml"` } type DomainVMWareDataCenterPath struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/domain/vmware/1.0 datacenterpath"` Value string `xml:",chardata"` } type DomainPerf struct { Events []DomainPerfEvent `xml:"event"` } type DomainPerfEvent struct { Name string `xml:"name,attr"` Enabled string `xml:"enabled,attr"` } type DomainGenID struct { Value string `xml:",chardata"` } // NB, try to keep the order of fields in this struct // matching the order of XML elements that libvirt // will generate when dumping XML. type Domain struct { XMLName xml.Name `xml:"domain"` Type string `xml:"type,attr,omitempty"` ID *int `xml:"id,attr"` Name string `xml:"name,omitempty"` UUID string `xml:"uuid,omitempty"` GenID *DomainGenID `xml:"genid"` Title string `xml:"title,omitempty"` Description string `xml:"description,omitempty"` Metadata *DomainMetadata `xml:"metadata"` MaximumMemory *DomainMaxMemory `xml:"maxMemory"` Memory *DomainMemory `xml:"memory"` CurrentMemory *DomainCurrentMemory `xml:"currentMemory"` BlockIOTune *DomainBlockIOTune `xml:"blkiotune"` MemoryTune *DomainMemoryTune `xml:"memtune"` MemoryBacking *DomainMemoryBacking `xml:"memoryBacking"` VCPU *DomainVCPU `xml:"vcpu"` VCPUs *DomainVCPUs `xml:"vcpus"` IOThreads uint `xml:"iothreads,omitempty"` IOThreadIDs *DomainIOThreadIDs `xml:"iothreadids"` CPUTune *DomainCPUTune `xml:"cputune"` NUMATune *DomainNUMATune `xml:"numatune"` Resource *DomainResource `xml:"resource"` SysInfo []DomainSysInfo `xml:"sysinfo"` Bootloader string `xml:"bootloader,omitempty"` BootloaderArgs string `xml:"bootloader_args,omitempty"` OS *DomainOS `xml:"os"` IDMap *DomainIDMap `xml:"idmap"` Features *DomainFeatureList `xml:"features"` CPU *DomainCPU `xml:"cpu"` Clock *DomainClock `xml:"clock"` OnPoweroff string `xml:"on_poweroff,omitempty"` OnReboot string `xml:"on_reboot,omitempty"` OnCrash string `xml:"on_crash,omitempty"` PM *DomainPM `xml:"pm"` Perf *DomainPerf `xml:"perf"` Devices *DomainDeviceList `xml:"devices"` SecLabel []DomainSecLabel `xml:"seclabel"` KeyWrap *DomainKeyWrap `xml:"keywrap"` LaunchSecurity *DomainLaunchSecurity `xml:"launchSecurity"` /* Hypervisor namespaces must all be last */ QEMUCommandline *DomainQEMUCommandline QEMUCapabilities *DomainQEMUCapabilities QEMUDeprecation *DomainQEMUDeprecation LXCNamespace *DomainLXCNamespace BHyveCommandline *DomainBHyveCommandline VMWareDataCenterPath *DomainVMWareDataCenterPath XenCommandline *DomainXenCommandline } func (d *Domain) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *Domain) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } type domainController DomainController type domainControllerPCI struct { DomainControllerPCI domainController } type domainControllerUSB struct { DomainControllerUSB domainController } type domainControllerVirtIOSerial struct { DomainControllerVirtIOSerial domainController } type domainControllerXenBus struct { DomainControllerXenBus domainController } func (a *DomainControllerPCITarget) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "chassisNr", a.ChassisNr, "%d") marshalUintAttr(&start, "chassis", a.Chassis, "%d") marshalUintAttr(&start, "port", a.Port, "%d") marshalUintAttr(&start, "busNr", a.BusNr, "%d") marshalUintAttr(&start, "index", a.Index, "%d") if a.Hotplug != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "hotplug"}, a.Hotplug, }) } e.EncodeToken(start) if a.NUMANode != nil { node := xml.StartElement{ Name: xml.Name{Local: "node"}, } e.EncodeToken(node) e.EncodeToken(xml.CharData(fmt.Sprintf("%d", *a.NUMANode))) e.EncodeToken(node.End()) } e.EncodeToken(start.End()) return nil } func (a *DomainControllerPCITarget) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "chassisNr" { if err := unmarshalUintAttr(attr.Value, &a.ChassisNr, 10); err != nil { return err } } else if attr.Name.Local == "chassis" { if err := unmarshalUintAttr(attr.Value, &a.Chassis, 10); err != nil { return err } } else if attr.Name.Local == "port" { if err := unmarshalUintAttr(attr.Value, &a.Port, 0); err != nil { return err } } else if attr.Name.Local == "busNr" { if err := unmarshalUintAttr(attr.Value, &a.BusNr, 10); err != nil { return err } } else if attr.Name.Local == "index" { if err := unmarshalUintAttr(attr.Value, &a.Index, 10); err != nil { return err } } else if attr.Name.Local == "hotplug" { a.Hotplug = attr.Value } } for { tok, err := d.Token() if err == io.EOF { break } if err != nil { return err } switch tok := tok.(type) { case xml.StartElement: if tok.Name.Local == "node" { data, err := d.Token() if err != nil { return err } switch data := data.(type) { case xml.CharData: val, err := strconv.ParseUint(string(data), 10, 64) if err != nil { return err } vali := uint(val) a.NUMANode = &vali } } } } return nil } func (a *DomainController) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "controller" if a.Type == "pci" { pci := domainControllerPCI{} pci.domainController = domainController(*a) if a.PCI != nil { pci.DomainControllerPCI = *a.PCI } return e.EncodeElement(pci, start) } else if a.Type == "usb" { usb := domainControllerUSB{} usb.domainController = domainController(*a) if a.USB != nil { usb.DomainControllerUSB = *a.USB } return e.EncodeElement(usb, start) } else if a.Type == "virtio-serial" { vioserial := domainControllerVirtIOSerial{} vioserial.domainController = domainController(*a) if a.VirtIOSerial != nil { vioserial.DomainControllerVirtIOSerial = *a.VirtIOSerial } return e.EncodeElement(vioserial, start) } else if a.Type == "xenbus" { xenbus := domainControllerXenBus{} xenbus.domainController = domainController(*a) if a.XenBus != nil { xenbus.DomainControllerXenBus = *a.XenBus } return e.EncodeElement(xenbus, start) } else { gen := domainController(*a) return e.EncodeElement(gen, start) } } func getAttr(attrs []xml.Attr, name string) (string, bool) { for _, attr := range attrs { if attr.Name.Local == name { return attr.Value, true } } return "", false } func (a *DomainController) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing 'type' attribute on domain controller") } if typ == "pci" { var pci domainControllerPCI err := d.DecodeElement(&pci, &start) if err != nil { return err } *a = DomainController(pci.domainController) a.PCI = &pci.DomainControllerPCI return nil } else if typ == "usb" { var usb domainControllerUSB err := d.DecodeElement(&usb, &start) if err != nil { return err } *a = DomainController(usb.domainController) a.USB = &usb.DomainControllerUSB return nil } else if typ == "virtio-serial" { var vioserial domainControllerVirtIOSerial err := d.DecodeElement(&vioserial, &start) if err != nil { return err } *a = DomainController(vioserial.domainController) a.VirtIOSerial = &vioserial.DomainControllerVirtIOSerial return nil } else if typ == "xenbus" { var xenbus domainControllerXenBus err := d.DecodeElement(&xenbus, &start) if err != nil { return err } *a = DomainController(xenbus.domainController) a.XenBus = &xenbus.DomainControllerXenBus return nil } else { var gen domainController err := d.DecodeElement(&gen, &start) if err != nil { return err } *a = DomainController(gen) return nil } } func (d *DomainGraphic) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainGraphic) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (d *DomainController) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainController) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (a *DomainDiskReservationsSource) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "source" src := DomainChardevSource(*a) typ := getChardevSourceType(&src) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } return e.EncodeElement(&src, start) } func (a *DomainDiskReservationsSource) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "unix" } src := createChardevSource(typ) err := d.DecodeElement(&src, &start) if err != nil { return err } *a = DomainDiskReservationsSource(*src) return nil } func (a *DomainDiskSourceVHostUser) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "source" src := DomainChardevSource(*a) typ := getChardevSourceType(&src) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } return e.EncodeElement(&src, start) } func (a *DomainDiskSourceVHostUser) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "unix" } src := createChardevSource(typ) err := d.DecodeElement(&src, &start) if err != nil { return err } *a = DomainDiskSourceVHostUser(*src) return nil } type domainDiskSource DomainDiskSource type domainDiskSourceFile struct { DomainDiskSourceFile domainDiskSource } type domainDiskSourceBlock struct { DomainDiskSourceBlock domainDiskSource } type domainDiskSourceDir struct { DomainDiskSourceDir domainDiskSource } type domainDiskSourceNetwork struct { DomainDiskSourceNetwork domainDiskSource } type domainDiskSourceVolume struct { DomainDiskSourceVolume domainDiskSource } type domainDiskSourceNVMEPCI struct { DomainDiskSourceNVMEPCI domainDiskSource } type domainDiskSourceVHostUser struct { DomainDiskSourceVHostUser domainDiskSource } func (a *DomainDiskSource) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.File != nil { if a.StartupPolicy == "" && a.Encryption == nil && a.File.File == "" { return nil } file := domainDiskSourceFile{ *a.File, domainDiskSource(*a), } return e.EncodeElement(&file, start) } else if a.Block != nil { if a.StartupPolicy == "" && a.Encryption == nil && a.Block.Dev == "" { return nil } block := domainDiskSourceBlock{ *a.Block, domainDiskSource(*a), } return e.EncodeElement(&block, start) } else if a.Dir != nil { dir := domainDiskSourceDir{ *a.Dir, domainDiskSource(*a), } return e.EncodeElement(&dir, start) } else if a.Network != nil { network := domainDiskSourceNetwork{ *a.Network, domainDiskSource(*a), } return e.EncodeElement(&network, start) } else if a.Volume != nil { if a.StartupPolicy == "" && a.Encryption == nil && a.Volume.Pool == "" && a.Volume.Volume == "" { return nil } volume := domainDiskSourceVolume{ *a.Volume, domainDiskSource(*a), } return e.EncodeElement(&volume, start) } else if a.NVME != nil { if a.NVME.PCI != nil { nvme := domainDiskSourceNVMEPCI{ *a.NVME.PCI, domainDiskSource(*a), } start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "pci", }) return e.EncodeElement(&nvme, start) } } else if a.VHostUser != nil { vhost := domainDiskSourceVHostUser{ *a.VHostUser, domainDiskSource(*a), } return e.EncodeElement(&vhost, start) } return nil } func (a *DomainDiskSource) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { if a.File != nil { file := domainDiskSourceFile{ *a.File, domainDiskSource(*a), } err := d.DecodeElement(&file, &start) if err != nil { return err } *a = DomainDiskSource(file.domainDiskSource) a.File = &file.DomainDiskSourceFile } else if a.Block != nil { block := domainDiskSourceBlock{ *a.Block, domainDiskSource(*a), } err := d.DecodeElement(&block, &start) if err != nil { return err } *a = DomainDiskSource(block.domainDiskSource) a.Block = &block.DomainDiskSourceBlock } else if a.Dir != nil { dir := domainDiskSourceDir{ *a.Dir, domainDiskSource(*a), } err := d.DecodeElement(&dir, &start) if err != nil { return err } *a = DomainDiskSource(dir.domainDiskSource) a.Dir = &dir.DomainDiskSourceDir } else if a.Network != nil { network := domainDiskSourceNetwork{ *a.Network, domainDiskSource(*a), } err := d.DecodeElement(&network, &start) if err != nil { return err } *a = DomainDiskSource(network.domainDiskSource) a.Network = &network.DomainDiskSourceNetwork } else if a.Volume != nil { volume := domainDiskSourceVolume{ *a.Volume, domainDiskSource(*a), } err := d.DecodeElement(&volume, &start) if err != nil { return err } *a = DomainDiskSource(volume.domainDiskSource) a.Volume = &volume.DomainDiskSourceVolume } else if a.NVME != nil { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing nvme source type") } if typ == "pci" { a.NVME.PCI = &DomainDiskSourceNVMEPCI{} nvme := domainDiskSourceNVMEPCI{ *a.NVME.PCI, domainDiskSource(*a), } err := d.DecodeElement(&nvme, &start) if err != nil { return err } *a = DomainDiskSource(nvme.domainDiskSource) a.NVME.PCI = &nvme.DomainDiskSourceNVMEPCI } } else if a.VHostUser != nil { vhost := domainDiskSourceVHostUser{ *a.VHostUser, domainDiskSource(*a), } err := d.DecodeElement(&vhost, &start) if err != nil { return err } *a = DomainDiskSource(vhost.domainDiskSource) a.VHostUser = &vhost.DomainDiskSourceVHostUser } return nil } type domainDiskBackingStore DomainDiskBackingStore func (a *DomainDiskBackingStore) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "backingStore" if a.Source != nil { if a.Source.File != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "file", }) } else if a.Source.Block != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "block", }) } else if a.Source.Dir != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "dir", }) } else if a.Source.Network != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "network", }) } else if a.Source.Volume != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "volume", }) } else if a.Source.VHostUser != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "vhostuser", }) } } disk := domainDiskBackingStore(*a) return e.EncodeElement(disk, start) } func (a *DomainDiskBackingStore) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "file" } a.Source = &DomainDiskSource{} if typ == "file" { a.Source.File = &DomainDiskSourceFile{} } else if typ == "block" { a.Source.Block = &DomainDiskSourceBlock{} } else if typ == "network" { a.Source.Network = &DomainDiskSourceNetwork{} } else if typ == "dir" { a.Source.Dir = &DomainDiskSourceDir{} } else if typ == "volume" { a.Source.Volume = &DomainDiskSourceVolume{} } else if typ == "vhostuser" { a.Source.VHostUser = &DomainDiskSourceVHostUser{} } disk := domainDiskBackingStore(*a) err := d.DecodeElement(&disk, &start) if err != nil { return err } *a = DomainDiskBackingStore(disk) if !ok && a.Source.File.File == "" { a.Source.File = nil } return nil } type domainDiskMirror DomainDiskMirror func (a *DomainDiskMirror) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "mirror" if a.Source != nil { if a.Source.File != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "file", }) if a.Source.File.File != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "file"}, a.Source.File.File, }) } if a.Format != nil && a.Format.Type != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "format"}, a.Format.Type, }) } } else if a.Source.Block != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "block", }) } else if a.Source.Dir != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "dir", }) } else if a.Source.Network != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "network", }) } else if a.Source.Volume != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "volume", }) } else if a.Source.VHostUser != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "vhostuser", }) } } disk := domainDiskMirror(*a) return e.EncodeElement(disk, start) } func (a *DomainDiskMirror) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "file" } a.Source = &DomainDiskSource{} if typ == "file" { a.Source.File = &DomainDiskSourceFile{} } else if typ == "block" { a.Source.Block = &DomainDiskSourceBlock{} } else if typ == "network" { a.Source.Network = &DomainDiskSourceNetwork{} } else if typ == "dir" { a.Source.Dir = &DomainDiskSourceDir{} } else if typ == "volume" { a.Source.Volume = &DomainDiskSourceVolume{} } else if typ == "vhostuser" { a.Source.VHostUser = &DomainDiskSourceVHostUser{} } disk := domainDiskMirror(*a) err := d.DecodeElement(&disk, &start) if err != nil { return err } *a = DomainDiskMirror(disk) if !ok { if a.Source.File.File == "" { file, ok := getAttr(start.Attr, "file") if ok { a.Source.File.File = file } else { a.Source.File = nil } } if a.Format == nil { format, ok := getAttr(start.Attr, "format") if ok { a.Format = &DomainDiskFormat{ Type: format, } } } } return nil } type domainDisk DomainDisk func (a *DomainDisk) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "disk" if a.Source != nil { if a.Source.File != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "file", }) } else if a.Source.Block != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "block", }) } else if a.Source.Dir != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "dir", }) } else if a.Source.Network != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "network", }) } else if a.Source.Volume != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "volume", }) } else if a.Source.NVME != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "nvme", }) } else if a.Source.VHostUser != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "vhostuser", }) } } disk := domainDisk(*a) return e.EncodeElement(disk, start) } func (a *DomainDisk) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "file" } a.Source = &DomainDiskSource{} if typ == "file" { a.Source.File = &DomainDiskSourceFile{} } else if typ == "block" { a.Source.Block = &DomainDiskSourceBlock{} } else if typ == "network" { a.Source.Network = &DomainDiskSourceNetwork{} } else if typ == "dir" { a.Source.Dir = &DomainDiskSourceDir{} } else if typ == "volume" { a.Source.Volume = &DomainDiskSourceVolume{} } else if typ == "nvme" { a.Source.NVME = &DomainDiskSourceNVME{} } else if typ == "vhostuser" { a.Source.VHostUser = &DomainDiskSourceVHostUser{} } disk := domainDisk(*a) err := d.DecodeElement(&disk, &start) if err != nil { return err } *a = DomainDisk(disk) return nil } func (d *DomainDisk) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainDisk) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } type domainInputSource DomainInputSource type domainInputSourcePassthrough struct { DomainInputSourcePassthrough domainInputSource } type domainInputSourceEVDev struct { DomainInputSourceEVDev domainInputSource } func (a *DomainInputSource) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.Passthrough != nil { passthrough := domainInputSourcePassthrough{ *a.Passthrough, domainInputSource(*a), } return e.EncodeElement(&passthrough, start) } else if a.EVDev != nil { evdev := domainInputSourceEVDev{ *a.EVDev, domainInputSource(*a), } return e.EncodeElement(&evdev, start) } return nil } func (a *DomainInputSource) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { if a.Passthrough != nil { passthrough := domainInputSourcePassthrough{ *a.Passthrough, domainInputSource(*a), } err := d.DecodeElement(&passthrough, &start) if err != nil { return err } *a = DomainInputSource(passthrough.domainInputSource) a.Passthrough = &passthrough.DomainInputSourcePassthrough } else if a.EVDev != nil { evdev := domainInputSourceEVDev{ *a.EVDev, domainInputSource(*a), } err := d.DecodeElement(&evdev, &start) if err != nil { return err } *a = DomainInputSource(evdev.domainInputSource) a.EVDev = &evdev.DomainInputSourceEVDev } return nil } type domainInput DomainInput func (a *DomainInput) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "input" input := domainInput(*a) return e.EncodeElement(input, start) } func (a *DomainInput) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if ok { a.Source = &DomainInputSource{} if typ == "passthrough" { a.Source.Passthrough = &DomainInputSourcePassthrough{} } else if typ == "evdev" { a.Source.EVDev = &DomainInputSourceEVDev{} } } input := domainInput(*a) err := d.DecodeElement(&input, &start) if err != nil { return err } *a = DomainInput(input) return nil } func (a *DomainFilesystemSource) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.Mount != nil { return e.EncodeElement(a.Mount, start) } else if a.Block != nil { return e.EncodeElement(a.Block, start) } else if a.File != nil { return e.EncodeElement(a.File, start) } else if a.Template != nil { return e.EncodeElement(a.Template, start) } else if a.RAM != nil { return e.EncodeElement(a.RAM, start) } else if a.Bind != nil { return e.EncodeElement(a.Bind, start) } else if a.Volume != nil { return e.EncodeElement(a.Volume, start) } return nil } func (a *DomainFilesystemSource) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { if a.Mount != nil { return d.DecodeElement(a.Mount, &start) } else if a.Block != nil { return d.DecodeElement(a.Block, &start) } else if a.File != nil { return d.DecodeElement(a.File, &start) } else if a.Template != nil { return d.DecodeElement(a.Template, &start) } else if a.RAM != nil { return d.DecodeElement(a.RAM, &start) } else if a.Bind != nil { return d.DecodeElement(a.Bind, &start) } else if a.Volume != nil { return d.DecodeElement(a.Volume, &start) } return nil } type domainFilesystem DomainFilesystem func (a *DomainFilesystem) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "filesystem" if a.Source != nil { if a.Source.Mount != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "mount", }) } else if a.Source.Block != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "block", }) } else if a.Source.File != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "file", }) } else if a.Source.Template != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "template", }) } else if a.Source.RAM != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "ram", }) } else if a.Source.Bind != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "bind", }) } else if a.Source.Volume != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "volume", }) } } fs := domainFilesystem(*a) return e.EncodeElement(fs, start) } func (a *DomainFilesystem) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "mount" } a.Source = &DomainFilesystemSource{} if typ == "mount" { a.Source.Mount = &DomainFilesystemSourceMount{} } else if typ == "block" { a.Source.Block = &DomainFilesystemSourceBlock{} } else if typ == "file" { a.Source.File = &DomainFilesystemSourceFile{} } else if typ == "template" { a.Source.Template = &DomainFilesystemSourceTemplate{} } else if typ == "ram" { a.Source.RAM = &DomainFilesystemSourceRAM{} } else if typ == "bind" { a.Source.Bind = &DomainFilesystemSourceBind{} } else if typ == "volume" { a.Source.Volume = &DomainFilesystemSourceVolume{} } fs := domainFilesystem(*a) err := d.DecodeElement(&fs, &start) if err != nil { return err } *a = DomainFilesystem(fs) return nil } func (d *DomainFilesystem) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainFilesystem) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (a *DomainInterfaceVirtualPortParams) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "parameters" if a.Any != nil { return e.EncodeElement(a.Any, start) } else if a.VEPA8021QBG != nil { return e.EncodeElement(a.VEPA8021QBG, start) } else if a.VNTag8011QBH != nil { return e.EncodeElement(a.VNTag8011QBH, start) } else if a.OpenVSwitch != nil { return e.EncodeElement(a.OpenVSwitch, start) } else if a.MidoNet != nil { return e.EncodeElement(a.MidoNet, start) } return nil } func (a *DomainInterfaceVirtualPortParams) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { if a.Any != nil { return d.DecodeElement(a.Any, &start) } else if a.VEPA8021QBG != nil { return d.DecodeElement(a.VEPA8021QBG, &start) } else if a.VNTag8011QBH != nil { return d.DecodeElement(a.VNTag8011QBH, &start) } else if a.OpenVSwitch != nil { return d.DecodeElement(a.OpenVSwitch, &start) } else if a.MidoNet != nil { return d.DecodeElement(a.MidoNet, &start) } return nil } type domainInterfaceVirtualPort DomainInterfaceVirtualPort func (a *DomainInterfaceVirtualPort) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "virtualport" if a.Params != nil { if a.Params.Any != nil { /* no type attr wanted */ } else if a.Params.VEPA8021QBG != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "802.1Qbg", }) } else if a.Params.VNTag8011QBH != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "802.1Qbh", }) } else if a.Params.OpenVSwitch != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "openvswitch", }) } else if a.Params.MidoNet != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "midonet", }) } } vp := domainInterfaceVirtualPort(*a) return e.EncodeElement(&vp, start) } func (a *DomainInterfaceVirtualPort) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") a.Params = &DomainInterfaceVirtualPortParams{} if !ok { var any DomainInterfaceVirtualPortParamsAny a.Params.Any = &any } else if typ == "802.1Qbg" { var vepa DomainInterfaceVirtualPortParamsVEPA8021QBG a.Params.VEPA8021QBG = &vepa } else if typ == "802.1Qbh" { var vntag DomainInterfaceVirtualPortParamsVNTag8021QBH a.Params.VNTag8011QBH = &vntag } else if typ == "openvswitch" { var ovs DomainInterfaceVirtualPortParamsOpenVSwitch a.Params.OpenVSwitch = &ovs } else if typ == "midonet" { var mido DomainInterfaceVirtualPortParamsMidoNet a.Params.MidoNet = &mido } vp := domainInterfaceVirtualPort(*a) err := d.DecodeElement(&vp, &start) if err != nil { return err } *a = DomainInterfaceVirtualPort(vp) return nil } func (a *DomainInterfaceSourceHostdev) MarshalXML(e *xml.Encoder, start xml.StartElement) error { e.EncodeToken(start) if a.PCI != nil { addr := xml.StartElement{ Name: xml.Name{Local: "address"}, } addr.Attr = append(addr.Attr, xml.Attr{ xml.Name{Local: "type"}, "pci", }) e.EncodeElement(a.PCI.Address, addr) } else if a.USB != nil { addr := xml.StartElement{ Name: xml.Name{Local: "address"}, } addr.Attr = append(addr.Attr, xml.Attr{ xml.Name{Local: "type"}, "usb", }) e.EncodeElement(a.USB.Address, addr) } e.EncodeToken(start.End()) return nil } func (a *DomainInterfaceSourceHostdev) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for { tok, err := d.Token() if err != nil { if err == io.EOF { break } return err } switch tok := tok.(type) { case xml.StartElement: if tok.Name.Local == "address" { typ, ok := getAttr(tok.Attr, "type") if !ok { return fmt.Errorf("Missing hostdev address type attribute") } if typ == "pci" { a.PCI = &DomainHostdevSubsysPCISource{ "", &DomainAddressPCI{}, } err := d.DecodeElement(a.PCI.Address, &tok) if err != nil { return err } } else if typ == "usb" { a.USB = &DomainHostdevSubsysUSBSource{ &DomainAddressUSB{}, } err := d.DecodeElement(a.USB, &tok) if err != nil { return err } } } } } d.Skip() return nil } func (a *DomainInterfaceSource) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.User != nil { /* We don't want an empty for User mode */ //return e.EncodeElement(a.User, start) return nil } else if a.Ethernet != nil { if len(a.Ethernet.IP) > 0 && len(a.Ethernet.Route) > 0 { return e.EncodeElement(a.Ethernet, start) } return nil } else if a.VHostUser != nil { typ := getChardevSourceType(a.VHostUser) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } return e.EncodeElement(a.VHostUser, start) } else if a.Server != nil { return e.EncodeElement(a.Server, start) } else if a.Client != nil { return e.EncodeElement(a.Client, start) } else if a.MCast != nil { return e.EncodeElement(a.MCast, start) } else if a.Network != nil { return e.EncodeElement(a.Network, start) } else if a.Bridge != nil { return e.EncodeElement(a.Bridge, start) } else if a.Internal != nil { return e.EncodeElement(a.Internal, start) } else if a.Direct != nil { return e.EncodeElement(a.Direct, start) } else if a.Hostdev != nil { return e.EncodeElement(a.Hostdev, start) } else if a.UDP != nil { return e.EncodeElement(a.UDP, start) } else if a.VDPA != nil { return e.EncodeElement(a.VDPA, start) } return nil } func (a *DomainInterfaceSource) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { if a.User != nil { return d.DecodeElement(a.User, &start) } else if a.Ethernet != nil { return d.DecodeElement(a.Ethernet, &start) } else if a.VHostUser != nil { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "pty" } a.VHostUser = createChardevSource(typ) return d.DecodeElement(a.VHostUser, &start) } else if a.Server != nil { return d.DecodeElement(a.Server, &start) } else if a.Client != nil { return d.DecodeElement(a.Client, &start) } else if a.MCast != nil { return d.DecodeElement(a.MCast, &start) } else if a.Network != nil { return d.DecodeElement(a.Network, &start) } else if a.Bridge != nil { return d.DecodeElement(a.Bridge, &start) } else if a.Internal != nil { return d.DecodeElement(a.Internal, &start) } else if a.Direct != nil { return d.DecodeElement(a.Direct, &start) } else if a.Hostdev != nil { return d.DecodeElement(a.Hostdev, &start) } else if a.UDP != nil { return d.DecodeElement(a.UDP, &start) } else if a.VDPA != nil { return d.DecodeElement(a.VDPA, &start) } return nil } type domainInterface DomainInterface func (a *DomainInterface) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "interface" if a.Source != nil { if a.Source.User != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "user", }) } else if a.Source.Ethernet != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "ethernet", }) } else if a.Source.VHostUser != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "vhostuser", }) } else if a.Source.Server != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "server", }) } else if a.Source.Client != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "client", }) } else if a.Source.MCast != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "mcast", }) } else if a.Source.Network != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "network", }) } else if a.Source.Bridge != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "bridge", }) } else if a.Source.Internal != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "internal", }) } else if a.Source.Direct != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "direct", }) } else if a.Source.Hostdev != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "hostdev", }) } else if a.Source.UDP != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "udp", }) } else if a.Source.VDPA != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "vdpa", }) } } fs := domainInterface(*a) return e.EncodeElement(fs, start) } func (a *DomainInterface) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing interface type attribute") } a.Source = &DomainInterfaceSource{} if typ == "user" { a.Source.User = &DomainInterfaceSourceUser{} } else if typ == "ethernet" { a.Source.Ethernet = &DomainInterfaceSourceEthernet{} } else if typ == "vhostuser" { a.Source.VHostUser = &DomainChardevSource{} } else if typ == "server" { a.Source.Server = &DomainInterfaceSourceServer{} } else if typ == "client" { a.Source.Client = &DomainInterfaceSourceClient{} } else if typ == "mcast" { a.Source.MCast = &DomainInterfaceSourceMCast{} } else if typ == "network" { a.Source.Network = &DomainInterfaceSourceNetwork{} } else if typ == "bridge" { a.Source.Bridge = &DomainInterfaceSourceBridge{} } else if typ == "internal" { a.Source.Internal = &DomainInterfaceSourceInternal{} } else if typ == "direct" { a.Source.Direct = &DomainInterfaceSourceDirect{} } else if typ == "hostdev" { a.Source.Hostdev = &DomainInterfaceSourceHostdev{} } else if typ == "udp" { a.Source.UDP = &DomainInterfaceSourceUDP{} } else if typ == "vdpa" { a.Source.VDPA = &DomainInterfaceSourceVDPA{} } fs := domainInterface(*a) err := d.DecodeElement(&fs, &start) if err != nil { return err } *a = DomainInterface(fs) return nil } func (d *DomainInterface) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainInterface) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } type domainSmartcard DomainSmartcard func (a *DomainSmartcard) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "smartcard" if a.Passthrough != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "passthrough", }) typ := getChardevSourceType(a.Passthrough) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } } else if a.Host != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "host", }) } else if len(a.HostCerts) != 0 { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "host-certificates", }) } smartcard := domainSmartcard(*a) return e.EncodeElement(smartcard, start) } func (a *DomainSmartcard) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { mode, ok := getAttr(start.Attr, "mode") if !ok { return fmt.Errorf("Missing mode on smartcard device") } if mode == "host" { a.Host = &DomainSmartcardHost{} } else if mode == "passthrough" { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "pty" } a.Passthrough = createChardevSource(typ) } smartcard := domainSmartcard(*a) err := d.DecodeElement(&smartcard, &start) if err != nil { return err } *a = DomainSmartcard(smartcard) return nil } func (d *DomainSmartcard) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainSmartcard) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (a *DomainTPMBackend) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "backend" if a.Passthrough != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "passthrough", }) err := e.EncodeElement(a.Passthrough, start) if err != nil { return err } } else if a.Emulator != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "emulator", }) err := e.EncodeElement(a.Emulator, start) if err != nil { return err } } return nil } func (a *DomainTPMBackend) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing TPM backend type") } if typ == "passthrough" { a.Passthrough = &DomainTPMBackendPassthrough{} err := d.DecodeElement(a.Passthrough, &start) if err != nil { return err } } else if typ == "emulator" { a.Emulator = &DomainTPMBackendEmulator{} err := d.DecodeElement(a.Emulator, &start) if err != nil { return err } } else { d.Skip() } return nil } func (d *DomainTPM) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainTPM) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (d *DomainShmem) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainShmem) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func getChardevSourceType(s *DomainChardevSource) string { if s.Null != nil { return "null" } else if s.VC != nil { return "vc" } else if s.Pty != nil { return "pty" } else if s.Dev != nil { return "dev" } else if s.File != nil { return "file" } else if s.Pipe != nil { return "pipe" } else if s.StdIO != nil { return "stdio" } else if s.UDP != nil { return "udp" } else if s.TCP != nil { return "tcp" } else if s.UNIX != nil { return "unix" } else if s.SpiceVMC != nil { return "spicevmc" } else if s.SpicePort != nil { return "spiceport" } else if s.NMDM != nil { return "nmdm" } return "" } func createChardevSource(typ string) *DomainChardevSource { switch typ { case "null": return &DomainChardevSource{ Null: &DomainChardevSourceNull{}, } case "vc": return &DomainChardevSource{ VC: &DomainChardevSourceVC{}, } case "pty": return &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, } case "dev": return &DomainChardevSource{ Dev: &DomainChardevSourceDev{}, } case "file": return &DomainChardevSource{ File: &DomainChardevSourceFile{}, } case "pipe": return &DomainChardevSource{ Pipe: &DomainChardevSourcePipe{}, } case "stdio": return &DomainChardevSource{ StdIO: &DomainChardevSourceStdIO{}, } case "udp": return &DomainChardevSource{ UDP: &DomainChardevSourceUDP{}, } case "tcp": return &DomainChardevSource{ TCP: &DomainChardevSourceTCP{}, } case "unix": return &DomainChardevSource{ UNIX: &DomainChardevSourceUNIX{}, } case "spicevmc": return &DomainChardevSource{ SpiceVMC: &DomainChardevSourceSpiceVMC{}, } case "spiceport": return &DomainChardevSource{ SpicePort: &DomainChardevSourceSpicePort{}, } case "nmdm": return &DomainChardevSource{ NMDM: &DomainChardevSourceNMDM{}, } } return nil } type domainChardevSourceUDPFlat struct { Mode string `xml:"mode,attr"` Host string `xml:"host,attr,omitempty"` Service string `xml:"service,attr,omitempty"` } func (a *DomainChardevSource) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.Null != nil { return nil } else if a.VC != nil { return nil } else if a.Pty != nil { if a.Pty.Path != "" { return e.EncodeElement(a.Pty, start) } return nil } else if a.Dev != nil { return e.EncodeElement(a.Dev, start) } else if a.File != nil { return e.EncodeElement(a.File, start) } else if a.Pipe != nil { return e.EncodeElement(a.Pipe, start) } else if a.StdIO != nil { return nil } else if a.UDP != nil { srcs := []domainChardevSourceUDPFlat{ domainChardevSourceUDPFlat{ Mode: "bind", Host: a.UDP.BindHost, Service: a.UDP.BindService, }, domainChardevSourceUDPFlat{ Mode: "connect", Host: a.UDP.ConnectHost, Service: a.UDP.ConnectService, }, } if srcs[0].Host != "" || srcs[0].Service != "" { err := e.EncodeElement(&srcs[0], start) if err != nil { return err } } if srcs[1].Host != "" || srcs[1].Service != "" { err := e.EncodeElement(&srcs[1], start) if err != nil { return err } } } else if a.TCP != nil { return e.EncodeElement(a.TCP, start) } else if a.UNIX != nil { if a.UNIX.Path == "" && a.UNIX.Mode == "" { return nil } return e.EncodeElement(a.UNIX, start) } else if a.SpiceVMC != nil { return nil } else if a.SpicePort != nil { return e.EncodeElement(a.SpicePort, start) } else if a.NMDM != nil { return e.EncodeElement(a.NMDM, start) } return nil } func (a *DomainChardevSource) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { if a.Null != nil { d.Skip() return nil } else if a.VC != nil { d.Skip() return nil } else if a.Pty != nil { return d.DecodeElement(a.Pty, &start) } else if a.Dev != nil { return d.DecodeElement(a.Dev, &start) } else if a.File != nil { return d.DecodeElement(a.File, &start) } else if a.Pipe != nil { return d.DecodeElement(a.Pipe, &start) } else if a.StdIO != nil { d.Skip() return nil } else if a.UDP != nil { src := domainChardevSourceUDPFlat{} err := d.DecodeElement(&src, &start) if src.Mode == "connect" { a.UDP.ConnectHost = src.Host a.UDP.ConnectService = src.Service } else { a.UDP.BindHost = src.Host a.UDP.BindService = src.Service } return err } else if a.TCP != nil { return d.DecodeElement(a.TCP, &start) } else if a.UNIX != nil { return d.DecodeElement(a.UNIX, &start) } else if a.SpiceVMC != nil { d.Skip() return nil } else if a.SpicePort != nil { return d.DecodeElement(a.SpicePort, &start) } else if a.NMDM != nil { return d.DecodeElement(a.NMDM, &start) } return nil } type domainConsole DomainConsole func (a *DomainConsole) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "console" if a.Source != nil { typ := getChardevSourceType(a.Source) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } } fs := domainConsole(*a) return e.EncodeElement(fs, start) } func (a *DomainConsole) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "pty" } a.Source = createChardevSource(typ) con := domainConsole(*a) err := d.DecodeElement(&con, &start) if err != nil { return err } *a = DomainConsole(con) return nil } func (d *DomainConsole) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainConsole) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } type domainSerial DomainSerial func (a *DomainSerial) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "serial" if a.Source != nil { typ := getChardevSourceType(a.Source) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } } s := domainSerial(*a) return e.EncodeElement(s, start) } func (a *DomainSerial) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "pty" } a.Source = createChardevSource(typ) con := domainSerial(*a) err := d.DecodeElement(&con, &start) if err != nil { return err } *a = DomainSerial(con) return nil } func (d *DomainSerial) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainSerial) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } type domainParallel DomainParallel func (a *DomainParallel) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "parallel" if a.Source != nil { typ := getChardevSourceType(a.Source) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } } s := domainParallel(*a) return e.EncodeElement(s, start) } func (a *DomainParallel) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "pty" } a.Source = createChardevSource(typ) con := domainParallel(*a) err := d.DecodeElement(&con, &start) if err != nil { return err } *a = DomainParallel(con) return nil } func (d *DomainParallel) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainParallel) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (d *DomainInput) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainInput) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (d *DomainVideo) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainVideo) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } type domainChannelTarget DomainChannelTarget func (a *DomainChannelTarget) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.VirtIO != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "virtio", }) return e.EncodeElement(a.VirtIO, start) } else if a.Xen != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "xen", }) return e.EncodeElement(a.Xen, start) } else if a.GuestFWD != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "guestfwd", }) return e.EncodeElement(a.GuestFWD, start) } return nil } func (a *DomainChannelTarget) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing channel target type") } if typ == "virtio" { a.VirtIO = &DomainChannelTargetVirtIO{} return d.DecodeElement(a.VirtIO, &start) } else if typ == "xen" { a.Xen = &DomainChannelTargetXen{} return d.DecodeElement(a.Xen, &start) } else if typ == "guestfwd" { a.GuestFWD = &DomainChannelTargetGuestFWD{} return d.DecodeElement(a.GuestFWD, &start) } d.Skip() return nil } type domainChannel DomainChannel func (a *DomainChannel) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "channel" if a.Source != nil { typ := getChardevSourceType(a.Source) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } } fs := domainChannel(*a) return e.EncodeElement(fs, start) } func (a *DomainChannel) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "pty" } a.Source = createChardevSource(typ) con := domainChannel(*a) err := d.DecodeElement(&con, &start) if err != nil { return err } *a = DomainChannel(con) return nil } func (d *DomainChannel) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainChannel) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (a *DomainRedirFilterUSB) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "class", a.Class, "0x%02x") marshalUintAttr(&start, "vendor", a.Vendor, "0x%04x") marshalUintAttr(&start, "product", a.Product, "0x%04x") if a.Version != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "version"}, a.Version, }) } start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "allow"}, a.Allow, }) e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainRedirFilterUSB) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "class" && attr.Value != "-1" { if err := unmarshalUintAttr(attr.Value, &a.Class, 0); err != nil { return err } } else if attr.Name.Local == "product" && attr.Value != "-1" { if err := unmarshalUintAttr(attr.Value, &a.Product, 0); err != nil { return err } } else if attr.Name.Local == "vendor" && attr.Value != "-1" { if err := unmarshalUintAttr(attr.Value, &a.Vendor, 0); err != nil { return err } } else if attr.Name.Local == "version" && attr.Value != "-1" { a.Version = attr.Value } else if attr.Name.Local == "allow" { a.Allow = attr.Value } } d.Skip() return nil } type domainRedirDev DomainRedirDev func (a *DomainRedirDev) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "redirdev" if a.Source != nil { typ := getChardevSourceType(a.Source) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } } fs := domainRedirDev(*a) return e.EncodeElement(fs, start) } func (a *DomainRedirDev) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "pty" } a.Source = createChardevSource(typ) con := domainRedirDev(*a) err := d.DecodeElement(&con, &start) if err != nil { return err } *a = DomainRedirDev(con) return nil } func (d *DomainRedirDev) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainRedirDev) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (d *DomainMemBalloon) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainMemBalloon) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (d *DomainVSock) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainVSock) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (d *DomainSound) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainSound) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } type domainRNGBackendEGD DomainRNGBackendEGD func (a *DomainRNGBackendEGD) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "backend" if a.Source != nil { typ := getChardevSourceType(a.Source) if typ != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, typ, }) } } egd := domainRNGBackendEGD(*a) return e.EncodeElement(egd, start) } func (a *DomainRNGBackendEGD) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "pty" } a.Source = createChardevSource(typ) con := domainRNGBackendEGD(*a) err := d.DecodeElement(&con, &start) if err != nil { return err } *a = DomainRNGBackendEGD(con) return nil } func (a *DomainRNGBackend) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.Random != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "model"}, "random", }) return e.EncodeElement(a.Random, start) } else if a.EGD != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "model"}, "egd", }) return e.EncodeElement(a.EGD, start) } else if a.BuiltIn != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "model"}, "builtin", }) return e.EncodeElement(a.BuiltIn, start) } return nil } func (a *DomainRNGBackend) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { model, ok := getAttr(start.Attr, "model") if !ok { return nil } if model == "random" { a.Random = &DomainRNGBackendRandom{} err := d.DecodeElement(a.Random, &start) if err != nil { return err } } else if model == "egd" { a.EGD = &DomainRNGBackendEGD{} err := d.DecodeElement(a.EGD, &start) if err != nil { return err } } else if model == "builtin" { a.BuiltIn = &DomainRNGBackendBuiltIn{} err := d.DecodeElement(a.BuiltIn, &start) if err != nil { return err } } d.Skip() return nil } func (d *DomainRNG) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainRNG) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (a *DomainHostdevSubsysSCSISource) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.Host != nil { return e.EncodeElement(a.Host, start) } else if a.ISCSI != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "protocol"}, "iscsi", }) return e.EncodeElement(a.ISCSI, start) } return nil } func (a *DomainHostdevSubsysSCSISource) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { proto, ok := getAttr(start.Attr, "protocol") if !ok { a.Host = &DomainHostdevSubsysSCSISourceHost{} err := d.DecodeElement(a.Host, &start) if err != nil { return err } } if proto == "iscsi" { a.ISCSI = &DomainHostdevSubsysSCSISourceISCSI{} err := d.DecodeElement(a.ISCSI, &start) if err != nil { return err } } d.Skip() return nil } type domainHostdev DomainHostdev type domainHostdevSubsysSCSI struct { DomainHostdevSubsysSCSI domainHostdev } type domainHostdevSubsysSCSIHost struct { DomainHostdevSubsysSCSIHost domainHostdev } type domainHostdevSubsysUSB struct { DomainHostdevSubsysUSB domainHostdev } type domainHostdevSubsysPCI struct { DomainHostdevSubsysPCI domainHostdev } type domainHostdevSubsysMDev struct { DomainHostdevSubsysMDev domainHostdev } type domainHostdevCapsStorage struct { DomainHostdevCapsStorage domainHostdev } type domainHostdevCapsMisc struct { DomainHostdevCapsMisc domainHostdev } type domainHostdevCapsNet struct { DomainHostdevCapsNet domainHostdev } func (a *DomainHostdev) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "hostdev" if a.SubsysSCSI != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "subsystem", }) start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "scsi", }) scsi := domainHostdevSubsysSCSI{} scsi.domainHostdev = domainHostdev(*a) scsi.DomainHostdevSubsysSCSI = *a.SubsysSCSI return e.EncodeElement(scsi, start) } else if a.SubsysSCSIHost != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "subsystem", }) start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "scsi_host", }) scsi_host := domainHostdevSubsysSCSIHost{} scsi_host.domainHostdev = domainHostdev(*a) scsi_host.DomainHostdevSubsysSCSIHost = *a.SubsysSCSIHost return e.EncodeElement(scsi_host, start) } else if a.SubsysUSB != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "subsystem", }) start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "usb", }) usb := domainHostdevSubsysUSB{} usb.domainHostdev = domainHostdev(*a) usb.DomainHostdevSubsysUSB = *a.SubsysUSB return e.EncodeElement(usb, start) } else if a.SubsysPCI != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "subsystem", }) start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "pci", }) pci := domainHostdevSubsysPCI{} pci.domainHostdev = domainHostdev(*a) pci.DomainHostdevSubsysPCI = *a.SubsysPCI return e.EncodeElement(pci, start) } else if a.SubsysMDev != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "subsystem", }) start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "mdev", }) mdev := domainHostdevSubsysMDev{} mdev.domainHostdev = domainHostdev(*a) mdev.DomainHostdevSubsysMDev = *a.SubsysMDev return e.EncodeElement(mdev, start) } else if a.CapsStorage != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "capabilities", }) start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "storage", }) storage := domainHostdevCapsStorage{} storage.domainHostdev = domainHostdev(*a) storage.DomainHostdevCapsStorage = *a.CapsStorage return e.EncodeElement(storage, start) } else if a.CapsMisc != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "capabilities", }) start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "misc", }) misc := domainHostdevCapsMisc{} misc.domainHostdev = domainHostdev(*a) misc.DomainHostdevCapsMisc = *a.CapsMisc return e.EncodeElement(misc, start) } else if a.CapsNet != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "mode"}, "capabilities", }) start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "net", }) net := domainHostdevCapsNet{} net.domainHostdev = domainHostdev(*a) net.DomainHostdevCapsNet = *a.CapsNet return e.EncodeElement(net, start) } else { gen := domainHostdev(*a) return e.EncodeElement(gen, start) } } func (a *DomainHostdev) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { mode, ok := getAttr(start.Attr, "mode") if !ok { return fmt.Errorf("Missing 'mode' attribute on domain hostdev") } typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing 'type' attribute on domain controller") } if mode == "subsystem" { if typ == "scsi" { var scsi domainHostdevSubsysSCSI err := d.DecodeElement(&scsi, &start) if err != nil { return err } *a = DomainHostdev(scsi.domainHostdev) a.SubsysSCSI = &scsi.DomainHostdevSubsysSCSI return nil } else if typ == "scsi_host" { var scsi_host domainHostdevSubsysSCSIHost err := d.DecodeElement(&scsi_host, &start) if err != nil { return err } *a = DomainHostdev(scsi_host.domainHostdev) a.SubsysSCSIHost = &scsi_host.DomainHostdevSubsysSCSIHost return nil } else if typ == "usb" { var usb domainHostdevSubsysUSB err := d.DecodeElement(&usb, &start) if err != nil { return err } *a = DomainHostdev(usb.domainHostdev) a.SubsysUSB = &usb.DomainHostdevSubsysUSB return nil } else if typ == "pci" { var pci domainHostdevSubsysPCI err := d.DecodeElement(&pci, &start) if err != nil { return err } *a = DomainHostdev(pci.domainHostdev) a.SubsysPCI = &pci.DomainHostdevSubsysPCI return nil } else if typ == "mdev" { var mdev domainHostdevSubsysMDev err := d.DecodeElement(&mdev, &start) if err != nil { return err } *a = DomainHostdev(mdev.domainHostdev) a.SubsysMDev = &mdev.DomainHostdevSubsysMDev return nil } } else if mode == "capabilities" { if typ == "storage" { var storage domainHostdevCapsStorage err := d.DecodeElement(&storage, &start) if err != nil { return err } *a = DomainHostdev(storage.domainHostdev) a.CapsStorage = &storage.DomainHostdevCapsStorage return nil } else if typ == "misc" { var misc domainHostdevCapsMisc err := d.DecodeElement(&misc, &start) if err != nil { return err } *a = DomainHostdev(misc.domainHostdev) a.CapsMisc = &misc.DomainHostdevCapsMisc return nil } else if typ == "net" { var net domainHostdevCapsNet err := d.DecodeElement(&net, &start) if err != nil { return err } *a = DomainHostdev(net.domainHostdev) a.CapsNet = &net.DomainHostdevCapsNet return nil } } var gen domainHostdev err := d.DecodeElement(&gen, &start) if err != nil { return err } *a = DomainHostdev(gen) return nil } func (d *DomainHostdev) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainHostdev) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (a *DomainGraphicListener) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "listen" if a.Address != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "address", }) return e.EncodeElement(a.Address, start) } else if a.Network != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "network", }) return e.EncodeElement(a.Network, start) } else if a.Socket != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "socket", }) return e.EncodeElement(a.Socket, start) } else { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "none", }) e.EncodeToken(start) e.EncodeToken(start.End()) } return nil } func (a *DomainGraphicListener) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing 'type' attribute on domain graphics listen") } if typ == "address" { var addr DomainGraphicListenerAddress err := d.DecodeElement(&addr, &start) if err != nil { return err } a.Address = &addr return nil } else if typ == "network" { var net DomainGraphicListenerNetwork err := d.DecodeElement(&net, &start) if err != nil { return err } a.Network = &net return nil } else if typ == "socket" { var sock DomainGraphicListenerSocket err := d.DecodeElement(&sock, &start) if err != nil { return err } a.Socket = &sock return nil } else if typ == "none" { d.Skip() } return nil } type domainGraphicSDL struct { DomainGraphicSDL Audio *DomainGraphicAudio `xml:"audio"` } type domainGraphicVNC struct { DomainGraphicVNC Audio *DomainGraphicAudio `xml:"audio"` } type domainGraphicRDP struct { DomainGraphicRDP Audio *DomainGraphicAudio `xml:"audio"` } type domainGraphicDesktop struct { DomainGraphicDesktop Audio *DomainGraphicAudio `xml:"audio"` } type domainGraphicSpice struct { DomainGraphicSpice Audio *DomainGraphicAudio `xml:"audio"` } type domainGraphicEGLHeadless struct { DomainGraphicEGLHeadless Audio *DomainGraphicAudio `xml:"audio"` } func (a *DomainGraphic) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "graphics" if a.SDL != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "sdl", }) sdl := domainGraphicSDL{*a.SDL, a.Audio} return e.EncodeElement(sdl, start) } else if a.VNC != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "vnc", }) vnc := domainGraphicVNC{*a.VNC, a.Audio} return e.EncodeElement(vnc, start) } else if a.RDP != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "rdp", }) rdp := domainGraphicRDP{*a.RDP, a.Audio} return e.EncodeElement(rdp, start) } else if a.Desktop != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "desktop", }) desktop := domainGraphicDesktop{*a.Desktop, a.Audio} return e.EncodeElement(desktop, start) } else if a.Spice != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "spice", }) spice := domainGraphicSpice{*a.Spice, a.Audio} return e.EncodeElement(spice, start) } else if a.EGLHeadless != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "egl-headless", }) egl := domainGraphicEGLHeadless{*a.EGLHeadless, a.Audio} return e.EncodeElement(egl, start) } return nil } func (a *DomainGraphic) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing 'type' attribute on domain graphics") } if typ == "sdl" { var sdl domainGraphicSDL err := d.DecodeElement(&sdl, &start) if err != nil { return err } a.SDL = &sdl.DomainGraphicSDL a.Audio = sdl.Audio return nil } else if typ == "vnc" { var vnc domainGraphicVNC err := d.DecodeElement(&vnc, &start) if err != nil { return err } a.VNC = &vnc.DomainGraphicVNC a.Audio = vnc.Audio return nil } else if typ == "rdp" { var rdp domainGraphicRDP err := d.DecodeElement(&rdp, &start) if err != nil { return err } a.RDP = &rdp.DomainGraphicRDP a.Audio = rdp.Audio return nil } else if typ == "desktop" { var desktop domainGraphicDesktop err := d.DecodeElement(&desktop, &start) if err != nil { return err } a.Desktop = &desktop.DomainGraphicDesktop a.Audio = desktop.Audio return nil } else if typ == "spice" { var spice domainGraphicSpice err := d.DecodeElement(&spice, &start) if err != nil { return err } a.Spice = &spice.DomainGraphicSpice a.Audio = spice.Audio return nil } else if typ == "egl-headless" { var egl domainGraphicEGLHeadless err := d.DecodeElement(&egl, &start) if err != nil { return err } a.EGLHeadless = &egl.DomainGraphicEGLHeadless a.Audio = egl.Audio return nil } return nil } func (a *DomainAudio) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "audio" if a.ID != 0 { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "id"}, fmt.Sprintf("%d", a.ID), }) } if a.None != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "none", }) return e.EncodeElement(a.None, start) } else if a.ALSA != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "alsa", }) return e.EncodeElement(a.ALSA, start) } else if a.CoreAudio != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "coreaudio", }) return e.EncodeElement(a.CoreAudio, start) } else if a.Jack != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "jack", }) return e.EncodeElement(a.Jack, start) } else if a.OSS != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "oss", }) return e.EncodeElement(a.OSS, start) } else if a.PulseAudio != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "pulseaudio", }) return e.EncodeElement(a.PulseAudio, start) } else if a.SDL != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "sdl", }) return e.EncodeElement(a.SDL, start) } else if a.SPICE != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "spice", }) return e.EncodeElement(a.SPICE, start) } else if a.File != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "file", }) return e.EncodeElement(a.File, start) } return nil } func (a *DomainAudio) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing 'type' attribute on domain audio") } id, ok := getAttr(start.Attr, "id") if ok { idval, err := strconv.ParseInt(id, 10, 32) if err != nil { return err } a.ID = int(idval) } if typ == "none" { var none DomainAudioNone err := d.DecodeElement(&none, &start) if err != nil { return err } a.None = &none return nil } else if typ == "alsa" { var alsa DomainAudioALSA err := d.DecodeElement(&alsa, &start) if err != nil { return err } a.ALSA = &alsa return nil } else if typ == "coreaudio" { var coreaudio DomainAudioCoreAudio err := d.DecodeElement(&coreaudio, &start) if err != nil { return err } a.CoreAudio = &coreaudio return nil } else if typ == "jack" { var jack DomainAudioJack err := d.DecodeElement(&jack, &start) if err != nil { return err } a.Jack = &jack return nil } else if typ == "oss" { var oss DomainAudioOSS err := d.DecodeElement(&oss, &start) if err != nil { return err } a.OSS = &oss return nil } else if typ == "pulseaudio" { var pulseaudio DomainAudioPulseAudio err := d.DecodeElement(&pulseaudio, &start) if err != nil { return err } a.PulseAudio = &pulseaudio return nil } else if typ == "sdl" { var sdl DomainAudioSDL err := d.DecodeElement(&sdl, &start) if err != nil { return err } a.SDL = &sdl return nil } else if typ == "spice" { var spice DomainAudioSPICE err := d.DecodeElement(&spice, &start) if err != nil { return err } a.SPICE = &spice return nil } else if typ == "file" { var file DomainAudioFile err := d.DecodeElement(&file, &start) if err != nil { return err } a.File = &file return nil } return nil } func (d *DomainMemorydev) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainMemorydev) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (d *DomainWatchdog) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainWatchdog) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func marshalUintAttr(start *xml.StartElement, name string, val *uint, format string) { if val != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: name}, fmt.Sprintf(format, *val), }) } } func marshalUint64Attr(start *xml.StartElement, name string, val *uint64, format string) { if val != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: name}, fmt.Sprintf(format, *val), }) } } func (a *DomainAddressPCI) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "domain", a.Domain, "0x%04x") marshalUintAttr(&start, "bus", a.Bus, "0x%02x") marshalUintAttr(&start, "slot", a.Slot, "0x%02x") marshalUintAttr(&start, "function", a.Function, "0x%x") if a.MultiFunction != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "multifunction"}, a.MultiFunction, }) } e.EncodeToken(start) if a.ZPCI != nil { zpci := xml.StartElement{} zpci.Name.Local = "zpci" err := e.EncodeElement(a.ZPCI, zpci) if err != nil { return err } } e.EncodeToken(start.End()) return nil } func (a *DomainAddressZPCI) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "uid", a.UID, "0x%04x") marshalUintAttr(&start, "fid", a.FID, "0x%04x") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressUSB) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "bus", a.Bus, "%d") if a.Port != "" { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "port"}, a.Port, }) } marshalUintAttr(&start, "device", a.Device, "%d") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressDrive) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "controller", a.Controller, "%d") marshalUintAttr(&start, "bus", a.Bus, "%d") marshalUintAttr(&start, "target", a.Target, "%d") marshalUintAttr(&start, "unit", a.Unit, "%d") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressDIMM) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "slot", a.Slot, "%d") marshalUint64Attr(&start, "base", a.Base, "0x%x") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressISA) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "iobase", a.IOBase, "0x%x") marshalUintAttr(&start, "irq", a.IRQ, "0x%x") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressVirtioMMIO) MarshalXML(e *xml.Encoder, start xml.StartElement) error { e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressCCW) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "cssid", a.CSSID, "0x%x") marshalUintAttr(&start, "ssid", a.SSID, "0x%x") marshalUintAttr(&start, "devno", a.DevNo, "0x%04x") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressVirtioSerial) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "controller", a.Controller, "%d") marshalUintAttr(&start, "bus", a.Bus, "%d") marshalUintAttr(&start, "port", a.Port, "%d") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressSpaprVIO) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUint64Attr(&start, "reg", a.Reg, "0x%x") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressCCID) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "controller", a.Controller, "%d") marshalUintAttr(&start, "slot", a.Slot, "%d") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressVirtioS390) MarshalXML(e *xml.Encoder, start xml.StartElement) error { e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddressUnassigned) MarshalXML(e *xml.Encoder, start xml.StartElement) error { e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *DomainAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.USB != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "usb", }) return e.EncodeElement(a.USB, start) } else if a.PCI != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "pci", }) return e.EncodeElement(a.PCI, start) } else if a.Drive != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "drive", }) return e.EncodeElement(a.Drive, start) } else if a.DIMM != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "dimm", }) return e.EncodeElement(a.DIMM, start) } else if a.ISA != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "isa", }) return e.EncodeElement(a.ISA, start) } else if a.VirtioMMIO != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "virtio-mmio", }) return e.EncodeElement(a.VirtioMMIO, start) } else if a.CCW != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "ccw", }) return e.EncodeElement(a.CCW, start) } else if a.VirtioSerial != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "virtio-serial", }) return e.EncodeElement(a.VirtioSerial, start) } else if a.SpaprVIO != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "spapr-vio", }) return e.EncodeElement(a.SpaprVIO, start) } else if a.CCID != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "ccid", }) return e.EncodeElement(a.CCID, start) } else if a.VirtioS390 != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "virtio-s390", }) return e.EncodeElement(a.VirtioS390, start) } else if a.Unassigned != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "unassigned", }) return e.EncodeElement(a.Unassigned, start) } else { return nil } } func unmarshalUint64Attr(valstr string, valptr **uint64, base int) error { if base == 16 { valstr = strings.TrimPrefix(valstr, "0x") } val, err := strconv.ParseUint(valstr, base, 64) if err != nil { return err } *valptr = &val return nil } func unmarshalUintAttr(valstr string, valptr **uint, base int) error { if base == 16 { valstr = strings.TrimPrefix(valstr, "0x") } val, err := strconv.ParseUint(valstr, base, 64) if err != nil { return err } vali := uint(val) *valptr = &vali return nil } func (a *DomainAddressUSB) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "bus" { if err := unmarshalUintAttr(attr.Value, &a.Bus, 10); err != nil { return err } } else if attr.Name.Local == "port" { a.Port = attr.Value } else if attr.Name.Local == "device" { if err := unmarshalUintAttr(attr.Value, &a.Device, 10); err != nil { return err } } } d.Skip() return nil } func (a *DomainAddressPCI) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "domain" { if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil { return err } } else if attr.Name.Local == "bus" { if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil { return err } } else if attr.Name.Local == "slot" { if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil { return err } } else if attr.Name.Local == "function" { if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil { return err } } else if attr.Name.Local == "multifunction" { a.MultiFunction = attr.Value } } for { tok, err := d.Token() if err == io.EOF { break } if err != nil { return err } switch tok := tok.(type) { case xml.StartElement: if tok.Name.Local == "zpci" { a.ZPCI = &DomainAddressZPCI{} err = d.DecodeElement(a.ZPCI, &tok) if err != nil { return err } } } } return nil } func (a *DomainAddressZPCI) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "fid" { if err := unmarshalUintAttr(attr.Value, &a.FID, 0); err != nil { return err } } else if attr.Name.Local == "uid" { if err := unmarshalUintAttr(attr.Value, &a.UID, 0); err != nil { return err } } } d.Skip() return nil } func (a *DomainAddressDrive) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "controller" { if err := unmarshalUintAttr(attr.Value, &a.Controller, 10); err != nil { return err } } else if attr.Name.Local == "bus" { if err := unmarshalUintAttr(attr.Value, &a.Bus, 10); err != nil { return err } } else if attr.Name.Local == "target" { if err := unmarshalUintAttr(attr.Value, &a.Target, 10); err != nil { return err } } else if attr.Name.Local == "unit" { if err := unmarshalUintAttr(attr.Value, &a.Unit, 10); err != nil { return err } } } d.Skip() return nil } func (a *DomainAddressDIMM) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "slot" { if err := unmarshalUintAttr(attr.Value, &a.Slot, 10); err != nil { return err } } else if attr.Name.Local == "base" { if err := unmarshalUint64Attr(attr.Value, &a.Base, 16); err != nil { return err } } } d.Skip() return nil } func (a *DomainAddressISA) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "iobase" { if err := unmarshalUintAttr(attr.Value, &a.IOBase, 16); err != nil { return err } } else if attr.Name.Local == "irq" { if err := unmarshalUintAttr(attr.Value, &a.IRQ, 16); err != nil { return err } } } d.Skip() return nil } func (a *DomainAddressVirtioMMIO) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { d.Skip() return nil } func (a *DomainAddressCCW) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "cssid" { if err := unmarshalUintAttr(attr.Value, &a.CSSID, 0); err != nil { return err } } else if attr.Name.Local == "ssid" { if err := unmarshalUintAttr(attr.Value, &a.SSID, 0); err != nil { return err } } else if attr.Name.Local == "devno" { if err := unmarshalUintAttr(attr.Value, &a.DevNo, 0); err != nil { return err } } } d.Skip() return nil } func (a *DomainAddressVirtioSerial) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "controller" { if err := unmarshalUintAttr(attr.Value, &a.Controller, 10); err != nil { return err } } else if attr.Name.Local == "bus" { if err := unmarshalUintAttr(attr.Value, &a.Bus, 10); err != nil { return err } } else if attr.Name.Local == "port" { if err := unmarshalUintAttr(attr.Value, &a.Port, 10); err != nil { return err } } } d.Skip() return nil } func (a *DomainAddressSpaprVIO) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "reg" { if err := unmarshalUint64Attr(attr.Value, &a.Reg, 16); err != nil { return err } } } d.Skip() return nil } func (a *DomainAddressCCID) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "controller" { if err := unmarshalUintAttr(attr.Value, &a.Controller, 10); err != nil { return err } } else if attr.Name.Local == "slot" { if err := unmarshalUintAttr(attr.Value, &a.Slot, 10); err != nil { return err } } } d.Skip() return nil } func (a *DomainAddressVirtioS390) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { d.Skip() return nil } func (a *DomainAddressUnassigned) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { d.Skip() return nil } func (a *DomainAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { var typ string for _, attr := range start.Attr { if attr.Name.Local == "type" { typ = attr.Value break } } if typ == "" { d.Skip() return nil } if typ == "usb" { a.USB = &DomainAddressUSB{} return d.DecodeElement(a.USB, &start) } else if typ == "pci" { a.PCI = &DomainAddressPCI{} return d.DecodeElement(a.PCI, &start) } else if typ == "drive" { a.Drive = &DomainAddressDrive{} return d.DecodeElement(a.Drive, &start) } else if typ == "dimm" { a.DIMM = &DomainAddressDIMM{} return d.DecodeElement(a.DIMM, &start) } else if typ == "isa" { a.ISA = &DomainAddressISA{} return d.DecodeElement(a.ISA, &start) } else if typ == "virtio-mmio" { a.VirtioMMIO = &DomainAddressVirtioMMIO{} return d.DecodeElement(a.VirtioMMIO, &start) } else if typ == "ccw" { a.CCW = &DomainAddressCCW{} return d.DecodeElement(a.CCW, &start) } else if typ == "virtio-serial" { a.VirtioSerial = &DomainAddressVirtioSerial{} return d.DecodeElement(a.VirtioSerial, &start) } else if typ == "spapr-vio" { a.SpaprVIO = &DomainAddressSpaprVIO{} return d.DecodeElement(a.SpaprVIO, &start) } else if typ == "ccid" { a.CCID = &DomainAddressCCID{} return d.DecodeElement(a.CCID, &start) } else if typ == "virtio-s390" { a.VirtioS390 = &DomainAddressVirtioS390{} return d.DecodeElement(a.VirtioS390, &start) } else if typ == "unassigned" { a.Unassigned = &DomainAddressUnassigned{} return d.DecodeElement(a.Unassigned, &start) } return nil } func (d *DomainCPU) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), d) } func (d *DomainCPU) Marshal() (string, error) { doc, err := xml.MarshalIndent(d, "", " ") if err != nil { return "", err } return string(doc), nil } func (a *DomainLaunchSecuritySEV) MarshalXML(e *xml.Encoder, start xml.StartElement) error { e.EncodeToken(start) if a.CBitPos != nil { cbitpos := xml.StartElement{ Name: xml.Name{Local: "cbitpos"}, } e.EncodeToken(cbitpos) e.EncodeToken(xml.CharData(fmt.Sprintf("%d", *a.CBitPos))) e.EncodeToken(cbitpos.End()) } if a.ReducedPhysBits != nil { reducedPhysBits := xml.StartElement{ Name: xml.Name{Local: "reducedPhysBits"}, } e.EncodeToken(reducedPhysBits) e.EncodeToken(xml.CharData(fmt.Sprintf("%d", *a.ReducedPhysBits))) e.EncodeToken(reducedPhysBits.End()) } if a.Policy != nil { policy := xml.StartElement{ Name: xml.Name{Local: "policy"}, } e.EncodeToken(policy) e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *a.Policy))) e.EncodeToken(policy.End()) } dhcert := xml.StartElement{ Name: xml.Name{Local: "dhCert"}, } e.EncodeToken(dhcert) e.EncodeToken(xml.CharData(fmt.Sprintf("%s", a.DHCert))) e.EncodeToken(dhcert.End()) session := xml.StartElement{ Name: xml.Name{Local: "session"}, } e.EncodeToken(session) e.EncodeToken(xml.CharData(fmt.Sprintf("%s", a.Session))) e.EncodeToken(session.End()) e.EncodeToken(start.End()) return nil } func (a *DomainLaunchSecuritySEV) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for { tok, err := d.Token() if err == io.EOF { break } if err != nil { return err } switch tok := tok.(type) { case xml.StartElement: if tok.Name.Local == "policy" { data, err := d.Token() if err != nil { return err } switch data := data.(type) { case xml.CharData: if err := unmarshalUintAttr(string(data), &a.Policy, 16); err != nil { return err } } } else if tok.Name.Local == "cbitpos" { data, err := d.Token() if err != nil { return err } switch data := data.(type) { case xml.CharData: if err := unmarshalUintAttr(string(data), &a.CBitPos, 10); err != nil { return err } } } else if tok.Name.Local == "reducedPhysBits" { data, err := d.Token() if err != nil { return err } switch data := data.(type) { case xml.CharData: if err := unmarshalUintAttr(string(data), &a.ReducedPhysBits, 10); err != nil { return err } } } else if tok.Name.Local == "dhCert" { data, err := d.Token() if err != nil { return err } switch data := data.(type) { case xml.CharData: a.DHCert = string(data) } } else if tok.Name.Local == "session" { data, err := d.Token() if err != nil { return err } switch data := data.(type) { case xml.CharData: a.Session = string(data) } } } } return nil } func (a *DomainLaunchSecurity) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.SEV != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "sev", }) return e.EncodeElement(a.SEV, start) } else { return nil } } func (a *DomainLaunchSecurity) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { var typ string for _, attr := range start.Attr { if attr.Name.Local == "type" { typ = attr.Value } } if typ == "" { d.Skip() return nil } if typ == "sev" { a.SEV = &DomainLaunchSecuritySEV{} return d.DecodeElement(a.SEV, &start) } return nil } type domainSysInfo DomainSysInfo type domainSysInfoSMBIOS struct { DomainSysInfoSMBIOS domainSysInfo } type domainSysInfoFWCfg struct { DomainSysInfoFWCfg domainSysInfo } func (a *DomainSysInfo) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "sysinfo" if a.SMBIOS != nil { smbios := domainSysInfoSMBIOS{} smbios.domainSysInfo = domainSysInfo(*a) smbios.DomainSysInfoSMBIOS = *a.SMBIOS start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "smbios", }) return e.EncodeElement(smbios, start) } else if a.FWCfg != nil { fwcfg := domainSysInfoFWCfg{} fwcfg.domainSysInfo = domainSysInfo(*a) fwcfg.DomainSysInfoFWCfg = *a.FWCfg start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "fwcfg", }) return e.EncodeElement(fwcfg, start) } else { gen := domainSysInfo(*a) return e.EncodeElement(gen, start) } } func (a *DomainSysInfo) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing 'type' attribute on domain controller") } if typ == "smbios" { var smbios domainSysInfoSMBIOS err := d.DecodeElement(&smbios, &start) if err != nil { return err } *a = DomainSysInfo(smbios.domainSysInfo) a.SMBIOS = &smbios.DomainSysInfoSMBIOS return nil } else if typ == "fwcfg" { var fwcfg domainSysInfoFWCfg err := d.DecodeElement(&fwcfg, &start) if err != nil { return err } *a = DomainSysInfo(fwcfg.domainSysInfo) a.FWCfg = &fwcfg.DomainSysInfoFWCfg return nil } else { var gen domainSysInfo err := d.DecodeElement(&gen, &start) if err != nil { return err } *a = DomainSysInfo(gen) return nil } } libvirt-go-xml-7.4.0/domain_capabilities.go000066400000000000000000000115071405573250200207140ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2016 Red Hat, Inc. * */ package libvirtxml import ( "encoding/xml" ) type DomainCaps struct { XMLName xml.Name `xml:"domainCapabilities"` Path string `xml:"path"` Domain string `xml:"domain"` Machine string `xml:"machine,omitempty"` Arch string `xml:"arch"` VCPU *DomainCapsVCPU `xml:"vcpu"` IOThreads *DomainCapsIOThreads `xml:"iothreads"` OS *DomainCapsOS `xml:"os"` CPU *DomainCapsCPU `xml:"cpu"` Devices *DomainCapsDevices `xml:"devices"` Features *DomainCapsFeatures `xml:"features"` } type DomainCapsVCPU struct { Max uint `xml:"max,attr"` } type DomainCapsOS struct { Supported string `xml:"supported,attr"` Loader *DomainCapsOSLoader `xml:"loader"` Enums []DomainCapsEnum `xml:"enum"` } type DomainCapsOSLoader struct { Supported string `xml:"supported,attr"` Values []string `xml:"value"` Enums []DomainCapsEnum `xml:"enum"` } type DomainCapsIOThreads struct { Supported string `xml:"supported,attr"` } type DomainCapsCPU struct { Modes []DomainCapsCPUMode `xml:"mode"` } type DomainCapsCPUMode struct { Name string `xml:"name,attr"` Supported string `xml:"supported,attr"` Models []DomainCapsCPUModel `xml:"model"` Vendor string `xml:"vendor,omitempty"` Features []DomainCapsCPUFeature `xml:"feature"` Enums []DomainCapsEnum `xml:"enum"` } type DomainCapsCPUModel struct { Name string `xml:",chardata"` Usable string `xml:"usable,attr,omitempty"` Fallback string `xml:"fallback,attr,omitempty"` Deprecated string `xml:"deprecated,attr,omitempty"` } type DomainCapsCPUFeature struct { Policy string `xml:"policy,attr,omitempty"` Name string `xml:"name,attr"` } type DomainCapsEnum struct { Name string `xml:"name,attr"` Values []string `xml:"value"` } type DomainCapsDevices struct { Disk *DomainCapsDevice `xml:"disk"` Graphics *DomainCapsDevice `xml:"graphics"` Video *DomainCapsDevice `xml:"video"` HostDev *DomainCapsDevice `xml:"hostdev"` RNG *DomainCapsDevice `xml:"rng"` FileSystem *DomainCapsDevice `xml:"filesystem"` } type DomainCapsDevice struct { Supported string `xml:"supported,attr"` Enums []DomainCapsEnum `xml:"enum"` } type DomainCapsFeatures struct { GIC *DomainCapsFeatureGIC `xml:"gic"` VMCoreInfo *DomainCapsFeatureVMCoreInfo `xml:"vmcoreinfo"` GenID *DomainCapsFeatureGenID `xml:"genid"` BackingStoreInput *DomainCapsFeatureBackingStoreInput `xml:"backingStoreInput"` Backup *DomainCapsFeatureBackup `xml:"backup"` SEV *DomainCapsFeatureSEV `xml:"sev"` } type DomainCapsFeatureGIC struct { Supported string `xml:"supported,attr"` Enums []DomainCapsEnum `xml:"enum"` } type DomainCapsFeatureVMCoreInfo struct { Supported string `xml:"supported,attr"` } type DomainCapsFeatureGenID struct { Supported string `xml:"supported,attr"` } type DomainCapsFeatureBackingStoreInput struct { Supported string `xml:"supported,attr"` } type DomainCapsFeatureBackup struct { Supported string `xml:"supported,attr"` } type DomainCapsFeatureSEV struct { Supported string `xml:"supported,attr"` CBitPos uint `xml:"cbitpos,omitempty"` ReducedPhysBits uint `xml:"reducedPhysBits,omitempty"` } func (c *DomainCaps) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), c) } func (c *DomainCaps) Marshal() (string, error) { doc, err := xml.MarshalIndent(c, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/domain_snapshot.go000066400000000000000000000100531405573250200201150ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ package libvirtxml import "encoding/xml" type DomainSnapshotDisk struct { Name string `xml:"name,attr"` Snapshot string `xml:"snapshot,attr,omitempty"` Driver *DomainDiskDriver `xml:"driver"` Source *DomainDiskSource `xml:"source"` } type DomainSnapshotDisks struct { Disks []DomainSnapshotDisk `xml:"disk"` } type DomainSnapshotMemory struct { Snapshot string `xml:"snapshot,attr"` File string `xml:"file,attr,omitempty"` } type DomainSnapshotParent struct { Name string `xml:"name"` } type DomainSnapshot struct { XMLName xml.Name `xml:"domainsnapshot"` Name string `xml:"name,omitempty"` Description string `xml:"description,omitempty"` State string `xml:"state,omitempty"` CreationTime string `xml:"creationTime,omitempty"` Parent *DomainSnapshotParent `xml:"parent"` Memory *DomainSnapshotMemory `xml:"memory"` Disks *DomainSnapshotDisks `xml:"disks"` Domain *Domain `xml:"domain"` Active *uint `xml:"active"` } type domainSnapshotDisk DomainSnapshotDisk func (a *DomainSnapshotDisk) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "disk" if a.Source != nil { if a.Source.File != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "file", }) } else if a.Source.Block != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "block", }) } else if a.Source.Dir != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "dir", }) } else if a.Source.Network != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "network", }) } else if a.Source.Volume != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "volume", }) } } disk := domainSnapshotDisk(*a) return e.EncodeElement(disk, start) } func (a *DomainSnapshotDisk) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { typ = "file" } a.Source = &DomainDiskSource{} if typ == "file" { a.Source.File = &DomainDiskSourceFile{} } else if typ == "block" { a.Source.Block = &DomainDiskSourceBlock{} } else if typ == "network" { a.Source.Network = &DomainDiskSourceNetwork{} } else if typ == "dir" { a.Source.Dir = &DomainDiskSourceDir{} } else if typ == "volume" { a.Source.Volume = &DomainDiskSourceVolume{} } disk := domainSnapshotDisk(*a) err := d.DecodeElement(&disk, &start) if err != nil { return err } *a = DomainSnapshotDisk(disk) return nil } func (s *DomainSnapshot) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *DomainSnapshot) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/domain_snapshot_test.go000066400000000000000000000121041405573250200211530ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ package libvirtxml import ( "strings" "testing" ) var domainSnapshotTestData = []struct { Object *DomainSnapshot Expected []string }{ { Object: &DomainSnapshot{ Description: "Snapshot", Disks: &DomainSnapshotDisks{ []DomainSnapshotDisk{ DomainSnapshotDisk{ Name: "/old", Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/new", }, }, }, DomainSnapshotDisk{ Name: "vdb", Snapshot: "no", }, }, }, }, Expected: []string{ ``, ` Snapshot`, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &DomainSnapshot{ Name: "1270477159", Description: "Snapshot of OS install and updates", State: "running", CreationTime: "1270477159", Parent: &DomainSnapshotParent{ Name: "bare-os-install", }, Memory: &DomainSnapshotMemory{ Snapshot: "no", }, Disks: &DomainSnapshotDisks{ Disks: []DomainSnapshotDisk{ DomainSnapshotDisk{ Name: "vda", Snapshot: "external", Driver: &DomainDiskDriver{ Type: "qcow2", }, Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/path/to/new", }, }, }, DomainSnapshotDisk{ Name: "vdb", Snapshot: "no", }, }, }, Domain: &Domain{ Name: "fedora", Memory: &DomainMemory{ Value: 1048576, }, Devices: &DomainDeviceList{ Disks: []DomainDisk{ DomainDisk{ Device: "disk", Driver: &DomainDiskDriver{ Name: "qemu", Type: "raw", }, Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/path/to/old", }, }, Target: &DomainDiskTarget{ Dev: "vda", Bus: "virtio", }, }, DomainDisk{ Device: "disk", Snapshot: "external", Driver: &DomainDiskDriver{ Name: "qemu", Type: "raw", }, Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/path/to/old2", }, }, Target: &DomainDiskTarget{ Dev: "vdb", Bus: "virtio", }, }, }, }, }, }, Expected: []string{ ``, ` 1270477159`, ` Snapshot of OS install and updates`, ` running`, ` 1270477159`, ` `, ` bare-os-install`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` fedora`, ` 1048576`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, } func TestDomainSnapshot(t *testing.T) { for _, test := range domainSnapshotTestData { doc, err := test.Object.Marshal() if err != nil { t.Fatal(err) } expect := strings.Join(test.Expected, "\n") if doc != expect { t.Fatal("Bad xml:\n", string(doc), "\n does not match\n", expect, "\n") } } } libvirt-go-xml-7.4.0/domain_test.go000066400000000000000000002715771405573250200172610ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2016 Red Hat, Inc. * */ package libvirtxml import ( "reflect" "strings" "testing" ) type PCIAddress struct { Domain uint Bus uint Slot uint Function uint } type DriveAddress struct { Controller uint Bus uint Target uint Unit uint } type ISAAddress struct { IOBase uint } var domainID int = 3 var uhciIndex uint = 0 var uhciAddr = PCIAddress{0, 0, 1, 2} var nvmeAddr = PCIAddress{0, 1, 3, 0} var pciIndex uint = 0 var pciTargetChassisNr uint = 7 var pciTargetChassis uint = 23 var pciTargetPort uint = 78 var pciTargetBusNr uint = 2 var pciTargetIndex uint = 3 var pciTargetNUMANode uint = 2 var scsiIndex uint = 0 var scsiQueues uint = 3 var scsiCmdPerLUN uint = 8 var scsiMaxSectors uint = 512 var usbHostBus uint = 14 var usbHostDevice uint = 6 var pciHostDomain uint = 0 var pciHostBus uint = 3 var pciHostSlot uint = 14 var pciHostFunction uint = 5 var diskAddr = PCIAddress{0, 0, 3, 0} var ifaceAddr = PCIAddress{0, 0, 4, 0} var videoAddr = PCIAddress{0, 0, 5, 0} var fsAddr = PCIAddress{0, 0, 6, 0} var balloonAddr = PCIAddress{0, 0, 7, 0} var panicAddr = ISAAddress{0x505} var duplexAddr = PCIAddress{0, 0, 8, 0} var watchdogAddr = PCIAddress{0, 0, 8, 0} var rngAddr = PCIAddress{0, 0, 9, 0} var hostdevSCSI = DriveAddress{0, 0, 3, 0} var serialPort uint = 0 var parallelPort uint = 0 var tabletBus uint = 0 var tabletPort string = "1.1" var nicAverage int = 1000 var nicBurst int = 10000 var vcpuId0 uint = 0 var vcpuOrder0 uint = 1 var vcpuId1 uint = 1 var memorydevAddressSlot uint = 0 var memorydevAddressBase uint64 = 4294967296 var rebootTimeout int = 0 var cellID0 uint = 0 var cellID1 uint = 1 var ipv6Prefix uint = 24 var iothreadPriority int = -3 var vcpuPriority int = -5 var vepaManagerID uint = 5 var vepaTypeID uint = 3 var vepaTypeIDVersion uint = 12 var vepaInstanceID = "c7bb5ab2-d42f-4690-89d6-f590eb199d0f" var vntagProfileID = "c7bb5ab2-d42f-4690-89d6-f590eb199d0f" var ovsProfileID = "c7bb5ab2-d42f-4690-89d6-f590eb199d0f" var ovsInterfaceID = "73728ac4-53d9-44de-8438-8d8f90beca00" var midoInterfaceID = "73728ac4-53d9-44de-8438-8d8f90beca00" var nvramReg uint64 = 0x4000 var smartcardController uint = 0 var smartcardSlot uint = 7 var redirBus uint = 0 var redirPort string = "3" var redirfilterClass uint = 0x08 var redirfilterProduct uint = 0x2007 var redirfilterVendor uint = 0x15e1 var domainTestData = []struct { Object Document Expected []string }{ { Object: &Domain{ Type: "kvm", Name: "test", ID: &domainID, }, Expected: []string{ ``, ` test`, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Title: "Test", Description: "A test guest config", Metadata: &DomainMetadata{ XML: "" + "", }, Devices: &DomainDeviceList{ Disks: []DomainDisk{ DomainDisk{ Device: "cdrom", Driver: &DomainDiskDriver{ Name: "qemu", Type: "qcow2", }, Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/var/lib/libvirt/images/demo.qcow2", }, }, Target: &DomainDiskTarget{ Dev: "vda", Bus: "virtio", }, Serial: "fishfood", Boot: &DomainDeviceBoot{ Order: 1, }, }, DomainDisk{ Device: "disk", Driver: &DomainDiskDriver{ Name: "qemu", Type: "raw", }, Source: &DomainDiskSource{ Block: &DomainDiskSourceBlock{ Dev: "/dev/sda1", }, }, Target: &DomainDiskTarget{ Dev: "vdb", Bus: "virtio", }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &diskAddr.Domain, Bus: &diskAddr.Bus, Slot: &diskAddr.Slot, Function: &diskAddr.Function, }, }, }, DomainDisk{ Device: "disk", Auth: &DomainDiskAuth{ Username: "fred", Secret: &DomainDiskSecret{ Type: "ceph", UUID: "e49f09c9-119e-43fd-b5a9-000d41e65493", }, }, Source: &DomainDiskSource{ Network: &DomainDiskSourceNetwork{ Protocol: "rbd", Name: "somepool/somevol", Hosts: []DomainDiskSourceHost{ DomainDiskSourceHost{ Transport: "tcp", Name: "rbd1.example.com", Port: "3000", }, DomainDiskSourceHost{ Transport: "tcp", Name: "rbd2.example.com", Port: "3000", }, }, }, }, Target: &DomainDiskTarget{ Dev: "vdc", Bus: "virtio", }, }, DomainDisk{ Device: "disk", Source: &DomainDiskSource{ Network: &DomainDiskSourceNetwork{ Protocol: "nbd", Hosts: []DomainDiskSourceHost{ DomainDiskSourceHost{ Transport: "unix", Socket: "/var/run/nbd.sock", }, }, }, }, Target: &DomainDiskTarget{ Dev: "vdd", Bus: "virtio", }, Shareable: &DomainDiskShareable{}, }, DomainDisk{ Device: "cdrom", Driver: &DomainDiskDriver{ Cache: "none", IO: "native", ErrorPolicy: "stop", }, Source: &DomainDiskSource{ Volume: &DomainDiskSourceVolume{ Pool: "default", Volume: "myvolume", }, }, Target: &DomainDiskTarget{ Dev: "vde", Bus: "virtio", }, ReadOnly: &DomainDiskReadOnly{}, }, }, }, }, Expected: []string{ ``, ` test`, ` Test`, ` A test guest config`, ` ` + `` + `` + ``, ` `, ` `, ` `, ` `, ` `, ` fishfood`, ` `, ` `, ` `, ` `, ` `, ` `, `
`, `
`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, `
`, `
`, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Inputs: []DomainInput{ DomainInput{ Type: "tablet", Bus: "usb", Address: &DomainAddress{ USB: &DomainAddressUSB{ Bus: &tabletBus, Port: tabletPort, }, }, }, DomainInput{ Type: "keyboard", Bus: "ps2", }, }, Videos: []DomainVideo{ DomainVideo{ Model: DomainVideoModel{ Type: "cirrus", Heads: 1, Ram: 4096, VRam: 8192, VGAMem: 256, }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &videoAddr.Domain, Bus: &videoAddr.Bus, Slot: &videoAddr.Slot, Function: &videoAddr.Function, }, }, }, }, TPMs: []DomainTPM{ DomainTPM{ Model: "tpm-tis", Backend: &DomainTPMBackend{ Passthrough: &DomainTPMBackendPassthrough{ Device: &DomainTPMBackendDevice{ Path: "/dev/tpm0", }, }, }, }, }, Graphics: []DomainGraphic{ DomainGraphic{ VNC: &DomainGraphicVNC{}, }, }, MemBalloon: &DomainMemBalloon{ Model: "virtio", Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &balloonAddr.Domain, Bus: &balloonAddr.Bus, Slot: &balloonAddr.Slot, Function: &balloonAddr.Function, }, }, }, Panics: []DomainPanic{ DomainPanic{ Model: "hyperv", }, DomainPanic{ Model: "isa", Address: &DomainAddress{ ISA: &DomainAddressISA{ IOBase: &panicAddr.IOBase, }, }, }, }, Consoles: []DomainConsole{ DomainConsole{ Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, }, Target: &DomainConsoleTarget{ Type: "virtio", Port: &serialPort, }, }, }, Serials: []DomainSerial{ DomainSerial{ Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, }, Target: &DomainSerialTarget{ Type: "isa", Port: &serialPort, }, }, DomainSerial{ Source: &DomainChardevSource{ File: &DomainChardevSourceFile{ Path: "/tmp/serial.log", Append: "off", }, }, Target: &DomainSerialTarget{ Port: &serialPort, }, }, DomainSerial{ Source: &DomainChardevSource{ TCP: &DomainChardevSourceTCP{ Mode: "bind", Host: "127.0.0.1", Service: "1234", TLS: "yes", }, }, Protocol: &DomainChardevProtocol{ Type: "telnet", }, Target: &DomainSerialTarget{ Port: &serialPort, }, }, }, Channels: []DomainChannel{ DomainChannel{ Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, }, Target: &DomainChannelTarget{ VirtIO: &DomainChannelTargetVirtIO{ Name: "org.redhat.spice", State: "connected", }, }, }, }, Sounds: []DomainSound{ DomainSound{ Model: "ich6", Codec: []DomainSoundCodec{ DomainSoundCodec{ Type: "duplex", }, }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &duplexAddr.Domain, Bus: &duplexAddr.Bus, Slot: &duplexAddr.Slot, Function: &duplexAddr.Function, }, }, }, }, RedirDevs: []DomainRedirDev{ DomainRedirDev{ Bus: "usb", Source: &DomainChardevSource{ SpiceVMC: &DomainChardevSourceSpiceVMC{}, }, Address: &DomainAddress{ USB: &DomainAddressUSB{ Bus: &redirBus, Port: redirPort, }, }, }, }, RedirFilters: []DomainRedirFilter{ DomainRedirFilter{ USB: []DomainRedirFilterUSB{ DomainRedirFilterUSB{ Class: &redirfilterClass, Product: &redirfilterProduct, Vendor: &redirfilterVendor, Version: "1.10", Allow: "yes", }, DomainRedirFilterUSB{ Version: "1.10", Allow: "no", }, DomainRedirFilterUSB{ Allow: "yes", }, }, }, }, RNGs: []DomainRNG{ DomainRNG{ Model: "virtio", Rate: &DomainRNGRate{ Period: 2000, Bytes: 1234, }, Backend: &DomainRNGBackend{ EGD: &DomainRNGBackendEGD{ Source: &DomainChardevSource{ Dev: &DomainChardevSourceDev{ Path: "/dev/ttyS0", }, }, Protocol: &DomainChardevProtocol{ Type: "raw", }, }, }, }, }, Memorydevs: []DomainMemorydev{ DomainMemorydev{ Model: "dimm", Access: "private", Target: &DomainMemorydevTarget{ Size: &DomainMemorydevTargetSize{ Value: 1, Unit: "GiB", }, Node: &DomainMemorydevTargetNode{ Value: 0, }, }, Address: &DomainAddress{ DIMM: &DomainAddressDIMM{ Slot: &memorydevAddressSlot, Base: &memorydevAddressBase, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, `
`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, `
`, `
`, ` `, ` `, `
`, `
`, ` `, ` `, ` `, ` `, ` `, ` `, `
`, `
`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, `
`, `
`, ` `, ` `, ` 1`, ` 0`, ` `, `
`, `
`, `
`, `
`, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Memory: &DomainMemory{ Unit: "KiB", Value: 8192, DumpCore: "yes", }, CurrentMemory: &DomainCurrentMemory{ Unit: "KiB", Value: 4096, }, MaximumMemory: &DomainMaxMemory{ Unit: "KiB", Value: 16384, Slots: 2, }, MemoryBacking: &DomainMemoryBacking{ MemoryHugePages: &DomainMemoryHugepages{ Hugepages: []DomainMemoryHugepage{ { Size: 1, Unit: "G", Nodeset: "0-3,5", }, { Size: 2, Unit: "M", Nodeset: "4", }, }, }, MemoryNosharepages: &DomainMemoryNosharepages{}, MemoryLocked: &DomainMemoryLocked{}, MemorySource: &DomainMemorySource{ Type: "file", }, MemoryAccess: &DomainMemoryAccess{ Mode: "shared", }, MemoryAllocation: &DomainMemoryAllocation{ Mode: "immediate", }, }, OS: &DomainOS{ Type: &DomainOSType{ Arch: "x86_64", Machine: "pc", Type: "hvm", }, BootDevices: []DomainBootDevice{ DomainBootDevice{ Dev: "hd", }, }, Loader: &DomainLoader{ Readonly: "yes", Secure: "no", Type: "rom", Path: "/loader", }, DTB: "/some/path", ACPI: &DomainACPI{ Tables: []DomainACPITable{ DomainACPITable{ Type: "slic", Path: "/some/data", }, }, }, SMBios: &DomainSMBios{ Mode: "sysinfo", }, BIOS: &DomainBIOS{ UseSerial: "yes", RebootTimeout: &rebootTimeout, }, Init: "/bin/systemd", InitArgs: []string{ "--unit", "emergency.service", }, InitEnv: []DomainOSInitEnv{ DomainOSInitEnv{ Name: "HOME", Value: "/home/fred", }, DomainOSInitEnv{ Name: "USER", Value: "fred", }, }, InitUser: "fred", InitGroup: "fred", InitDir: "/home/fred", }, SysInfo: []DomainSysInfo{ DomainSysInfo{ SMBIOS: &DomainSysInfoSMBIOS{ BIOS: &DomainSysInfoBIOS{ Entry: []DomainSysInfoEntry{ DomainSysInfoEntry{ Name: "vendor", Value: "vendor", }, }, }, System: &DomainSysInfoSystem{ Entry: []DomainSysInfoEntry{ DomainSysInfoEntry{ Name: "manufacturer", Value: "manufacturer", }, DomainSysInfoEntry{ Name: "product", Value: "product", }, DomainSysInfoEntry{ Name: "version", Value: "version", }, }, }, BaseBoard: []DomainSysInfoBaseBoard{ DomainSysInfoBaseBoard{ Entry: []DomainSysInfoEntry{ DomainSysInfoEntry{ Name: "manufacturer", Value: "manufacturer", }, DomainSysInfoEntry{ Name: "product", Value: "product", }, DomainSysInfoEntry{ Name: "version", Value: "version", }, DomainSysInfoEntry{ Name: "serial", Value: "serial", }, }, }, }, }, }, DomainSysInfo{ FWCfg: &DomainSysInfoFWCfg{ Entry: []DomainSysInfoEntry{ DomainSysInfoEntry{ Name: "vendor", Value: "vendor", }, DomainSysInfoEntry{ Name: "installer", File: "/some/path.cfg", }, }, }, }, }, Clock: &DomainClock{ Offset: "variable", Basis: "utc", Adjustment: "28794", TimeZone: "Europe/Paris", Timer: []DomainTimer{ DomainTimer{ Name: "rtc", Track: "boot", TickPolicy: "catchup", CatchUp: &DomainTimerCatchUp{ Threshold: 123, Slew: 120, Limit: 10000, }, Frequency: 120, Mode: "auto", }, }, }, }, Expected: []string{ ``, ` test`, ` 16384`, ` 8192`, ` 4096`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` vendor`, ` `, ` `, ` manufacturer`, ` product`, ` version`, ` `, ` `, ` manufacturer`, ` product`, ` version`, ` serial`, ` `, ` `, ` `, ` vendor`, ` `, ` `, ` `, ` hvm`, ` /bin/systemd`, ` --unit`, ` emergency.service`, ` /home/fred`, ` fred`, ` /home/fred`, ` fred`, ` fred`, ` /loader`, ` /some/path`, ` `, ` /some/data
`, `
`, ` `, ` `, ` `, `
`, ` `, ` `, ` `, ` `, ` `, `
`, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Clock: &DomainClock{ Offset: "variable", Basis: "utc", Adjustment: "reset", }, }, Expected: []string{ ``, ` test`, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", OS: &DomainOS{ NVRam: &DomainNVRam{ Template: "/t.fd", NVRam: "/vars.fd", }, BootMenu: &DomainBootMenu{ Enable: "yes", Timeout: "3000", }, }, }, Expected: []string{ ``, ` test`, ` `, ` /vars.fd`, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", BlockIOTune: &DomainBlockIOTune{ Weight: 900, Device: []DomainBlockIOTuneDevice{ DomainBlockIOTuneDevice{ Path: "/dev/sda", Weight: 500, ReadIopsSec: 300, WriteIopsSec: 200, ReadBytesSec: 3000, WriteBytesSec: 2000, }, DomainBlockIOTuneDevice{ Path: "/dev/sdb", Weight: 600, ReadIopsSec: 100, WriteIopsSec: 40, ReadBytesSec: 1000, WriteBytesSec: 400, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` 900`, ` `, ` /dev/sda`, ` 500`, ` 300`, ` 200`, ` 3000`, ` 2000`, ` `, ` `, ` /dev/sdb`, ` 600`, ` 100`, ` 40`, ` 1000`, ` 400`, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", MemoryTune: &DomainMemoryTune{ HardLimit: &DomainMemoryTuneLimit{ Value: 1024, Unit: "MiB", }, SoftLimit: &DomainMemoryTuneLimit{ Value: 1024, }, MinGuarantee: &DomainMemoryTuneLimit{ Value: 1024, }, SwapHardLimit: &DomainMemoryTuneLimit{ Value: 1024, }, }, }, Expected: []string{ ``, ` test`, ` `, ` 1024`, ` 1024`, ` 1024`, ` 1024`, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", PM: &DomainPM{ SuspendToMem: &DomainPMPolicy{ Enabled: "no", }, SuspendToDisk: &DomainPMPolicy{ Enabled: "yes", }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", SecLabel: []DomainSecLabel{ DomainSecLabel{ Type: "dynamic", Model: "selinux", Relabel: "yes", Label: "system_u:system_r:svirt_t:s0:c143,c762", ImageLabel: "system_u:object_r:svirt_image_t:s0:c143,c762", BaseLabel: "system_u:system_r:svirt_t:s0", }, DomainSecLabel{ Type: "dynamic", Model: "dac", Relabel: "no", }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` system_u:object_r:svirt_image_t:s0:c143,c762`, ` system_u:system_r:svirt_t:s0`, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", OS: &DomainOS{ Kernel: "/vmlinuz", Initrd: "/initrd", Cmdline: "arg", }, }, Expected: []string{ ``, ` test`, ` `, ` /vmlinuz`, ` /initrd`, ` arg`, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Resource: &DomainResource{ Partition: "/machines/production", }, }, Expected: []string{ ``, ` test`, ` `, ` /machines/production`, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", VCPU: &DomainVCPU{ Placement: "static", CPUSet: "1-4,^3,6", Current: 1, Value: 2, }, VCPUs: &DomainVCPUs{ VCPU: []DomainVCPUsVCPU{ DomainVCPUsVCPU{ Id: &vcpuId0, Enabled: "yes", Hotpluggable: "no", Order: &vcpuOrder0, }, DomainVCPUsVCPU{ Id: &vcpuId1, Enabled: "no", Hotpluggable: "yes", Order: nil, }, }, }, Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "00:11:22:33:44:55", }, Model: &DomainInterfaceModel{ Type: "virtio", }, Source: &DomainInterfaceSource{ Network: &DomainInterfaceSourceNetwork{ Network: "default", }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` 2`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", CPU: &DomainCPU{ Match: "exact", Check: "none", Model: &DomainCPUModel{ Fallback: "allow", Value: "core2duo", VendorID: "LibvirtQEMU", }, Vendor: "Intel", Topology: &DomainCPUTopology{ Sockets: 1, Cores: 2, Threads: 1, }, Features: []DomainCPUFeature{ DomainCPUFeature{Policy: "disable", Name: "lahf_lm"}, }, Cache: &DomainCPUCache{ Level: 1, Mode: "emulate", }, Numa: &DomainNuma{ []DomainCell{ { ID: &cellID0, CPUs: "0-1", Memory: 512000, Unit: "KiB", MemAccess: "private", Distances: &DomainCellDistances{ Siblings: []DomainCellSibling{ DomainCellSibling{ ID: 1, Value: 20, }, }, }, }, { ID: &cellID1, CPUs: "2-3", Memory: 512000, Unit: "KiB", MemAccess: "private", Distances: &DomainCellDistances{ Siblings: []DomainCellSibling{ DomainCellSibling{ ID: 0, Value: 20, }, }, }, }, }, nil, }, }, Devices: &DomainDeviceList{ Emulator: "/bin/qemu-kvm", }, }, Expected: []string{ ``, ` test`, ` `, ` core2duo`, ` Intel`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` /bin/qemu-kvm`, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "06:39:b4:00:00:46", }, Model: &DomainInterfaceModel{ Type: "virtio", }, Source: &DomainInterfaceSource{ Bridge: &DomainInterfaceSourceBridge{ Bridge: "private", }, }, Target: &DomainInterfaceTarget{ Dev: "vnet3", }, Alias: &DomainAlias{ Name: "net1", }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "vmware", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "06:39:b4:00:00:46", }, Model: &DomainInterfaceModel{ Type: "e1000", }, Source: &DomainInterfaceSource{ Bridge: &DomainInterfaceSourceBridge{ Bridge: "", }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "52:54:00:39:97:ac", }, Model: &DomainInterfaceModel{ Type: "e1000", }, Source: &DomainInterfaceSource{ Network: &DomainInterfaceSourceNetwork{ Network: "default", }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "52:54:00:39:97:ac", }, Model: &DomainInterfaceModel{ Type: "virtio", }, Source: &DomainInterfaceSource{ UDP: &DomainInterfaceSourceUDP{ Address: "127.0.0.1", Port: 1234, Local: &DomainInterfaceSourceLocal{ Address: "127.0.0.1", Port: 1235, }, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ Source: &DomainInterfaceSource{ Direct: &DomainInterfaceSourceDirect{ Dev: "eth0", Mode: "bridge", }, }, VirtualPort: &DomainInterfaceVirtualPort{ Params: &DomainInterfaceVirtualPortParams{ VEPA8021QBG: &DomainInterfaceVirtualPortParamsVEPA8021QBG{ ManagerID: &vepaManagerID, TypeID: &vepaTypeID, TypeIDVersion: &vepaTypeIDVersion, InstanceID: vepaInstanceID, }, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ Source: &DomainInterfaceSource{ Direct: &DomainInterfaceSourceDirect{ Dev: "eth0", Mode: "bridge", }, }, VirtualPort: &DomainInterfaceVirtualPort{ Params: &DomainInterfaceVirtualPortParams{ VNTag8011QBH: &DomainInterfaceVirtualPortParamsVNTag8021QBH{ ProfileID: vntagProfileID, }, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ Source: &DomainInterfaceSource{ Direct: &DomainInterfaceSourceDirect{ Dev: "eth0", Mode: "bridge", }, }, VirtualPort: &DomainInterfaceVirtualPort{ Params: &DomainInterfaceVirtualPortParams{ OpenVSwitch: &DomainInterfaceVirtualPortParamsOpenVSwitch{ ProfileID: ovsProfileID, InterfaceID: ovsInterfaceID, }, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ Source: &DomainInterfaceSource{ Direct: &DomainInterfaceSourceDirect{ Dev: "eth0", Mode: "bridge", }, }, VirtualPort: &DomainInterfaceVirtualPort{ Params: &DomainInterfaceVirtualPortParams{ MidoNet: &DomainInterfaceVirtualPortParamsMidoNet{ InterfaceID: midoInterfaceID, }, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "52:54:00:39:97:ac", }, Model: &DomainInterfaceModel{ Type: "virtio", }, Source: &DomainInterfaceSource{ User: &DomainInterfaceSourceUser{}, }, Link: &DomainInterfaceLink{ State: "up", }, Boot: &DomainDeviceBoot{ Order: 1, }, Driver: &DomainInterfaceDriver{ Name: "vhost", Queues: 5, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "52:54:00:39:97:ac", }, Model: &DomainInterfaceModel{ Type: "virtio", }, Source: &DomainInterfaceSource{ Server: &DomainInterfaceSourceServer{ Address: "127.0.0.1", Port: 1234, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "52:54:00:39:97:ac", }, Model: &DomainInterfaceModel{ Type: "virtio", }, Source: &DomainInterfaceSource{ Ethernet: &DomainInterfaceSourceEthernet{}, }, Script: &DomainInterfaceScript{ Path: "/etc/qemu-ifup", }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &ifaceAddr.Domain, Bus: &ifaceAddr.Bus, Slot: &ifaceAddr.Slot, Function: &ifaceAddr.Function, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, `
`, `
`, `
`, `
`, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "52:54:00:39:97:ac", }, Model: &DomainInterfaceModel{ Type: "virtio", }, Source: &DomainInterfaceSource{ VHostUser: &DomainChardevSource{ UNIX: &DomainChardevSourceUNIX{ Path: "/tmp/vhost0.sock", Mode: "server", }, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "52:54:00:39:97:ac", }, Model: &DomainInterfaceModel{ Type: "virtio", }, Source: &DomainInterfaceSource{ VHostUser: &DomainChardevSource{ UNIX: &DomainChardevSourceUNIX{ Path: "/tmp/vhost0.sock", Mode: "server", }, }, }, Bandwidth: &DomainInterfaceBandwidth{ Inbound: &DomainInterfaceBandwidthParams{ Average: &nicAverage, Burst: &nicBurst, }, Outbound: &DomainInterfaceBandwidthParams{ Average: new(int), Burst: new(int), }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Interfaces: []DomainInterface{ DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "52:54:00:39:97:ac", }, Source: &DomainInterfaceSource{ Hostdev: &DomainInterfaceSourceHostdev{ PCI: &DomainHostdevSubsysPCISource{ Address: &DomainAddressPCI{ Domain: &pciHostDomain, Bus: &pciHostBus, Slot: &pciHostSlot, Function: &pciHostFunction, }, }, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, `
`, ` `, `
`, `
`, `
`, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Filesystems: []DomainFilesystem{ DomainFilesystem{ AccessMode: "mapped", Driver: &DomainFilesystemDriver{ Type: "path", WRPolicy: "immediate", }, Source: &DomainFilesystemSource{ Mount: &DomainFilesystemSourceMount{ Dir: "/home/user/test", }, }, Target: &DomainFilesystemTarget{ Dir: "user-test-mount", }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &fsAddr.Domain, Bus: &fsAddr.Bus, Slot: &fsAddr.Slot, Function: &fsAddr.Function, }, }, }, DomainFilesystem{ AccessMode: "passthrough", Driver: &DomainFilesystemDriver{ Name: "loop", Type: "raw", }, Source: &DomainFilesystemSource{ File: &DomainFilesystemSourceFile{ File: "/home/user/test.img", }, }, Target: &DomainFilesystemTarget{ Dir: "user-file-test-mount", }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, `
`, `
`, ` `, ` `, ` `, ` `, ` `, `
`, `
`, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Features: &DomainFeatureList{ PAE: &DomainFeature{}, ACPI: &DomainFeature{}, APIC: &DomainFeatureAPIC{}, HAP: &DomainFeatureState{}, PrivNet: &DomainFeature{}, HyperV: &DomainFeatureHyperV{ Relaxed: &DomainFeatureState{State: "on"}, VAPIC: &DomainFeatureState{State: "on"}, Spinlocks: &DomainFeatureHyperVSpinlocks{ DomainFeatureState{State: "on"}, 4096, }, VPIndex: &DomainFeatureState{State: "on"}, Runtime: &DomainFeatureState{State: "on"}, Synic: &DomainFeatureState{State: "on"}, Reset: &DomainFeatureState{State: "on"}, VendorId: &DomainFeatureHyperVVendorId{ DomainFeatureState{State: "on"}, "KVM Hv", }, }, KVM: &DomainFeatureKVM{ Hidden: &DomainFeatureState{State: "on"}, }, PVSpinlock: &DomainFeatureState{State: "on"}, GIC: &DomainFeatureGIC{Version: "2"}, Capabilities: &DomainFeatureCapabilities{ Policy: "default", MkNod: &DomainFeatureCapability{ State: "on", }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Controllers: []DomainController{ DomainController{ Type: "usb", Index: &uhciIndex, Model: "piix3-uhci", Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &uhciAddr.Domain, Bus: &uhciAddr.Bus, Slot: &uhciAddr.Slot, Function: &uhciAddr.Function, }, }, }, DomainController{ Type: "usb", Index: nil, Model: "ehci", USB: &DomainControllerUSB{ Master: &DomainControllerUSBMaster{ StartPort: 0, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, `
`, `
`, ` `, ` `, ` `, `
`, `
`, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Controllers: []DomainController{ DomainController{ Type: "pci", Index: &pciIndex, Model: "pci-expander-bus", PCI: &DomainControllerPCI{ Model: &DomainControllerPCIModel{ Name: "pxb", }, Target: &DomainControllerPCITarget{ ChassisNr: &pciTargetChassisNr, Chassis: &pciTargetChassis, Port: &pciTargetPort, BusNr: &pciTargetBusNr, Index: &pciTargetIndex, NUMANode: &pciTargetNUMANode, }, Hole64: &DomainControllerPCIHole64{ Size: 1024, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` 2`, ` `, ` 1024`, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Controllers: []DomainController{ DomainController{ Type: "scsi", Index: &scsiIndex, Driver: &DomainControllerDriver{ Queues: &scsiQueues, CmdPerLUN: &scsiCmdPerLUN, MaxSectors: &scsiMaxSectors, IOEventFD: "yes", IOThread: 3, IOMMU: "yes", ATS: "no", }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Hubs: []DomainHub{ DomainHub{ Type: "usb", }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ IOMMU: &DomainIOMMU{ Model: "intel", Driver: &DomainIOMMUDriver{ EIM: "on", IntRemap: "on", CachingMode: "on", AWBits: 48, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Perf: &DomainPerf{ Events: []DomainPerfEvent{ DomainPerfEvent{ Name: "cmt", Enabled: "yes", }, DomainPerfEvent{ Name: "mbmt", Enabled: "no", }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ Leases: []DomainLease{ DomainLease{ Lockspace: "foo", Key: "bar", Target: &DomainLeaseTarget{ Path: "/some/file", Offset: 1024, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` foo`, ` bar`, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "kvm", Name: "test", Devices: &DomainDeviceList{ NVRAM: &DomainNVRAM{ Address: &DomainAddress{ SpaprVIO: &DomainAddressSpaprVIO{ Reg: &nvramReg, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, `
`, `
`, `
`, `
`, }, }, { Object: &Domain{ Type: "qemu", Name: "test", QEMUCommandline: &DomainQEMUCommandline{ Args: []DomainQEMUCommandlineArg{ DomainQEMUCommandlineArg{Value: "-newarg"}, DomainQEMUCommandlineArg{Value: "-oldarg"}, }, Envs: []DomainQEMUCommandlineEnv{ DomainQEMUCommandlineEnv{Name: "QEMU_ENV", Value: "VAL"}, DomainQEMUCommandlineEnv{Name: "QEMU_VAR", Value: "VAR"}, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "lxc", Name: "test", LXCNamespace: &DomainLXCNamespace{ ShareNet: &DomainLXCNamespaceMap{ Type: "netns", Value: "red", }, ShareIPC: &DomainLXCNamespaceMap{ Type: "pid", Value: "12345", }, ShareUTS: &DomainLXCNamespaceMap{ Type: "name", Value: "container1", }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Type: "vmware", Name: "test", VMWareDataCenterPath: &DomainVMWareDataCenterPath{ Value: "folder1/folder2/datacenter1", }, }, Expected: []string{ ``, ` test`, ` folder1/folder2/datacenter1`, ``, }, }, { Object: &Domain{ Name: "test", IOThreads: 4, IOThreadIDs: &DomainIOThreadIDs{ IOThreads: []DomainIOThread{ DomainIOThread{ ID: 0, }, DomainIOThread{ ID: 1, }, DomainIOThread{ ID: 2, }, DomainIOThread{ ID: 3, }, }, }, CPUTune: &DomainCPUTune{ Shares: &DomainCPUTuneShares{Value: 1024}, Period: &DomainCPUTunePeriod{Value: 500000}, Quota: &DomainCPUTuneQuota{Value: -1}, GlobalPeriod: &DomainCPUTunePeriod{Value: 500000}, GlobalQuota: &DomainCPUTuneQuota{Value: 500}, EmulatorPeriod: &DomainCPUTunePeriod{Value: 900000}, EmulatorQuota: &DomainCPUTuneQuota{Value: 100}, IOThreadPeriod: &DomainCPUTunePeriod{Value: 100000}, IOThreadQuota: &DomainCPUTuneQuota{Value: 2000}, VCPUPin: []DomainCPUTuneVCPUPin{ DomainCPUTuneVCPUPin{ VCPU: 0, CPUSet: "0-1", }, DomainCPUTuneVCPUPin{ VCPU: 1, CPUSet: "2-3", }, }, EmulatorPin: &DomainCPUTuneEmulatorPin{ CPUSet: "0-3", }, IOThreadPin: []DomainCPUTuneIOThreadPin{ DomainCPUTuneIOThreadPin{ IOThread: 0, CPUSet: "0-1", }, DomainCPUTuneIOThreadPin{ IOThread: 1, CPUSet: "2-3", }, }, VCPUSched: []DomainCPUTuneVCPUSched{ DomainCPUTuneVCPUSched{ VCPUs: "0-1", Scheduler: "fifo", Priority: &vcpuPriority, }, }, IOThreadSched: []DomainCPUTuneIOThreadSched{ DomainCPUTuneIOThreadSched{ IOThreads: "0-1", Scheduler: "fifo", Priority: &iothreadPriority, }, }, }, }, Expected: []string{ ``, ` test`, ` 4`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` 1024`, ` 500000`, ` -1`, ` 500000`, ` 500`, ` 900000`, ` 100`, ` 100000`, ` 2000`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Name: "test", KeyWrap: &DomainKeyWrap{ Ciphers: []DomainKeyWrapCipher{ DomainKeyWrapCipher{ Name: "aes", State: "on", }, DomainKeyWrapCipher{ Name: "dea", State: "off", }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Name: "test", IDMap: &DomainIDMap{ UIDs: []DomainIDMapRange{ DomainIDMapRange{ Start: 0, Target: 1000, Count: 50, }, DomainIDMapRange{ Start: 1000, Target: 5000, Count: 5000, }, }, GIDs: []DomainIDMapRange{ DomainIDMapRange{ Start: 0, Target: 1000, Count: 50, }, DomainIDMapRange{ Start: 1000, Target: 5000, Count: 5000, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Name: "test", NUMATune: &DomainNUMATune{ Memory: &DomainNUMATuneMemory{ Mode: "strict", Nodeset: "2-3", Placement: "static", }, MemNodes: []DomainNUMATuneMemNode{ DomainNUMATuneMemNode{ CellID: 0, Mode: "strict", Nodeset: "2", }, DomainNUMATuneMemNode{ CellID: 1, Mode: "strict", Nodeset: "3", }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, ` `, ` `, ``, }, }, /* Tests for sub-documents that can be hotplugged */ { Object: &DomainController{ Type: "usb", Index: &uhciIndex, Model: "piix3-uhci", Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &uhciAddr.Domain, Bus: &uhciAddr.Bus, Slot: &uhciAddr.Slot, Function: &uhciAddr.Function, }, }, }, Expected: []string{ ``, `
`, `
`, }, }, { Object: &DomainDisk{ Device: "cdrom", Driver: &DomainDiskDriver{ Name: "qemu", Type: "qcow2", }, Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/var/lib/libvirt/images/demo.qcow2", }, }, BackingStore: &DomainDiskBackingStore{ Index: 1, Format: &DomainDiskFormat{ Type: "qcow2", }, Source: &DomainDiskSource{ Block: &DomainDiskSourceBlock{ Dev: "/dev/HostVG/QEMUGuest", }, }, BackingStore: &DomainDiskBackingStore{ Index: 2, Format: &DomainDiskFormat{ Type: "qcow2", }, Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/tmp/image2.qcow2", }, }, BackingStore: &DomainDiskBackingStore{ Index: 3, Format: &DomainDiskFormat{ Type: "raw", }, Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/tmp/image3.iso", }, }, BackingStore: &DomainDiskBackingStore{}, }, }, }, Target: &DomainDiskTarget{ Dev: "vda", Bus: "virtio", }, Serial: "fishfood", WWN: "0123456789abcdef", }, Expected: []string{ ``, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` fishfood`, ` 0123456789abcdef`, ``, }, }, { Object: &DomainDisk{ Device: "cdrom", Driver: &DomainDiskDriver{ Name: "qemu", Type: "qcow2", }, Source: &DomainDiskSource{ Block: &DomainDiskSourceBlock{ Dev: "/dev/HostVG/QEMUGuest1", }, }, Mirror: &DomainDiskMirror{ Job: "copy", Ready: "yes", Source: &DomainDiskSource{ Block: &DomainDiskSourceBlock{ Dev: "/dev/HostVG/QEMUGuest1Copy", }, }, }, Target: &DomainDiskTarget{ Dev: "vda", Bus: "virtio", }, }, Expected: []string{ ``, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &DomainDisk{ Device: "cdrom", Driver: &DomainDiskDriver{ Name: "qemu", Type: "qcow2", }, Source: &DomainDiskSource{ NVME: &DomainDiskSourceNVME{ PCI: &DomainDiskSourceNVMEPCI{ Managed: "yes", Namespace: 15, Address: &DomainAddressPCI{ Domain: &nvmeAddr.Domain, Bus: &nvmeAddr.Bus, Slot: &nvmeAddr.Slot, Function: &nvmeAddr.Function, }, }, }, }, Target: &DomainDiskTarget{ Dev: "vda", Bus: "virtio", }, }, Expected: []string{ ``, ` `, ` `, `
`, ` `, ` `, `
`, }, }, { Object: &DomainDisk{ Device: "cdrom", Driver: &DomainDiskDriver{ Name: "qemu", Type: "qcow2", }, Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/var/lib/libvirt/images/demo.qcow2", }, }, Mirror: &DomainDiskMirror{ Job: "copy", Format: &DomainDiskFormat{ Type: "qcow2", }, Source: &DomainDiskSource{ File: &DomainDiskSourceFile{ File: "/var/lib/libvirt/images/demo-copy.qcow2", }, }, }, Target: &DomainDiskTarget{ Dev: "vda", Bus: "virtio", }, }, Expected: []string{ ``, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &DomainFilesystem{ AccessMode: "mapped", Driver: &DomainFilesystemDriver{ Type: "path", WRPolicy: "immediate", }, Source: &DomainFilesystemSource{ Mount: &DomainFilesystemSourceMount{ Dir: "/home/user/test", }, }, Target: &DomainFilesystemTarget{ Dir: "user-test-mount", }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &fsAddr.Domain, Bus: &fsAddr.Bus, Slot: &fsAddr.Slot, Function: &fsAddr.Function, }, }, }, Expected: []string{ ``, ` `, ` `, ` `, `
`, `
`, }, }, { Object: &DomainInterface{ MAC: &DomainInterfaceMAC{ Address: "00:11:22:33:44:55", }, Model: &DomainInterfaceModel{ Type: "virtio", }, Source: &DomainInterfaceSource{ Network: &DomainInterfaceSourceNetwork{ Network: "default", }, }, }, Expected: []string{ ``, ` `, ` `, ` `, ``, }, }, { Object: &DomainSerial{ Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, }, Target: &DomainSerialTarget{ Type: "isa", Port: &serialPort, Model: &DomainSerialTargetModel{ Name: "isa-serial", }, }, Log: &DomainChardevLog{ File: "/some/path", Append: "on", }, }, Expected: []string{ ``, ` `, ` `, ` `, ` `, ``, }, }, { Object: &DomainParallel{ Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, }, Target: &DomainParallelTarget{ Type: "isa", Port: ¶llelPort, }, Log: &DomainChardevLog{ File: "/some/path", Append: "on", }, }, Expected: []string{ ``, ` `, ` `, ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, }, Target: &DomainConsoleTarget{ Type: "virtio", Port: &serialPort, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainSmartcard{ Host: &DomainSmartcardHost{}, Address: &DomainAddress{ CCID: &DomainAddressCCID{ Controller: &smartcardController, Slot: &smartcardSlot, }, }, }, Expected: []string{ ``, `
`, `
`, }, }, { Object: &DomainSmartcard{ Passthrough: &DomainChardevSource{ TCP: &DomainChardevSourceTCP{ Mode: "connect", Host: "localhost", Service: "12345", }, }, Protocol: &DomainChardevProtocol{ Type: "raw", }, Address: &DomainAddress{ CCID: &DomainAddressCCID{ Controller: &smartcardController, Slot: &smartcardSlot, }, }, }, Expected: []string{ ``, ` `, ` `, `
`, `
`, }, }, { Object: &DomainSmartcard{ HostCerts: []DomainSmartcardHostCert{ DomainSmartcardHostCert{ File: "/some/cert1", }, DomainSmartcardHostCert{ File: "/some/cert2", }, DomainSmartcardHostCert{ File: "/some/cert3", }, }, Address: &DomainAddress{ CCID: &DomainAddressCCID{ Controller: &smartcardController, Slot: &smartcardSlot, }, }, }, Expected: []string{ ``, ` /some/cert1`, ` /some/cert2`, ` /some/cert3`, `
`, `
`, }, }, { Object: &DomainTPM{ Model: "tpm-tis", Backend: &DomainTPMBackend{ Passthrough: &DomainTPMBackendPassthrough{ Device: &DomainTPMBackendDevice{ Path: "/dev/tpm0", }, }, }, }, Expected: []string{ ``, ` `, ` `, ` `, ``, }, }, { Object: &DomainShmem{ Name: "demo", Size: &DomainShmemSize{ Value: 1, Unit: "GiB", }, Model: &DomainShmemModel{ Type: "ivshmem-doorbell", }, Server: &DomainShmemServer{ Path: "/some/server", }, MSI: &DomainShmemMSI{ Enabled: "yes", Vectors: 5, IOEventFD: "yes", }, }, Expected: []string{ ``, ` 1`, ` `, ` `, ` `, ``, }, }, { Object: &DomainInput{ Type: "tablet", Bus: "usb", Address: &DomainAddress{ USB: &DomainAddressUSB{ Bus: &tabletBus, Port: tabletPort, }, }, }, Expected: []string{ ``, `
`, ``, }, }, { Object: &DomainVideo{ Driver: &DomainVideoDriver{ VGAConf: "io", }, Model: DomainVideoModel{ Type: "cirrus", Heads: 1, Ram: 4096, VRam: 8192, VRam64: 8192, VGAMem: 256, Primary: "yes", Accel: &DomainVideoAccel{ Accel3D: "yes", Accel2D: "no", }, }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &videoAddr.Domain, Bus: &videoAddr.Bus, Slot: &videoAddr.Slot, Function: &videoAddr.Function, MultiFunction: "on", }, }, }, Expected: []string{ ``, }, }, { Object: &DomainChannel{ Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, }, Target: &DomainChannelTarget{ VirtIO: &DomainChannelTargetVirtIO{ Name: "org.redhat.spice", State: "connected", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainChannel{ Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, }, Target: &DomainChannelTarget{ Xen: &DomainChannelTargetXen{ Name: "org.redhat.spice", State: "connected", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainRedirDev{ Bus: "usb", Source: &DomainChardevSource{ SpiceVMC: &DomainChardevSourceSpiceVMC{}, }, Address: &DomainAddress{ USB: &DomainAddressUSB{ Bus: &redirBus, Port: redirPort, }, }, }, Expected: []string{ ``, `
`, `
`, }, }, { Object: &DomainRedirDev{ Bus: "usb", Source: &DomainChardevSource{ TCP: &DomainChardevSourceTCP{ Mode: "connect", Host: "localhost", Service: "1234", }, }, Protocol: &DomainChardevProtocol{ Type: "raw", }, Boot: &DomainDeviceBoot{ Order: 1, }, Address: &DomainAddress{ USB: &DomainAddressUSB{ Bus: &redirBus, Port: redirPort, }, }, }, Expected: []string{ ``, ` `, ` `, ` `, `
`, `
`, }, }, { Object: &DomainChannel{ Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{}, }, Target: &DomainChannelTarget{ GuestFWD: &DomainChannelTargetGuestFWD{ Address: "192.168.1.1", Port: "123", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &Domain{ Name: "demo", Devices: &DomainDeviceList{ Graphics: []DomainGraphic{ DomainGraphic{ Spice: &DomainGraphicSpice{ Port: 5903, TLSPort: 5904, AutoPort: "no", Listen: "127.0.0.1", DefaultMode: "secure", Listeners: []DomainGraphicListener{ DomainGraphicListener{ Address: &DomainGraphicListenerAddress{ Address: "127.0.0.1", }, }, }, Channel: []DomainGraphicSpiceChannel{ DomainGraphicSpiceChannel{ Name: "main", Mode: "secure", }, DomainGraphicSpiceChannel{ Name: "inputs", Mode: "insecure", }, }, Image: &DomainGraphicSpiceImage{ Compression: "auto_glz", }, JPEG: &DomainGraphicSpiceJPEG{ Compression: "auto", }, ZLib: &DomainGraphicSpiceZLib{ Compression: "auto", }, Playback: &DomainGraphicSpicePlayback{ Compression: "on", }, Streaming: &DomainGraphicSpiceStreaming{ Mode: "filter", }, ClipBoard: &DomainGraphicSpiceClipBoard{ CopyPaste: "no", }, FileTransfer: &DomainGraphicSpiceFileTransfer{ Enable: "no", }, }, }, }, }, }, Expected: []string{ ``, ` demo`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &Domain{ Name: "demo", Devices: &DomainDeviceList{ Graphics: []DomainGraphic{ DomainGraphic{ VNC: &DomainGraphicVNC{ Port: 5903, AutoPort: "no", Listeners: []DomainGraphicListener{ DomainGraphicListener{}, }, }, }, }, }, }, Expected: []string{ ``, ` demo`, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &DomainMemBalloon{ Model: "virtio", AutoDeflate: "on", Stats: &DomainMemBalloonStats{ Period: 10, }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &balloonAddr.Domain, Bus: &balloonAddr.Bus, Slot: &balloonAddr.Slot, Function: &balloonAddr.Function, }, }, }, Expected: []string{ ``, ` `, `
`, `
`, }, }, { Object: &DomainWatchdog{ Model: "ib700", Action: "inject-nmi", Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &watchdogAddr.Domain, Bus: &watchdogAddr.Bus, Slot: &watchdogAddr.Slot, Function: &watchdogAddr.Function, }, }, }, Expected: []string{ ``, `
`, `
`, }, }, { Object: &DomainSound{ Model: "ich6", Codec: []DomainSoundCodec{ DomainSoundCodec{ Type: "duplex", }, DomainSoundCodec{ Type: "micro", }, }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &duplexAddr.Domain, Bus: &duplexAddr.Bus, Slot: &duplexAddr.Slot, Function: &duplexAddr.Function, }, }, }, Expected: []string{ ``, ` `, ` `, `
`, `
`, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ Null: &DomainChardevSourceNull{}, }, }, Expected: []string{ ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ VC: &DomainChardevSourceVC{}, }, }, Expected: []string{ ``, }, }, { Object: &DomainConsole{ TTY: "/dev/pts/3", Source: &DomainChardevSource{ Pty: &DomainChardevSourcePty{ Path: "/dev/pts/3", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ Dev: &DomainChardevSourceDev{ Path: "/dev/ttyS0", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ File: &DomainChardevSourceFile{ Path: "/tmp/file.log", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ Pipe: &DomainChardevSourcePipe{ Path: "/tmp/file.fifo", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ StdIO: &DomainChardevSourceStdIO{}, }, }, Expected: []string{ ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ UDP: &DomainChardevSourceUDP{ ConnectHost: "some.server", ConnectService: "4999", BindHost: "my.server", BindService: "5921", }, }, }, Expected: []string{ ``, ` `, ` `, ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ TCP: &DomainChardevSourceTCP{ Mode: "connect", Host: "localhost", Service: "25", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ UNIX: &DomainChardevSourceUNIX{ Mode: "connect", Path: "/tmp/myvm.sock", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ SpiceVMC: &DomainChardevSourceSpiceVMC{}, }, }, Expected: []string{ ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ SpicePort: &DomainChardevSourceSpicePort{ Channel: "org.qemu.console.serial.0", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainConsole{ Source: &DomainChardevSource{ NMDM: &DomainChardevSourceNMDM{ Master: "/dev/nmdm0A", Slave: "/dev/nmdm0B", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainRNG{ Model: "virtio", Rate: &DomainRNGRate{ Period: 2000, Bytes: 1234, }, Backend: &DomainRNGBackend{ Random: &DomainRNGBackendRandom{ Device: "/dev/random", }, }, Address: &DomainAddress{ PCI: &DomainAddressPCI{ Domain: &rngAddr.Domain, Bus: &rngAddr.Bus, Slot: &rngAddr.Slot, Function: &rngAddr.Function, }, }, }, Expected: []string{ ``, ` `, ` /dev/random`, `
`, `
`, }, }, { Object: &DomainRNG{ Model: "virtio", Rate: &DomainRNGRate{ Period: 2000, Bytes: 1234, }, Backend: &DomainRNGBackend{ EGD: &DomainRNGBackendEGD{ Source: &DomainChardevSource{ UDP: &DomainChardevSourceUDP{ BindService: "1234", ConnectHost: "1.2.3.4", ConnectService: "1234", }, }, }, }, }, Expected: []string{ ``, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &DomainHostdev{ SubsysSCSI: &DomainHostdevSubsysSCSI{ SGIO: "unfiltered", RawIO: "yes", Source: &DomainHostdevSubsysSCSISource{ Host: &DomainHostdevSubsysSCSISourceHost{ Adapter: &DomainHostdevSubsysSCSIAdapter{ Name: "scsi_host0", }, Address: &DomainAddressDrive{ Bus: &hostdevSCSI.Bus, Target: &hostdevSCSI.Target, Unit: &hostdevSCSI.Unit, }, }, }, }, Address: &DomainAddress{ Drive: &DomainAddressDrive{ Controller: &hostdevSCSI.Controller, Bus: &hostdevSCSI.Bus, Target: &hostdevSCSI.Target, Unit: &hostdevSCSI.Unit, }, }, }, Expected: []string{ ``, ` `, ` `, `
`, ` `, `
`, `
`, }, }, { Object: &DomainHostdev{ SubsysSCSI: &DomainHostdevSubsysSCSI{ SGIO: "unfiltered", RawIO: "yes", Source: &DomainHostdevSubsysSCSISource{ ISCSI: &DomainHostdevSubsysSCSISourceISCSI{ Name: "iqn.1992-01.com.example:storage/1", Host: []DomainDiskSourceHost{ DomainDiskSourceHost{ Name: "example.org", Port: "3260", }, }, Auth: &DomainDiskAuth{ Username: "myname", Secret: &DomainDiskSecret{ Type: "iscsi", Usage: "mycluster_myname", }, }, }, }, }, Address: &DomainAddress{ Drive: &DomainAddressDrive{ Controller: &hostdevSCSI.Controller, Bus: &hostdevSCSI.Bus, Target: &hostdevSCSI.Target, Unit: &hostdevSCSI.Unit, }, }, }, Expected: []string{ ``, ` `, ` `, ` `, ` `, ` `, ` `, `
`, `
`, }, }, { Object: &DomainHostdev{ SubsysSCSIHost: &DomainHostdevSubsysSCSIHost{ Source: &DomainHostdevSubsysSCSIHostSource{ Protocol: "vhost", WWPN: "naa.5123456789abcde0", }, }, }, Expected: []string{ ``, ` `, ``, }, }, { Object: &DomainHostdev{ SubsysUSB: &DomainHostdevSubsysUSB{ Source: &DomainHostdevSubsysUSBSource{ Address: &DomainAddressUSB{ Bus: &usbHostBus, Device: &usbHostDevice, }, }, }, }, Expected: []string{ ``, ` `, `
`, ` `, `
`, }, }, { Object: &DomainHostdev{ Managed: "yes", SubsysPCI: &DomainHostdevSubsysPCI{ Source: &DomainHostdevSubsysPCISource{ Address: &DomainAddressPCI{ Domain: &pciHostDomain, Bus: &pciHostBus, Slot: &pciHostSlot, Function: &pciHostFunction, }, }, }, }, Expected: []string{ ``, ` `, `
`, ` `, `
`, }, }, { Object: &DomainHostdev{ SubsysMDev: &DomainHostdevSubsysMDev{ Model: "vfio-pci", Source: &DomainHostdevSubsysMDevSource{ Address: &DomainAddressMDev{ UUID: "53764d0e-85a0-42b4-af5c-2046b460b1dc", }, }, }, }, Expected: []string{ ``, ` `, `
`, ` `, `
`, }, }, { Object: &DomainHostdev{ CapsStorage: &DomainHostdevCapsStorage{ Source: &DomainHostdevCapsStorageSource{ Block: "/dev/sda", }, }, }, Expected: []string{ ``, ` `, ` /dev/sda`, ` `, ``, }, }, { Object: &DomainHostdev{ CapsMisc: &DomainHostdevCapsMisc{ Source: &DomainHostdevCapsMiscSource{ Char: "/dev/kvm", }, }, }, Expected: []string{ ``, ` `, ` /dev/kvm`, ` `, ``, }, }, { Object: &DomainHostdev{ CapsNet: &DomainHostdevCapsNet{ Source: &DomainHostdevCapsNetSource{ Interface: "eth0", }, IP: []DomainIP{ DomainIP{ Address: "192.168.122.2", Family: "ipv4", }, DomainIP{ Address: "2003:db8:1:0:214:1234:fe0b:3596", Family: "ipv6", Prefix: &ipv6Prefix, }, }, Route: []DomainRoute{ DomainRoute{ Family: "ipv4", Address: "0.0.0.0", Gateway: "192.168.122.1", }, DomainRoute{ Family: "ipv6", Address: "::", Gateway: "2003:db8:1:0:214:1234:fe0b:3595", }, }, }, }, Expected: []string{ ``, ` `, ` eth0`, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &DomainMemorydev{ Model: "dimm", Access: "private", Source: &DomainMemorydevSource{ PageSize: &DomainMemorydevSourcePagesize{ Value: 2048, Unit: "KiB", }, Path: "/tmp/nvdimm", NodeMask: "0-1", }, Target: &DomainMemorydevTarget{ Size: &DomainMemorydevTargetSize{ Value: 1, Unit: "GiB", }, Node: &DomainMemorydevTargetNode{ Value: 0, }, Label: &DomainMemorydevTargetLabel{ Size: &DomainMemorydevTargetSize{ Value: 200, Unit: "KiB", }, }, }, }, Expected: []string{ ``, ` `, ` 0-1`, ` 2048`, ` /tmp/nvdimm`, ` `, ` `, ` 1`, ` 0`, ` `, ` `, ``, }, }, /* Host Bootloader -- bhyve, Xen */ { Object: &Domain{ Type: "bhyve", Name: "test", Bootloader: "/usr/local/sbin/grub-bhyve", BootloaderArgs: "-r cd0 -m /tmp/test-device.map -M 1024M linuxguest", }, Expected: []string{ ``, ` test`, ` /usr/local/sbin/grub-bhyve`, ` -r cd0 -m /tmp/test-device.map -M 1024M linuxguest`, ``, }, }, { Object: &Domain{ Name: "demo", Devices: &DomainDeviceList{ Graphics: []DomainGraphic{ DomainGraphic{SDL: &DomainGraphicSDL{}}, DomainGraphic{VNC: &DomainGraphicVNC{}}, DomainGraphic{RDP: &DomainGraphicRDP{}}, DomainGraphic{Desktop: &DomainGraphicDesktop{}}, DomainGraphic{Spice: &DomainGraphicSpice{}}, }, }, }, Expected: []string{ ``, ` demo`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, } func TestDomain(t *testing.T) { for _, test := range domainTestData { doc, err := test.Object.Marshal() if err != nil { t.Fatal(err) } expect := strings.Join(test.Expected, "\n") if doc != expect { t.Fatal("Bad initial xml:\n", string(doc), "\n does not match\n", expect, "\n") } typ := reflect.ValueOf(test.Object).Elem().Type() newobj := reflect.New(typ) newdocobj, ok := newobj.Interface().(Document) if !ok { t.Fatalf("Could not clone %s", newobj.Interface()) } err = newdocobj.Unmarshal(expect) if err != nil { t.Fatal(err) } doc, err = newdocobj.Marshal() if err != nil { t.Fatal(err) } if doc != expect { t.Fatal("Bad roundtrip xml:\n", string(doc), "\n does not match\n", expect, "\n") } } } libvirt-go-xml-7.4.0/interface.go000066400000000000000000000100731405573250200166710ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Lian Duan * */ package libvirtxml import ( "encoding/xml" ) type Interface struct { XMLName xml.Name `xml:"interface"` Name string `xml:"name,attr,omitempty"` Start *InterfaceStart `xml:"start"` MTU *InterfaceMTU `xml:"mtu"` Protocol []InterfaceProtocol `xml:"protocol"` Link *InterfaceLink `xml:"link"` MAC *InterfaceMAC `xml:"mac"` Bond *InterfaceBond `xml:"bond"` Bridge *InterfaceBridge `xml:"bridge"` VLAN *InterfaceVLAN `xml:"vlan"` } type InterfaceStart struct { Mode string `xml:"mode,attr"` } type InterfaceMTU struct { Size uint `xml:"size,attr"` } type InterfaceProtocol struct { Family string `xml:"family,attr,omitempty"` AutoConf *InterfaceAutoConf `xml:"autoconf"` DHCP *InterfaceDHCP `xml:"dhcp"` IPs []InterfaceIP `xml:"ip"` Route []InterfaceRoute `xml:"route"` } type InterfaceAutoConf struct { } type InterfaceDHCP struct { PeerDNS string `xml:"peerdns,attr,omitempty"` } type InterfaceIP struct { Address string `xml:"address,attr"` Prefix uint `xml:"prefix,attr,omitempty"` } type InterfaceRoute struct { Gateway string `xml:"gateway,attr"` } type InterfaceLink struct { Speed uint `xml:"speed,attr,omitempty"` State string `xml:"state,attr,omitempty"` } type InterfaceMAC struct { Address string `xml:"address,attr"` } type InterfaceBond struct { Mode string `xml:"mode,attr,omitempty"` ARPMon *InterfaceBondARPMon `xml:"arpmon"` MIIMon *InterfaceBondMIIMon `xml:"miimon"` Interfaces []Interface `xml:"interface"` } type InterfaceBondARPMon struct { Interval uint `xml:"interval,attr,omitempty"` Target string `xml:"target,attr,omitempty"` Validate string `xml:"validate,attr,omitempty"` } type InterfaceBondMIIMon struct { Freq uint `xml:"freq,attr,omitempty"` UpDelay uint `xml:"updelay,attr,omitempty"` Carrier string `xml:"carrier,attr,omitempty"` } type InterfaceBridge struct { STP string `xml:"stp,attr,omitempty"` Delay *float64 `xml:"delay,attr"` Interfaces []Interface `xml:"interface"` } type InterfaceVLAN struct { Tag *uint `xml:"tag,attr"` Interface *Interface `xml:"interface"` } type interfaceDup Interface func (s *Interface) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "interface" typ := "ethernet" if s.Bond != nil { typ = "bond" } else if s.Bridge != nil { typ = "bridge" } else if s.VLAN != nil { typ = "vlan" } start.Attr = append(start.Attr, xml.Attr{ Name: xml.Name{Local: "type"}, Value: typ, }) i := interfaceDup(*s) return e.EncodeElement(i, start) } func (s *Interface) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *Interface) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/network.go000066400000000000000000000405251405573250200164270ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Lian Duan * */ package libvirtxml import ( "encoding/xml" ) type NetworkBridge struct { Name string `xml:"name,attr,omitempty"` STP string `xml:"stp,attr,omitempty"` Delay string `xml:"delay,attr,omitempty"` MACTableManager string `xml:"macTableManager,attr,omitempty"` Zone string `xml:"zone,attr,omitempty"` } type NetworkVirtualPort struct { Params *NetworkVirtualPortParams `xml:"parameters"` } type NetworkVirtualPortParams struct { Any *NetworkVirtualPortParamsAny `xml:"-"` VEPA8021QBG *NetworkVirtualPortParamsVEPA8021QBG `xml:"-"` VNTag8011QBH *NetworkVirtualPortParamsVNTag8021QBH `xml:"-"` OpenVSwitch *NetworkVirtualPortParamsOpenVSwitch `xml:"-"` MidoNet *NetworkVirtualPortParamsMidoNet `xml:"-"` } type NetworkVirtualPortParamsAny struct { ManagerID *uint `xml:"managerid,attr"` TypeID *uint `xml:"typeid,attr"` TypeIDVersion *uint `xml:"typeidversion,attr"` InstanceID string `xml:"instanceid,attr,omitempty"` ProfileID string `xml:"profileid,attr,omitempty"` InterfaceID string `xml:"interfaceid,attr,omitempty"` } type NetworkVirtualPortParamsVEPA8021QBG struct { ManagerID *uint `xml:"managerid,attr"` TypeID *uint `xml:"typeid,attr"` TypeIDVersion *uint `xml:"typeidversion,attr"` InstanceID string `xml:"instanceid,attr,omitempty"` } type NetworkVirtualPortParamsVNTag8021QBH struct { ProfileID string `xml:"profileid,attr,omitempty"` } type NetworkVirtualPortParamsOpenVSwitch struct { InterfaceID string `xml:"interfaceid,attr,omitempty"` ProfileID string `xml:"profileid,attr,omitempty"` } type NetworkVirtualPortParamsMidoNet struct { InterfaceID string `xml:"interfaceid,attr,omitempty"` } type NetworkDomain struct { Name string `xml:"name,attr,omitempty"` LocalOnly string `xml:"localOnly,attr,omitempty"` } type NetworkForwardNATAddress struct { Start string `xml:"start,attr"` End string `xml:"end,attr"` } type NetworkForwardNATPort struct { Start uint `xml:"start,attr"` End uint `xml:"end,attr"` } type NetworkForwardNAT struct { IPv6 string `xml:"ipv6,attr,omitempty"` Addresses []NetworkForwardNATAddress `xml:"address"` Ports []NetworkForwardNATPort `xml:"port"` } type NetworkForward struct { Mode string `xml:"mode,attr,omitempty"` Dev string `xml:"dev,attr,omitempty"` Managed string `xml:"managed,attr,omitempty"` Driver *NetworkForwardDriver `xml:"driver"` PFs []NetworkForwardPF `xml:"pf"` NAT *NetworkForwardNAT `xml:"nat"` Interfaces []NetworkForwardInterface `xml:"interface"` Addresses []NetworkForwardAddress `xml:"address"` } type NetworkForwardDriver struct { Name string `xml:"name,attr"` } type NetworkForwardPF struct { Dev string `xml:"dev,attr"` } type NetworkForwardAddress struct { PCI *NetworkForwardAddressPCI `xml:"-"` } type NetworkForwardAddressPCI struct { Domain *uint `xml:"domain,attr"` Bus *uint `xml:"bus,attr"` Slot *uint `xml:"slot,attr"` Function *uint `xml:"function,attr"` } type NetworkForwardInterface struct { XMLName xml.Name `xml:"interface"` Dev string `xml:"dev,attr,omitempty"` } type NetworkMAC struct { Address string `xml:"address,attr,omitempty"` } type NetworkDHCPRange struct { XMLName xml.Name `xml:"range"` Start string `xml:"start,attr,omitempty"` End string `xml:"end,attr,omitempty"` Lease *NetworkDHCPLease `xml:"lease"` } type NetworkDHCPLease struct { Expiry uint `xml:"expiry,attr"` Unit string `xml:"unit,attr,omitempty"` } type NetworkDHCPHost struct { XMLName xml.Name `xml:"host"` ID string `xml:"id,attr,omitempty"` MAC string `xml:"mac,attr,omitempty"` Name string `xml:"name,attr,omitempty"` IP string `xml:"ip,attr,omitempty"` Lease *NetworkDHCPLease `xml:"lease"` } type NetworkBootp struct { File string `xml:"file,attr,omitempty"` Server string `xml:"server,attr,omitempty"` } type NetworkDHCP struct { Ranges []NetworkDHCPRange `xml:"range"` Hosts []NetworkDHCPHost `xml:"host"` Bootp []NetworkBootp `xml:"bootp"` } type NetworkIP struct { Address string `xml:"address,attr,omitempty"` Family string `xml:"family,attr,omitempty"` Netmask string `xml:"netmask,attr,omitempty"` Prefix uint `xml:"prefix,attr,omitempty"` LocalPtr string `xml:"localPtr,attr,omitempty"` DHCP *NetworkDHCP `xml:"dhcp"` TFTP *NetworkTFTP `xml:"tftp"` } type NetworkTFTP struct { Root string `xml:"root,attr,omitempty"` } type NetworkRoute struct { Family string `xml:"family,attr,omitempty"` Address string `xml:"address,attr,omitempty"` Netmask string `xml:"netmask,attr,omitempty"` Prefix uint `xml:"prefix,attr,omitempty"` Gateway string `xml:"gateway,attr,omitempty"` Metric string `xml:"metric,attr,omitempty"` } type NetworkDNSForwarder struct { Domain string `xml:"domain,attr,omitempty"` Addr string `xml:"addr,attr,omitempty"` } type NetworkDNSTXT struct { XMLName xml.Name `xml:"txt"` Name string `xml:"name,attr"` Value string `xml:"value,attr"` } type NetworkDNSHostHostname struct { Hostname string `xml:",chardata"` } type NetworkDNSHost struct { XMLName xml.Name `xml:"host"` IP string `xml:"ip,attr"` Hostnames []NetworkDNSHostHostname `xml:"hostname"` } type NetworkDNSSRV struct { XMLName xml.Name `xml:"srv"` Service string `xml:"service,attr,omitempty"` Protocol string `xml:"protocol,attr,omitempty"` Target string `xml:"target,attr,omitempty"` Port uint `xml:"port,attr,omitempty"` Priority uint `xml:"priority,attr,omitempty"` Weight uint `xml:"weight,attr,omitempty"` Domain string `xml:"domain,attr,omitempty"` } type NetworkDNS struct { Enable string `xml:"enable,attr,omitempty"` ForwardPlainNames string `xml:"forwardPlainNames,attr,omitempty"` Forwarders []NetworkDNSForwarder `xml:"forwarder"` TXTs []NetworkDNSTXT `xml:"txt"` Host []NetworkDNSHost `xml:"host"` SRVs []NetworkDNSSRV `xml:"srv"` } type NetworkMetadata struct { XML string `xml:",innerxml"` } type NetworkMTU struct { Size uint `xml:"size,attr"` } type Network struct { XMLName xml.Name `xml:"network"` IPv6 string `xml:"ipv6,attr,omitempty"` TrustGuestRxFilters string `xml:"trustGuestRxFilters,attr,omitempty"` Name string `xml:"name,omitempty"` UUID string `xml:"uuid,omitempty"` Metadata *NetworkMetadata `xml:"metadata"` Forward *NetworkForward `xml:"forward"` Bridge *NetworkBridge `xml:"bridge"` MTU *NetworkMTU `xml:"mtu"` MAC *NetworkMAC `xml:"mac"` Domain *NetworkDomain `xml:"domain"` DNS *NetworkDNS `xml:"dns"` VLAN *NetworkVLAN `xml:"vlan"` Bandwidth *NetworkBandwidth `xml:"bandwidth"` PortOptions *NetworkPortOptions `xml:"port"` IPs []NetworkIP `xml:"ip"` Routes []NetworkRoute `xml:"route"` VirtualPort *NetworkVirtualPort `xml:"virtualport"` PortGroups []NetworkPortGroup `xml:"portgroup"` DnsmasqOptions *NetworkDnsmasqOptions } type NetworkPortOptions struct { Isolated string `xml:"isolated,attr,omitempty"` } type NetworkPortGroup struct { XMLName xml.Name `xml:"portgroup"` Name string `xml:"name,attr,omitempty"` Default string `xml:"default,attr,omitempty"` TrustGuestRxFilters string `xml:"trustGuestRxFilters,attr,omitempty"` VLAN *NetworkVLAN `xml:"vlan"` VirtualPort *NetworkVirtualPort `xml:"virtualport"` } type NetworkVLAN struct { Trunk string `xml:"trunk,attr,omitempty"` Tags []NetworkVLANTag `xml:"tag"` } type NetworkVLANTag struct { ID uint `xml:"id,attr"` NativeMode string `xml:"nativeMode,attr,omitempty"` } type NetworkBandwidthParams struct { Average *uint `xml:"average,attr"` Peak *uint `xml:"peak,attr"` Burst *uint `xml:"burst,attr"` Floor *uint `xml:"floor,attr"` } type NetworkBandwidth struct { ClassID uint `xml:"classID,attr,omitempty"` Inbound *NetworkBandwidthParams `xml:"inbound"` Outbound *NetworkBandwidthParams `xml:"outbound"` } type NetworkDnsmasqOptions struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/network/dnsmasq/1.0 options"` Option []NetworkDnsmasqOption `xml:"option"` } type NetworkDnsmasqOption struct { Value string `xml:"value,attr"` } func (a *NetworkVirtualPortParams) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "parameters" if a.Any != nil { return e.EncodeElement(a.Any, start) } else if a.VEPA8021QBG != nil { return e.EncodeElement(a.VEPA8021QBG, start) } else if a.VNTag8011QBH != nil { return e.EncodeElement(a.VNTag8011QBH, start) } else if a.OpenVSwitch != nil { return e.EncodeElement(a.OpenVSwitch, start) } else if a.MidoNet != nil { return e.EncodeElement(a.MidoNet, start) } return nil } func (a *NetworkVirtualPortParams) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { if a.Any != nil { return d.DecodeElement(a.Any, &start) } else if a.VEPA8021QBG != nil { return d.DecodeElement(a.VEPA8021QBG, &start) } else if a.VNTag8011QBH != nil { return d.DecodeElement(a.VNTag8011QBH, &start) } else if a.OpenVSwitch != nil { return d.DecodeElement(a.OpenVSwitch, &start) } else if a.MidoNet != nil { return d.DecodeElement(a.MidoNet, &start) } return nil } type networkVirtualPort NetworkVirtualPort func (a *NetworkVirtualPort) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "virtualport" if a.Params != nil { if a.Params.Any != nil { /* no type attr wanted */ } else if a.Params.VEPA8021QBG != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "802.1Qbg", }) } else if a.Params.VNTag8011QBH != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "802.1Qbh", }) } else if a.Params.OpenVSwitch != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "openvswitch", }) } else if a.Params.MidoNet != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "midonet", }) } } vp := networkVirtualPort(*a) return e.EncodeElement(&vp, start) } func (a *NetworkVirtualPort) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") a.Params = &NetworkVirtualPortParams{} if !ok { var any NetworkVirtualPortParamsAny a.Params.Any = &any } else if typ == "802.1Qbg" { var vepa NetworkVirtualPortParamsVEPA8021QBG a.Params.VEPA8021QBG = &vepa } else if typ == "802.1Qbh" { var vntag NetworkVirtualPortParamsVNTag8021QBH a.Params.VNTag8011QBH = &vntag } else if typ == "openvswitch" { var ovs NetworkVirtualPortParamsOpenVSwitch a.Params.OpenVSwitch = &ovs } else if typ == "midonet" { var mido NetworkVirtualPortParamsMidoNet a.Params.MidoNet = &mido } vp := networkVirtualPort(*a) err := d.DecodeElement(&vp, &start) if err != nil { return err } *a = NetworkVirtualPort(vp) return nil } func (a *NetworkForwardAddressPCI) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "domain", a.Domain, "0x%04x") marshalUintAttr(&start, "bus", a.Bus, "0x%02x") marshalUintAttr(&start, "slot", a.Slot, "0x%02x") marshalUintAttr(&start, "function", a.Function, "0x%x") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *NetworkForwardAddressPCI) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "domain" { if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil { return err } } else if attr.Name.Local == "bus" { if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil { return err } } else if attr.Name.Local == "slot" { if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil { return err } } else if attr.Name.Local == "function" { if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil { return err } } } d.Skip() return nil } func (a *NetworkForwardAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if a.PCI != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "pci", }) return e.EncodeElement(a.PCI, start) } else { return nil } } func (a *NetworkForwardAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { var typ string for _, attr := range start.Attr { if attr.Name.Local == "type" { typ = attr.Value break } } if typ == "" { d.Skip() return nil } if typ == "pci" { a.PCI = &NetworkForwardAddressPCI{} return d.DecodeElement(a.PCI, &start) } return nil } func (s *NetworkDHCPHost) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NetworkDHCPHost) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } func (s *NetworkDNSHost) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NetworkDNSHost) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } func (s *NetworkPortGroup) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NetworkPortGroup) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } func (s *NetworkDNSTXT) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NetworkDNSTXT) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } func (s *NetworkDNSSRV) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NetworkDNSSRV) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } func (s *NetworkDHCPRange) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NetworkDHCPRange) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } func (s *NetworkForwardInterface) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NetworkForwardInterface) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } func (s *Network) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *Network) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/network_port.go000066400000000000000000000145541405573250200174760ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2019 Red Hat, Inc. * */ package libvirtxml import ( "encoding/xml" "fmt" ) type NetworkPort struct { XMLName xml.Name `xml:"networkport"` UUID string `xml:"uuid,omitempty"` Owner *NetworkPortOwner `xml:"owner",` MAC *NetworkPortMAC `xml:"mac"` Group string `xml:"group,omitempty"` Bandwidth *NetworkBandwidth `xml:"bandwidth"` VLAN *NetworkPortVLAN `xml:"vlan"` PortOptions *NetworkPortPortOptions `xml:"port"` VirtualPort *NetworkVirtualPort `xml:"virtualport"` RXFilters *NetworkPortRXFilters `xml:"rxfilters"` Plug *NetworkPortPlug `xml:"plug"` } type NetworkPortPortOptions struct { Isolated string `xml:"isolated,attr,omitempty"` } type NetworkPortVLAN struct { Trunk string `xml:"trunk,attr,omitempty"` Tags []NetworkPortVLANTag `xml:"tag"` } type NetworkPortVLANTag struct { ID uint `xml:"id,attr"` NativeMode string `xml:"nativeMode,attr,omitempty"` } type NetworkPortOwner struct { UUID string `xml:"uuid,omitempty"` Name string `xml:"name,omitempty"` } type NetworkPortMAC struct { Address string `xml:"address,attr"` } type NetworkPortRXFilters struct { TrustGuest string `xml:"trustGuest,attr"` } type NetworkPortPlug struct { Bridge *NetworkPortPlugBridge `xml:"-"` Network *NetworkPortPlugNetwork `xml:"-"` Direct *NetworkPortPlugDirect `xml:"-"` HostDevPCI *NetworkPortPlugHostDevPCI `xml:"-"` } type NetworkPortPlugBridge struct { Bridge string `xml:"bridge,attr"` MacTableManager string `xml:"macTableManager,attr,omitempty"` } type NetworkPortPlugNetwork struct { Bridge string `xml:"bridge,attr"` MacTableManager string `xml:"macTableManager,attr,omitempty"` } type NetworkPortPlugDirect struct { Dev string `xml:"dev,attr"` Mode string `xml:"mode,attr"` } type NetworkPortPlugHostDevPCI struct { Managed string `xml:"managed,attr,omitempty"` Driver *NetworkPortPlugHostDevPCIDriver `xml:"driver"` Address *NetworkPortPlugHostDevPCIAddress `xml:"address"` } type NetworkPortPlugHostDevPCIDriver struct { Name string `xml:"name,attr"` } type NetworkPortPlugHostDevPCIAddress struct { Domain *uint `xml:"domain,attr"` Bus *uint `xml:"bus,attr"` Slot *uint `xml:"slot,attr"` Function *uint `xml:"function,attr"` } func (a *NetworkPortPlugHostDevPCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "domain", a.Domain, "0x%04x") marshalUintAttr(&start, "bus", a.Bus, "0x%02x") marshalUintAttr(&start, "slot", a.Slot, "0x%02x") marshalUintAttr(&start, "function", a.Function, "0x%x") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *NetworkPortPlugHostDevPCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "domain" { if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil { return err } } else if attr.Name.Local == "bus" { if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil { return err } } else if attr.Name.Local == "slot" { if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil { return err } } else if attr.Name.Local == "function" { if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil { return err } } } d.Skip() return nil } func (p *NetworkPortPlug) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "plug" if p.Bridge != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "bridge", }) return e.EncodeElement(p.Bridge, start) } else if p.Network != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "network", }) return e.EncodeElement(p.Network, start) } else if p.Direct != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "direct", }) return e.EncodeElement(p.Direct, start) } else if p.HostDevPCI != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "hostdev-pci", }) return e.EncodeElement(p.HostDevPCI, start) } return nil } func (p *NetworkPortPlug) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing type attribute on plug") } else if typ == "bridge" { var pb NetworkPortPlugBridge if err := d.DecodeElement(&pb, &start); err != nil { return err } p.Bridge = &pb } else if typ == "network" { var pn NetworkPortPlugNetwork if err := d.DecodeElement(&pn, &start); err != nil { return err } p.Network = &pn } else if typ == "direct" { var pd NetworkPortPlugDirect if err := d.DecodeElement(&pd, &start); err != nil { return err } p.Direct = &pd } else if typ == "hostdev-pci" { var ph NetworkPortPlugHostDevPCI if err := d.DecodeElement(&ph, &start); err != nil { return err } p.HostDevPCI = &ph } d.Skip() return nil } func (s *NetworkPort) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NetworkPort) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/network_test.go000066400000000000000000000236641405573250200174730ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Lian Duan * */ package libvirtxml import ( "strings" "testing" ) var nicInAverage uint = 1000 var nicInBurst uint = 10000 var nicInPeak uint = 2000 var nicInFloor uint = 500 var nicOutAverage uint = 2000 var netFwdDomain uint = 0 var netFwdBus uint = 3 var netFwdSlot uint = 0 var netFwdFunc1 uint = 1 var netFwdFunc2 uint = 2 var networkTestData = []struct { Object *Network Expected []string }{ { Object: &Network{ Name: "test", IPv6: "yes", Metadata: &NetworkMetadata{ XML: "" + "", }, }, Expected: []string{ ``, ` test`, ` ` + `` + `` + ``, ``, }, }, { Object: &Network{ Name: "test", MTU: &NetworkMTU{ Size: 1400, }, Domain: &NetworkDomain{ Name: "example.com", }, Forward: &NetworkForward{ Mode: "hostdev", Managed: "yes", Driver: &NetworkForwardDriver{ Name: "vfio", }, Addresses: []NetworkForwardAddress{ NetworkForwardAddress{ PCI: &NetworkForwardAddressPCI{ Domain: &netFwdDomain, Bus: &netFwdBus, Slot: &netFwdSlot, Function: &netFwdFunc1, }, }, NetworkForwardAddress{ PCI: &NetworkForwardAddressPCI{ Domain: &netFwdDomain, Bus: &netFwdBus, Slot: &netFwdSlot, Function: &netFwdFunc2, }, }, }, PFs: []NetworkForwardPF{ NetworkForwardPF{ Dev: "eth2", }, }, }, PortGroups: []NetworkPortGroup{ NetworkPortGroup{ Name: "main", Default: "yes", VLAN: &NetworkVLAN{ Trunk: "yes", Tags: []NetworkVLANTag{ NetworkVLANTag{ ID: 123, NativeMode: "tagged", }, NetworkVLANTag{ ID: 444, }, }, }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, ` `, `
`, `
`, `
`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, `
`, }, }, { Object: &Network{ Name: "test", Bridge: &NetworkBridge{ Name: "virbr0", }, VirtualPort: &NetworkVirtualPort{ Params: &NetworkVirtualPortParams{ OpenVSwitch: &NetworkVirtualPortParamsOpenVSwitch{ InterfaceID: "09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f", }, }, }, Forward: &NetworkForward{ Mode: "nat", NAT: &NetworkForwardNAT{ Addresses: []NetworkForwardNATAddress{ NetworkForwardNATAddress{ Start: "1.2.3.4", End: "1.2.3.10", }, }, Ports: []NetworkForwardNATPort{ NetworkForwardNATPort{ Start: 500, End: 1000, }, }, }, Interfaces: []NetworkForwardInterface{ NetworkForwardInterface{ Dev: "eth0", }, }, }, IPs: []NetworkIP{ NetworkIP{ Address: "192.168.122.1", Netmask: "255.255.255.0", DHCP: &NetworkDHCP{ Ranges: []NetworkDHCPRange{ NetworkDHCPRange{ Start: "192.168.122.2", End: "192.168.122.254", }, }, Hosts: []NetworkDHCPHost{ NetworkDHCPHost{ MAC: "00:16:3e:77:e2:ed", Name: "foo.example.com", IP: "192.168.122.10", }, }, Bootp: []NetworkBootp{ NetworkBootp{ File: "pxelinux.0", Server: "192.168.122.1", }, }, }, TFTP: &NetworkTFTP{ Root: "/var/lib/tftp", }, }, NetworkIP{ Family: "ipv6", Address: "2001:db8:ca2:2::1", Prefix: 64, DHCP: &NetworkDHCP{ Hosts: []NetworkDHCPHost{ NetworkDHCPHost{ IP: "2001:db8:ca2:2:3::1", Name: "paul", }, NetworkDHCPHost{ ID: "0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66", IP: "2001:db8:ca2:2:3::2", }, }, }, }, }, DNS: &NetworkDNS{ Enable: "yes", ForwardPlainNames: "no", Forwarders: []NetworkDNSForwarder{ NetworkDNSForwarder{ Addr: "8.8.8.8", }, NetworkDNSForwarder{ Domain: "example.com", Addr: "8.8.4.4", }, NetworkDNSForwarder{ Domain: "www.example.com", }, }, TXTs: []NetworkDNSTXT{ NetworkDNSTXT{ Name: "example", Value: "example value", }, }, Host: []NetworkDNSHost{ NetworkDNSHost{ IP: "192.168.122.2", Hostnames: []NetworkDNSHostHostname{ NetworkDNSHostHostname{ Hostname: "myhost", }, NetworkDNSHostHostname{ Hostname: "myhostalias", }, }, }, }, SRVs: []NetworkDNSSRV{ NetworkDNSSRV{ Service: "name", Protocol: "tcp", Domain: "test-domain-name", Target: ".", Port: 1024, Priority: 10, Weight: 10, }, }, }, Bandwidth: &NetworkBandwidth{ Inbound: &NetworkBandwidthParams{ Average: &nicInAverage, Peak: &nicInPeak, Burst: &nicInBurst, Floor: &nicInFloor, }, Outbound: &NetworkBandwidthParams{ Average: &nicOutAverage, }, }, Routes: []NetworkRoute{ NetworkRoute{ Address: "192.168.222.0", Netmask: "255.255.255.0", Gateway: "192.168.122.10", }, NetworkRoute{ Family: "ipv6", Address: "2001:db8:ac10:fc00::", Prefix: 64, Gateway: "2001:db8:ac10:fd01::1:24", }, }, VLAN: &NetworkVLAN{ Tags: []NetworkVLANTag{ NetworkVLANTag{ ID: 49, }, NetworkVLANTag{ ID: 52, NativeMode: "tagged", }, }, }, }, Expected: []string{ ``, ` test`, ` `, ` `, `
`, ` `, `
`, ` `, `
`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` myhost`, ` myhostalias`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, `
`, }, }, } func TestNetwork(t *testing.T) { for _, test := range networkTestData { doc, err := test.Object.Marshal() if err != nil { t.Fatal(err) } expect := strings.Join(test.Expected, "\n") if doc != expect { t.Fatal("Bad xml:\n", string(doc), "\n does not match\n", expect, "\n") } } } libvirt-go-xml-7.4.0/node_device.go000066400000000000000000000664431405573250200172110ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ package libvirtxml import ( "encoding/xml" "fmt" "io" "strconv" "strings" ) type NodeDevice struct { XMLName xml.Name `xml:"device"` Name string `xml:"name"` Path string `xml:"path,omitempty"` DevNodes []NodeDeviceDevNode `xml:"devnode"` Parent string `xml:"parent,omitempty"` Driver *NodeDeviceDriver `xml:"driver"` Capability NodeDeviceCapability `xml:"capability"` } type NodeDeviceDevNode struct { Type string `xml:"type,attr,omitempty"` Path string `xml:",chardata"` } type NodeDeviceDriver struct { Name string `xml:"name"` } type NodeDeviceCapability struct { System *NodeDeviceSystemCapability PCI *NodeDevicePCICapability USB *NodeDeviceUSBCapability USBDevice *NodeDeviceUSBDeviceCapability Net *NodeDeviceNetCapability SCSIHost *NodeDeviceSCSIHostCapability SCSITarget *NodeDeviceSCSITargetCapability SCSI *NodeDeviceSCSICapability Storage *NodeDeviceStorageCapability DRM *NodeDeviceDRMCapability CCW *NodeDeviceCCWCapability MDev *NodeDeviceMDevCapability CSS *NodeDeviceCSSCapability APQueue *NodeDeviceAPQueueCapability APCard *NodeDeviceAPCardCapability APMatrix *NodeDeviceAPMatrixCapability } type NodeDeviceIDName struct { ID string `xml:"id,attr"` Name string `xml:",chardata"` } type NodeDevicePCIExpress struct { Links []NodeDevicePCIExpressLink `xml:"link"` } type NodeDevicePCIExpressLink struct { Validity string `xml:"validity,attr,omitempty"` Speed float64 `xml:"speed,attr,omitempty"` Port *uint `xml:"port,attr"` Width *uint `xml:"width,attr"` } type NodeDeviceIOMMUGroup struct { Number int `xml:"number,attr"` Address []NodeDevicePCIAddress `xml:"address"` } type NodeDeviceNUMA struct { Node int `xml:"node,attr"` } type NodeDevicePCICapability struct { Class string `xml:"class,omitempty"` Domain *uint `xml:"domain"` Bus *uint `xml:"bus"` Slot *uint `xml:"slot"` Function *uint `xml:"function"` Product NodeDeviceIDName `xml:"product,omitempty"` Vendor NodeDeviceIDName `xml:"vendor,omitempty"` IOMMUGroup *NodeDeviceIOMMUGroup `xml:"iommuGroup"` NUMA *NodeDeviceNUMA `xml:"numa"` PCIExpress *NodeDevicePCIExpress `xml:"pci-express"` Capabilities []NodeDevicePCISubCapability `xml:"capability"` } type NodeDevicePCIAddress struct { Domain *uint `xml:"domain,attr"` Bus *uint `xml:"bus,attr"` Slot *uint `xml:"slot,attr"` Function *uint `xml:"function,attr"` } type NodeDevicePCISubCapability struct { VirtFunctions *NodeDevicePCIVirtFunctionsCapability PhysFunction *NodeDevicePCIPhysFunctionCapability MDevTypes *NodeDevicePCIMDevTypesCapability Bridge *NodeDevicePCIBridgeCapability } type NodeDevicePCIVirtFunctionsCapability struct { Address []NodeDevicePCIAddress `xml:"address,omitempty"` MaxCount int `xml:"maxCount,attr,omitempty"` } type NodeDevicePCIPhysFunctionCapability struct { Address NodeDevicePCIAddress `xml:"address,omitempty"` } type NodeDevicePCIMDevTypesCapability struct { Types []NodeDeviceMDevType `xml:"type"` } type NodeDeviceMDevType struct { ID string `xml:"id,attr"` Name string `xml:"name"` DeviceAPI string `xml:"deviceAPI"` AvailableInstances uint `xml:"availableInstances"` } type NodeDevicePCIBridgeCapability struct { } type NodeDeviceSystemHardware struct { Vendor string `xml:"vendor"` Version string `xml:"version"` Serial string `xml:"serial"` UUID string `xml:"uuid"` } type NodeDeviceSystemFirmware struct { Vendor string `xml:"vendor"` Version string `xml:"version"` ReleaseData string `xml:"release_date"` } type NodeDeviceSystemCapability struct { Product string `xml:"product,omitempty"` Hardware *NodeDeviceSystemHardware `xml:"hardware"` Firmware *NodeDeviceSystemFirmware `xml:"firmware"` } type NodeDeviceUSBDeviceCapability struct { Bus int `xml:"bus"` Device int `xml:"device"` Product NodeDeviceIDName `xml:"product,omitempty"` Vendor NodeDeviceIDName `xml:"vendor,omitempty"` } type NodeDeviceUSBCapability struct { Number int `xml:"number"` Class int `xml:"class"` Subclass int `xml:"subclass"` Protocol int `xml:"protocol"` Description string `xml:"description,omitempty"` } type NodeDeviceNetOffloadFeatures struct { Name string `xml:"name,attr"` } type NodeDeviceNetLink struct { State string `xml:"state,attr"` Speed string `xml:"speed,attr,omitempty"` } type NodeDeviceNetSubCapability struct { Wireless80211 *NodeDeviceNet80211Capability Ethernet80203 *NodeDeviceNet80203Capability } type NodeDeviceNet80211Capability struct { } type NodeDeviceNet80203Capability struct { } type NodeDeviceNetCapability struct { Interface string `xml:"interface"` Address string `xml:"address"` Link *NodeDeviceNetLink `xml:"link"` Features []NodeDeviceNetOffloadFeatures `xml:"feature,omitempty"` Capability []NodeDeviceNetSubCapability `xml:"capability"` } type NodeDeviceSCSIVPortOpsCapability struct { VPorts int `xml:"vports,omitempty"` MaxVPorts int `xml:"maxvports,omitempty"` } type NodeDeviceSCSIFCHostCapability struct { WWNN string `xml:"wwnn,omitempty"` WWPN string `xml:"wwpn,omitempty"` FabricWWN string `xml:"fabric_wwn,omitempty"` } type NodeDeviceSCSIHostSubCapability struct { VPortOps *NodeDeviceSCSIVPortOpsCapability FCHost *NodeDeviceSCSIFCHostCapability } type NodeDeviceSCSIHostCapability struct { Host uint `xml:"host"` UniqueID *uint `xml:"unique_id"` Capability []NodeDeviceSCSIHostSubCapability `xml:"capability"` } type NodeDeviceSCSITargetCapability struct { Target string `xml:"target"` Capability []NodeDeviceSCSITargetSubCapability `xml:"capability"` } type NodeDeviceSCSITargetSubCapability struct { FCRemotePort *NodeDeviceSCSIFCRemotePortCapability } type NodeDeviceSCSIFCRemotePortCapability struct { RPort string `xml:"rport"` WWPN string `xml:"wwpn"` } type NodeDeviceSCSICapability struct { Host int `xml:"host"` Bus int `xml:"bus"` Target int `xml:"target"` Lun int `xml:"lun"` Type string `xml:"type"` } type NodeDeviceStorageSubCapability struct { Removable *NodeDeviceStorageRemovableCapability } type NodeDeviceStorageRemovableCapability struct { MediaAvailable *uint `xml:"media_available"` MediaSize *uint `xml:"media_size"` MediaLabel string `xml:"media_label,omitempty"` LogicalBlockSize *uint `xml:"logical_block_size"` NumBlocks *uint `xml:"num_blocks"` } type NodeDeviceStorageCapability struct { Block string `xml:"block,omitempty"` Bus string `xml:"bus,omitempty"` DriverType string `xml:"drive_type,omitempty"` Model string `xml:"model,omitempty"` Vendor string `xml:"vendor,omitempty"` Serial string `xml:"serial,omitempty"` Size *uint `xml:"size"` LogicalBlockSize *uint `xml:"logical_block_size"` NumBlocks *uint `xml:"num_blocks"` Capability []NodeDeviceStorageSubCapability `xml:"capability"` } type NodeDeviceDRMCapability struct { Type string `xml:"type"` } type NodeDeviceCCWCapability struct { CSSID *uint `xml:"cssid"` SSID *uint `xml:"ssid"` DevNo *uint `xml:"devno"` } type NodeDeviceMDevCapability struct { Type *NodeDeviceMDevCapabilityType `xml:"type"` IOMMUGroup *NodeDeviceIOMMUGroup `xml:"iommuGroup"` UUID string `xml:"uuid,omitempty"` Attrs []NodeDeviceMDevCapabilityAttrs `xml:"attr,omitempty"` } type NodeDeviceMDevCapabilityType struct { ID string `xml:"id,attr"` } type NodeDeviceMDevCapabilityAttrs struct { Name string `xml:"name,attr"` Value string `xml:"value,attr"` } type NodeDeviceCSSCapability struct { CSSID *uint `xml:"cssid"` SSID *uint `xml:"ssid"` DevNo *uint `xml:"devno"` Capabilities []NodeDeviceCSSSubCapability `xml:"capability"` } type NodeDeviceCSSSubCapability struct { MDevTypes *NodeDeviceCSSMDevTypesCapability } type NodeDeviceCSSMDevTypesCapability struct { Types []NodeDeviceMDevType `xml:"type"` } type NodeDeviceAPQueueCapability struct { APAdapter string `xml:"ap-adapter"` APDomain string `xml:"ap-domain"` } type NodeDeviceAPCardCapability struct { APAdapter string `xml:"ap-adapter"` } type NodeDeviceAPMatrixCapability struct { Capabilities []NodeDeviceAPMatrixSubCapability `xml:"capability"` } type NodeDeviceAPMatrixSubCapability struct { MDevTypes *NodeDeviceAPMatrixMDevTypesCapability } type NodeDeviceAPMatrixMDevTypesCapability struct { Types []NodeDeviceMDevType `xml:"type"` } func (a *NodeDevicePCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "domain", a.Domain, "0x%04x") marshalUintAttr(&start, "bus", a.Bus, "0x%02x") marshalUintAttr(&start, "slot", a.Slot, "0x%02x") marshalUintAttr(&start, "function", a.Function, "0x%x") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *NodeDevicePCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "domain" { if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil { return err } } else if attr.Name.Local == "bus" { if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil { return err } } else if attr.Name.Local == "slot" { if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil { return err } } else if attr.Name.Local == "function" { if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil { return err } } } d.Skip() return nil } func (c *NodeDeviceCSSSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing node device capability type") } switch typ { case "mdev_types": var mdevTypesCaps NodeDeviceCSSMDevTypesCapability if err := d.DecodeElement(&mdevTypesCaps, &start); err != nil { return err } c.MDevTypes = &mdevTypesCaps } d.Skip() return nil } func (c *NodeDeviceCSSSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if c.MDevTypes != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "mdev_types", }) return e.EncodeElement(c.MDevTypes, start) } return nil } func (c *NodeDeviceCCWCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { e.EncodeToken(start) if c.CSSID != nil { cssid := xml.StartElement{ Name: xml.Name{Local: "cssid"}, } e.EncodeToken(cssid) e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID))) e.EncodeToken(cssid.End()) } if c.SSID != nil { ssid := xml.StartElement{ Name: xml.Name{Local: "ssid"}, } e.EncodeToken(ssid) e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID))) e.EncodeToken(ssid.End()) } if c.DevNo != nil { devno := xml.StartElement{ Name: xml.Name{Local: "devno"}, } e.EncodeToken(devno) e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo))) e.EncodeToken(devno.End()) } e.EncodeToken(start.End()) return nil } func (c *NodeDeviceCCWCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for { tok, err := d.Token() if err == io.EOF { break } if err != nil { return err } switch tok := tok.(type) { case xml.StartElement: cdata, err := d.Token() if err != nil { return err } if tok.Name.Local != "cssid" && tok.Name.Local != "ssid" && tok.Name.Local != "devno" { continue } chardata, ok := cdata.(xml.CharData) if !ok { return fmt.Errorf("Expected text for CCW '%s'", tok.Name.Local) } valstr := strings.TrimPrefix(string(chardata), "0x") val, err := strconv.ParseUint(valstr, 16, 64) if err != nil { return err } vali := uint(val) if tok.Name.Local == "cssid" { c.CSSID = &vali } else if tok.Name.Local == "ssid" { c.SSID = &vali } else if tok.Name.Local == "devno" { c.DevNo = &vali } } } return nil } func (c *NodeDeviceCSSCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { e.EncodeToken(start) if c.CSSID != nil { cssid := xml.StartElement{ Name: xml.Name{Local: "cssid"}, } e.EncodeToken(cssid) e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID))) e.EncodeToken(cssid.End()) } if c.SSID != nil { ssid := xml.StartElement{ Name: xml.Name{Local: "ssid"}, } e.EncodeToken(ssid) e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID))) e.EncodeToken(ssid.End()) } if c.DevNo != nil { devno := xml.StartElement{ Name: xml.Name{Local: "devno"}, } e.EncodeToken(devno) e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo))) e.EncodeToken(devno.End()) } if c.Capabilities != nil { for _, subcap := range c.Capabilities { start := xml.StartElement{ Name: xml.Name{Local: "capability"}, } e.EncodeElement(&subcap, start) } } e.EncodeToken(start.End()) return nil } func (c *NodeDeviceCSSCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for { tok, err := d.Token() if err == io.EOF { break } if err != nil { return err } switch tok := tok.(type) { case xml.StartElement: cdata, err := d.Token() if err != nil { return err } if tok.Name.Local == "capability" { subcap := &NodeDeviceCSSSubCapability{} err := d.DecodeElement(subcap, &tok) if err != nil { return err } c.Capabilities = append(c.Capabilities, *subcap) continue } if tok.Name.Local != "cssid" && tok.Name.Local != "ssid" && tok.Name.Local != "devno" { continue } chardata, ok := cdata.(xml.CharData) if !ok { return fmt.Errorf("Expected text for CSS '%s'", tok.Name.Local) } valstr := strings.TrimPrefix(string(chardata), "0x") val, err := strconv.ParseUint(valstr, 16, 64) if err != nil { return err } vali := uint(val) if tok.Name.Local == "cssid" { c.CSSID = &vali } else if tok.Name.Local == "ssid" { c.SSID = &vali } else if tok.Name.Local == "devno" { c.DevNo = &vali } } } return nil } func (c *NodeDevicePCISubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing node device capability type") } switch typ { case "virt_functions": var virtFuncCaps NodeDevicePCIVirtFunctionsCapability if err := d.DecodeElement(&virtFuncCaps, &start); err != nil { return err } c.VirtFunctions = &virtFuncCaps case "phys_function": var physFuncCaps NodeDevicePCIPhysFunctionCapability if err := d.DecodeElement(&physFuncCaps, &start); err != nil { return err } c.PhysFunction = &physFuncCaps case "mdev_types": var mdevTypeCaps NodeDevicePCIMDevTypesCapability if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil { return err } c.MDevTypes = &mdevTypeCaps case "pci-bridge": var bridgeCaps NodeDevicePCIBridgeCapability if err := d.DecodeElement(&bridgeCaps, &start); err != nil { return err } c.Bridge = &bridgeCaps } d.Skip() return nil } func (c *NodeDevicePCISubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if c.VirtFunctions != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "virt_functions", }) return e.EncodeElement(c.VirtFunctions, start) } else if c.PhysFunction != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "phys_function", }) return e.EncodeElement(c.PhysFunction, start) } else if c.MDevTypes != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "mdev_types", }) return e.EncodeElement(c.MDevTypes, start) } else if c.Bridge != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "pci-bridge", }) return e.EncodeElement(c.Bridge, start) } return nil } func (c *NodeDeviceSCSITargetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing node device capability type") } switch typ { case "fc_remote_port": var fcCaps NodeDeviceSCSIFCRemotePortCapability if err := d.DecodeElement(&fcCaps, &start); err != nil { return err } c.FCRemotePort = &fcCaps } d.Skip() return nil } func (c *NodeDeviceSCSITargetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if c.FCRemotePort != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "fc_remote_port", }) return e.EncodeElement(c.FCRemotePort, start) } return nil } func (c *NodeDeviceSCSIHostSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing node device capability type") } switch typ { case "fc_host": var fcCaps NodeDeviceSCSIFCHostCapability if err := d.DecodeElement(&fcCaps, &start); err != nil { return err } c.FCHost = &fcCaps case "vport_ops": var vportCaps NodeDeviceSCSIVPortOpsCapability if err := d.DecodeElement(&vportCaps, &start); err != nil { return err } c.VPortOps = &vportCaps } d.Skip() return nil } func (c *NodeDeviceSCSIHostSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if c.FCHost != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "fc_host", }) return e.EncodeElement(c.FCHost, start) } else if c.VPortOps != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "vport_ops", }) return e.EncodeElement(c.VPortOps, start) } return nil } func (c *NodeDeviceStorageSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing node device capability type") } switch typ { case "removable": var removeCaps NodeDeviceStorageRemovableCapability if err := d.DecodeElement(&removeCaps, &start); err != nil { return err } c.Removable = &removeCaps } d.Skip() return nil } func (c *NodeDeviceStorageSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if c.Removable != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "removable", }) return e.EncodeElement(c.Removable, start) } return nil } func (c *NodeDeviceNetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing node device capability type") } switch typ { case "80211": var wlanCaps NodeDeviceNet80211Capability if err := d.DecodeElement(&wlanCaps, &start); err != nil { return err } c.Wireless80211 = &wlanCaps case "80203": var ethCaps NodeDeviceNet80203Capability if err := d.DecodeElement(ðCaps, &start); err != nil { return err } c.Ethernet80203 = ðCaps } d.Skip() return nil } func (c *NodeDeviceNetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if c.Wireless80211 != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "80211", }) return e.EncodeElement(c.Wireless80211, start) } else if c.Ethernet80203 != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "80203", }) return e.EncodeElement(c.Ethernet80203, start) } return nil } func (c *NodeDeviceAPMatrixSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing node device capability type") } switch typ { case "mdev_types": var mdevTypeCaps NodeDeviceAPMatrixMDevTypesCapability if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil { return err } c.MDevTypes = &mdevTypeCaps } d.Skip() return nil } func (c *NodeDeviceAPMatrixSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if c.MDevTypes != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "mdev_types", }) return e.EncodeElement(c.MDevTypes, start) } return nil } func (c *NodeDeviceCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { typ, ok := getAttr(start.Attr, "type") if !ok { return fmt.Errorf("Missing node device capability type") } switch typ { case "pci": var pciCaps NodeDevicePCICapability if err := d.DecodeElement(&pciCaps, &start); err != nil { return err } c.PCI = &pciCaps case "system": var systemCaps NodeDeviceSystemCapability if err := d.DecodeElement(&systemCaps, &start); err != nil { return err } c.System = &systemCaps case "usb_device": var usbdevCaps NodeDeviceUSBDeviceCapability if err := d.DecodeElement(&usbdevCaps, &start); err != nil { return err } c.USBDevice = &usbdevCaps case "usb": var usbCaps NodeDeviceUSBCapability if err := d.DecodeElement(&usbCaps, &start); err != nil { return err } c.USB = &usbCaps case "net": var netCaps NodeDeviceNetCapability if err := d.DecodeElement(&netCaps, &start); err != nil { return err } c.Net = &netCaps case "scsi_host": var scsiHostCaps NodeDeviceSCSIHostCapability if err := d.DecodeElement(&scsiHostCaps, &start); err != nil { return err } c.SCSIHost = &scsiHostCaps case "scsi_target": var scsiTargetCaps NodeDeviceSCSITargetCapability if err := d.DecodeElement(&scsiTargetCaps, &start); err != nil { return err } c.SCSITarget = &scsiTargetCaps case "scsi": var scsiCaps NodeDeviceSCSICapability if err := d.DecodeElement(&scsiCaps, &start); err != nil { return err } c.SCSI = &scsiCaps case "storage": var storageCaps NodeDeviceStorageCapability if err := d.DecodeElement(&storageCaps, &start); err != nil { return err } c.Storage = &storageCaps case "drm": var drmCaps NodeDeviceDRMCapability if err := d.DecodeElement(&drmCaps, &start); err != nil { return err } c.DRM = &drmCaps case "ccw": var ccwCaps NodeDeviceCCWCapability if err := d.DecodeElement(&ccwCaps, &start); err != nil { return err } c.CCW = &ccwCaps case "mdev": var mdevCaps NodeDeviceMDevCapability if err := d.DecodeElement(&mdevCaps, &start); err != nil { return err } c.MDev = &mdevCaps case "css": var cssCaps NodeDeviceCSSCapability if err := d.DecodeElement(&cssCaps, &start); err != nil { return err } c.CSS = &cssCaps case "ap_queue": var apCaps NodeDeviceAPQueueCapability if err := d.DecodeElement(&apCaps, &start); err != nil { return err } c.APQueue = &apCaps case "ap_matrix": var apCaps NodeDeviceAPMatrixCapability if err := d.DecodeElement(&apCaps, &start); err != nil { return err } c.APMatrix = &apCaps case "ap_card": var apCaps NodeDeviceAPCardCapability if err := d.DecodeElement(&apCaps, &start); err != nil { return err } c.APCard = &apCaps } d.Skip() return nil } func (c *NodeDeviceCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if c.PCI != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "pci", }) return e.EncodeElement(c.PCI, start) } else if c.System != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "system", }) return e.EncodeElement(c.System, start) } else if c.USB != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "usb", }) return e.EncodeElement(c.USB, start) } else if c.USBDevice != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "usb_device", }) return e.EncodeElement(c.USBDevice, start) } else if c.Net != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "net", }) return e.EncodeElement(c.Net, start) } else if c.SCSI != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "scsi", }) return e.EncodeElement(c.SCSI, start) } else if c.SCSIHost != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "scsi_host", }) return e.EncodeElement(c.SCSIHost, start) } else if c.SCSITarget != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "scsi_target", }) return e.EncodeElement(c.SCSITarget, start) } else if c.Storage != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "storage", }) return e.EncodeElement(c.Storage, start) } else if c.DRM != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "drm", }) return e.EncodeElement(c.DRM, start) } else if c.CCW != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "ccw", }) return e.EncodeElement(c.CCW, start) } else if c.MDev != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "mdev", }) return e.EncodeElement(c.MDev, start) } else if c.CSS != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "css", }) return e.EncodeElement(c.CSS, start) } else if c.APQueue != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "ap_queue", }) return e.EncodeElement(c.APQueue, start) } else if c.APCard != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "ap_card", }) return e.EncodeElement(c.APCard, start) } else if c.APMatrix != nil { start.Attr = append(start.Attr, xml.Attr{ xml.Name{Local: "type"}, "ap_matrix", }) return e.EncodeElement(c.APMatrix, start) } return nil } func (c *NodeDevice) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), c) } func (c *NodeDevice) Marshal() (string, error) { doc, err := xml.MarshalIndent(c, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/node_device_test.go000066400000000000000000000063641405573250200202440ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ package libvirtxml import ( "strings" "testing" ) var pciDomain uint = 1 var pciBus uint = 21 var pciSlot uint = 10 var pciFunc uint = 50 var NodeDeviceTestData = []struct { Object *NodeDevice XML []string }{ { Object: &NodeDevice{ Name: "pci_0000_81_00_0", Parent: "pci_0000_80_01_0", Driver: &NodeDeviceDriver{ Name: "ixgbe", }, Capability: NodeDeviceCapability{ PCI: &NodeDevicePCICapability{ Domain: &pciDomain, Bus: &pciBus, Slot: &pciSlot, Function: &pciFunc, Product: NodeDeviceIDName{ ID: "0x1528", Name: "Ethernet Controller 10-Gigabit X540-AT2", }, Vendor: NodeDeviceIDName{ ID: "0x8086", Name: "Intel Corporation", }, IOMMUGroup: &NodeDeviceIOMMUGroup{ Number: 3, }, NUMA: &NodeDeviceNUMA{ Node: 1, }, Capabilities: []NodeDevicePCISubCapability{ NodeDevicePCISubCapability{ VirtFunctions: &NodeDevicePCIVirtFunctionsCapability{ MaxCount: 63, }, }, }, }, }, }, XML: []string{ ``, ` pci_0000_81_00_0`, ` pci_0000_80_01_0`, ` `, ` ixgbe`, ` `, ` `, ` 1`, ` 21`, ` 10`, ` 50`, ` Ethernet Controller 10-Gigabit X540-AT2`, ` Intel Corporation`, ` `, ` `, ` `, ` `, ``, }, }, } func TestNodeDevice(t *testing.T) { for _, test := range NodeDeviceTestData { expect := strings.Join(test.XML, "\n") nodeDevice := NodeDevice{} err := nodeDevice.Unmarshal(expect) if err != nil { t.Fatal(err) } doc, err := nodeDevice.Marshal() if err != nil { t.Fatal(err) } if doc != expect { t.Fatal("Bad xml:\n", string(doc), "\n does not match\n", expect, "\n") } } } libvirt-go-xml-7.4.0/nwfilter.go000066400000000000000000000371271405573250200165740ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Lian Duan * */ package libvirtxml import ( "encoding/xml" "fmt" "io" "strconv" "strings" ) type NWFilter struct { XMLName xml.Name `xml:"filter"` Name string `xml:"name,attr"` UUID string `xml:"uuid,omitempty"` Chain string `xml:"chain,attr,omitempty"` Priority int `xml:"priority,attr,omitempty"` Entries []NWFilterEntry } type NWFilterEntry struct { Rule *NWFilterRule Ref *NWFilterRef } type NWFilterRef struct { Filter string `xml:"filter,attr"` Parameters []NWFilterParameter `xml:"parameter"` } type NWFilterParameter struct { Name string `xml:"name,attr"` Value string `xml:"value,attr"` } type NWFilterField struct { Var string Str string Uint *uint } type NWFilterRule struct { Action string `xml:"action,attr,omitempty"` Direction string `xml:"direction,attr,omitempty"` Priority int `xml:"priority,attr,omitempty"` StateMatch string `xml:"statematch,attr,omitempty"` ARP *NWFilterRuleARP `xml:"arp"` RARP *NWFilterRuleRARP `xml:"rarp"` MAC *NWFilterRuleMAC `xml:"mac"` VLAN *NWFilterRuleVLAN `xml:"vlan"` STP *NWFilterRuleSTP `xml:"stp"` IP *NWFilterRuleIP `xml:"ip"` IPv6 *NWFilterRuleIPv6 `xml:"ipv6"` TCP *NWFilterRuleTCP `xml:"tcp"` UDP *NWFilterRuleUDP `xml:"udp"` UDPLite *NWFilterRuleUDPLite `xml:"udplite"` ESP *NWFilterRuleESP `xml:"esp"` AH *NWFilterRuleAH `xml:"ah"` SCTP *NWFilterRuleSCTP `xml:"sctp"` ICMP *NWFilterRuleICMP `xml:"icmp"` All *NWFilterRuleAll `xml:"all"` IGMP *NWFilterRuleIGMP `xml:"igmp"` TCPIPv6 *NWFilterRuleTCPIPv6 `xml:"tcp-ipv6"` UDPIPv6 *NWFilterRuleUDPIPv6 `xml:"udp-ipv6"` UDPLiteIPv6 *NWFilterRuleUDPLiteIPv6 `xml:"udplite-ipv6"` ESPIPv6 *NWFilterRuleESPIPv6 `xml:"esp-ipv6"` AHIPv6 *NWFilterRuleAHIPv6 `xml:"ah-ipv6"` SCTPIPv6 *NWFilterRuleSCTPIPv6 `xml:"sctp-ipv6"` ICMPv6 *NWFilterRuleICMPIPv6 `xml:"icmpv6"` AllIPv6 *NWFilterRuleAllIPv6 `xml:"all-ipv6"` } type NWFilterRuleCommonMAC struct { SrcMACAddr NWFilterField `xml:"srcmacaddr,attr,omitempty"` SrcMACMask NWFilterField `xml:"srcmacmask,attr,omitempty"` DstMACAddr NWFilterField `xml:"dstmacaddr,attr,omitempty"` DstMACMask NWFilterField `xml:"dstmacmask,attr,omitempty"` } type NWFilterRuleCommonIP struct { SrcMACAddr NWFilterField `xml:"srcmacaddr,attr,omitempty"` SrcIPAddr NWFilterField `xml:"srcipaddr,attr,omitempty"` SrcIPMask NWFilterField `xml:"srcipmask,attr,omitempty"` DstIPAddr NWFilterField `xml:"dstipaddr,attr,omitempty"` DstIPMask NWFilterField `xml:"dstipmask,attr,omitempty"` SrcIPFrom NWFilterField `xml:"srcipfrom,attr,omitempty"` SrcIPTo NWFilterField `xml:"srcipto,attr,omitempty"` DstIPFrom NWFilterField `xml:"dstipfrom,attr,omitempty"` DstIPTo NWFilterField `xml:"dstipto,attr,omitempty"` DSCP NWFilterField `xml:"dscp,attr"` ConnLimitAbove NWFilterField `xml:"connlimit-above,attr"` State NWFilterField `xml:"state,attr,omitempty"` IPSet NWFilterField `xml:"ipset,attr,omitempty"` IPSetFlags NWFilterField `xml:"ipsetflags,attr,omitempty"` } type NWFilterRuleCommonPort struct { SrcPortStart NWFilterField `xml:"srcportstart,attr"` SrcPortEnd NWFilterField `xml:"srcportend,attr"` DstPortStart NWFilterField `xml:"dstportstart,attr"` DstPortEnd NWFilterField `xml:"dstportend,attr"` } type NWFilterRuleARP struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonMAC HWType NWFilterField `xml:"hwtype,attr"` ProtocolType NWFilterField `xml:"protocoltype,attr"` OpCode NWFilterField `xml:"opcode,attr,omitempty"` ARPSrcMACAddr NWFilterField `xml:"arpsrcmacaddr,attr,omitempty"` ARPDstMACAddr NWFilterField `xml:"arpdstmacaddr,attr,omitempty"` ARPSrcIPAddr NWFilterField `xml:"arpsrcipaddr,attr,omitempty"` ARPSrcIPMask NWFilterField `xml:"arpsrcipmask,attr,omitempty"` ARPDstIPAddr NWFilterField `xml:"arpdstipaddr,attr,omitempty"` ARPDstIPMask NWFilterField `xml:"arpdstipmask,attr,omitempty"` Gratuitous NWFilterField `xml:"gratuitous,attr,omitempty"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleRARP struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonMAC HWType NWFilterField `xml:"hwtype,attr"` ProtocolType NWFilterField `xml:"protocoltype,attr"` OpCode NWFilterField `xml:"opcode,attr,omitempty"` ARPSrcMACAddr NWFilterField `xml:"arpsrcmacaddr,attr,omitempty"` ARPDstMACAddr NWFilterField `xml:"arpdstmacaddr,attr,omitempty"` ARPSrcIPAddr NWFilterField `xml:"arpsrcipaddr,attr,omitempty"` ARPSrcIPMask NWFilterField `xml:"arpsrcipmask,attr,omitempty"` ARPDstIPAddr NWFilterField `xml:"arpdstipaddr,attr,omitempty"` ARPDstIPMask NWFilterField `xml:"arpdstipmask,attr,omitempty"` Gratuitous NWFilterField `xml:"gratuitous,attr,omitempty"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleMAC struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonMAC ProtocolID NWFilterField `xml:"protocolid,attr,omitempty"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleVLAN struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonMAC VLANID NWFilterField `xml:"vlanid,attr,omitempty"` EncapProtocol NWFilterField `xml:"encap-protocol,attr,omitempty"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleSTP struct { Match NWFilterField `xml:"match,attr,omitempty"` SrcMACAddr NWFilterField `xml:"srcmacaddr,attr,omitempty"` SrcMACMask NWFilterField `xml:"srcmacmask,attr,omitempty"` Type NWFilterField `xml:"type,attr"` Flags NWFilterField `xml:"flags,attr"` RootPriority NWFilterField `xml:"root-priority,attr"` RootPriorityHi NWFilterField `xml:"root-priority-hi,attr"` RootAddress NWFilterField `xml:"root-address,attr,omitempty"` RootAddressMask NWFilterField `xml:"root-address-mask,attr,omitempty"` RootCost NWFilterField `xml:"root-cost,attr"` RootCostHi NWFilterField `xml:"root-cost-hi,attr"` SenderPriority NWFilterField `xml:"sender-priority,attr"` SenderPriorityHi NWFilterField `xml:"sender-priority-hi,attr"` SenderAddress NWFilterField `xml:"sender-address,attr,omitempty"` SenderAddressMask NWFilterField `xml:"sender-address-mask,attr,omitempty"` Port NWFilterField `xml:"port,attr"` PortHi NWFilterField `xml:"port-hi,attr"` Age NWFilterField `xml:"age,attr"` AgeHi NWFilterField `xml:"age-hi,attr"` MaxAge NWFilterField `xml:"max-age,attr"` MaxAgeHi NWFilterField `xml:"max-age-hi,attr"` HelloTime NWFilterField `xml:"hello-time,attr"` HelloTimeHi NWFilterField `xml:"hello-time-hi,attr"` ForwardDelay NWFilterField `xml:"forward-delay,attr"` ForwardDelayHi NWFilterField `xml:"forward-delay-hi,attr"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleIP struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonMAC SrcIPAddr NWFilterField `xml:"srcipaddr,attr,omitempty"` SrcIPMask NWFilterField `xml:"srcipmask,attr,omitempty"` DstIPAddr NWFilterField `xml:"dstipaddr,attr,omitempty"` DstIPMask NWFilterField `xml:"dstipmask,attr,omitempty"` Protocol NWFilterField `xml:"protocol,attr,omitempty"` NWFilterRuleCommonPort DSCP NWFilterField `xml:"dscp,attr"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleIPv6 struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonMAC SrcIPAddr NWFilterField `xml:"srcipaddr,attr,omitempty"` SrcIPMask NWFilterField `xml:"srcipmask,attr,omitempty"` DstIPAddr NWFilterField `xml:"dstipaddr,attr,omitempty"` DstIPMask NWFilterField `xml:"dstipmask,attr,omitempty"` Protocol NWFilterField `xml:"protocol,attr,omitempty"` NWFilterRuleCommonPort Type NWFilterField `xml:"type,attr"` TypeEnd NWFilterField `xml:"typeend,attr"` Code NWFilterField `xml:"code,attr"` CodeEnd NWFilterField `xml:"codeend,attr"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleTCP struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP NWFilterRuleCommonPort Option NWFilterField `xml:"option,attr"` Flags NWFilterField `xml:"flags,attr,omitempty"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleUDP struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP NWFilterRuleCommonPort Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleUDPLite struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleESP struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleAH struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleSCTP struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP NWFilterRuleCommonPort Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleICMP struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Type NWFilterField `xml:"type,attr"` Code NWFilterField `xml:"code,attr"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleAll struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleIGMP struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleTCPIPv6 struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP NWFilterRuleCommonPort Option NWFilterField `xml:"option,attr"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleUDPIPv6 struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP NWFilterRuleCommonPort Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleUDPLiteIPv6 struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleESPIPv6 struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleAHIPv6 struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleSCTPIPv6 struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP NWFilterRuleCommonPort Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleICMPIPv6 struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Type NWFilterField `xml:"type,attr"` Code NWFilterField `xml:"code,attr"` Comment string `xml:"comment,attr,omitempty"` } type NWFilterRuleAllIPv6 struct { Match string `xml:"match,attr,omitempty"` NWFilterRuleCommonIP Comment string `xml:"comment,attr,omitempty"` } func (s *NWFilterField) MarshalXMLAttr(name xml.Name) (xml.Attr, error) { if s == nil { return xml.Attr{}, nil } if s.Str != "" { return xml.Attr{ Name: name, Value: s.Str, }, nil } else if s.Var != "" { return xml.Attr{ Name: name, Value: "$" + s.Str, }, nil } else if s.Uint != nil { return xml.Attr{ Name: name, Value: fmt.Sprintf("0x%x", *s.Uint), }, nil } else { return xml.Attr{}, nil } } func (s *NWFilterField) UnmarshalXMLAttr(attr xml.Attr) error { if attr.Value == "" { return nil } if attr.Value[0] == '$' { s.Var = attr.Value[1:] } if strings.HasPrefix(attr.Value, "0x") { val, err := strconv.ParseUint(attr.Value[2:], 16, 64) if err != nil { return err } uval := uint(val) s.Uint = &uval } s.Str = attr.Value return nil } func (a *NWFilter) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name.Local = "filter" start.Attr = append(start.Attr, xml.Attr{ Name: xml.Name{Local: "name"}, Value: a.Name, }) if a.Chain != "" { start.Attr = append(start.Attr, xml.Attr{ Name: xml.Name{Local: "chain"}, Value: a.Chain, }) } if a.Priority != 0 { start.Attr = append(start.Attr, xml.Attr{ Name: xml.Name{Local: "priority"}, Value: fmt.Sprintf("%d", a.Priority), }) } err := e.EncodeToken(start) if err != nil { return err } if a.UUID != "" { uuid := xml.StartElement{ Name: xml.Name{Local: "uuid"}, } e.EncodeToken(uuid) e.EncodeToken(xml.CharData(a.UUID)) e.EncodeToken(uuid.End()) } for _, entry := range a.Entries { if entry.Rule != nil { rule := xml.StartElement{ Name: xml.Name{Local: "rule"}, } e.EncodeElement(entry.Rule, rule) } else if entry.Ref != nil { ref := xml.StartElement{ Name: xml.Name{Local: "filterref"}, } e.EncodeElement(entry.Ref, ref) } } err = e.EncodeToken(start.End()) if err != nil { return err } return nil } func (a *NWFilter) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { name, ok := getAttr(start.Attr, "name") if !ok { return fmt.Errorf("Missing filter name") } a.Name = name a.Chain, _ = getAttr(start.Attr, "chain") prio, ok := getAttr(start.Attr, "priority") if ok { val, err := strconv.ParseInt(prio, 10, 64) if err != nil { return err } a.Priority = int(val) } for { tok, err := d.Token() if err == io.EOF { break } switch tok := tok.(type) { case xml.StartElement: { if tok.Name.Local == "uuid" { txt, err := d.Token() if err != nil { return err } txt2, ok := txt.(xml.CharData) if !ok { return fmt.Errorf("Expected UUID string") } a.UUID = string(txt2) } else if tok.Name.Local == "rule" { entry := NWFilterEntry{ Rule: &NWFilterRule{}, } d.DecodeElement(entry.Rule, &tok) a.Entries = append(a.Entries, entry) } else if tok.Name.Local == "filterref" { entry := NWFilterEntry{ Ref: &NWFilterRef{}, } d.DecodeElement(entry.Ref, &tok) a.Entries = append(a.Entries, entry) } } } } return nil } func (s *NWFilter) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NWFilter) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/nwfilter_binding.go000066400000000000000000000044261405573250200202620ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Lian Duan * */ package libvirtxml import ( "encoding/xml" ) type NWFilterBinding struct { XMLName xml.Name `xml:"filterbinding"` Owner *NWFilterBindingOwner `xml:"owner"` PortDev *NWFilterBindingPortDev `xml:"portdev"` MAC *NWFilterBindingMAC `xml:"mac"` FilterRef *NWFilterBindingFilterRef `xml:"filterref"` } type NWFilterBindingOwner struct { UUID string `xml:"uuid,omitempty"` Name string `xml:"name,omitempty"` } type NWFilterBindingPortDev struct { Name string `xml:"name,attr"` } type NWFilterBindingMAC struct { Address string `xml:"address,attr"` } type NWFilterBindingFilterRef struct { Filter string `xml:"filter,attr"` Parameters []NWFilterBindingFilterParam `xml:"parameter"` } type NWFilterBindingFilterParam struct { Name string `xml:"name,attr"` Value string `xml:"value,attr"` } func (s *NWFilterBinding) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *NWFilterBinding) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/secret.go000066400000000000000000000036631405573250200162250ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2016 Red Hat, Inc. * */ package libvirtxml import ( "encoding/xml" ) type SecretUsage struct { Type string `xml:"type,attr"` Volume string `xml:"volume,omitempty"` Name string `xml:"name,omitempty"` Target string `xml:"target,omitempty"` } type Secret struct { XMLName xml.Name `xml:"secret"` Ephemeral string `xml:"ephemeral,attr,omitempty"` Private string `xml:"private,attr,omitempty"` Description string `xml:"description,omitempty"` UUID string `xml:"uuid,omitempty"` Usage *SecretUsage `xml:"usage"` } func (s *Secret) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *Secret) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/secret_test.go000066400000000000000000000100651405573250200172560ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2016 Red Hat, Inc. * */ package libvirtxml import ( "strings" "testing" ) var secretTestData = []struct { Object *Secret Expected []string }{ { Object: &Secret{ Description: "Demo", }, Expected: []string{ ``, ` Demo`, ``, }, }, { Object: &Secret{ Description: "Demo", Private: "yes", Ephemeral: "yes", UUID: "55806c7d-8e93-456f-829b-607d8c198367", }, Expected: []string{ ``, ` Demo`, ` 55806c7d-8e93-456f-829b-607d8c198367`, ``, }, }, { Object: &Secret{ Description: "Demo", Private: "yes", Ephemeral: "yes", UUID: "55806c7d-8e93-456f-829b-607d8c198367", Usage: &SecretUsage{ Type: "volume", Volume: "/var/lib/libvirt/images/puppyname.img", }, }, Expected: []string{ ``, ` Demo`, ` 55806c7d-8e93-456f-829b-607d8c198367`, ` `, ` /var/lib/libvirt/images/puppyname.img`, ` `, ``, }, }, { Object: &Secret{ Description: "Demo", Private: "yes", Ephemeral: "yes", UUID: "55806c7d-8e93-456f-829b-607d8c198367", Usage: &SecretUsage{ Type: "ceph", Name: "mycluster", }, }, Expected: []string{ ``, ` Demo`, ` 55806c7d-8e93-456f-829b-607d8c198367`, ` `, ` mycluster`, ` `, ``, }, }, { Object: &Secret{ Description: "Demo", Private: "yes", Ephemeral: "yes", UUID: "55806c7d-8e93-456f-829b-607d8c198367", Usage: &SecretUsage{ Type: "iscsi", Target: "libvirtiscsi", }, }, Expected: []string{ ``, ` Demo`, ` 55806c7d-8e93-456f-829b-607d8c198367`, ` `, ` libvirtiscsi`, ` `, ``, }, }, { Object: &Secret{ Description: "Demo", Private: "yes", Ephemeral: "yes", UUID: "55806c7d-8e93-456f-829b-607d8c198367", Usage: &SecretUsage{ Type: "tls", Name: "Demo cert", }, }, Expected: []string{ ``, ` Demo`, ` 55806c7d-8e93-456f-829b-607d8c198367`, ` `, ` Demo cert`, ` `, ``, }, }, } func TestSecret(t *testing.T) { for _, test := range secretTestData { doc, err := test.Object.Marshal() if err != nil { t.Fatal(err) } expect := strings.Join(test.Expected, "\n") if doc != expect { t.Fatal("Bad xml:\n", string(doc), "\n does not match\n", expect, "\n") } } } libvirt-go-xml-7.4.0/storage_encryption.go000066400000000000000000000034041405573250200206470ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ package libvirtxml type StorageEncryptionSecret struct { Type string `xml:"type,attr"` UUID string `xml:"uuid,attr"` } type StorageEncryptionCipher struct { Name string `xml:"name,attr"` Size uint64 `xml:"size,attr"` Mode string `xml:"mode,attr"` Hash string `xml:"hash,attr"` } type StorageEncryptionIvgen struct { Name string `xml:"name,attr"` Hash string `xml:"hash,attr"` } type StorageEncryption struct { Format string `xml:"format,attr"` Secret *StorageEncryptionSecret `xml:"secret"` Cipher *StorageEncryptionCipher `xml:"cipher"` Ivgen *StorageEncryptionIvgen `xml:"ivgen"` } libvirt-go-xml-7.4.0/storage_pool.go000066400000000000000000000171641405573250200174360ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ package libvirtxml import "encoding/xml" type StoragePoolSize struct { Unit string `xml:"unit,attr,omitempty"` Value uint64 `xml:",chardata"` } type StoragePoolTargetPermissions struct { Owner string `xml:"owner,omitempty"` Group string `xml:"group,omitempty"` Mode string `xml:"mode,omitempty"` Label string `xml:"label,omitempty"` } type StoragePoolTargetTimestamps struct { Atime string `xml:"atime"` Mtime string `xml:"mtime"` Ctime string `xml:"ctime"` } type StoragePoolTarget struct { Path string `xml:"path,omitempty"` Permissions *StoragePoolTargetPermissions `xml:"permissions"` Timestamps *StoragePoolTargetTimestamps `xml:"timestamps"` Encryption *StorageEncryption `xml:"encryption"` } type StoragePoolSourceFormat struct { Type string `xml:"type,attr"` } type StoragePoolSourceProtocol struct { Version string `xml:"ver,attr"` } type StoragePoolSourceHost struct { Name string `xml:"name,attr"` Port string `xml:"port,attr,omitempty"` } type StoragePoolSourceDevice struct { Path string `xml:"path,attr"` PartSeparator string `xml:"part_separator,attr,omitempty"` FreeExtents []StoragePoolSourceDeviceFreeExtent `xml:"freeExtent"` } type StoragePoolSourceDeviceFreeExtent struct { Start uint64 `xml:"start,attr"` End uint64 `xml:"end,attr"` } type StoragePoolSourceAuthSecret struct { Usage string `xml:"usage,attr,omitempty"` UUID string `xml:"uuid,attr,omitempty"` } type StoragePoolSourceAuth struct { Type string `xml:"type,attr"` Username string `xml:"username,attr"` Secret *StoragePoolSourceAuthSecret `xml:"secret"` } type StoragePoolSourceVendor struct { Name string `xml:"name,attr"` } type StoragePoolSourceProduct struct { Name string `xml:"name,attr"` } type StoragePoolPCIAddress struct { Domain *uint `xml:"domain,attr"` Bus *uint `xml:"bus,attr"` Slot *uint `xml:"slot,attr"` Function *uint `xml:"function,attr"` } type StoragePoolSourceAdapterParentAddr struct { UniqueID uint64 `xml:"unique_id,attr"` Address *StoragePoolPCIAddress `xml:"address"` } type StoragePoolSourceAdapter struct { Type string `xml:"type,attr,omitempty"` Name string `xml:"name,attr,omitempty"` Parent string `xml:"parent,attr,omitempty"` Managed string `xml:"managed,attr,omitempty"` WWNN string `xml:"wwnn,attr,omitempty"` WWPN string `xml:"wwpn,attr,omitempty"` ParentAddr *StoragePoolSourceAdapterParentAddr `xml:"parentaddr"` } type StoragePoolSourceDir struct { Path string `xml:"path,attr"` } type StoragePoolSourceInitiator struct { IQN StoragePoolSourceInitiatorIQN `xml:"iqn"` } type StoragePoolSourceInitiatorIQN struct { Name string `xml:"name,attr,omitempty"` } type StoragePoolSource struct { Name string `xml:"name,omitempty"` Dir *StoragePoolSourceDir `xml:"dir"` Host []StoragePoolSourceHost `xml:"host"` Device []StoragePoolSourceDevice `xml:"device"` Auth *StoragePoolSourceAuth `xml:"auth"` Vendor *StoragePoolSourceVendor `xml:"vendor"` Product *StoragePoolSourceProduct `xml:"product"` Format *StoragePoolSourceFormat `xml:"format"` Protocol *StoragePoolSourceProtocol `xml:"protocol"` Adapter *StoragePoolSourceAdapter `xml:"adapter"` Initiator *StoragePoolSourceInitiator `xml:"initiator"` } type StoragePoolRefreshVol struct { Allocation string `xml:"allocation,attr"` } type StoragePoolRefresh struct { Volume StoragePoolRefreshVol `xml:"volume"` } type StoragePoolFeatures struct { COW StoragePoolFeatureCOW `xml:"cow"` } type StoragePoolFeatureCOW struct { State string `xml:"state,attr"` } type StoragePool struct { XMLName xml.Name `xml:"pool"` Type string `xml:"type,attr"` Name string `xml:"name,omitempty"` UUID string `xml:"uuid,omitempty"` Allocation *StoragePoolSize `xml:"allocation"` Capacity *StoragePoolSize `xml:"capacity"` Available *StoragePoolSize `xml:"available"` Features *StoragePoolFeatures `xml:"features"` Target *StoragePoolTarget `xml:"target"` Source *StoragePoolSource `xml:"source"` Refresh *StoragePoolRefresh `xml:"refresh"` /* Pool backend namespcaes must be last */ FSCommandline *StoragePoolFSCommandline RBDCommandline *StoragePoolRBDCommandline } type StoragePoolFSCommandlineOption struct { Name string `xml:"name,attr"` } type StoragePoolFSCommandline struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/storagepool/fs/1.0 mount_opts"` Options []StoragePoolFSCommandlineOption `xml:"option"` } type StoragePoolRBDCommandlineOption struct { Name string `xml:"name,attr"` Value string `xml:"value,attr"` } type StoragePoolRBDCommandline struct { XMLName xml.Name `xml:"http://libvirt.org/schemas/storagepool/rbd/1.0 config_opts"` Options []StoragePoolRBDCommandlineOption `xml:"option"` } func (a *StoragePoolPCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error { marshalUintAttr(&start, "domain", a.Domain, "0x%04x") marshalUintAttr(&start, "bus", a.Bus, "0x%02x") marshalUintAttr(&start, "slot", a.Slot, "0x%02x") marshalUintAttr(&start, "function", a.Function, "0x%x") e.EncodeToken(start) e.EncodeToken(start.End()) return nil } func (a *StoragePoolPCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for _, attr := range start.Attr { if attr.Name.Local == "domain" { if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil { return err } } else if attr.Name.Local == "bus" { if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil { return err } } else if attr.Name.Local == "slot" { if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil { return err } } else if attr.Name.Local == "function" { if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil { return err } } } d.Skip() return nil } func (s *StoragePool) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *StoragePool) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/storage_pool_test.go000066400000000000000000000140421405573250200204650ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ package libvirtxml import ( "strings" "testing" ) var adapterDomain uint = 0 var adapterBus uint = 0 var adapterSlot uint = 31 var adapterFunction uint = 2 var storagePoolTestData = []struct { Object *StoragePool Expected []string }{ { Object: &StoragePool{ Type: "dir", Name: "pool", UUID: "3e3fce45-4f53-4fa7-bb32-11f34168b82b", Allocation: &StoragePoolSize{Value: 1000000}, Capacity: &StoragePoolSize{Value: 5000000}, Available: &StoragePoolSize{Value: 3000000}, }, Expected: []string{ ``, ` pool`, ` 3e3fce45-4f53-4fa7-bb32-11f34168b82b`, ` 1000000`, ` 5000000`, ` 3000000`, ``, }, }, { Object: &StoragePool{ Type: "iscsi", Name: "pool", Source: &StoragePoolSource{ Host: []StoragePoolSourceHost{ StoragePoolSourceHost{ Name: "host.example.com", }, }, Device: []StoragePoolSourceDevice{ StoragePoolSourceDevice{ Path: "pool.example.com:iscsi-pool", }, }, Auth: &StoragePoolSourceAuth{ Type: "chap", Username: "username", Secret: &StoragePoolSourceAuthSecret{ Usage: "cluster", }, }, Vendor: &StoragePoolSourceVendor{ Name: "vendor", }, Product: &StoragePoolSourceProduct{ Name: "product", }, }, }, Expected: []string{ ``, ` pool`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &StoragePool{ Type: "disk", Name: "pool", Source: &StoragePoolSource{ Device: []StoragePoolSourceDevice{ StoragePoolSourceDevice{ Path: "/dev/mapper/pool", PartSeparator: "no", }, }, Format: &StoragePoolSourceFormat{ Type: "gpt", }, }, }, Expected: []string{ ``, ` pool`, ` `, ` `, ` `, ` `, ``, }, }, { Object: &StoragePool{ Type: "scsi", Name: "pool", Source: &StoragePoolSource{ Adapter: &StoragePoolSourceAdapter{ Type: "scsi_host", Name: "scsi_host", }, }, }, Expected: []string{ ``, ` pool`, ` `, ` `, ` `, ``, }, }, { Object: &StoragePool{ Type: "scsi", Name: "pool", Source: &StoragePoolSource{ Adapter: &StoragePoolSourceAdapter{ Type: "scsi_host", ParentAddr: &StoragePoolSourceAdapterParentAddr{ UniqueID: 1, Address: &StoragePoolPCIAddress{ Domain: &adapterDomain, Bus: &adapterBus, Slot: &adapterSlot, Function: &adapterFunction, }, }, }, }, }, Expected: []string{ ``, ` pool`, ` `, ` `, ` `, `
`, `
`, `
`, ` `, `
`, }, }, { Object: &StoragePool{ Type: "fs", Name: "pool", Source: &StoragePoolSource{ Adapter: &StoragePoolSourceAdapter{ Type: "fc_host", Parent: "scsi_parent", WWNN: "20000000c9831b4b", WWPN: "10000000c9831b4b", }, }, }, Expected: []string{ ``, ` pool`, ` `, ` `, ` `, ``, }, }, { Object: &StoragePool{ Type: "dir", Name: "pool", Target: &StoragePoolTarget{ Path: "/pool", Permissions: &StoragePoolTargetPermissions{ Owner: "1", Group: "1", Mode: "0744", Label: "pool", }, }, }, Expected: []string{ ``, ` pool`, ` `, ` /pool`, ` `, ` 1`, ` 1`, ` 0744`, ` `, ` `, ` `, ``, }, }, } func TestStoragePool(t *testing.T) { for _, test := range storagePoolTestData { doc, err := test.Object.Marshal() if err != nil { t.Fatal(err) } expect := strings.Join(test.Expected, "\n") if doc != expect { t.Fatal("Bad xml:\n", string(doc), "\n does not match\n", expect, "\n") } } } libvirt-go-xml-7.4.0/storage_vol.go000066400000000000000000000070271405573250200172620ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ package libvirtxml import "encoding/xml" type StorageVolumeSize struct { Unit string `xml:"unit,attr,omitempty"` Value uint64 `xml:",chardata"` } type StorageVolumeTargetPermissions struct { Owner string `xml:"owner,omitempty"` Group string `xml:"group,omitempty"` Mode string `xml:"mode,omitempty"` Label string `xml:"label,omitempty"` } type StorageVolumeTargetFeature struct { LazyRefcounts *struct{} `xml:"lazy_refcounts"` } type StorageVolumeTargetFormat struct { Type string `xml:"type,attr"` } type StorageVolumeTargetTimestamps struct { Atime string `xml:"atime"` Mtime string `xml:"mtime"` Ctime string `xml:"ctime"` } type StorageVolumeTargetCluterSize struct { Unit string `xml:"unit,attr,omitempty"` Value uint64 `xml:",chardata"` } type StorageVolumeTarget struct { Path string `xml:"path,omitempty"` Format *StorageVolumeTargetFormat `xml:"format"` Permissions *StorageVolumeTargetPermissions `xml:"permissions"` Timestamps *StorageVolumeTargetTimestamps `xml:"timestamps"` Compat string `xml:"compat,omitempty"` ClusterSize *StorageVolumeTargetCluterSize `xml:"clusterSize"` NoCOW *struct{} `xml:"nocow"` Features []StorageVolumeTargetFeature `xml:"features"` Encryption *StorageEncryption `xml:"encryption"` } type StorageVolumeBackingStore struct { Path string `xml:"path"` Format *StorageVolumeTargetFormat `xml:"format"` Permissions *StorageVolumeTargetPermissions `xml:"permissions"` } type StorageVolume struct { XMLName xml.Name `xml:"volume"` Type string `xml:"type,attr,omitempty"` Name string `xml:"name"` Key string `xml:"key,omitempty"` Allocation *StorageVolumeSize `xml:"allocation"` Capacity *StorageVolumeSize `xml:"capacity"` Physical *StorageVolumeSize `xml:"physical"` Target *StorageVolumeTarget `xml:"target"` BackingStore *StorageVolumeBackingStore `xml:"backingStore"` } func (s *StorageVolume) Unmarshal(doc string) error { return xml.Unmarshal([]byte(doc), s) } func (s *StorageVolume) Marshal() (string, error) { doc, err := xml.MarshalIndent(s, "", " ") if err != nil { return "", err } return string(doc), nil } libvirt-go-xml-7.4.0/storage_vol_test.go000066400000000000000000000141221405573250200203130ustar00rootroot00000000000000/* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2017 Red Hat, Inc. * */ package libvirtxml import ( "strings" "testing" ) var storageVolumeTestData = []struct { Object *StorageVolume Expected []string }{ { Object: &StorageVolume{ Type: "file", Name: "file.img", Key: "/file.img", Allocation: &StorageVolumeSize{ Value: 0, }, Capacity: &StorageVolumeSize{ Unit: "T", Value: 1, }, }, Expected: []string{ ``, ` file.img`, ` /file.img`, ` 0`, ` 1`, ``, }, }, { Object: &StorageVolume{ Type: "file", Name: "file.img", Target: &StorageVolumeTarget{ Path: "/file.img", Format: &StorageVolumeTargetFormat{ Type: "qcow2", }, Permissions: &StorageVolumeTargetPermissions{ Owner: "107", Group: "107", Mode: "0744", Label: "image", }, Timestamps: &StorageVolumeTargetTimestamps{ Atime: "1341933637.273190990", Mtime: "1341930622.047245868", Ctime: "1341930622.047245868", }, Compat: "1.1", NoCOW: &struct{}{}, Features: []StorageVolumeTargetFeature{ StorageVolumeTargetFeature{ LazyRefcounts: &struct{}{}, }, }, }, }, Expected: []string{ ``, ` file.img`, ` `, ` /file.img`, ` `, ` `, ` 107`, ` 107`, ` 0744`, ` `, ` `, ` `, ` 1341933637.273190990`, ` 1341930622.047245868`, ` 1341930622.047245868`, ` `, ` 1.1`, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &StorageVolume{ Type: "file", Name: "file.img", BackingStore: &StorageVolumeBackingStore{ Path: "/master.img", Format: &StorageVolumeTargetFormat{ Type: "raw", }, Permissions: &StorageVolumeTargetPermissions{ Owner: "107", Group: "107", Mode: "0744", Label: "label", }, }, }, Expected: []string{ ``, ` file.img`, ` `, ` /master.img`, ` `, ` `, ` 107`, ` 107`, ` 0744`, ` `, ` `, ` `, ``, }, }, { Object: &StorageVolume{ Name: "luks.img", Capacity: &StorageVolumeSize{ Unit: "G", Value: 5, }, Target: &StorageVolumeTarget{ Path: "/luks.img", Format: &StorageVolumeTargetFormat{ Type: "raw", }, Encryption: &StorageEncryption{ Format: "luks", Secret: &StorageEncryptionSecret{ Type: "passphrase", UUID: "f52a81b2-424e-490c-823d-6bd4235bc572", }, }, }, }, Expected: []string{ ``, ` luks.img`, ` 5`, ` `, ` /luks.img`, ` `, ` `, ` `, ` `, ` `, ``, }, }, { Object: &StorageVolume{ Name: "twofish", Capacity: &StorageVolumeSize{ Unit: "G", Value: 5, }, Target: &StorageVolumeTarget{ Path: "/twofish.luks", Format: &StorageVolumeTargetFormat{ Type: "raw", }, Encryption: &StorageEncryption{ Format: "luks", Secret: &StorageEncryptionSecret{ Type: "passphrase", UUID: "f52a81b2-424e-490c-823d-6bd4235bc572", }, Cipher: &StorageEncryptionCipher{ Name: "twofish", Size: 256, Mode: "cbc", Hash: "sha256", }, Ivgen: &StorageEncryptionIvgen{ Name: "plain64", Hash: "sha256", }, }, }, }, Expected: []string{ ``, ` twofish`, ` 5`, ` `, ` /twofish.luks`, ` `, ` `, ` `, ` `, ` `, ` `, ` `, ``, }, }, } func TestStorageVolume(t *testing.T) { for _, test := range storageVolumeTestData { doc, err := test.Object.Marshal() if err != nil { t.Fatal(err) } expect := strings.Join(test.Expected, "\n") if doc != expect { t.Fatal("Bad xml:\n", string(doc), "\n does not match\n", expect, "\n") } } } libvirt-go-xml-7.4.0/xml_test.go000066400000000000000000000470521405573250200165770ustar00rootroot00000000000000// +build xmlroundtrip /* * This file is part of the libvirt-go-xml project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (C) 2016 Red Hat, Inc. * */ package libvirtxml import ( "fmt" "io/ioutil" "os" "os/exec" "strings" "testing" ) var xmldirs = []string{ "testdata/libvirt/tests/bhyveargv2xmldata", "testdata/libvirt/tests/bhyvexml2argvdata", "testdata/libvirt/tests/bhyvexml2xmloutdata", "testdata/libvirt/tests/capabilityschemadata", "testdata/libvirt/tests/cputestdata", "testdata/libvirt/tests/domaincapsdata", "testdata/libvirt/tests/domainconfdata", "testdata/libvirt/tests/domainschemadata", "testdata/libvirt/tests/genericxml2xmlindata", "testdata/libvirt/tests/genericxml2xmloutdata", "testdata/libvirt/tests/interfaceschemadata", "testdata/libvirt/tests/libxlxml2domconfigdata", "testdata/libvirt/tests/lxcconf2xmldata", "testdata/libvirt/tests/lxcxml2xmldata", "testdata/libvirt/tests/lxcxml2xmloutdata", "testdata/libvirt/tests/networkxml2confdata", "testdata/libvirt/tests/networkxml2firewalldata", "testdata/libvirt/tests/networkxml2xmlin", "testdata/libvirt/tests/networkxml2xmlout", "testdata/libvirt/tests/networkxml2xmlupdatein", "testdata/libvirt/tests/networkxml2xmlupdateout", "testdata/libvirt/tests/nodedevschemadata", "testdata/libvirt/tests/nwfilterxml2firewalldata", "testdata/libvirt/tests/nwfilterxml2xmlin", "testdata/libvirt/tests/nwfilterxml2xmlout", "testdata/libvirt/tests/qemuagentdata", "testdata/libvirt/tests/qemucapabilitiesdata", "testdata/libvirt/tests/qemudomainsnapshotxml2xmlin", "testdata/libvirt/tests/qemudomainsnapshotxml2xmlout", "testdata/libvirt/tests/qemuhotplugtestcpus", "testdata/libvirt/tests/qemuhotplugtestdevices", "testdata/libvirt/tests/qemuhotplugtestdomains", "testdata/libvirt/tests/qemumemlockdata", "testdata/libvirt/tests/qemuxml2argvdata", "testdata/libvirt/tests/qemuxml2xmloutdata", "testdata/libvirt/tests/secretxml2xmlin", "testdata/libvirt/tests/securityselinuxlabeldata", "testdata/libvirt/tests/storagepoolschemadata", "testdata/libvirt/tests/storagepoolxml2xmlin", "testdata/libvirt/tests/storagepoolxml2xmlout", "testdata/libvirt/tests/storagevolschemadata", "testdata/libvirt/tests/storagevolxml2xmlin", "testdata/libvirt/tests/storagevolxml2xmlout", "testdata/libvirt/tests/vircaps2xmldata", "testdata/libvirt/tests/virnwfilterbindingxml2xmldata", "testdata/libvirt/tests/virnetworkportxml2xmldata", "testdata/libvirt/tests/virnwfilterbindingxml2xmldata", "testdata/libvirt/tests/virstorageutildata", "testdata/libvirt/tests/vmx2xmldata", "testdata/libvirt/tests/xlconfigdata", "testdata/libvirt/tests/xmconfigdata", "testdata/libvirt/tests/xml2vmxdata", } var consoletype = "/domain[0]/devices[0]/console[0]/@type" var volsrc = "/volume[0]/source[0]" var blacklist = map[string]bool{ // intentionally invalid xml "testdata/libvirt/tests/genericxml2xmlindata/chardev-unix-redirdev-missing-path.xml": true, "testdata/libvirt/tests/genericxml2xmlindata/chardev-unix-rng-missing-path.xml": true, "testdata/libvirt/tests/qemuxml2argvdata/virtio-rng-egd-crash.xml": true, "testdata/libvirt/tests/genericxml2xmlindata/chardev-unix-smartcard-missing-path.xml": true, "testdata/libvirt/tests/genericxml2xmlindata/chardev-tcp-multiple-source.xml": true, "testdata/libvirt/tests/networkxml2xmlupdatein/dns-host-gateway-incomplete.xml": true, "testdata/libvirt/tests/networkxml2xmlupdatein/host-new-incomplete.xml": true, "testdata/libvirt/tests/networkxml2xmlupdatein/unparsable-dns-host.xml": true, // udp source in different order "testdata/libvirt/tests/genericxml2xmlindata/chardev-udp.xml": true, "testdata/libvirt/tests/genericxml2xmlindata/chardev-udp-multiple-source.xml": true, } var extraActualNodes = map[string][]string{ "testdata/libvirt/tests/qemuxml2argvdata/disk-discard.xml": []string{ "/domain[0]/devices[0]/disk[0]/@type", }, "testdata/libvirt/tests/qemuxml2argvdata/fs9p-ccw.xml": []string{ "/domain[0]/devices[0]/filesystem[1]/@type", "/domain[0]/devices[0]/filesystem[2]/@type", }, "testdata/libvirt/tests/qemuxml2argvdata/fs9p.xml": []string{ "/domain[0]/devices[0]/filesystem[1]/@type", "/domain[0]/devices[0]/filesystem[2]/@type", }, "testdata/libvirt/tests/qemuxml2argvdata/disk-drive-discard.xml": []string{ "/domain[0]/devices[0]/disk[0]/@type", }, "testdata/libvirt/tests/genericxml2xmlindata/chardev-udp.xml": []string{ "/domain[0]/devices[0]/channel[0]/source[0]/@mode", }, "testdata/libvirt/tests/qemuxml2argvdata/disk-mirror-old.xml": []string{ "/domain[0]/devices[0]/disk[0]/mirror[0]/@type", "/domain[0]/devices[0]/disk[0]/mirror[0]/source[0]", "/domain[0]/devices[0]/disk[2]/mirror[0]/@type", "/domain[0]/devices[0]/disk[2]/mirror[0]/format[0]", "/domain[0]/devices[0]/disk[2]/mirror[0]/source[0]", }, "testdata/libvirt/tests/xlconfigdata/test-fullvirt-ovswitch-tagged.xml": []string{ "/domain[0]/devices[0]/interface[0]/virtualport[0]/parameters[0]", }, "testdata/libvirt/tests/xlconfigdata/test-fullvirt-ovswitch-trunked.xml": []string{ "/domain[0]/devices[0]/interface[0]/virtualport[0]/parameters[0]", }, "testdata/libvirt/tests/networkxml2xmlin/openvswitch-net.xml": []string{ "/network[0]/virtualport[0]/parameters[0]", }, "testdata/libvirt/tests/networkxml2xmlout/openvswitch-net.xml": []string{ "/network[0]/virtualport[0]/parameters[0]", }, "testdata/libvirt/tests/networkxml2xmlupdateout/openvswitch-net-modified.xml": []string{ "/network[0]/virtualport[0]/parameters[0]", }, "testdata/libvirt/tests/networkxml2xmlupdateout/openvswitch-net-more-portgroups.xml": []string{ "/network[0]/virtualport[0]/parameters[0]", }, "testdata/libvirt/tests/networkxml2xmlupdateout/openvswitch-net-without-alice.xml": []string{ "/network[0]/virtualport[0]/parameters[0]", }, "testdata/libvirt/tests/interfaceschemadata/bridge-vlan.xml": []string{ "/interface[0]/bridge[0]/interface[0]/vlan[0]/interface[0]/@type", }, "testdata/libvirt/tests/interfaceschemadata/vlan.xml": []string{ "/interface[0]/vlan[0]/interface[0]/@type", }, "testdata/libvirt/tests/qemudomainsnapshotxml2xmlin/disk_driver_name_null.xml": []string{ "/domainsnapshot[0]/disks[0]/disk[0]/@type", }, "testdata/libvirt/tests/qemudomainsnapshotxml2xmlin/disk_snapshot.xml": []string{ "/domainsnapshot[0]/disks[0]/disk[0]/@type", "/domainsnapshot[0]/disks[0]/disk[1]/@type", "/domainsnapshot[0]/disks[0]/disk[2]/@type", "/domainsnapshot[0]/disks[0]/disk[3]/@type", "/domainsnapshot[0]/disks[0]/disk[4]/@type", }, "testdata/libvirt/tests/qemudomainsnapshotxml2xmlout/disk_snapshot.xml": []string{ "/domainsnapshot[0]/disks[0]/disk[0]/@type", "/domainsnapshot[0]/disks[0]/disk[1]/@type", "/domainsnapshot[0]/disks[0]/disk[2]/@type", }, "testdata/libvirt/tests/qemudomainsnapshotxml2xmlout/disk_snapshot_redefine.xml": []string{ "/domainsnapshot[0]/disks[0]/disk[0]/@type", "/domainsnapshot[0]/disks[0]/disk[1]/@type", "/domainsnapshot[0]/disks[0]/disk[2]/@type", }, "testdata/libvirt/tests/qemudomainsnapshotxml2xmlout/external_vm_redefine.xml": []string{ "/domainsnapshot[0]/disks[0]/disk[0]/@type", }, "testdata/libvirt/tests/qemudomainsnapshotxml2xmlin/qcow2-metadata-cache.xml": []string{ "/domainsnapshot[0]/disks[0]/disk[0]/@type", }, "testdata/libvirt/tests/bhyvexml2argvdata/bhyvexml2argv-fs-9p.xml": []string{ "/domain[0]/devices[0]/filesystem[0]/@type", }, "testdata/libvirt/tests/bhyvexml2argvdata/bhyvexml2argv-fs-9p-readonly.xml": []string{ "/domain[0]/devices[0]/filesystem[0]/@type", }, "testdata/libvirt/tests/bhyvexml2argvdata/bhyvexml2argv-fs-9p-unsupported-accessmode.xml": []string{ "/domain[0]/devices[0]/filesystem[0]/@type", }, "testdata/libvirt/tests/bhyvexml2argvdata/bhyvexml2argv-fs-9p-unsupported-driver.xml": []string{ "/domain[0]/devices[0]/filesystem[0]/@type", }, "testdata/libvirt/tests/bhyvexml2argvdata/bhyvexml2argv-console-master-slave-not-specified.xml": []string{ "/domain[0]/devices[0]/console[0]/source[0]", }, } var extraExpectNodes = map[string][]string{ "testdata/libvirt/tests/qemuxml2argvdata/usb-redir-filter.xml": []string{ "/domain[0]/devices[0]/redirfilter[0]/usbdev[1]/@vendor", "/domain[0]/devices[0]/redirfilter[0]/usbdev[1]/@product", "/domain[0]/devices[0]/redirfilter[0]/usbdev[1]/@class", "/domain[0]/devices[0]/redirfilter[0]/usbdev[1]/@version", }, "testdata/libvirt/tests/domainschemadata/domain-parallels-ct-simple.xml": []string{ "/domain[0]/description[0]", }, "testdata/libvirt/tests/storagevolxml2xmlin/vol-encrypt1.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-encrypt2.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-file-backing.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-file-iso.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-file-naming.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-file-qcow2.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-file.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-gluster-dir-neg-uid.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-gluster-dir.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-logical-backing.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-logical.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-luks-cipher.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-luks-convert.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-luks.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-partition.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-0.10-lazy.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-1.1.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-lazy.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-luks.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-luks-convert.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-encryption.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-nobacking.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-nocapacity-backing.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-nocapacity.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2-nocow.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-qcow2.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlin/vol-sheepdog.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-file-backing.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-file-iso.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-file-naming.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-file.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-gluster-dir-neg-uid.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-gluster-dir.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-logical-backing.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-logical.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-luks-cipher.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-luks.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-partition.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2-0.10-lazy.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2-1.1.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2-encryption.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2-lazy.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2-luks.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2-nobacking.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2-nocapacity-backing.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2-nocapacity.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2-nocow.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-qcow2.xml": []string{volsrc}, "testdata/libvirt/tests/storagevolxml2xmlout/vol-sheepdog.xml": []string{volsrc}, "testdata/libvirt/tests/qemudomainsnapshotxml2xmlin/disk_snapshot.xml": []string{ "/domainsnapshot[0]/disks[0]/disk[3]/source[0]", }, } func trimXML(xml string) string { xml = strings.TrimSpace(xml) if strings.HasPrefix(xml, "") if end != -1 { xml = xml[end+2:] xml = strings.TrimSpace(xml) } } if strings.HasPrefix(xml, "") if end != -1 { xml = xml[end+3:] xml = strings.TrimSpace(xml) } } return xml } func testRoundTrip(t *testing.T, xml string, filename string) { if strings.HasSuffix(filename, "-invalid.xml") { return } xml = trimXML(xml) var doc Document if strings.HasPrefix(xml, "