mirror of https://github.com/ceph/go-ceph
rbd: add rbd package
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
This commit is contained in:
parent
ac99e00c8e
commit
44c15bf439
|
@ -36,6 +36,11 @@ type IOContext struct {
|
|||
ioctx C.rados_ioctx_t
|
||||
}
|
||||
|
||||
// Pointer returns a uintptr representation of the IOContext.
|
||||
func (ioctx *IOContext) Pointer() uintptr {
|
||||
return uintptr(ioctx.ioctx)
|
||||
}
|
||||
|
||||
// Write writes len(data) bytes to the object with key oid starting at byte
|
||||
// offset offset. It returns an error, if any.
|
||||
func (ioctx *IOContext) Write(oid string, data []byte, offset uint64) error {
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package rbd
|
||||
|
||||
// #cgo LDFLAGS: -lrbd
|
||||
// #include <stdlib.h>
|
||||
// #include <rados/librados.h>
|
||||
// #include <rbd/librbd.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/noahdesu/go-rados/rados"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
//
|
||||
type RBDError int
|
||||
|
||||
//
|
||||
func (e RBDError) Error() string {
|
||||
return fmt.Sprintf("rbd: ret=%d", e)
|
||||
}
|
||||
|
||||
//
|
||||
func Version() (int, int, int) {
|
||||
var c_major, c_minor, c_patch C.int
|
||||
C.rbd_version(&c_major, &c_minor, &c_patch)
|
||||
return int(c_major), int(c_minor), int(c_patch)
|
||||
}
|
||||
|
||||
// Create
|
||||
func Create(ioctx *rados.IOContext, name string, size uint64) error {
|
||||
var c_order C.int
|
||||
c_name := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(c_name))
|
||||
ret := C.rbd_create(C.rados_ioctx_t(ioctx.Pointer()), c_name, C.uint64_t(size), &c_order)
|
||||
if ret < 0 {
|
||||
return RBDError(ret)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetImageNames returns the list of current RBD images.
|
||||
func GetImageNames(ioctx *rados.IOContext) (names []string, err error) {
|
||||
buf := make([]byte, 4096)
|
||||
for {
|
||||
size := C.size_t(len(buf))
|
||||
ret := C.rbd_list(C.rados_ioctx_t(ioctx.Pointer()),
|
||||
(*C.char)(unsafe.Pointer(&buf[0])), &size)
|
||||
if ret == -34 { // FIXME
|
||||
buf = make([]byte, size)
|
||||
continue
|
||||
} else if ret < 0 {
|
||||
return nil, RBDError(ret)
|
||||
}
|
||||
tmp := bytes.Split(buf[:size-1], []byte{0})
|
||||
for _, s := range tmp {
|
||||
if len(s) > 0 {
|
||||
name := C.GoString((*C.char)(unsafe.Pointer(&s[0])))
|
||||
names = append(names, name)
|
||||
}
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package rbd_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/noahdesu/go-rados/rados"
|
||||
"github.com/noahdesu/go-rados/rbd"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os/exec"
|
||||
"sort"
|
||||
)
|
||||
|
||||
func GetUUID() string {
|
||||
out, _ := exec.Command("uuidgen").Output()
|
||||
return string(out[:36])
|
||||
}
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
var major, minor, patch = rbd.Version()
|
||||
assert.False(t, major < 0 || major > 1000, "invalid major")
|
||||
assert.False(t, minor < 0 || minor > 1000, "invalid minor")
|
||||
assert.False(t, patch < 0 || patch > 1000, "invalid patch")
|
||||
}
|
||||
|
||||
func TestGetImageNames(t *testing.T) {
|
||||
conn, _ := rados.NewConn()
|
||||
conn.ReadDefaultConfigFile()
|
||||
conn.Connect()
|
||||
|
||||
poolname := GetUUID()
|
||||
err := conn.MakePool(poolname)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ioctx, err := conn.OpenIOContext(poolname)
|
||||
assert.NoError(t, err)
|
||||
|
||||
createdList := []string{}
|
||||
for i := 0; i < 10; i++ {
|
||||
name := GetUUID()
|
||||
err = rbd.Create(ioctx, name, 1<<22)
|
||||
assert.NoError(t, err)
|
||||
createdList = append(createdList, name)
|
||||
}
|
||||
|
||||
imageNames, err := rbd.GetImageNames(ioctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
sort.Strings(createdList)
|
||||
sort.Strings(imageNames)
|
||||
assert.Equal(t, createdList, imageNames)
|
||||
|
||||
ioctx.Destroy()
|
||||
conn.Shutdown()
|
||||
}
|
Loading…
Reference in New Issue