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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user