RGW User信息是如何保存在RADOS中的

rgw支持使用uid、access key和email来标记一个User,这些数据最终都会保存在default.rgw.meta数据池中。我们通过librados中的接口来读出用户数据,并解析成 RGWUserInfo,以此来熟悉librados接口,为后续rgw开发工作做准备(熟悉代码啊)~

分析

default.rgw.meta中,存在如下命名空间:

  • users.uid
  • users.keys
  • users.email

我们使用如下命令创建一个user:
./bin/radosgw-admin user create --uid=hello --display-name=Hello --email=hello@gmail.com --access-key=accesskey --secret-key =secretkey
查看meta数据池中各个命名空间的对象:

$ ./bin/rados ls -p default.rgw.meta --all
users.email     hello@gmail.com
users.keys      accesskey
users.uid       hello

$ ./bin/rados stat -p default.rgw.meta -N users.email hello@gmail.com
default.rgw.meta/hello@gmail.com mtime 2022-08-04 19:30:26.000000, size 9

$ ./bin/rados stat -p default.rgw.meta -N users.keys accesskey
default.rgw.meta/accesskey mtime 2022-08-04 19:30:26.000000, size 9

$ ./bin/rados stat -p default.rgw.meta -N users.uid hello
default.rgw.meta/hello mtime 2022-08-04 19:30:26.000000, size 268

直接说结论,rgw中,使用email和accesskey获取到uid,在通过uid获取RGWUserInfo
接下来,我们将通过代码来获取这些信息~

code

test case 1: 通过email 获取uid

TEST(RGW_RADOS_USER, USERS_EMAIL) {

  librados::Rados rados;
  EXPECT_EQ(rados.init2("client.admin", "ceph", 0), 0);
  EXPECT_EQ(rados.conf_read_file("/XXXXXX/ceph/build/ceph.conf"), 0);
  EXPECT_EQ(rados.connect(), 0);

  librados::IoCtx ioctx;
  EXPECT_EQ(rados.ioctx_create("default.rgw.meta", ioctx), 0);

  //设置namespace
  ioctx.set_namespace("users.email");

  // int operate(const std::string& oid, ObjectReadOperation *op, bufferlist *pbl);
  bufferlist bl;
  librados::ObjectReadOperation op;

  uint64_t size = 0;
  struct timespec ts{};
  
  //获取对象大小及创建时间
  op.stat2(&size, &ts, nullptr);

  EXPECT_EQ(size, 0);
  //不太清楚出参bufferlist的作用
  EXPECT_EQ(ioctx.operate("hello@gmail.com", &op, &bl), 0);
  
  librados::ObjectReadOperation rop;
  bufferlist bl1;
  rop.read(0, size, &bl1, nullptr);
  //不太清楚出参bufferlist的作用
  EXPECT_EQ(ioctx.operate("hello@gmail.com", &rop, &bl), 0);

  //最终落盘的userid时 RGWUID 不是 rgw_user
  RGWUID user;
  bufferlist::const_iterator bliter = bl1.cbegin();
  user.decode(bliter);

  EXPECT_EQ("hello", user.user_id.id);

  rados.shutdown();
}

通过ObjectReadOperation读取一个对象内容比较麻烦,要先通过stat获取其size,然后再read。
使用access key获取uid基本相同,只要将 namespace 更改为users.keys 并将object name 更改为 accesskey 即可。
image

test case 2:通过uid获取用户详细信息(RGWUserInfo)

#include <iostream>
#include "include/rados/librados.hpp"
#include <gtest/gtest.h>
#include "rgw/rgw_basic_types.h"
#include "rgw/rgw_user.h"
#include "rgw/rgw_common.h"

using namespace std;
TEST(RGW_RADOS_USER, USERS_INFO) {

  librados::Rados rados;
  EXPECT_EQ(rados.init2("client.admin", "ceph", 0), 0);
  EXPECT_EQ(rados.conf_read_file("/XXXXXX/ceph/build/ceph.conf"), 0);
  EXPECT_EQ(rados.connect(), 0);

  librados::IoCtx ioctx;
  EXPECT_EQ(rados.ioctx_create("default.rgw.meta", ioctx), 0);

  ioctx.set_namespace("users.uid");

  bufferlist bl;
  librados::ObjectReadOperation op;

  uint64_t size = 0;
  struct timespec ts{};
  
  op.stat2(&size, &ts, nullptr);

  EXPECT_EQ(size, 0);
  EXPECT_EQ(ioctx.operate("hello", &op, &bl), 0);


  librados::ObjectReadOperation rop;
  bufferlist bl1;
  rop.read(0, size, &bl1, nullptr);
  EXPECT_EQ(ioctx.operate("hello", &rop, &bl), 0);


  RGWUID uid;
  RGWUserInfo user_info;
  bufferlist::const_iterator bliter = bl1.cbegin();
  uid.decode(bliter);
  user_info.decode(bliter);

  EXPECT_EQ(uid.user_id, user_info.user_id);
  EXPECT_EQ("hello", user_info.user_id.id);
  EXPECT_EQ("accesskey", user_info.access_keys.begin()->first);
  EXPECT_EQ("hello@gmail.com", user_info.user_email);

  rados.shutdown();
}

image

meta:users.uid:uid对象保存的数据为 RGWUID+RGWUserInfo~

posted @ 2022-08-04 20:36  liutimo  阅读(153)  评论(1编辑  收藏  举报