committed by
					
						
						Ben LeMasurier
					
				
			
			
				
	
			
			
			
						parent
						
							d41d9eb855
						
					
				
				
					commit
					208ef2aff1
				
			@@ -50,6 +50,7 @@ const (
 | 
				
			|||||||
	ProcDomainGetState             = 212
 | 
						ProcDomainGetState             = 212
 | 
				
			||||||
	ProcDomainUndefineFlags        = 231
 | 
						ProcDomainUndefineFlags        = 231
 | 
				
			||||||
	ProcDomainDestroyFlags         = 234
 | 
						ProcDomainDestroyFlags         = 234
 | 
				
			||||||
 | 
						ProcDomainShutdownFlags        = 258
 | 
				
			||||||
	ProcConnectListAllDomains      = 273
 | 
						ProcConnectListAllDomains      = 273
 | 
				
			||||||
	ProcConnectListAllStoragePools = 281
 | 
						ProcConnectListAllStoragePools = 281
 | 
				
			||||||
	ProcConnectListAllSecrets      = 287
 | 
						ProcConnectListAllSecrets      = 287
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										53
									
								
								libvirt.go
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								libvirt.go
									
									
									
									
									
								
							@@ -191,6 +191,25 @@ const (
 | 
				
			|||||||
	DestroyFlagGraceful
 | 
						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
 | 
					// DomainState specifies state of the domain
 | 
				
			||||||
type DomainState uint32
 | 
					type DomainState uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -967,6 +986,40 @@ func (l *Libvirt) Version() (string, error) {
 | 
				
			|||||||
	return versionString, nil
 | 
						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.
 | 
					// 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 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -380,3 +380,13 @@ func TestDomainCreateWithFlags(t *testing.T) {
 | 
				
			|||||||
		t.Fatalf("unexpected create error: %v", err)
 | 
							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
 | 
						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.
 | 
					// MockLibvirt provides a mock libvirt server for testing.
 | 
				
			||||||
type MockLibvirt struct {
 | 
					type MockLibvirt struct {
 | 
				
			||||||
	net.Conn
 | 
						net.Conn
 | 
				
			||||||
@@ -438,6 +448,8 @@ func (m *MockLibvirt) handleRemote(procedure uint32, conn net.Conn) {
 | 
				
			|||||||
		conn.Write(m.reply(testDefineXML))
 | 
							conn.Write(m.reply(testDefineXML))
 | 
				
			||||||
	case constants.ProcDomainCreateWithFlags:
 | 
						case constants.ProcDomainCreateWithFlags:
 | 
				
			||||||
		conn.Write(m.reply(testCreateWithFlags))
 | 
							conn.Write(m.reply(testCreateWithFlags))
 | 
				
			||||||
 | 
						case constants.ProcDomainShutdownFlags:
 | 
				
			||||||
 | 
							conn.Write(m.reply(testShutdownReply))
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		fmt.Fprintln(os.Stderr, "unknown procedure", procedure)
 | 
							fmt.Fprintln(os.Stderr, "unknown procedure", procedure)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user