]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: open (source) image as read-only
authorJosh Durgin <josh.durgin@inktank.com>
Sun, 30 Dec 2012 04:26:57 +0000 (20:26 -0800)
committerJosh Durgin <josh.durgin@inktank.com>
Sun, 30 Dec 2012 08:06:11 +0000 (00:06 -0800)
This allows users without write access to copy, export and list
information about an image.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
qa/workunits/rbd/permissions.sh [new file with mode: 0755]
src/rbd.cc

diff --git a/qa/workunits/rbd/permissions.sh b/qa/workunits/rbd/permissions.sh
new file mode 100755 (executable)
index 0000000..40428df
--- /dev/null
@@ -0,0 +1,121 @@
+#!/bin/bash -ex
+
+create_pools() {
+    ceph osd pool create images 100
+    ceph osd pool create volumes 100
+}
+
+delete_pools() {
+    (ceph osd pool delete images || true) >/dev/null 2>&1
+    (ceph osd pool delete volumes || true) >/dev/null 2>&1
+
+}
+
+recreate_pools() {
+    create_pools
+    delete_pools
+}
+
+delete_uers() {
+    (ceph auth del client.volumes || true) >/dev/null 2>&1
+    (ceph auth del client.images || true) >/dev/null 2>&1
+}
+
+create_users() {
+    ceph auth get-or-create client.volumes mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow r class-read pool images, allow rwx pool volumes' >> $KEYRING
+    ceph auth get-or-create client.images mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool images' >> $KEYRING
+}
+
+test_images_access() {
+    rbd -k $KEYRING --id images create --format 2 -s 1 images/foo
+    rbd -k $KEYRING --id images snap create images/foo@snap
+    rbd -k $KEYRING --id images snap protect images/foo@snap
+    rbd -k $KEYRING --id images snap unprotect images/foo@snap
+    rbd -k $KEYRING --id images snap protect images/foo@snap
+    rbd -k $KEYRING --id images export images/foo@snap - >/dev/null
+    ! rbd -k $KEYRING --id images snap rm images/foo@snap
+
+    rbd -k $KEYRING --id volumes clone images/foo@snap volumes/child
+    ! rbd -k $KEYRING --id images snap unprotect images/foo@snap
+    ! rbd -k $KEYRING --id volumes snap unprotect images/foo@snap
+    ! rbd -k $KEYRING --id images flatten volumes/child
+    rbd -k $KEYRING --id volumes flatten volumes/child
+    ! rbd -k $KEYRING --id volumes snap unprotect images/foo@snap
+    rbd -k $KEYRING --id images snap unprotect images/foo@snap
+
+    ! rbd -k $KEYRING --id images rm images/foo
+    rbd -k $KEYRING --id images snap rm images/foo@snap
+    rbd -k $KEYRING --id images rm images/foo
+    rbd -k $KEYRING --id volumes rm volumes/child
+}
+
+test_volumes_access() {
+    rbd -k $KEYRING --id images create --format 2 -s 1 images/foo
+    rbd -k $KEYRING --id images snap create images/foo@snap
+    rbd -k $KEYRING --id images snap protect images/foo@snap
+
+    # commands that work with read-only access
+    rbd -k $KEYRING --id volumes info images/foo@snap
+    rbd -k $KEYRING --id volumes snap ls images/foo
+    rbd -k $KEYRING --id volumes export images/foo - >/dev/null
+    rbd -k $KEYRING --id volumes cp images/foo volumes/foo_copy
+    rbd -k $KEYRING --id volumes rm volumes/foo_copy
+    rbd -k $KEYRING --id volumes children images/foo@snap
+    rbd -k $KEYRING --id volumes lock list images/foo
+
+    # commands that fail with read-only access
+    ! rbd -k $KEYRING --id volumes resize -s 2 images/foo
+    ! rbd -k $KEYRING --id volumes snap create images/foo@2
+    ! rbd -k $KEYRING --id volumes snap rollback images/foo@snap
+    ! rbd -k $KEYRING --id volumes snap remove images/foo@snap
+    ! rbd -k $KEYRING --id volumes snap purge images/foo
+    ! rbd -k $KEYRING --id volumes snap unprotect images/foo@snap
+    ! rbd -k $KEYRING --id volumes flatten images/foo
+    ! rbd -k $KEYRING --id volumes lock add images/foo test
+    ! rbd -k $KEYRING --id volumes lock remove images/foo test locker
+    ! rbd -k $KEYRING --id volumes ls rbd
+
+    # create clone and snapshot
+    rbd -k $KEYRING --id volumes clone images/foo@snap volumes/child
+    rbd -k $KEYRING --id volumes snap create volumes/child@snap1
+    rbd -k $KEYRING --id volumes snap protect volumes/child@snap1
+    rbd -k $KEYRING --id volumes snap create volumes/child@snap2
+
+    # make sure original snapshot stays protected
+    ! rbd -k $KEYRING --id images snap unprotect images/foo@snap
+    rbd -k $KEYRING --id volumes flatten volumes/child
+    ! rbd -k $KEYRING --id images snap unprotect images/foo@snap
+    rbd -k $KEYRING --id volumes snap rm volumes/child@snap2
+    ! rbd -k $KEYRING --id images snap unprotect images/foo@snap
+    ! rbd -k $KEYRING --id volumes snap rm volumes/child@snap2
+    rbd -k $KEYRING --id volumes snap unprotect volumes/child@snap1
+    ! rbd -k $KEYRING --id images snap unprotect images/foo@snap
+
+    # clean up
+    rbd -k $KEYRING --id volumes snap rm volumes/child@snap1
+    rbd -k $KEYRING --id images snap unprotect images/foo@snap
+    rbd -k $KEYRING --id images snap rm images/foo@snap
+    rbd -k $KEYRING --id images rm images/foo
+    rbd -k $KEYRING --id volumes rm volumes/child
+}
+
+cleanup() {
+    rm -f $KEYRING
+}
+KEYRING=$(mktemp)
+trap cleanup EXIT ERR HUP INT QUIT
+
+delete_users
+create_users
+
+recreate_pools
+test_images_access
+
+recreate_pools
+test_volumes_access
+
+delete_pools
+delete_users
+
+echo OK
+exit 0
index 2b098b3d983ecad222cee227730063ff7dcf90e5..2a13706f18ed5bbc6661de3473780081b676b569 100644 (file)
@@ -200,7 +200,7 @@ static int do_list(librbd::RBD &rbd, librados::IoCtx& io_ctx, bool lflag)
     librbd::image_info_t info;
     librbd::Image im;
 
-    r = rbd.open(io_ctx, im, i->c_str());
+    r = rbd.open_read_only(io_ctx, im, i->c_str(), NULL);
     // image might disappear between rbd.list() and rbd.open(); ignore
     // that, warn about other possible errors (EPERM, say, for opening
     // an old-format image, because you need execute permission for the
@@ -1864,16 +1864,23 @@ if (!set_conf_param(v, p1, p2, p3)) { \
   }
 
   if (imgname && talk_to_cluster &&
-      (opt_cmd == OPT_RESIZE || opt_cmd == OPT_INFO ||
-       opt_cmd == OPT_SNAP_LIST || opt_cmd == OPT_SNAP_CREATE ||
+      (opt_cmd == OPT_RESIZE || opt_cmd == OPT_SNAP_CREATE ||
        opt_cmd == OPT_SNAP_ROLLBACK || opt_cmd == OPT_SNAP_REMOVE ||
-       opt_cmd == OPT_SNAP_PURGE || opt_cmd == OPT_EXPORT ||
-       opt_cmd == OPT_SNAP_PROTECT || opt_cmd == OPT_SNAP_UNPROTECT ||
-       opt_cmd == OPT_WATCH || opt_cmd == OPT_COPY ||
-       opt_cmd == OPT_FLATTEN || opt_cmd == OPT_CHILDREN ||
-       opt_cmd == OPT_LOCK_LIST || opt_cmd == OPT_LOCK_ADD ||
-       opt_cmd == OPT_LOCK_REMOVE || opt_cmd == OPT_BENCH_WRITE)) {
-    r = rbd.open(io_ctx, image, imgname);
+       opt_cmd == OPT_SNAP_PURGE || opt_cmd == OPT_SNAP_PROTECT ||
+       opt_cmd == OPT_SNAP_UNPROTECT || opt_cmd == OPT_WATCH ||
+       opt_cmd == OPT_FLATTEN || opt_cmd == OPT_LOCK_ADD ||
+       opt_cmd == OPT_LOCK_REMOVE || opt_cmd == OPT_BENCH_WRITE ||
+       opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST ||
+       opt_cmd == OPT_EXPORT || opt_cmd == OPT_COPY ||
+       opt_cmd == OPT_CHILDREN || opt_cmd == OPT_LOCK_LIST)) {
+
+    if (opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST ||
+       opt_cmd == OPT_EXPORT || opt_cmd == OPT_COPY ||
+       opt_cmd == OPT_CHILDREN || opt_cmd == OPT_LOCK_LIST) {
+      r = rbd.open_read_only(io_ctx, image, imgname, NULL);
+    } else {
+      r = rbd.open(io_ctx, image, imgname);
+    }
     if (r < 0) {
       cerr << "rbd: error opening image " << imgname << ": "
           << cpp_strerror(-r) << std::endl;