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:
|
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 ./...
|
||||||
|
@ -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
|
||||||
|
58
libvirt.go
58
libvirt.go
@ -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)
|
||||||
|
@ -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
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