committed by
					
						 Ben LeMasurier
						Ben LeMasurier
					
				
			
			
				
	
			
			
			
						parent
						
							d41d9eb855
						
					
				
				
					commit
					208ef2aff1
				
			| @@ -50,6 +50,7 @@ const ( | ||||
| 	ProcDomainGetState             = 212 | ||||
| 	ProcDomainUndefineFlags        = 231 | ||||
| 	ProcDomainDestroyFlags         = 234 | ||||
| 	ProcDomainShutdownFlags        = 258 | ||||
| 	ProcConnectListAllDomains      = 273 | ||||
| 	ProcConnectListAllStoragePools = 281 | ||||
| 	ProcConnectListAllSecrets      = 287 | ||||
|   | ||||
							
								
								
									
										53
									
								
								libvirt.go
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								libvirt.go
									
									
									
									
									
								
							| @@ -191,6 +191,25 @@ const ( | ||||
| 	DestroyFlagGraceful | ||||
| ) | ||||
|  | ||||
| // ShutdownFlags specifies options available when shutting down a domain. | ||||
| type ShutdownFlags uint32 | ||||
| const ( | ||||
| 	// ShutdownAcpiPowerBtn - send ACPI event | ||||
| 	ShutdownAcpiPowerBtn ShutdownFlags = 1 << iota | ||||
|  | ||||
| 	// ShutdownGuestAgent - use guest agent | ||||
| 	ShutdownGuestAgent | ||||
|  | ||||
| 	// ShutdownInitctl - use initctl | ||||
| 	ShutdownInitctl | ||||
|  | ||||
| 	// ShutdownSignal - use signal | ||||
| 	ShutdownSignal | ||||
|  | ||||
| 	// ShutdownParavirt - use paravirt guest control | ||||
| 	ShutdownParavirt | ||||
| ) | ||||
|  | ||||
| // DomainState specifies state of the domain | ||||
| type DomainState uint32 | ||||
|  | ||||
| @@ -967,6 +986,40 @@ func (l *Libvirt) Version() (string, error) { | ||||
| 	return versionString, nil | ||||
| } | ||||
|  | ||||
| // Shutdown shuts down a domain. Note that the guest OS may ignore the request. | ||||
| // If flags is set to 0 then the hypervisor will choose the method of shutdown it considers best. | ||||
| func (l *Libvirt) Shutdown(dom string, flags ShutdownFlags) error { | ||||
| 	d, err := l.lookup(dom) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Domain Domain | ||||
| 		Flags  ShutdownFlags | ||||
| 	}{ | ||||
| 		Domain: *d, | ||||
| 		Flags:  flags, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainShutdownFlags, 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. | ||||
| func (l *Libvirt) lookup(name string) (*Domain, error) { | ||||
| 	payload := struct { | ||||
|   | ||||
| @@ -380,3 +380,13 @@ func TestDomainCreateWithFlags(t *testing.T) { | ||||
| 		t.Fatalf("unexpected create error: %v", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestShutdown(t *testing.T) { | ||||
| 	conn := libvirttest.New() | ||||
| 	l := New(conn) | ||||
|  | ||||
| 	var flags ShutdownFlags | ||||
| 	if err := l.Shutdown("test", flags); err != nil { | ||||
| 		t.Fatalf("unexpected shutdown error: %v", err) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -359,6 +359,16 @@ var testCreateWithFlags = []byte{ | ||||
| 	0xff, 0xff, 0xff, 0xff, // id | ||||
| } | ||||
|  | ||||
| var testShutdownReply = []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. | ||||
| type MockLibvirt struct { | ||||
| 	net.Conn | ||||
| @@ -438,6 +448,8 @@ func (m *MockLibvirt) handleRemote(procedure uint32, conn net.Conn) { | ||||
| 		conn.Write(m.reply(testDefineXML)) | ||||
| 	case constants.ProcDomainCreateWithFlags: | ||||
| 		conn.Write(m.reply(testCreateWithFlags)) | ||||
| 	case constants.ProcDomainShutdownFlags: | ||||
| 		conn.Write(m.reply(testShutdownReply)) | ||||
| 	default: | ||||
| 		fmt.Fprintln(os.Stderr, "unknown procedure", procedure) | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user