Adds support for dumping domain XML

This adds support for dumping a domain's XML definition, akin to `virsh
dumpxml <domain>`. The returned data is quite large so I've included an
integration test rather than adding a huge blob of hex to `libvirttest`.
This commit is contained in:
Ben LeMasurier 2016-11-30 18:37:30 -07:00
parent 850adbae3f
commit c6e0d02f28
5 changed files with 121 additions and 1 deletions

View File

@ -35,9 +35,11 @@ install:
before_script: before_script:
- go get -d ./... - go get -d ./...
- sudo qemu-img create -f raw -o size=10M /var/lib/libvirt/images/test.raw
- sudo virsh define ./test-domain.xml
- sudo virsh start test
script: script:
- virsh list
- ./scripts/licensecheck.sh - ./scripts/licensecheck.sh
- go build ./... - go build ./...
- golint -set_exit_status ./... - golint -set_exit_status ./...

View File

@ -38,6 +38,7 @@ const (
const ( const (
ProcConnectOpen = 1 ProcConnectOpen = 1
ProcConnectClose = 2 ProcConnectClose = 2
ProcDomainGetXMLDesc = 14
ProcDomainLookupByName = 23 ProcDomainLookupByName = 23
ProcAuthList = 66 ProcAuthList = 66
ProcConnectGetLibVersion = 157 ProcConnectGetLibVersion = 157

View File

@ -78,6 +78,23 @@ type qemuError struct {
} `json:"error"` } `json:"error"`
} }
// DomainXMLFlags specifies options for dumping a domain's XML.
type DomainXMLFlags uint32
const (
// DomainXMLFlagSecure dumps XML with sensitive information included.
DomainXMLFlagSecure DomainXMLFlags = 1 << iota
// DomainXMLFlagInactive dumps XML with inactive domain information.
DomainXMLFlagInactive
// DomainXMLFlagUpdateCPU dumps XML with guest CPU requirements according to the host CPU.
DomainXMLFlagUpdateCPU
// DomainXMLFlagMigratable dumps XML suitable for migration.
DomainXMLFlagMigratable
)
// MigrateFlags specifies options when performing a migration. // MigrateFlags specifies options when performing a migration.
type MigrateFlags uint32 type MigrateFlags uint32
@ -496,6 +513,47 @@ func (l *Libvirt) Destroy(dom string, flags DestroyFlags) error {
return nil return nil
} }
// XML returns a domain's raw XML definition, akin to `virsh dumpxml <domain>`.
// See DomainXMLFlag* for optional flags.
func (l *Libvirt) XML(dom string, flags DomainXMLFlags) ([]byte, error) {
d, err := l.lookup(dom)
if err != nil {
return nil, err
}
payload := struct {
Domain Domain
Flags DomainXMLFlags
}{
Domain: *d,
Flags: flags,
}
buf, err := encode(&payload)
if err != nil {
return nil, err
}
resp, err := l.request(constants.ProcDomainGetXMLDesc, constants.ProgramRemote, &buf)
if err != nil {
return nil, err
}
r := <-resp
if r.Status != StatusOK {
return nil, decodeError(r.Payload)
}
pl := bytes.NewReader(r.Payload)
dec := xdr.NewDecoder(pl)
s, _, err := dec.DecodeString()
if err != nil {
return nil, err
}
return []byte(s), nil
}
// Version returns the version of the libvirt daemon. // Version returns the version of the libvirt daemon.
func (l *Libvirt) Version() (string, error) { func (l *Libvirt) Version() (string, error) {
resp, err := l.request(constants.ProcConnectGetLibVersion, constants.ProgramRemote, nil) resp, err := l.request(constants.ProcConnectGetLibVersion, constants.ProgramRemote, nil)

View File

@ -17,6 +17,7 @@
package libvirt package libvirt
import ( import (
"encoding/xml"
"net" "net"
"testing" "testing"
"time" "time"
@ -40,6 +41,26 @@ func TestDisconnectIntegration(t *testing.T) {
} }
} }
func TestXMLIntegration(t *testing.T) {
l := New(testConn(t))
if err := l.Connect(); err != nil {
t.Error(err)
}
defer l.Disconnect()
var flags DomainXMLFlags
data, err := l.XML("test", flags)
if err != nil {
t.Fatal(err)
}
var v interface{}
if err := xml.Unmarshal(data, &v); err != nil {
t.Error(err)
}
}
func testConn(t *testing.T) net.Conn { func testConn(t *testing.T) net.Conn {
conn, err := net.DialTimeout("tcp", testAddr, time.Second*2) conn, err := net.DialTimeout("tcp", testAddr, time.Second*2)
if err != nil { if err != nil {

38
test-domain.xml Normal file
View File

@ -0,0 +1,38 @@
<!-- simple integration test domain for go-libvirt -->
<domain type="qemu">
<name>test</name>
<currentMemory>1024</currentMemory>
<memory>1024</memory>
<uuid>afc2ef71-66e0-45a7-a5ec-d8ba1ea8177d</uuid>
<os>
<type arch='x86_64'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/><apic/><pae/>
</features>
<clock offset="utc"/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<vcpu>1</vcpu>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/var/lib/libvirt/images/test.raw'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='block' device='cdrom'>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
<input type='tablet' bus='usb'/>
<graphics type='vnc' port='-1'/>
<console type='pty'/>
<sound model='ac97'/>
<video>
<model type='cirrus'/>
</video>
</devices>
</domain>