Add Reboot and Reset methods (#37)
This commit is contained in:
		
				
					committed by
					
						 Ben LeMasurier
						Ben LeMasurier
					
				
			
			
				
	
			
			
			
						parent
						
							208ef2aff1
						
					
				
				
					commit
					c09ce7b21d
				
			| @@ -41,6 +41,7 @@ const ( | |||||||
| 	ProcConnectGetCapabilties      = 7 | 	ProcConnectGetCapabilties      = 7 | ||||||
| 	ProcDomainGetXMLDesc           = 14 | 	ProcDomainGetXMLDesc           = 14 | ||||||
| 	ProcDomainLookupByName         = 23 | 	ProcDomainLookupByName         = 23 | ||||||
|  | 	ProcDomainReboot 	       = 27 | ||||||
| 	ProcAuthList                   = 66 | 	ProcAuthList                   = 66 | ||||||
| 	ProcStoragePoolRefresh         = 83 | 	ProcStoragePoolRefresh         = 83 | ||||||
| 	ProcStoragePoolLookupByName    = 84 | 	ProcStoragePoolLookupByName    = 84 | ||||||
| @@ -50,6 +51,7 @@ const ( | |||||||
| 	ProcDomainGetState             = 212 | 	ProcDomainGetState             = 212 | ||||||
| 	ProcDomainUndefineFlags        = 231 | 	ProcDomainUndefineFlags        = 231 | ||||||
| 	ProcDomainDestroyFlags         = 234 | 	ProcDomainDestroyFlags         = 234 | ||||||
|  | 	ProcDomainReset 	       = 245 | ||||||
| 	ProcDomainShutdownFlags        = 258 | 	ProcDomainShutdownFlags        = 258 | ||||||
| 	ProcConnectListAllDomains      = 273 | 	ProcConnectListAllDomains      = 273 | ||||||
| 	ProcConnectListAllStoragePools = 281 | 	ProcConnectListAllStoragePools = 281 | ||||||
|   | |||||||
							
								
								
									
										86
									
								
								libvirt.go
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								libvirt.go
									
									
									
									
									
								
							| @@ -299,6 +299,25 @@ const ( | |||||||
| 	DomainCreateFlagStartValidate | 	DomainCreateFlagStartValidate | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // RebootFlags specifies domain reboot methods | ||||||
|  | type RebootFlags uint32 | ||||||
|  | const ( | ||||||
|  | 	// RebootAcpiPowerBtn - send ACPI event | ||||||
|  | 	RebootAcpiPowerBtn RebootFlags = 1 << iota | ||||||
|  |  | ||||||
|  | 	// RebootGuestAgent - use guest agent | ||||||
|  | 	RebootGuestAgent | ||||||
|  |  | ||||||
|  | 	// RebootInitctl - use initctl | ||||||
|  | 	RebootInitctl | ||||||
|  |  | ||||||
|  | 	// RebootSignal - use signal | ||||||
|  | 	RebootSignal | ||||||
|  |  | ||||||
|  | 	// RebootParavirt - use paravirt guest control | ||||||
|  | 	RebootParavirt | ||||||
|  | ) | ||||||
|  |  | ||||||
| // Capabilities returns an XML document describing the host's capabilties. | // Capabilities returns an XML document describing the host's capabilties. | ||||||
| func (l *Libvirt) Capabilities() ([]byte, error) { | func (l *Libvirt) Capabilities() ([]byte, error) { | ||||||
| 	resp, err := l.request(constants.ProcConnectGetCapabilties, constants.ProgramRemote, nil) | 	resp, err := l.request(constants.ProcConnectGetCapabilties, constants.ProgramRemote, nil) | ||||||
| @@ -1020,6 +1039,73 @@ func (l *Libvirt) Shutdown(dom string, flags ShutdownFlags) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Reboot reboots the domain. Note that the guest OS may ignore the request. | ||||||
|  | // If flags is set to zero, then the hypervisor will choose the method of shutdown it considers best. | ||||||
|  | func (l *Libvirt) Reboot(dom string, flags RebootFlags) error { | ||||||
|  | 	d, err := l.lookup(dom) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	payload := struct { | ||||||
|  | 		Domain Domain | ||||||
|  | 		Flags  RebootFlags | ||||||
|  | 	}{ | ||||||
|  | 		Domain: *d, | ||||||
|  | 		Flags:  flags, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	buf, err := encode(&payload) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	resp, err := l.request(constants.ProcDomainReboot, constants.ProgramRemote, &buf) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	r := <-resp | ||||||
|  | 	if r.Status != StatusOK { | ||||||
|  | 		return decodeError(r.Payload) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Reset resets domain immediately without any guest OS shutdown | ||||||
|  | func (l *Libvirt) Reset(dom string) error { | ||||||
|  | 	d, err := l.lookup(dom) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	payload := struct { | ||||||
|  | 		Domain Domain | ||||||
|  | 		Flags 	uint32 | ||||||
|  | 	}{ | ||||||
|  | 		Domain: *d, | ||||||
|  | 		Flags:  0, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	buf, err := encode(&payload) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	resp, err := l.request(constants.ProcDomainReset, constants.ProgramRemote, &buf) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	r := <-resp | ||||||
|  | 	if r.Status != StatusOK { | ||||||
|  | 		return decodeError(r.Payload) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // lookup returns a domain as seen by libvirt. | // lookup returns a domain as seen by libvirt. | ||||||
| func (l *Libvirt) lookup(name string) (*Domain, error) { | func (l *Libvirt) lookup(name string) (*Domain, error) { | ||||||
| 	payload := struct { | 	payload := struct { | ||||||
|   | |||||||
| @@ -390,3 +390,22 @@ func TestShutdown(t *testing.T) { | |||||||
| 		t.Fatalf("unexpected shutdown error: %v", err) | 		t.Fatalf("unexpected shutdown error: %v", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestReboot(t *testing.T) { | ||||||
|  | 	conn := libvirttest.New() | ||||||
|  | 	l := New(conn) | ||||||
|  |  | ||||||
|  | 	var flags RebootFlags | ||||||
|  | 	if err := l.Reboot("test", flags); err != nil { | ||||||
|  | 		t.Fatalf("unexpected reboot error: %v", err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestReset(t *testing.T) { | ||||||
|  | 	conn := libvirttest.New() | ||||||
|  | 	l := New(conn) | ||||||
|  |  | ||||||
|  | 	if err := l.Reset("test"); err != nil { | ||||||
|  | 		t.Fatalf("unexpected reset error: %v", err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -369,6 +369,16 @@ var testShutdownReply = []byte{ | |||||||
| 	0x00, 0x00, 0x00, 0x00, // status | 	0x00, 0x00, 0x00, 0x00, // status | ||||||
| } | } | ||||||
|  |  | ||||||
|  | var testRebootReply = []byte{ | ||||||
|  | 	0x00, 0x00, 0x00, 0x1c, // length | ||||||
|  | 	0x20, 0x00, 0x80, 0x86, // program | ||||||
|  | 	0x00, 0x00, 0x00, 0x01, // version | ||||||
|  | 	0x00, 0x00, 0x00, 0xea, // procedure | ||||||
|  | 	0x00, 0x00, 0x00, 0x01, // type | ||||||
|  | 	0x00, 0x00, 0x00, 0x00, // serial | ||||||
|  | 	0x00, 0x00, 0x00, 0x00, // status | ||||||
|  | } | ||||||
|  |  | ||||||
| // MockLibvirt provides a mock libvirt server for testing. | // MockLibvirt provides a mock libvirt server for testing. | ||||||
| type MockLibvirt struct { | type MockLibvirt struct { | ||||||
| 	net.Conn | 	net.Conn | ||||||
| @@ -446,6 +456,10 @@ func (m *MockLibvirt) handleRemote(procedure uint32, conn net.Conn) { | |||||||
| 		conn.Write(m.reply(testDestroyReply)) | 		conn.Write(m.reply(testDestroyReply)) | ||||||
| 	case constants.ProcDomainDefineXMLFlags: | 	case constants.ProcDomainDefineXMLFlags: | ||||||
| 		conn.Write(m.reply(testDefineXML)) | 		conn.Write(m.reply(testDefineXML)) | ||||||
|  | 	case constants.ProcDomainReboot: | ||||||
|  | 		conn.Write(m.reply(testRebootReply)) | ||||||
|  | 	case constants.ProcDomainReset: | ||||||
|  | 		conn.Write(m.reply(testRebootReply)) | ||||||
| 	case constants.ProcDomainCreateWithFlags: | 	case constants.ProcDomainCreateWithFlags: | ||||||
| 		conn.Write(m.reply(testCreateWithFlags)) | 		conn.Write(m.reply(testCreateWithFlags)) | ||||||
| 	case constants.ProcDomainShutdownFlags: | 	case constants.ProcDomainShutdownFlags: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user