]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librgw: partial delete/unlink support
authorMatt Benjamin <mbenjamin@redhat.com>
Fri, 23 Oct 2015 16:39:05 +0000 (12:39 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 17:04:57 +0000 (12:04 -0500)
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/rgw/rgw_file.cc
src/rgw/rgw_file.h
src/test/CMakeLists.txt
src/test/librgw_file.cc
src/test/librgw_file_cd.cc [new file with mode: 0644]

index a9a4bd441c6effe882f70e40b96d8aee30fd195b..89cfa613c6906ca13b7bcf69f2ee0dc729be5e3c 100644 (file)
@@ -176,16 +176,43 @@ int rgw_rename(struct rgw_fs *rgw_fs,
               const struct rgw_file_handle *olddir, const char* old_name,
               const struct rgw_file_handle *newdir, const char* new_name)
 {
-  return 0;
+  /* -ENOTSUP */
+  return -EINVAL;
 }
 
 /*
   remove file or directory
 */
-int rgw_unlink(struct rgw_fs *rgw_fs,
-              const struct rgw_file_handle* parent_handle, const char* path)
+int rgw_unlink(struct rgw_fs *rgw_fs, const struct rgw_file_handle* parent,
+             const char* path)
 {
-  return 0;
+  string uri;
+  int rc = 0;
+
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
+
+  if (fs->is_root(rgw_fs)) {
+    /* for now, root always contains one user's bucket namespace */
+    uri = "/";
+    uri += path;
+    RGWDeleteBucketRequest req(cct, fs->get_user(), uri);
+    rc = librgw.get_fe()->execute_req(&req);
+  } else {
+    /*
+     * object
+     */
+      rc = librgw.get_uri(parent->handle, uri);
+      if (rc < 0 ) { /* invalid parent */
+       return rc;
+      }
+      uri += path;
+      /* TODO: implement
+       * RGWDeleteObjectRequest req(cct, fs->get_user(), uri);
+      */
+  }
+
+  return rc;
 }
 
 /*
index 240815766ed7daa0cc4e880680baec158870831d..6eac368b2077102005100607787cb81666f8fd5c 100644 (file)
@@ -50,6 +50,10 @@ public:
   struct rgw_fs* get_fs() { return &fs; }
   RGWUserInfo* get_user() { return &user; }
 
+  bool is_root(struct rgw_fs* _fs) {
+    return (&fs == _fs);
+  }
+
 }; /* RGWLibFS */
 
 /*
@@ -275,6 +279,9 @@ public:
 
     return 0;
   }
+
+  virtual void send_response() {}
+
 }; /* RGWDeleteBucketRequest */
 
 #endif /* RGW_FILE_H */
index f63ba999f51d49aa81490c8341d0b43d9a2e7d4e..46933d88702c95e11e18aa5b9ff8958fafa474b2 100644 (file)
@@ -2399,6 +2399,22 @@ target_link_libraries(test_librgw_file
   ${CMAKE_DL_LIBS}
   )
 
+# librgw_file_cd (just the rgw_file create-delete bucket ops)
+add_executable(test_librgw_file_cd
+  librgw_file_cd.cc
+  $<TARGET_OBJECTS:heap_profiler_objs>
+  )
+set_target_properties(test_librgw_file_cd PROPERTIES COMPILE_FLAGS
+  ${UNITTEST_CXX_FLAGS})
+target_link_libraries(test_librgw_file_cd
+  rgw
+  librados
+  ${UNITTEST_LIBS}
+  ${EXTRALIBS}
+  ${ALLOC_LIBS}
+  ${CMAKE_DL_LIBS}
+  )
+
 if(${HAVE_LIBFUSE})
   add_executable(test_cfuse_cache_invalidate
     test_cfuse_cache_invalidate.cc
index bd1dae5d462684024c485c837145482008351837..e0ced5866d8ae78f36f00d89ec83b623d84d45b2 100644 (file)
@@ -62,6 +62,11 @@ TEST(LibRGW, CREATE_BUCKET) {
   ASSERT_EQ(ret, 0);
 }
 
+TEST(LibRGW, DELETE_BUCKET) {
+  int ret = rgw_unlink(fs, &fs->root_fh, "sorry_dave");
+  ASSERT_EQ(ret, 0);
+}
+
 extern "C" {
   static bool r1_cb(const char* name, void *arg, uint64_t offset) {
     // don't need arg--it would point to fids1
diff --git a/src/test/librgw_file_cd.cc b/src/test/librgw_file_cd.cc
new file mode 100644 (file)
index 0000000..1ebc5c0
--- /dev/null
@@ -0,0 +1,160 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include <stdint.h>
+#include <tuple>
+#include <iostream>
+
+#include "include/rados/librgw.h"
+#include "include/rados/rgw_file.h"
+
+#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
+#include "common/debug.h"
+#include "global/global_init.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+namespace {
+  librgw_t rgw = nullptr;
+  string uid("testuser");
+  string access_key("");
+  string secret_key("");
+  struct rgw_fs *fs = nullptr;
+  typedef std::tuple<string,uint64_t, struct rgw_file_handle*> fid_type; //in c++2014 can alias...
+  std::vector<fid_type> fids1;
+
+  bool do_create = false;
+  string bucket_name = "sorry_dave";
+
+  struct {
+    int argc;
+    char **argv;
+  } saved_args;
+}
+
+TEST(LibRGW, INIT) {
+  int ret = librgw_create(&rgw, nullptr, saved_args.argc, saved_args.argv);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(rgw, nullptr);
+}
+
+TEST(LibRGW, MOUNT) {
+  int ret = rgw_mount(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
+                     &fs);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(fs, nullptr);
+}
+
+TEST(LibRGW, CREATE_BUCKET) {
+  if (do_create) {
+    struct stat st;
+    struct rgw_file_handle fh;
+    int ret = rgw_mkdir(fs, &fs->root_fh, bucket_name.c_str(), 755, &st, &fh);
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, DELETE_BUCKET) {
+  int ret = rgw_unlink(fs, &fs->root_fh, bucket_name.c_str());
+  ASSERT_EQ(ret, 0);
+}
+
+extern "C" {
+  static bool r1_cb(const char* name, void *arg, uint64_t offset) {
+    // don't need arg--it would point to fids1
+    fids1.push_back(fid_type(name, offset, nullptr /* handle */));
+    return true; /* XXX ? */
+  }
+}
+
+TEST(LibRGW, LIST_BUCKETS) {
+  /* list buckets via readdir in fs root */
+  using std::get;
+
+  if (! fs)
+    return;
+
+  bool eof = false;
+  uint64_t offset = 0;
+  int ret = rgw_readdir(fs, &fs->root_fh, &offset, r1_cb, &fids1, &eof);
+  for (auto& fid : fids1) {
+    std::cout << "fname: " << get<0>(fid) << " fid: " << get<1>(fid)
+             << std::endl;
+  }
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, CLEANUP) {
+  using std::get;
+  for (auto& fids : { fids1 }) {
+    for (auto& fid : fids) {
+      delete get<2>(fid);
+    }
+  }
+}
+
+TEST(LibRGW, UMOUNT) {
+  if (! fs)
+    return;
+
+  int ret = rgw_umount(fs);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, SHUTDOWN) {
+  librgw_shutdown(rgw);
+}
+
+int main(int argc, char *argv[])
+{
+  char *v{nullptr};
+  string val;
+  vector<const char*> args;
+
+  argv_to_vec(argc, const_cast<const char**>(argv), args);
+  env_to_vec(args);
+
+  v = getenv("AWS_ACCESS_KEY_ID");
+  if (v) {
+    access_key = v;
+  }
+
+  v = getenv("AWS_SECRET_ACCESS_KEY");
+  if (v) {
+    secret_key = v;
+  }
+
+  for (auto arg_iter = args.begin(); arg_iter != args.end();) {
+    if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
+                             (char*) NULL)) {
+      access_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--secret",
+                                    (char*) NULL)) {
+      secret_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--uid",
+                                    (char*) NULL)) {
+      uid = val;
+    }
+    else {
+      ++arg_iter;
+    }
+  }
+
+  saved_args.argc = argc;
+  saved_args.argv = argv;
+
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}