Skip to content

Commit

Permalink
#156: doveadm rmb plugin new commands:
Browse files Browse the repository at this point in the history
- ls / get / set
  • Loading branch information
jrse committed Jun 7, 2018
1 parent 2cccd4f commit 8edebf0
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 41 deletions.
44 changes: 44 additions & 0 deletions src/librmb/tools/rmb/rmb-commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "rados-metadata-storage-ima.h"
#include "rados-metadata-storage-default.h"
#include "rados-save-log.h"
#include "ls_cmd_parser.h"

namespace librmb {

Expand Down Expand Up @@ -481,5 +482,48 @@ RadosStorageMetadataModule *RmbCommands::init_metadata_storage_module(librmb::Ra
print_debug("end: init_metadata_storage_module");
return ms;
}
int RmbCommands::update_attributes(librmb::RadosStorageMetadataModule *ms,
std::map<std::string, std::string> *metadata) {
std::string oid = (*opts)["set"];
if (!oid.empty() && metadata->size() > 0) {
for (std::map<std::string, std::string>::iterator it = metadata->begin(); it != metadata->end(); ++it) {
std::cout << oid << "=> " << it->first << " = " << it->second << '\n';
librmb::rbox_metadata_key ke = static_cast<librmb::rbox_metadata_key>(it->first[0]);
std::string value = it->second;
if (librmb::RadosUtils::is_date_attribute(ke)) {
if (!librmb::RadosUtils::is_numeric(value)) {
std::string date;
if (librmb::RadosUtils::convert_string_to_date(value, &date)) {
value = date;
}
}
}
librmb::RadosMailObject obj;
obj.set_oid(oid);
ms->load_metadata(&obj);
librmb::RadosMetadata attr(ke, value);
ms->set_metadata(&obj, attr);
std::cout << " saving object ..." << std::endl;
}
} else {
std::cerr << " invalid number of arguments, check usage " << std::endl;
return -1;
}
return 0;
}
void RmbCommands::set_output_path(librmb::CmdLineParser *parser) {
if ((*opts).find("out") != (*opts).end()) {
parser->set_output_dir((*opts)["out"]);
} else {
char outpath[PATH_MAX];
char *home = getenv("HOME");
if (home != NULL) {
snprintf(outpath, sizeof(outpath), "%s/rmb", home);
} else {
snprintf(outpath, sizeof(outpath), "rmb");
}
parser->set_output_dir(outpath);
}
}

} /* namespace librmb */
4 changes: 3 additions & 1 deletion src/librmb/tools/rmb/rmb-commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class RmbCommands {

int load_objects(librmb::RadosStorageMetadataModule *ms, std::vector<librmb::RadosMailObject *> &mail_objects,
std::string &sort_string);

int update_attributes(librmb::RadosStorageMetadataModule *ms, std::map<std::string, std::string> *metadata);
int print_mail(std::map<std::string, librmb::RadosMailBox *> *mailbox, std::string &output_dir, bool download);
int query_mail_storage(std::vector<librmb::RadosMailObject *> *mail_objects, librmb::CmdLineParser *parser,
bool download);
Expand All @@ -59,6 +59,8 @@ class RmbCommands {
static bool sort_phy_size(librmb::RadosMailObject *i, librmb::RadosMailObject *j);
static bool sort_save_date(librmb::RadosMailObject *i, librmb::RadosMailObject *j);

void set_output_path(librmb::CmdLineParser *parser);

private:
std::map<std::string, std::string> *opts;
librmb::RadosStorage *storage;
Expand Down
37 changes: 2 additions & 35 deletions src/librmb/tools/rmb/rmb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,48 +410,15 @@ int main(int argc, const char **argv) {
} else if (opts.find("get") != opts.end()) {
librmb::CmdLineParser parser(opts["get"]);

if (opts.find("out") != opts.end()) {
parser.set_output_dir(opts["out"]);
} else {
char outpath[PATH_MAX];
char *home = getenv("HOME");
if (home != NULL) {
snprintf(outpath, sizeof(outpath), "%s/rmb", home);
} else {
snprintf(outpath, sizeof(outpath), "rmb");
}
parser.set_output_dir(outpath);
}
rmb_commands->set_output_path(&parser);

if (opts["get"].compare("all") == 0 || opts["get"].compare("-") == 0 || parser.parse_ls_string()) {
// get load all objects metadata into memory
rmb_commands->load_objects(ms, mail_objects, sort_type);
rmb_commands->query_mail_storage(&mail_objects, &parser, true);
}
} else if (opts.find("set") != opts.end()) {
std::string oid = opts["set"];
if (!oid.empty() && metadata.size() > 0) {
for (std::map<std::string, std::string>::iterator it = metadata.begin(); it != metadata.end(); ++it) {
std::cout << oid << "=> " << it->first << " = " << it->second << '\n';
librmb::rbox_metadata_key ke = static_cast<librmb::rbox_metadata_key>(it->first[0]);
std::string value = it->second;
if (librmb::RadosUtils::is_date_attribute(ke)) {
if (!librmb::RadosUtils::is_numeric(value)) {
std::string date;
if (librmb::RadosUtils::convert_string_to_date(value, &date)) {
value = date;
}
}
}
librmb::RadosMailObject obj;
obj.set_oid(oid);
ms->load_metadata(&obj);
librmb::RadosMetadata attr(ke, value);
ms->set_metadata(&obj, attr);
}
} else {
std::cerr << " invalid number of arguments, check usage " << std::endl;
}
rmb_commands->update_attributes(ms, &metadata);
}

delete rmb_commands;
Expand Down
173 changes: 172 additions & 1 deletion src/storage-rbox/doveadm-rbox-plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,140 @@ static int cmd_rmb_config_create_run(struct doveadm_mail_cmd_context *ctx, struc
return 0;
}

static int cmd_rmb_ls_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user) {
const char *search_query = ctx->args[0];

const char *sort = ctx->args[1];
std::string sort_type = sort != NULL ? sort : "uid";
RboxDoveadmPlugin plugin;
plugin.read_plugin_configuration(user);
int open = plugin.open_connection();
if (open < 0) {
i_error("error opening rados connection, check config: %d", open);
return open;
}
librmb::RadosCephConfig *cfg = (static_cast<librmb::RadosDovecotCephCfgImpl *>(plugin.config))->get_rados_ceph_cfg();
int ret = cfg->load_cfg();
if (ret < 0) {
i_error("error accessing configuration");
return ret;
}
std::map<std::string, std::string> opts;
opts["ls"] = search_query;
opts["namespace"] = user->username;
librmb::RmbCommands rmb_cmds(plugin.storage, plugin.cluster, &opts);

std::string uid;
librmb::RadosStorageMetadataModule *ms = rmb_cmds.init_metadata_storage_module(*cfg, &uid);
if (ms == nullptr) {
i_error(" Error initializing metadata module ");
delete ms;
return -1;
}
std::vector<librmb::RadosMailObject *> mail_objects;
librmb::CmdLineParser parser(opts["ls"]);
if (opts["ls"].compare("all") == 0 || opts["ls"].compare("-") == 0 || parser.parse_ls_string()) {
rmb_cmds.load_objects(ms, mail_objects, sort_type);
rmb_cmds.query_mail_storage(&mail_objects, &parser, false);
}
delete ms;

return 0;
}

static int cmd_rmb_get_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user) {
const char *search_query = ctx->args[0];
const char *sort = ctx->args[1];
const char *output_path = ctx->args[2];

std::string sort_type = sort != NULL ? sort : "uid";
RboxDoveadmPlugin plugin;
plugin.read_plugin_configuration(user);
int open = plugin.open_connection();
if (open < 0) {
i_error("error opening rados connection, check config: %d", open);
return open;
}
librmb::RadosCephConfig *cfg = (static_cast<librmb::RadosDovecotCephCfgImpl *>(plugin.config))->get_rados_ceph_cfg();
int ret = cfg->load_cfg();
if (ret < 0) {
i_error("error accessing configuration");
return ret;
}
std::map<std::string, std::string> opts;
opts["get"] = search_query;
opts["namespace"] = user->username;
opts["out"] = output_path;
librmb::RmbCommands rmb_cmds(plugin.storage, plugin.cluster, &opts);

std::string uid;
librmb::RadosStorageMetadataModule *ms = rmb_cmds.init_metadata_storage_module(*cfg, &uid);
if (ms == nullptr) {
i_error(" Error initializing metadata module ");
delete ms;
return -1;
}
std::vector<librmb::RadosMailObject *> mail_objects;
librmb::CmdLineParser parser(opts["get"]);
rmb_cmds.set_output_path(&parser);
if (opts["get"].compare("all") == 0 || opts["ls"].compare("-") == 0 || parser.parse_ls_string()) {
rmb_cmds.load_objects(ms, mail_objects, sort_type);
rmb_cmds.query_mail_storage(&mail_objects, &parser, true);
}
delete ms;
return 0;
}
static int cmd_rmb_set_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user) {
const char *oid = ctx->args[0];
const char *key_value_pair = ctx->args[1];
if (oid == NULL || key_value_pair == NULL) {
i_error("error check params: %s : %s ", oid, key_value_pair);
return -1;
}

RboxDoveadmPlugin plugin;
plugin.read_plugin_configuration(user);
int open = plugin.open_connection();
if (open < 0) {
i_error("error opening rados connection, check config: %d", open);
return open;
}
librmb::RadosCephConfig *cfg = (static_cast<librmb::RadosDovecotCephCfgImpl *>(plugin.config))->get_rados_ceph_cfg();
int ret = cfg->load_cfg();
if (ret < 0) {
i_error("error accessing configuration");
return ret;
}
std::map<std::string, std::string> opts;
opts["set"] = oid;
opts["namespace"] = user->username;

librmb::RmbCommands rmb_cmds(plugin.storage, plugin.cluster, &opts);

std::string uid;
librmb::RadosStorageMetadataModule *ms = rmb_cmds.init_metadata_storage_module(*cfg, &uid);
if (ms == nullptr) {
i_error(" Error initializing metadata module ");
delete ms;
return -1;
}
std::map<std::string, std::string> metadata;
std::stringstream left(key_value_pair);
std::vector<std::string> tokens;
std::string item;
while (std::getline(left, item, '=')) {
tokens.push_back(item);
}
if (tokens.size() == 2) {
metadata[tokens[0]] = tokens[1];
ret = rmb_cmds.update_attributes(ms, &metadata);
std::cout << " token " << tokens[0] << " : " << tokens[1] << std::endl;
} else {
std::cerr << "check params: key_value_pair(" << key_value_pair << ") is not valid: use key=value" << std::endl;
}
delete ms;
return ret;
}
static void cmd_rmb_lspools_init(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED, const char *const args[]) {
if (str_array_length(args) > 0) {
doveadm_mail_help_name("rmb lspools");
Expand All @@ -163,7 +297,21 @@ static void cmd_rmb_config_update_init(struct doveadm_mail_cmd_context *ctx ATTR
doveadm_mail_help_name("rmb config update key=value");
}
}

static void cmd_rmb_ls_init(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED, const char *const args[]) {
if (str_array_length(args) > 2) {
doveadm_mail_help_name("rmb ls <-|key=value> <uid|recv_date|save_date|phy_size>");
}
}
static void cmd_rmb_get_init(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED, const char *const args[]) {
if (str_array_length(args) > 3) {
doveadm_mail_help_name("rmb get <-|key=value> <uid|recv_date|save_date|phy_size> <output path>");
}
}
static void cmd_rmb_set_init(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED, const char *const args[]) {
if (str_array_length(args) > 3) {
doveadm_mail_help_name("rmb set <oid> <key=value> ");
}
}
struct doveadm_mail_cmd_context *cmd_rmb_lspools_alloc(void) {
struct doveadm_mail_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
Expand Down Expand Up @@ -192,3 +340,26 @@ struct doveadm_mail_cmd_context *cmd_rmb_config_update_alloc(void) {
ctx->v.init = cmd_rmb_config_update_init;
return ctx;
}

struct doveadm_mail_cmd_context *cmd_rmb_ls_alloc(void) {
struct doveadm_mail_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
ctx->v.run = cmd_rmb_ls_run;
ctx->v.init = cmd_rmb_ls_init;
return ctx;
}

struct doveadm_mail_cmd_context *cmd_rmb_get_alloc(void) {
struct doveadm_mail_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
ctx->v.run = cmd_rmb_get_run;
ctx->v.init = cmd_rmb_get_init;
return ctx;
}
struct doveadm_mail_cmd_context *cmd_rmb_set_alloc(void) {
struct doveadm_mail_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
ctx->v.run = cmd_rmb_set_run;
ctx->v.init = cmd_rmb_set_init;
return ctx;
}
3 changes: 3 additions & 0 deletions src/storage-rbox/doveadm-rbox-plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ extern struct doveadm_mail_cmd_context *cmd_rmb_lspools_alloc(void);
extern struct doveadm_mail_cmd_context *cmd_rmb_config_create_alloc(void);
extern struct doveadm_mail_cmd_context *cmd_rmb_config_show_alloc(void);
extern struct doveadm_mail_cmd_context *cmd_rmb_config_update_alloc(void);
extern struct doveadm_mail_cmd_context *cmd_rmb_ls_alloc(void);
extern struct doveadm_mail_cmd_context *cmd_rmb_get_alloc(void);
extern struct doveadm_mail_cmd_context *cmd_rmb_set_alloc(void);

#endif // SRC_DOVEADM_RBOX_PLUGIN_H_
12 changes: 8 additions & 4 deletions src/storage-rbox/doveadm-rbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@
#define DOVEADM_EXPIRE_MAIL_CMD_CONTEXT(obj) MODULE_CONTEXT(obj, doveadm_expire_mail_cmd_module)
const char *doveadm_rbox_plugin_version = DOVECOT_ABI_VERSION;

static struct doveadm_mail_cmd rmb_commands[] = {{cmd_rmb_lspools_alloc, "rmb lspools", NULL},
{cmd_rmb_config_create_alloc, "rmb config create", NULL},
{cmd_rmb_config_show_alloc, "rmb config show", NULL},
{cmd_rmb_config_update_alloc, "rmb config update", "key=value"}};
static struct doveadm_mail_cmd rmb_commands[] = {
{cmd_rmb_lspools_alloc, "rmb lspools", NULL},
{cmd_rmb_config_create_alloc, "rmb config create", NULL},
{cmd_rmb_config_show_alloc, "rmb config show", NULL},
{cmd_rmb_config_update_alloc, "rmb config update", "key=value"},
{cmd_rmb_ls_alloc, "rmb ls", "-|key=value", "uid|recv_date|save_date|phy_size"},
{cmd_rmb_get_alloc, "rmb get", "-|key=value", "uid|recv_date|save_date|phy_size", "output path"},
{cmd_rmb_set_alloc, "rmb set", "oid", "key=value"}};

void doveadm_rbox_plugin_init(struct module *module ATTR_UNUSED) {

Expand Down

0 comments on commit 8edebf0

Please sign in to comment.