#include "rgw_sal_rados.h"
#include "rgw_lua.h"
#ifdef WITH_RADOSGW_LUA_PACKAGES
+#include <filesystem>
#include <boost/process.hpp>
-#include <boost/filesystem.hpp>
#include "rgw_lua_version.h"
#endif
}
-int read_script(rgw::sal::RGWRadosStore* store, const std::string& tenant, optional_yield y, context ctx, std::string& script)
+int read_script(const DoutPrefixProvider *dpp, rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx, std::string& script)
{
- RGWSysObjectCtx obj_ctx(store->svc()->sysobj->init_obj_ctx());
- RGWObjVersionTracker objv_tracker;
+ auto lua_script = store->get_lua_script_manager();
- rgw_raw_obj obj(store->svc()->zone->get_zone_params().log_pool, script_oid(ctx, tenant));
-
- bufferlist bl;
-
- const auto rc = rgw_get_system_obj(
- obj_ctx,
- obj.pool,
- obj.oid,
- bl,
- &objv_tracker,
- nullptr,
- y,
- nullptr,
- nullptr);
-
- if (rc < 0) {
- return rc;
- }
-
- auto iter = bl.cbegin();
- try {
- ceph::decode(script, iter);
- } catch (buffer::error& err) {
- return -EIO;
- }
-
- return 0;
+ return lua_script->get(dpp, y, script_oid(ctx, tenant), script);
}
-int write_script(const DoutPrefixProvider *dpp, rgw::sal::RGWRadosStore* store, const std::string& tenant, optional_yield y, context ctx, const std::string& script)
+int write_script(const DoutPrefixProvider *dpp, rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx, const std::string& script)
{
- RGWSysObjectCtx obj_ctx(store->svc()->sysobj->init_obj_ctx());
- RGWObjVersionTracker objv_tracker;
-
- rgw_raw_obj obj(store->svc()->zone->get_zone_params().log_pool, script_oid(ctx, tenant));
-
- bufferlist bl;
- ceph::encode(script, bl);
-
- const auto rc = rgw_put_system_obj(
- dpp,
- obj_ctx,
- obj.pool,
- obj.oid,
- bl,
- false,
- &objv_tracker,
- real_time(),
- y);
-
- if (rc < 0) {
- return rc;
- }
+ auto lua_script = store->get_lua_script_manager();
- return 0;
+ return lua_script->put(dpp, y, script_oid(ctx, tenant), script);
}
-int delete_script(const DoutPrefixProvider *dpp, rgw::sal::RGWRadosStore* store, const std::string& tenant, optional_yield y, context ctx)
+int delete_script(const DoutPrefixProvider *dpp, rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx)
{
- RGWObjVersionTracker objv_tracker;
-
- rgw_raw_obj obj(store->svc()->zone->get_zone_params().log_pool, script_oid(ctx, tenant));
-
- const auto rc = rgw_delete_system_obj(
- dpp,
- store->svc()->sysobj,
- obj.pool,
- obj.oid,
- &objv_tracker,
- y);
+ auto lua_script = store->get_lua_script_manager();
- if (rc < 0 && rc != -ENOENT) {
- return rc;
- }
-
- return 0;
+ return lua_script->del(dpp, y, script_oid(ctx, tenant));
}
#ifdef WITH_RADOSGW_LUA_PACKAGES
namespace bp = boost::process;
-int add_package(const DoutPrefixProvider *dpp, rgw::sal::RGWRadosStore* store, optional_yield y, const std::string& package_name, bool allow_compilation) {
- // verify that luarocks can load this oackage
+int add_package(const DoutPrefixProvider *dpp, rgw::sal::RadosStore* store, optional_yield y, const std::string& package_name, bool allow_compilation) {
+ // verify that luarocks can load this package
const auto p = bp::search_path("luarocks");
if (p.empty()) {
return -ECHILD;
return -EINVAL;
}
+ //replace previous versions of the package
+ const std::string package_name_no_version = package_name.substr(0, package_name.find(" "));
+ ret = remove_package(dpp, store, y, package_name_no_version);
+ if (ret < 0) {
+ return ret;
+ }
+
// add package to list
const bufferlist empty_bl;
std::map<std::string, bufferlist> new_package{{package_name, empty_bl}};
librados::ObjectWriteOperation op;
op.omap_set(new_package);
- ret = rgw_rados_operate(dpp, *(store->getRados()->get_lc_pool_ctx()),
+ ret = rgw_rados_operate(dpp, *(store->getRados()->get_lc_pool_ctx()),
PACKAGE_LIST_OBJECT_NAME, &op, y);
if (ret < 0) {
return 0;
}
-int remove_package(const DoutPrefixProvider *dpp, rgw::sal::RGWRadosStore* store, optional_yield y, const std::string& package_name) {
+int remove_package(const DoutPrefixProvider *dpp, rgw::sal::RadosStore* store, optional_yield y, const std::string& package_name) {
librados::ObjectWriteOperation op;
- op.omap_rm_keys(std::set<std::string>({package_name}));
- const auto ret = rgw_rados_operate(dpp, *(store->getRados()->get_lc_pool_ctx()),
- PACKAGE_LIST_OBJECT_NAME, &op, y);
-
- if (ret < 0) {
+ size_t pos = package_name.find(" ");
+ if (pos != package_name.npos) {
+ // remove specfic version of the the package
+ op.omap_rm_keys(std::set<std::string>({package_name}));
+ auto ret = rgw_rados_operate(dpp, *(store->getRados()->get_lc_pool_ctx()),
+ PACKAGE_LIST_OBJECT_NAME, &op, y);
+ if (ret < 0) {
+ return ret;
+ }
+ return 0;
+ }
+ // otherwise, remove any existing versions of the package
+ packages_t packages;
+ auto ret = list_packages(dpp, store, y, packages);
+ if (ret < 0 && ret != -ENOENT) {
return ret;
}
-
+ for(const auto& package : packages) {
+ const std::string package_no_version = package.substr(0, package.find(" "));
+ if (package_no_version.compare(package_name) == 0) {
+ op.omap_rm_keys(std::set<std::string>({package}));
+ ret = rgw_rados_operate(dpp, *(store->getRados()->get_lc_pool_ctx()),
+ PACKAGE_LIST_OBJECT_NAME, &op, y);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+ }
return 0;
}
-int list_packages(const DoutPrefixProvider *dpp, rgw::sal::RGWRadosStore* store, optional_yield y, packages_t& packages) {
+int list_packages(const DoutPrefixProvider *dpp, rgw::sal::RadosStore* store, optional_yield y, packages_t& packages) {
constexpr auto max_chunk = 1024U;
std::string start_after;
bool more = true;
return 0;
}
-int install_packages(const DoutPrefixProvider *dpp, rgw::sal::RGWRadosStore* store, optional_yield y, packages_t& failed_packages, std::string& output) {
+int install_packages(const DoutPrefixProvider *dpp, rgw::sal::RadosStore* store, optional_yield y, packages_t& failed_packages, std::string& output) {
// luarocks directory cleanup
- boost::system::error_code ec;
+ std::error_code ec;
const auto& luarocks_path = store->get_luarocks_path();
- boost::filesystem::remove_all(luarocks_path, ec);
- if (ec.value() != 0 && ec.value() != ENOENT) {
+ if (std::filesystem::remove_all(luarocks_path, ec)
+ == static_cast<std::uintmax_t>(-1) &&
+ ec != std::errc::no_such_file_or_directory) {
output.append("failed to clear luarock directory: ");
output.append(ec.message());
output.append("\n");
// the lua rocks install dir will be created by luarocks the first time it is called
for (const auto& package : packages) {
bp::ipstream is;
- bp::child c(p, "install", "--lua-version", CEPH_LUA_VERSION, "--tree", luarocks_path, "--deps-mode", "one", package,
- bp::std_in.close(),
- (bp::std_err & bp::std_out) > is);
+ const auto cmd = p.string() + " install --lua-version " + CEPH_LUA_VERSION + " --tree " + luarocks_path + " --deps-mode one " + package;
+ bp::child c(cmd, bp::std_in.close(), (bp::std_err & bp::std_out) > is);
// once package reload is supported, code should yield when reading output
- std::string line = "CMD: luarocks install --lua-version " + std::string(CEPH_LUA_VERSION) + std::string(" --tree ") +
- luarocks_path + " --deps-mode one " + package;
+ std::string line = std::string("CMD: ") + cmd;
do {
if (!line.empty()) {