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