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:
parent
850adbae3f
commit
c6e0d02f28
@ -35,9 +35,11 @@ install:
|
||||
|
||||
before_script:
|
||||
- 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:
|
||||
- virsh list
|
||||
- ./scripts/licensecheck.sh
|
||||
- go build ./...
|
||||
- golint -set_exit_status ./...
|
||||
|
@ -38,6 +38,7 @@ const (
|
||||
const (
|
||||
ProcConnectOpen = 1
|
||||
ProcConnectClose = 2
|
||||
ProcDomainGetXMLDesc = 14
|
||||
ProcDomainLookupByName = 23
|
||||
ProcAuthList = 66
|
||||
ProcConnectGetLibVersion = 157
|
||||
|
58
libvirt.go
58
libvirt.go
@ -78,6 +78,23 @@ type qemuError struct {
|
||||
} `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.
|
||||
type MigrateFlags uint32
|
||||
|
||||
@ -496,6 +513,47 @@ func (l *Libvirt) Destroy(dom string, flags DestroyFlags) error {
|
||||
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.
|
||||
func (l *Libvirt) Version() (string, error) {
|
||||
resp, err := l.request(constants.ProcConnectGetLibVersion, constants.ProgramRemote, nil)
|
||||
|
@ -17,6 +17,7 @@
|
||||
package libvirt
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"net"
|
||||
"testing"
|
||||
"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 {
|
||||
conn, err := net.DialTimeout("tcp", testAddr, time.Second*2)
|
||||
if err != nil {
|
||||
|
38
test-domain.xml
Normal file
38
test-domain.xml
Normal 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>
|
Loading…
Reference in New Issue
Block a user