Adds StoragePool(), StoragePoolRefresh() (#28)
This adds two new methods: - `StoragePool()`, used to lookup a storage pool by name. - `StoragePoolRefresh()`, used to refresh a storage pool by name.
This commit is contained in:
parent
591f6798f1
commit
cfa567708b
@ -42,6 +42,8 @@ const (
|
||||
ProcDomainGetXMLDesc = 14
|
||||
ProcDomainLookupByName = 23
|
||||
ProcAuthList = 66
|
||||
ProcStoragePoolRefresh = 83
|
||||
ProcStoragePoolLookupByName = 84
|
||||
ProcConnectGetLibVersion = 157
|
||||
ProcDomainMigrateSetMaxSpeed = 207
|
||||
ProcDomainGetState = 212
|
||||
|
70
libvirt.go
70
libvirt.go
@ -572,6 +572,76 @@ func (l *Libvirt) Run(dom string, cmd []byte) ([]byte, error) {
|
||||
return bytes.TrimRight(data[4:], "\x00"), nil
|
||||
}
|
||||
|
||||
// StoragePool returns the storage pool associated with the provided name.
|
||||
// An error is returned if the requested storage pool is not found.
|
||||
func (l *Libvirt) StoragePool(name string) (*StoragePool, error) {
|
||||
req := struct {
|
||||
Name string
|
||||
}{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
buf, err := encode(&req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := l.request(constants.ProcStoragePoolLookupByName, constants.ProgramRemote, &buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := <-resp
|
||||
if r.Status != StatusOK {
|
||||
return nil, decodeError(r.Payload)
|
||||
}
|
||||
|
||||
result := struct {
|
||||
Pool StoragePool
|
||||
}{}
|
||||
|
||||
dec := xdr.NewDecoder(bytes.NewReader(r.Payload))
|
||||
_, err = dec.Decode(&result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &result.Pool, nil
|
||||
}
|
||||
|
||||
// StoragePoolRefresh refreshes the storage pool specified by name.
|
||||
func (l *Libvirt) StoragePoolRefresh(name string) error {
|
||||
pool, err := l.StoragePool(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req := struct {
|
||||
Pool StoragePool
|
||||
Flags uint32
|
||||
}{
|
||||
Pool: *pool,
|
||||
Flags: 0, // unused per libvirt source, callers should pass 0
|
||||
}
|
||||
|
||||
buf, err := encode(&req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := l.request(constants.ProcStoragePoolRefresh, constants.ProgramRemote, &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := <-resp
|
||||
if r.Status != StatusOK {
|
||||
return decodeError(r.Payload)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StoragePools returns a list of defined storage pools. Pools are filtered by
|
||||
// the provided flags. See StoragePools*.
|
||||
func (l *Libvirt) StoragePools(flags StoragePoolsFlags) ([]StoragePool, error) {
|
||||
|
@ -70,6 +70,40 @@ func TestCapabilities(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoragePoolIntegration(t *testing.T) {
|
||||
l := New(testConn(t))
|
||||
defer l.Disconnect()
|
||||
|
||||
if err := l.Connect(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
wantName := "test"
|
||||
pool, err := l.StoragePool(wantName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gotName := pool.Name
|
||||
if gotName != wantName {
|
||||
t.Errorf("expected name %q, got %q", wantName, gotName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoragePoolInvalidIntegration(t *testing.T) {
|
||||
l := New(testConn(t))
|
||||
defer l.Disconnect()
|
||||
|
||||
if err := l.Connect(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err := l.StoragePool("test-does-not-exist")
|
||||
if err == nil {
|
||||
t.Errorf("expected non-existent storage pool return error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoragePoolsIntegration(t *testing.T) {
|
||||
l := New(testConn(t))
|
||||
defer l.Disconnect()
|
||||
@ -116,6 +150,34 @@ func TestStoragePoolsAutostartIntegration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoragePoolRefreshIntegration(t *testing.T) {
|
||||
l := New(testConn(t))
|
||||
defer l.Disconnect()
|
||||
|
||||
if err := l.Connect(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err := l.StoragePoolRefresh("test")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoragePoolRefreshInvalidIntegration(t *testing.T) {
|
||||
l := New(testConn(t))
|
||||
defer l.Disconnect()
|
||||
|
||||
if err := l.Connect(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err := l.StoragePoolRefresh("test-does-not-exist")
|
||||
if err == nil {
|
||||
t.Error("expected non-existent storage pool to fail refresh")
|
||||
}
|
||||
}
|
||||
|
||||
func TestXMLIntegration(t *testing.T) {
|
||||
l := New(testConn(t))
|
||||
|
||||
|
@ -221,6 +221,32 @@ func TestRunFail(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoragePool(t *testing.T) {
|
||||
conn := libvirttest.New()
|
||||
l := New(conn)
|
||||
|
||||
wantName := "default"
|
||||
pool, err := l.StoragePool(wantName)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
gotName := pool.Name
|
||||
if gotName != wantName {
|
||||
t.Errorf("expected name %q, got %q", wantName, gotName)
|
||||
}
|
||||
|
||||
// bb30a11c-0846-4827-8bba-3e6b5cf1b65f
|
||||
wantUUID := [constants.UUIDSize]byte{
|
||||
0xbb, 0x30, 0xa1, 0x1c, 0x08, 0x46, 0x48, 0x27,
|
||||
0x8b, 0xba, 0x3e, 0x6b, 0x5c, 0xf1, 0xb6, 0x5f,
|
||||
}
|
||||
gotUUID := pool.UUID
|
||||
if gotUUID != wantUUID {
|
||||
t.Errorf("expected UUID %q, got %q", wantUUID, gotUUID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoragePools(t *testing.T) {
|
||||
conn := libvirttest.New()
|
||||
l := New(conn)
|
||||
@ -253,6 +279,16 @@ func TestStoragePools(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoragePoolRefresh(t *testing.T) {
|
||||
conn := libvirttest.New()
|
||||
l := New(conn)
|
||||
|
||||
err := l.StoragePoolRefresh("default")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUndefine(t *testing.T) {
|
||||
conn := libvirttest.New()
|
||||
l := New(conn)
|
||||
|
@ -217,6 +217,34 @@ var testDomainStateReply = []byte{
|
||||
0x00, 0x00, 0x00, 0x01, // reason
|
||||
}
|
||||
|
||||
var testStoragePoolLookup = []byte{
|
||||
0x00, 0x00, 0x00, 0x38, // length
|
||||
0x20, 0x00, 0x80, 0x86, // program
|
||||
0x00, 0x00, 0x00, 0x01, // version
|
||||
0x00, 0x00, 0x00, 0x54, // procedure
|
||||
0x00, 0x00, 0x00, 0x01, // type
|
||||
0x00, 0x00, 0x00, 0x00, // serial
|
||||
0x00, 0x00, 0x00, 0x00, // status
|
||||
|
||||
// pool: name = default
|
||||
0x00, 0x00, 0x00, 0x07, 0x64, 0x65, 0x66, 0x61,
|
||||
0x75, 0x6c, 0x74, 0x00,
|
||||
|
||||
// uuid = bb30a11c084648278bba3e6b5cf1b65f
|
||||
0xbb, 0x30, 0xa1, 0x1c, 0x08, 0x46, 0x48, 0x27,
|
||||
0x8b, 0xba, 0x3e, 0x6b, 0x5c, 0xf1, 0xb6, 0x5f,
|
||||
}
|
||||
|
||||
var testStoragePoolRefresh = []byte{
|
||||
0x00, 0x00, 0x00, 0x1c, // length
|
||||
0x20, 0x00, 0x80, 0x86, // program
|
||||
0x00, 0x00, 0x00, 0x01, // version
|
||||
0x00, 0x00, 0x00, 0x53, // procedure
|
||||
0x00, 0x00, 0x00, 0x01, // type
|
||||
0x00, 0x00, 0x00, 0x00, // serial
|
||||
0x00, 0x00, 0x00, 0x00, // status
|
||||
}
|
||||
|
||||
var testListPoolsReply = []byte{
|
||||
0x00, 0x00, 0x00, 0x40, // length
|
||||
0x20, 0x00, 0x80, 0x86, // program
|
||||
@ -333,6 +361,10 @@ func (m *MockLibvirt) handleRemote(procedure uint32, conn net.Conn) {
|
||||
switch procedure {
|
||||
case constants.ProcAuthList:
|
||||
conn.Write(m.reply(testAuthReply))
|
||||
case constants.ProcStoragePoolRefresh:
|
||||
conn.Write(m.reply(testStoragePoolRefresh))
|
||||
case constants.ProcStoragePoolLookupByName:
|
||||
conn.Write(m.reply(testStoragePoolLookup))
|
||||
case constants.ProcConnectOpen:
|
||||
conn.Write(m.reply(testConnectReply))
|
||||
case constants.ProcConnectClose:
|
||||
|
Loading…
Reference in New Issue
Block a user