diff --git a/docs/api-status.json b/docs/api-status.json index 40d1540..c101f86 100644 --- a/docs/api-status.json +++ b/docs/api-status.json @@ -1052,6 +1052,12 @@ "comment": "WatcherFlush flushes all pending notifications of the cluster.\n PREVIEW\n\nImplements:\n int rados_watch_flush(rados_t cluster)\n", "added_in_version": "v0.14.0", "expected_stable_version": "v0.16.0" + }, + { + "name": "IOContext.SetLocator", + "comment": "SetLocator sets the key for mapping objects to pgs within an io context.\nUntil a different locator key is set, all objects in this io context will be placed in the same pg.\nTo reset the locator, an empty string must be set.\n PREVIEW\n\nImplements:\n void rados_ioctx_locator_set_key(rados_ioctx_t io, const char *key);\n", + "added_in_version": "v0.15.0", + "expected_stable_version": "v0.17.0" } ] }, diff --git a/docs/api-status.md b/docs/api-status.md index c21dcf6..63b9873 100644 --- a/docs/api-status.md +++ b/docs/api-status.md @@ -37,6 +37,7 @@ IOContext.Notify | v0.14.0 | v0.16.0 | IOContext.NotifyWithTimeout | v0.14.0 | v0.16.0 | NotifyEvent.Ack | v0.14.0 | v0.16.0 | Conn.WatcherFlush | v0.14.0 | v0.16.0 | +IOContext.SetLocator | v0.15.0 | v0.17.0 | ## Package: rbd diff --git a/rados/rados_set_locator.go b/rados/rados_set_locator.go new file mode 100644 index 0000000..e802867 --- /dev/null +++ b/rados/rados_set_locator.go @@ -0,0 +1,31 @@ +//go:build ceph_preview +// +build ceph_preview + +package rados + +// #cgo LDFLAGS: -lrados +// #include +// #include +// +import "C" + +import ( + "unsafe" +) + +// SetLocator sets the key for mapping objects to pgs within an io context. +// Until a different locator key is set, all objects in this io context will be placed in the same pg. +// To reset the locator, an empty string must be set. +// PREVIEW +// +// Implements: +// void rados_ioctx_locator_set_key(rados_ioctx_t io, const char *key); +func (ioctx *IOContext) SetLocator(locator string) { + if locator == "" { + C.rados_ioctx_locator_set_key(ioctx.ioctx, nil) + } else { + var cLoc *C.char = C.CString(locator) + defer C.free(unsafe.Pointer(cLoc)) + C.rados_ioctx_locator_set_key(ioctx.ioctx, cLoc) + } +} diff --git a/rados/rados_set_locator_test.go b/rados/rados_set_locator_test.go new file mode 100644 index 0000000..b273527 --- /dev/null +++ b/rados/rados_set_locator_test.go @@ -0,0 +1,50 @@ +//go:build ceph_preview +// +build ceph_preview + +package rados + +import ( + "github.com/stretchr/testify/assert" +) + +func (suite *RadosTestSuite) TestSetLocator() { + suite.SetupConnection() + + // create normal object without locator - used later to test reset of locator + testDataNoLocator := []byte("no locator") + err := suite.ioctx.Write("default-locator", testDataNoLocator, 0) + assert.NoError(suite.T(), err) + + // test create and read with different locator + testDataLocator := []byte("test data") + suite.ioctx.SetLocator("SomeOtherLocator") + err = suite.ioctx.Write("different-locator", testDataLocator, 0) + assert.NoError(suite.T(), err) + + _, err = suite.ioctx.Stat("different-locator") + assert.NoError(suite.T(), err) + + bytesOut := make([]byte, len(testDataLocator)) + nOut, err := suite.ioctx.Read("different-locator", bytesOut, 0) + assert.NoError(suite.T(), err) + assert.Equal(suite.T(), nOut, len(testDataLocator)) + assert.Equal(suite.T(), testDataLocator, bytesOut) + + // test stat with wrong locator + suite.ioctx.SetLocator("SomeWrongLocator") + _, err = suite.ioctx.Stat("different-locator") + assert.Error(suite.T(), err) + _, err = suite.ioctx.Stat("default-locator") + assert.Error(suite.T(), err) + + // test reset of locator and access to object without locator + suite.ioctx.SetLocator("") + _, err = suite.ioctx.Stat("default-locator") + assert.NoError(suite.T(), err) + + bytesOut = make([]byte, len(testDataNoLocator)) + nOut, err = suite.ioctx.Read("default-locator", bytesOut, 0) + assert.NoError(suite.T(), err) + assert.Equal(suite.T(), nOut, len(testDataNoLocator)) + assert.Equal(suite.T(), testDataNoLocator, bytesOut) +}