Merge pull request #24 from digitalocean/dumpxml
Adds support for dumping domain XML
This commit is contained in:
		| @@ -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> | ||||
		Reference in New Issue
	
	Block a user