By default, all Lua standard libraries are available in the script, however, in order to allow for other Lua modules to be used in the script, we support adding packages to an allowlist:
- - All packages in the allowlist are being re-installed using the luarocks package manager on radosgw restart. Therefore a restart is needed for adding or removing of packages to take effect
+ - Adding a Lua package to the allowlist, or removing a packge from it does not install or remove it. For the changes to take affect a "reload" command should be called.
+ - In addition all packages in the allowlist are being re-installed using the luarocks package manager on radosgw restart.
- To add a package that contains C source code that needs to be compiled, use the ``--allow-compilation`` flag. In this case a C compiler needs to be available on the host
- Lua packages are installed in, and used from, a directory local to the radosgw. Meaning that Lua packages in the allowlist are separated from any Lua packages available on the host.
By default, this directory would be ``/tmp/luarocks/<entity name>``. Its prefix part (``/tmp/luarocks/``) could be set to a different location via the ``rgw_luarocks_location`` configuration parameter.
# radosgw-admin script-package list
+To apply changes from the allowlist to all RGWs:
+
+::
+
+ # radosgw-admin script-package reload
+
+
Context Free Functions
----------------------
Debug Log
return current_period->get_id();
}
-std::unique_ptr<LuaManager> DaosStore::get_lua_manager() {
- return std::make_unique<DaosLuaManager>(this);
+std::unique_ptr<LuaManager> DaosStore::get_lua_manager(const DoutPrefixProvider *dpp, const std::string& luarocks_path) {
+ return std::make_unique<DaosLuaManager>(this, dpp, luarocks_path);
}
int DaosObject::get_obj_state(const DoutPrefixProvider* dpp,
}
virtual std::string get_host_id() { return ""; }
- virtual std::unique_ptr<LuaManager> get_lua_manager() override;
+ std::unique_ptr<LuaManager> get_lua_manager(const DoutPrefixProvider *dpp = nullptr, const std::string& luarocks_path = "") override;
virtual std::unique_ptr<RGWRole> get_role(
std::string name, std::string tenant, std::string path = "",
std::string trust_policy = "", std::string max_session_duration_str = "",
return current_period->get_id();
}
-std::unique_ptr<LuaManager> MotrStore::get_lua_manager()
+std::unique_ptr<LuaManager> MotrStore::get_lua_manager(const DoutPrefixProvider *dpp, const std::string& luarocks_path)
{
- return std::make_unique<MotrLuaManager>(this);
+ return std::make_unique<MotrLuaManager>(this, dpp, luarocks_path);
}
int MotrObject::get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **_state, optional_yield y, bool follow_olh)
{
return -ENOENT;
}
+
+ int MotrLuaManager::reload_packages(const DoutPrefixProvider* dpp, optional_yield y)
+ {
+ return -ENOENT;
+ }
} // namespace rgw::sal
extern "C" {
virtual int remove_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name) override;
/** List lua packages */
virtual int list_packages(const DoutPrefixProvider* dpp, optional_yield y, rgw::lua::packages_t& packages) override;
+ /** Reload lua packages */
+ virtual int reload_packages(const DoutPrefixProvider* dpp, optional_yield y) override;
};
class MotrOIDCProvider : public RGWOIDCProvider {
virtual const RGWSyncModuleInstanceRef& get_sync_module() { return sync_module; }
virtual std::string get_host_id() { return ""; }
- virtual std::unique_ptr<LuaManager> get_lua_manager() override;
+ std::unique_ptr<LuaManager> get_lua_manager(const DoutPrefixProvider *dpp = nullptr, const std::string& luarocks_path = "") override;
virtual std::unique_ptr<RGWRole> get_role(std::string name,
std::string tenant,
std::string path="",
cerr << "ERROR: failed to set bucket owner: " << cpp_strerror(-r) << std::endl;
return r;
}
-
+
return 0;
}
return pubsub_oid_prefix + get_tenant() + ".bucket." + get_name() + "/" + get_marker();
}
-int RadosBucket::read_topics(rgw_pubsub_bucket_topics& notifications,
- RGWObjVersionTracker* objv_tracker, optional_yield y, const DoutPrefixProvider *dpp)
+int RadosBucket::read_topics(rgw_pubsub_bucket_topics& notifications,
+ RGWObjVersionTracker* objv_tracker, optional_yield y, const DoutPrefixProvider *dpp)
{
// read from cache
auto cache = store->getRados()->get_topic_cache();
try {
decode(notifications, iter);
} catch (buffer::error& err) {
- ldpp_dout(dpp, 20) << " failed to decode bucket notifications from oid: " << topics_oid() << ". for bucket: "
+ ldpp_dout(dpp, 20) << " failed to decode bucket notifications from oid: " << topics_oid() << ". for bucket: "
<< get_name() << ". error: " << err.what() << dendl;
return -EIO;
}
encode(notifications, bl);
return rgw_put_system_obj(dpp, store->svc()->sysobj,
- store->svc()->zone->get_zone_params().log_pool,
+ store->svc()->zone->get_zone_params().log_pool,
topics_oid(),
bl, false, objv_tracker, real_time(), y);
}
-int RadosBucket::remove_topics(RGWObjVersionTracker* objv_tracker,
+int RadosBucket::remove_topics(RGWObjVersionTracker* objv_tracker,
optional_yield y, const DoutPrefixProvider *dpp) {
- return rgw_delete_system_obj(dpp, store->svc()->sysobj,
+ return rgw_delete_system_obj(dpp, store->svc()->sysobj,
store->svc()->zone->get_zone_params().log_pool,
topics_oid(),
objv_tracker, y);
try {
decode(topics, iter);
} catch (buffer::error& err) {
- ldpp_dout(dpp, 20) << " failed to decode topics from oid: " << topics_oid(tenant) <<
+ ldpp_dout(dpp, 20) << " failed to decode topics from oid: " << topics_oid(tenant) <<
". error: " << err.what() << dendl;
return -EIO;
}
encode(topics, bl);
return rgw_put_system_obj(dpp, svc()->sysobj,
- svc()->zone->get_zone_params().log_pool,
+ svc()->zone->get_zone_params().log_pool,
topics_oid(tenant),
bl, false, objv_tracker, real_time(), y);
}
int RadosStore::remove_topics(const std::string& tenant, RGWObjVersionTracker* objv_tracker,
optional_yield y, const DoutPrefixProvider *dpp) {
- return rgw_delete_system_obj(dpp, svc()->sysobj,
+ return rgw_delete_system_obj(dpp, svc()->sysobj,
svc()->zone->get_zone_params().log_pool,
topics_oid(tenant),
objv_tracker, y);
mgr->register_resource("ratelimit", new RGWRESTMgr_Ratelimit);
}
-std::unique_ptr<LuaManager> RadosStore::get_lua_manager()
+std::unique_ptr<LuaManager> RadosStore::get_lua_manager(const std::string& luarocks_path)
{
- return std::make_unique<RadosLuaManager>(this);
+ return std::make_unique<RadosLuaManager>(this, luarocks_path);
}
std::unique_ptr<RGWRole> RadosStore::get_role(std::string name,
if (!remove_objs.empty()) {
del_op->params.remove_objs = &remove_objs;
}
-
+
del_op->params.abortmp = true;
del_op->params.parts_accounted_size = parts_accounted_size;
ldpp_dout(dpp, 0) << "ERROR: compression type was changed during multipart upload ("
<< cs_info.compression_type << ">>" << obj_part.cs_info.compression_type << ")" << dendl;
ret = -ERR_INVALID_PART;
- return ret;
+ return ret;
}
-
+
if (part_compressed) {
int64_t new_ofs; // offset in compression data for new part
if (cs_info.blocks.size() > 0)
cb.len = block.len;
cs_info.blocks.push_back(cb);
new_ofs = cb.new_ofs + cb.len;
- }
+ }
if (!compressed)
cs_info.compression_type = obj_part.cs_info.compression_type;
cs_info.orig_size += obj_part.cs_info.orig_size;
return store->svc()->zone->get_sync_policy_handler(get_id());
}
-RadosLuaManager::RadosLuaManager(RadosStore* _s) :
+RadosLuaManager::RadosLuaManager(RadosStore* _s, const std::string& _luarocks_path) :
+ StoreLuaManager(_luarocks_path),
store(_s),
- pool((store->svc() && store->svc()->zone) ? store->svc()->zone->get_zone_params().log_pool : rgw_pool())
+ pool((store->svc() && store->svc()->zone) ? store->svc()->zone->get_zone_params().log_pool : rgw_pool()),
+ ioctx(*store->getRados()->get_lc_pool_ctx()),
+ packages_watcher(this)
{ }
int RadosLuaManager::get_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script)
{
if (pool.empty()) {
- ldpp_dout(dpp, 10) << "WARNING: missing pool when reading lua script " << dendl;
+ ldpp_dout(dpp, 10) << "WARNING: missing pool when reading Lua script " << dendl;
return 0;
}
bufferlist bl;
int RadosLuaManager::put_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script)
{
if (pool.empty()) {
- ldpp_dout(dpp, 10) << "WARNING: missing pool when writing lua script " << dendl;
+ ldpp_dout(dpp, 10) << "WARNING: missing pool when writing Lua script " << dendl;
return 0;
}
bufferlist bl;
int RadosLuaManager::del_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key)
{
if (pool.empty()) {
- ldpp_dout(dpp, 10) << "WARNING: missing pool when deleting lua script " << dendl;
+ ldpp_dout(dpp, 10) << "WARNING: missing pool when deleting Lua script " << dendl;
return 0;
}
int r = rgw_delete_system_obj(dpp, store->svc()->sysobj, pool, key, nullptr, y);
int RadosLuaManager::add_package(const DoutPrefixProvider *dpp, optional_yield y, const std::string& package_name)
{
+ if (!ioctx.is_valid()) {
+ ldpp_dout(dpp, 10) << "WARNING: missing pool when adding Lua package" << dendl;
+ return 0;
+ }
// 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);
- auto ret = rgw_rados_operate(dpp, *(store->getRados()->get_lc_pool_ctx()),
+ return rgw_rados_operate(dpp, ioctx,
PACKAGE_LIST_OBJECT_NAME, &op, y);
-
- if (ret < 0) {
- return ret;
- }
- return 0;
}
int RadosLuaManager::remove_package(const DoutPrefixProvider *dpp, optional_yield y, const std::string& package_name)
{
+ if (!ioctx.is_valid()) {
+ ldpp_dout(dpp, 10) << "WARNING: missing pool when removing Lua package" << dendl;
+ return -ENOENT;
+ }
librados::ObjectWriteOperation op;
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()),
+ auto ret = rgw_rados_operate(dpp, ioctx,
PACKAGE_LIST_OBJECT_NAME, &op, y);
if (ret < 0) {
return ret;
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()),
+ ret = rgw_rados_operate(dpp, ioctx,
PACKAGE_LIST_OBJECT_NAME, &op, y);
if (ret < 0) {
return ret;
int RadosLuaManager::list_packages(const DoutPrefixProvider *dpp, optional_yield y, rgw::lua::packages_t& packages)
{
+ if (!ioctx.is_valid()) {
+ ldpp_dout(dpp, 10) << "WARNING: missing pool when listing Lua packages" << dendl;
+ return -ENOENT;
+ }
constexpr auto max_chunk = 1024U;
std::string start_after;
bool more = true;
librados::ObjectReadOperation op;
rgw::lua::packages_t packages_chunk;
op.omap_get_keys2(start_after, max_chunk, &packages_chunk, &more, &rval);
- const auto ret = rgw_rados_operate(dpp, *(store->getRados()->get_lc_pool_ctx()),
+ const auto ret = rgw_rados_operate(dpp, ioctx,
PACKAGE_LIST_OBJECT_NAME, &op, nullptr, y);
if (ret < 0) {
return 0;
}
+int RadosLuaManager::watch_reload(const DoutPrefixProvider* dpp)
+{
+ if (!ioctx.is_valid()) {
+ ldpp_dout(dpp, 10) << "WARNING: missing pool when watching reloads of Lua packages" << dendl;
+ return -ENOENT;
+ }
+ // create the object to watch (object may already exist)
+ librados::ObjectWriteOperation op;
+ op.create(false);
+ auto r = rgw_rados_operate(dpp, ioctx,
+ PACKAGE_LIST_OBJECT_NAME, &op, null_yield);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to watch " << PACKAGE_LIST_OBJECT_NAME
+ << ". cannot create object. error: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+ r = ioctx.watch2(PACKAGE_LIST_OBJECT_NAME, &watch_handle, &packages_watcher);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to watch " << PACKAGE_LIST_OBJECT_NAME
+ << ". error: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+ ldpp_dout(dpp, 20) << "Started watching for reloads of " << PACKAGE_LIST_OBJECT_NAME
+ << " with handle: " << watch_handle << dendl;
+
+ return 0;
+}
+
+int RadosLuaManager::unwatch_reload(const DoutPrefixProvider* dpp)
+{
+ if (watch_handle == 0) {
+ // nothing to unwatch
+ return 0;
+ }
+
+ if (!ioctx.is_valid()) {
+ ldpp_dout(dpp, 10) << "WARNING: missing pool when unwatching reloads of Lua packages" << dendl;
+ return -ENOENT;
+ }
+ const auto r = ioctx.unwatch2(watch_handle);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to unwatch " << PACKAGE_LIST_OBJECT_NAME
+ << ". error: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+ ldpp_dout(dpp, 20) << "Stopped watching for reloads of " << PACKAGE_LIST_OBJECT_NAME
+ << " with handle: " << watch_handle << dendl;
+
+ return 0;
+}
+
+void RadosLuaManager::ack_reload(const DoutPrefixProvider* dpp, uint64_t notify_id, uint64_t cookie, int reload_status) {
+ if (!ioctx.is_valid()) {
+ ldpp_dout(dpp, 10) << "WARNING: missing pool when acking reload of Lua packages" << dendl;
+ return;
+ }
+ bufferlist reply;
+ ceph::encode(reload_status, reply);
+ ioctx.notify_ack(PACKAGE_LIST_OBJECT_NAME, notify_id, cookie, reply);
+}
+
+void RadosLuaManager::handle_reload_notify(const DoutPrefixProvider* dpp, optional_yield y, uint64_t notify_id, uint64_t cookie) {
+ if (cookie != watch_handle) {
+ return;
+ }
+
+ rgw::lua::packages_t failed_packages;
+ std::string install_dir;
+ auto r = rgw::lua::install_packages(dpp, store,
+ y, store->ctx()->_conf.get_val<std::string>("rgw_luarocks_location"),
+ failed_packages, install_dir);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "WARNING: failed to install Lua packages from allowlist. error code: " << r
+ << dendl;
+ }
+ set_luarocks_path(install_dir);
+ for (const auto &p : failed_packages) {
+ ldpp_dout(dpp, 5) << "WARNING: failed to install Lua package: " << p
+ << " from allowlist" << dendl;
+ }
+
+ ack_reload(dpp, notify_id, cookie, r);
+}
+
+int RadosLuaManager::reload_packages(const DoutPrefixProvider *dpp, optional_yield y)
+{
+ if (!ioctx.is_valid()) {
+ ldpp_dout(dpp, 10) << "WARNING: missing pool trying to notify reload of Lua packages" << dendl;
+ return -ENOENT;
+ }
+ bufferlist empty_bl;
+ bufferlist reply_bl;
+ const uint64_t timeout_ms = 0;
+ auto r = rgw_rados_notify(dpp,
+ ioctx,
+ PACKAGE_LIST_OBJECT_NAME,
+ empty_bl, timeout_ms, &reply_bl, y);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to notify reload on " << PACKAGE_LIST_OBJECT_NAME
+ << ". error: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+
+ std::vector<librados::notify_ack_t> acks;
+ std::vector<librados::notify_timeout_t> timeouts;
+ ioctx.decode_notify_response(reply_bl, &acks, &timeouts);
+ if (timeouts.size() > 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to notify reload on " << PACKAGE_LIST_OBJECT_NAME
+ << ". error: timeout" << dendl;
+ return -EAGAIN;
+ }
+ for (auto& ack : acks) {
+ try {
+ auto iter = ack.payload_bl.cbegin();
+ ceph::decode(r, iter);
+ } catch (buffer::error& err) {
+ ldpp_dout(dpp, 1) << "ERROR: couldn't decode Lua packages reload status. error: " <<
+ err.what() << dendl;
+ return -EINVAL;
+ }
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+void RadosLuaManager::PackagesWatcher::handle_notify(uint64_t notify_id, uint64_t cookie, uint64_t notifier_id, bufferlist &bl)
+{
+ parent->handle_reload_notify(this, null_yield, notify_id, cookie);
+}
+
+void RadosLuaManager::PackagesWatcher::handle_error(uint64_t cookie, int err)
+{
+ if (parent->watch_handle != cookie) {
+ return;
+ }
+ ldpp_dout(this, 5) << "WARNING: restarting reload watch handler. error: " << err << dendl;
+
+ parent->unwatch_reload(this);
+ parent->watch_reload(this);
+}
+
+CephContext* RadosLuaManager::PackagesWatcher::get_cct() const {
+ return parent->store->ctx();
+}
+
+unsigned RadosLuaManager::PackagesWatcher::get_subsys() const {
+ return dout_subsys;
+}
+
+std::ostream& RadosLuaManager::PackagesWatcher::gen_prefix(std::ostream& out) const {
+ return out << "rgw lua package reloader: ";
+}
+
int RadosOIDCProvider::store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y)
{
auto sysobj = store->svc()->sysobj;
virtual int meta_remove(const DoutPrefixProvider* dpp, std::string& metadata_key, optional_yield y) override;
virtual const RGWSyncModuleInstanceRef& get_sync_module() { return rados->get_sync_module(); }
virtual std::string get_host_id() { return rados->host_id; }
- virtual std::unique_ptr<LuaManager> get_lua_manager() override;
+ std::unique_ptr<LuaManager> get_lua_manager(const std::string& luarocks_path) override;
virtual std::unique_ptr<RGWRole> get_role(std::string name,
std::string tenant,
std::string path="",
};
class RadosLuaManager : public StoreLuaManager {
+ class PackagesWatcher : public librados::WatchCtx2, public DoutPrefixProvider {
+ RadosLuaManager* const parent;
+ public:
+ PackagesWatcher(RadosLuaManager* _parent) :
+ parent(_parent) {}
+ ~PackagesWatcher() override = default;
+ void handle_notify(uint64_t notify_id, uint64_t cookie,
+ uint64_t notifier_id, bufferlist& bl) override;
+ void handle_error(uint64_t cookie, int err) override;
+
+ // DoutPrefixProvider iterface
+ CephContext* get_cct() const override;
+ unsigned get_subsys() const override;
+ std::ostream& gen_prefix(std::ostream& out) const override;
+ };
+
RadosStore* const store;
rgw_pool pool;
+ librados::IoCtx& ioctx;
+ PackagesWatcher packages_watcher;
+ void ack_reload(const DoutPrefixProvider* dpp, uint64_t notify_id, uint64_t cookie, int reload_status);
+ void handle_reload_notify(const DoutPrefixProvider* dpp, optional_yield y, uint64_t notify_id, uint64_t cookie);
+ uint64_t watch_handle = 0;
public:
- RadosLuaManager(RadosStore* _s);
- virtual ~RadosLuaManager() = default;
-
- virtual int get_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script);
- virtual int put_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script);
- virtual int del_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key);
- virtual int add_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name);
- virtual int remove_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name);
- virtual int list_packages(const DoutPrefixProvider* dpp, optional_yield y, rgw::lua::packages_t& packages);
+ RadosLuaManager(RadosStore* _s, const std::string& _luarocks_path);
+ ~RadosLuaManager() override = default;
+
+ int get_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script) override;
+ int put_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script) override;
+ int del_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key) override;
+ int add_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name) override;
+ int remove_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name) override;
+ int list_packages(const DoutPrefixProvider* dpp, optional_yield y, rgw::lua::packages_t& packages) override;
+ int reload_packages(const DoutPrefixProvider* dpp, optional_yield y) override;
+ int watch_reload(const DoutPrefixProvider* dpp);
+ int unwatch_reload(const DoutPrefixProvider* dpp);
};
class RadosOIDCProvider : public RGWOIDCProvider {
cout << " topic get get a bucket notifications topic\n";
cout << " topic rm remove a bucket notifications topic\n";
cout << " topic stats get a bucket notifications persistent topic stats (i.e. reservations, entries & size)\n";
- cout << " script put upload a lua script to a context\n";
- cout << " script get get the lua script of a context\n";
- cout << " script rm remove the lua scripts of a context\n";
- cout << " script-package add add a lua package to the scripts allowlist\n";
- cout << " script-package rm remove a lua package from the scripts allowlist\n";
- cout << " script-package list get the lua packages allowlist\n";
+ cout << " script put upload a Lua script to a context\n";
+ cout << " script get get the Lua script of a context\n";
+ cout << " script rm remove the Lua scripts of a context\n";
+ cout << " script-package add add a Lua package to the scripts allowlist\n";
+ cout << " script-package rm remove a Lua package from the scripts allowlist\n";
+ cout << " script-package list get the Lua packages allowlist\n";
+ cout << " script-package reload install/remove Lua packages according to allowlist\n";
cout << " notification list list bucket notifications configuration\n";
cout << " notification get get a bucket notifications configuration\n";
cout << " notification rm remove a bucket notifications configuration\n";
cout << " --notification-id bucket notifications id\n";
cout << "\nScript options:\n";
cout << " --context context in which the script runs. one of: "+LUA_CONTEXT_LIST+"\n";
- cout << " --package name of the lua package that should be added/removed to/from the allowlist\n";
+ cout << " --package name of the Lua package that should be added/removed to/from the allowlist\n";
cout << " --allow-compilation package is allowed to compile C code as part of its installation\n";
cout << "\nBucket check olh/unlinked options:\n";
cout << " --min-age-hours minimum age of unlinked objects to consider for bucket check unlinked (default: 1)\n";
SCRIPT_RM,
SCRIPT_PACKAGE_ADD,
SCRIPT_PACKAGE_RM,
- SCRIPT_PACKAGE_LIST
+ SCRIPT_PACKAGE_LIST,
+ SCRIPT_PACKAGE_RELOAD
};
}
{ "script-package add", OPT::SCRIPT_PACKAGE_ADD },
{ "script-package rm", OPT::SCRIPT_PACKAGE_RM },
{ "script-package list", OPT::SCRIPT_PACKAGE_LIST },
+ { "script-package reload", OPT::SCRIPT_PACKAGE_RELOAD },
};
static SimpleCmd::Aliases cmd_aliases = {
cerr << "ERROR: cannot specify tenant in background context" << std::endl;
return EINVAL;
}
- auto lua_manager = driver->get_lua_manager();
+ auto lua_manager = driver->get_lua_manager("");
rc = rgw::lua::write_script(dpp(), lua_manager.get(), tenant, null_yield, script_ctx, script);
if (rc < 0) {
cerr << "ERROR: failed to put script. error: " << rc << std::endl;
cerr << "ERROR: invalid script context: " << *str_script_ctx << ". must be one of: " << LUA_CONTEXT_LIST << std::endl;
return EINVAL;
}
- auto lua_manager = driver->get_lua_manager();
+ auto lua_manager = driver->get_lua_manager("");
std::string script;
const auto rc = rgw::lua::read_script(dpp(), lua_manager.get(), tenant, null_yield, script_ctx, script);
if (rc == -ENOENT) {
cerr << "ERROR: invalid script context: " << *str_script_ctx << ". must be one of: " << LUA_CONTEXT_LIST << std::endl;
return EINVAL;
}
- auto lua_manager = driver->get_lua_manager();
+ auto lua_manager = driver->get_lua_manager("");
const auto rc = rgw::lua::delete_script(dpp(), lua_manager.get(), tenant, null_yield, script_ctx);
if (rc < 0) {
cerr << "ERROR: failed to remove script. error: " << rc << std::endl;
if (opt_cmd == OPT::SCRIPT_PACKAGE_ADD) {
#ifdef WITH_RADOSGW_LUA_PACKAGES
if (!script_package) {
- cerr << "ERROR: lua package name was not provided (via --package)" << std::endl;
+ cerr << "ERROR: Lua package name was not provided (via --package)" << std::endl;
return EINVAL;
}
const auto rc = rgw::lua::add_package(dpp(), driver, null_yield, *script_package, bool(allow_compilation));
if (rc < 0) {
- cerr << "ERROR: failed to add lua package: " << script_package << " .error: " << rc << std::endl;
+ cerr << "ERROR: failed to add Lua package: " << script_package << " .error: " << rc << std::endl;
return -rc;
}
#else
- cerr << "ERROR: adding lua packages is not permitted" << std::endl;
+ cerr << "ERROR: adding Lua packages is not permitted" << std::endl;
return EPERM;
#endif
}
if (opt_cmd == OPT::SCRIPT_PACKAGE_RM) {
#ifdef WITH_RADOSGW_LUA_PACKAGES
if (!script_package) {
- cerr << "ERROR: lua package name was not provided (via --package)" << std::endl;
+ cerr << "ERROR: Lua package name was not provided (via --package)" << std::endl;
return EINVAL;
}
const auto rc = rgw::lua::remove_package(dpp(), driver, null_yield, *script_package);
return 0;
}
if (rc < 0) {
- cerr << "ERROR: failed to remove lua package: " << script_package << " .error: " << rc << std::endl;
+ cerr << "ERROR: failed to remove Lua package: " << script_package << " .error: " << rc << std::endl;
return -rc;
}
#else
- cerr << "ERROR: removing lua packages in not permitted" << std::endl;
+ cerr << "ERROR: removing Lua packages in not permitted" << std::endl;
return EPERM;
#endif
}
rgw::lua::packages_t packages;
const auto rc = rgw::lua::list_packages(dpp(), driver, null_yield, packages);
if (rc == -ENOENT) {
- std::cout << "no lua packages in allowlist" << std::endl;
+ std::cout << "no Lua packages in allowlist" << std::endl;
} else if (rc < 0) {
- cerr << "ERROR: failed to read lua packages allowlist. error: " << rc << std::endl;
+ cerr << "ERROR: failed to read Lua packages allowlist. error: " << rc << std::endl;
return rc;
} else {
for (const auto& package : packages) {
}
}
#else
- cerr << "ERROR: listing lua packages in not permitted" << std::endl;
+ cerr << "ERROR: listing Lua packages in not permitted" << std::endl;
return EPERM;
#endif
}
+ if (opt_cmd == OPT::SCRIPT_PACKAGE_RELOAD) {
+#ifdef WITH_RADOSGW_LUA_PACKAGES
+ const auto rc = rgw::lua::reload_packages(dpp(), driver, null_yield);
+ if (rc < 0) {
+ cerr << "ERROR: failed to reload Lua packages. error: " << rc << std::endl;
+ return rc;
+ }
+#else
+ cerr << "ERROR: reloading Lua packages in not permitted" << std::endl;
+ return EPERM;
+#endif
+ }
return 0;
}
{
rgw::sal::Driver* driver = env.driver;
int r{0};
- std::string path = g_conf().get_val<std::string>("rgw_luarocks_location");
+ std::string install_dir;
#ifdef WITH_RADOSGW_LUA_PACKAGES
rgw::lua::packages_t failed_packages;
- r = rgw::lua::install_packages(dpp, driver, null_yield, path,
- failed_packages, env.lua.luarocks_path);
+ r = rgw::lua::install_packages(dpp, driver, null_yield, g_conf().get_val<std::string>("rgw_luarocks_location"),
+ failed_packages, install_dir);
if (r < 0) {
- dout(1) << "WARNING: failed to install lua packages from allowlist. error: " << r
+ ldpp_dout(dpp, 5) << "WARNING: failed to install Lua packages from allowlist. error: " << r
<< dendl;
}
for (const auto &p : failed_packages) {
- dout(5) << "WARNING: failed to install lua package: " << p
+ ldpp_dout(dpp, 5) << "WARNING: failed to install Lua package: " << p
<< " from allowlist" << dendl;
}
#endif
- env.lua.manager = env.driver->get_lua_manager();
-
+ env.lua.manager = env.driver->get_lua_manager(install_dir);
if (driver->get_name() == "rados") { /* Supported for only RadosStore */
lua_background = std::make_unique<
- rgw::lua::Background>(driver, dpp->get_cct(), path);
+ rgw::lua::Background>(driver, dpp->get_cct(), env.lua.manager.get());
lua_background->start();
env.lua.background = lua_background.get();
+ static_cast<rgw::sal::RadosLuaManager*>(env.lua.manager.get())->watch_reload(dpp);
}
} /* init_lua */
{
if (env.driver->get_name() == "rados") {
reloader.reset(); // stop the realm reloader
+ static_cast<rgw::sal::RadosLuaManager*>(env.lua.manager.get())->unwatch_reload(dpp);
}
for (auto& fe : fes) {
namespace bp = boost::process;
-int add_package(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, optional_yield y, const std::string& package_name, bool allow_compilation)
+int add_package(const DoutPrefixProvider* dpp, rgw::sal::Driver* driver, 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");
return ret;
}
- auto lua_mgr = driver->get_lua_manager();
-
- return lua_mgr->add_package(dpp, y, package_name);
+ return driver->get_lua_manager("")->add_package(dpp, y, package_name);
}
int remove_package(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, optional_yield y, const std::string& package_name)
{
- auto lua_mgr = driver->get_lua_manager();
-
- return lua_mgr->remove_package(dpp, y, package_name);
+ return driver->get_lua_manager("")->remove_package(dpp, y, package_name);
}
namespace bp = boost::process;
int list_packages(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, optional_yield y, packages_t& packages)
{
- auto lua_mgr = driver->get_lua_manager();
-
- return lua_mgr->list_packages(dpp, y, packages);
+ return driver->get_lua_manager("")->list_packages(dpp, y, packages);
}
namespace fs = std::filesystem;
ldpp_dout(dpp, 20) << lines << dendl;
}
- // luarocks directory cleanup
- /*std::error_code ec;
- if (fs::remove_all(luarocks_path, ec)
- == static_cast<std::uintmax_t>(-1) &&
- ec != std::errc::no_such_file_or_directory) {
- ldpp_dout(dpp, 1) << "Lua ERROR: failed to clear luarocks directory: " <<
- luarocks_path << ". error: " << ec.message() << dendl;
- return -ec.value();
- }*/
- /*auto rc = create_directory_p(dpp, luarocks_path);
- if (rc < 0) {
- ldpp_dout(dpp, 1) << "Lua ERROR: failed to recreate luarocks directory: " <<
- luarocks_path << ". error: " << rc << dendl;
- return rc;
- }*/
-
- // switch temporary install directory to luarocks one
- /*fs::rename(tmp_luarocks_path, luarocks_path, ec);
- if (ec) {
- ldpp_dout(dpp, 1) << "Lua ERROR: failed to switch between temp directory: " <<
- tmp_luarocks_path << " and luarocks directory: " << luarocks_path <<
- " . error: " << ec.message() << dendl;
- return -ec.value();
- }*/
-
return 0;
}
+int reload_packages(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, optional_yield y)
+{
+ return driver->get_lua_manager("")->reload_packages(dpp, y);
+}
+
#endif // WITH_RADOSGW_LUA_PACKAGES
}
// list lua packages in the allowlist
int list_packages(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, optional_yield y, packages_t& packages);
+// reload lua packages
+int reload_packages(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, optional_yield y);
+
// install all packages from the allowlist
// return (by reference) the list of packages that failed to install
// and return (by reference) the temporary director in which the packages were installed
optional_yield y, const std::string& luarocks_path,
packages_t& failed_packages,
std::string& install_dir);
+
#endif
}
return 0;
}
-Background::Background(rgw::sal::Driver* driver,
- CephContext* cct,
- const std::string& luarocks_path,
- int execute_interval) :
- execute_interval(execute_interval),
- dp(cct, dout_subsys, "lua background: "),
- lua_manager(driver->get_lua_manager()),
- cct(cct),
- luarocks_path(luarocks_path) {}
+Background::Background(rgw::sal::Driver* _driver,
+ CephContext* _cct,
+ rgw::sal::LuaManager* _lua_manager,
+ int _execute_interval) :
+ execute_interval(_execute_interval)
+ , dp(_cct, dout_subsys, "lua background: ")
+ , lua_manager(_lua_manager)
+ , cct(_cct)
+{}
void Background::shutdown(){
stopped = true;
}
void Background::resume(rgw::sal::Driver* driver) {
- lua_manager = driver->get_lua_manager();
paused = false;
cond.notify_all();
}
return -EAGAIN;
}
std::string tenant;
- return rgw::lua::read_script(&dp, lua_manager.get(), tenant, null_yield, rgw::lua::context::background, rgw_script);
+ return rgw::lua::read_script(&dp, lua_manager, tenant, null_yield, rgw::lua::context::background, rgw_script);
}
const BackgroundMapValue Background::empty_table_value;
}
try {
open_standard_libs(L);
- set_package_path(L, luarocks_path);
+ set_package_path(L, lua_manager->luarocks_path());
create_debug_action(L, cct);
create_background_metatable(L);
} catch (const std::runtime_error& e) {
}
ldpp_dout(dpp, 10) << "Lua background thread resumed" << dendl;
}
+
const auto rc = read_script();
if (rc == -ENOENT || rc == -EAGAIN) {
// either no script or paused, nothing to do
ceph_assert(lua_istable(L, -1));
}
+void Background::set_manager(rgw::sal::LuaManager* _lua_manager) {
+ lua_manager = _lua_manager;
+}
+
} //namespace rgw::lua
class Background : public RGWRealmReloader::Pauser {
public:
static const BackgroundMapValue empty_table_value;
+
private:
BackgroundMap rgw_map;
bool stopped = false;
bool paused = false;
int execute_interval;
const DoutPrefix dp;
- std::unique_ptr<rgw::sal::LuaManager> lua_manager;
+ rgw::sal::LuaManager* lua_manager;
CephContext* const cct;
- const std::string luarocks_path;
std::thread runner;
mutable std::mutex table_mutex;
std::mutex cond_mutex;
virtual int read_script();
public:
- Background(rgw::sal::Driver* driver,
- CephContext* cct,
- const std::string& luarocks_path,
- int execute_interval = INIT_EXECUTE_INTERVAL);
-
- virtual ~Background() = default;
- void start();
- void shutdown();
- void create_background_metatable(lua_State* L);
- const BackgroundMapValue& get_table_value(const std::string& key) const;
- template<typename T>
- void put_table_value(const std::string& key, T value) {
- std::unique_lock cond_lock(table_mutex);
- rgw_map[key] = value;
- }
-
- void pause() override;
- void resume(rgw::sal::Driver* _driver) override;
+ Background(rgw::sal::Driver* _driver,
+ CephContext* _cct,
+ rgw::sal::LuaManager* _lua_manager,
+ int _execute_interval = INIT_EXECUTE_INTERVAL);
+
+ ~Background() override = default;
+ void start();
+ void shutdown();
+ void create_background_metatable(lua_State* L);
+ const BackgroundMapValue& get_table_value(const std::string& key) const;
+ template<typename T>
+ void put_table_value(const std::string& key, T value) {
+ std::unique_lock cond_lock(table_mutex);
+ rgw_map[key] = value;
+ }
+
+ // update the manager after
+ void set_manager(rgw::sal::LuaManager* _lua_manager);
+ void pause() override;
+ void resume(rgw::sal::Driver* _driver) override;
};
} //namepsace rgw::lua
int rc = 0;
try {
open_standard_libs(L);
- set_package_path(L, s->penv.lua.luarocks_path);
+ set_package_path(L, s->penv.lua.manager->luarocks_path());
create_debug_action(L, s->cct);
plb.add_u64(l_rgw_pubsub_push_pending, "pubsub_push_pending", "Pubsub events pending reply from endpoint");
plb.add_u64_counter(l_rgw_pubsub_missing_conf, "pubsub_missing_conf", "Pubsub events could not be handled because of missing configuration");
- plb.add_u64_counter(l_rgw_lua_script_ok, "lua_script_ok", "Successfull executions of lua scripts");
- plb.add_u64_counter(l_rgw_lua_script_fail, "lua_script_fail", "Failed executions of lua scripts");
+ plb.add_u64_counter(l_rgw_lua_script_ok, "lua_script_ok", "Successfull executions of Lua scripts");
+ plb.add_u64_counter(l_rgw_lua_script_fail, "lua_script_fail", "Failed executions of Lua scripts");
plb.add_u64(l_rgw_lua_current_vms, "lua_current_vms", "Number of Lua VMs currently being executed");
perfcounter = plb.create_perf_counters();
#endif
struct RGWLuaProcessEnv {
- std::string luarocks_path;
rgw::lua::Background* background = nullptr;
std::unique_ptr<rgw::sal::LuaManager> manager;
};
* the dynamic reconfiguration. */
env.auth_registry = rgw::auth::StrategyRegistry::create(
cct, implicit_tenants, env.driver);
- env.lua.manager = env.driver->get_lua_manager();
+ env.lua.manager = env.driver->get_lua_manager(env.lua.manager->luarocks_path());
+ if (env.lua.background) {
+ env.lua.background->set_manager(env.lua.manager.get());
+ }
ldpp_dout(&dp, 1) << "Resuming frontends with new realm configuration." << dendl;
virtual const RGWSyncModuleInstanceRef& get_sync_module() = 0;
/** Get the ID of the current host */
virtual std::string get_host_id() = 0;
- /** Get a Lua script manager for running lua scripts */
- virtual std::unique_ptr<LuaManager> get_lua_manager() = 0;
+ /** Get a Lua script manager for running lua scripts and reloading packages */
+ virtual std::unique_ptr<LuaManager> get_lua_manager(const std::string& luarocks_path) = 0;
/** Get an IAM Role by name etc. */
virtual std::unique_ptr<RGWRole> get_role(std::string name,
std::string tenant,
virtual int remove_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name) = 0;
/** List lua packages */
virtual int list_packages(const DoutPrefixProvider* dpp, optional_yield y, rgw::lua::packages_t& packages) = 0;
+ /** Reload lua packages */
+ virtual int reload_packages(const DoutPrefixProvider* dpp, optional_yield y) = 0;
+ /** Get the path to the loarocks install location **/
+ virtual const std::string& luarocks_path() const = 0;
+ /** Set the path to the loarocks install location **/
+ virtual void set_luarocks_path(const std::string& path) = 0;
};
/** @} namespace rgw::sal in group RGWSAL */
return nullptr;
}
- std::unique_ptr<LuaManager> DBStore::get_lua_manager()
+ std::unique_ptr<LuaManager> DBStore::get_lua_manager(const std::string& luarocks_path)
{
return std::make_unique<DBLuaManager>(this);
}
{
return -ENOENT;
}
+
+ int DBLuaManager::reload_packages(const DoutPrefixProvider* dpp, optional_yield y)
+ {
+ return -ENOENT;
+ }
+
} // namespace rgw::sal
extern "C" {
virtual int remove_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name) override;
/** List lua packages */
virtual int list_packages(const DoutPrefixProvider* dpp, optional_yield y, rgw::lua::packages_t& packages) override;
+ /** Reload lua packages */
+ virtual int reload_packages(const DoutPrefixProvider* dpp, optional_yield y) override;
};
class DBOIDCProvider : public RGWOIDCProvider {
virtual const RGWSyncModuleInstanceRef& get_sync_module() { return sync_module; }
virtual std::string get_host_id() { return ""; }
- virtual std::unique_ptr<LuaManager> get_lua_manager() override;
+ std::unique_ptr<LuaManager> get_lua_manager(const std::string& luarocks_path) override;
virtual std::unique_ptr<RGWRole> get_role(std::string name,
std::string tenant,
std::string path="",
return next->get_sync_module();
}
-std::unique_ptr<LuaManager> FilterDriver::get_lua_manager()
+std::unique_ptr<LuaManager> FilterDriver::get_lua_manager(const std::string& luarocks_path)
{
- std::unique_ptr<LuaManager> nm = next->get_lua_manager();
+ std::unique_ptr<LuaManager> nm = next->get_lua_manager(luarocks_path);
return std::make_unique<FilterLuaManager>(std::move(nm));
}
return next->list_packages(dpp, y, packages);
}
+int FilterLuaManager::reload_packages(const DoutPrefixProvider* dpp, optional_yield y)
+{
+ return next->reload_packages(dpp, y);
+}
+
+const std::string& FilterLuaManager::luarocks_path() const {
+ return next->luarocks_path();
+}
+
+void FilterLuaManager::set_luarocks_path(const std::string& path) {
+ next->set_luarocks_path(path);
+}
+
} } // namespace rgw::sal
extern "C" {
std::string& metadata_key, optional_yield y) override;
virtual const RGWSyncModuleInstanceRef& get_sync_module() override;
virtual std::string get_host_id() override { return next->get_host_id(); }
- virtual std::unique_ptr<LuaManager> get_lua_manager() override;
+ virtual std::unique_ptr<LuaManager> get_lua_manager(const std::string& luarocks_path) override;
virtual std::unique_ptr<RGWRole> get_role(std::string name,
std::string tenant,
std::string path="",
virtual int add_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name) override;
virtual int remove_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name) override;
virtual int list_packages(const DoutPrefixProvider* dpp, optional_yield y, rgw::lua::packages_t& packages) override;
+ virtual int reload_packages(const DoutPrefixProvider* dpp, optional_yield y) override;
+ const std::string& luarocks_path() const override;
+ void set_luarocks_path(const std::string& path) override;
+
};
} } // namespace rgw::sal
};
class StoreLuaManager : public LuaManager {
+protected:
+ std::string _luarocks_path;
public:
+ const std::string& luarocks_path() const override {
+ return _luarocks_path;
+ }
+ void set_luarocks_path(const std::string& path) override {
+ _luarocks_path = path;
+ }
+ StoreLuaManager() = default;
+ StoreLuaManager(const std::string& __luarocks_path) :
+ _luarocks_path(__luarocks_path) {}
virtual ~StoreLuaManager() = default;
};
topic get get a bucket notifications topic
topic rm remove a bucket notifications topic
topic stats get a bucket notifications persistent topic stats (i.e. reservations, entries & size)
- script put upload a lua script to a context
- script get get the lua script of a context
- script rm remove the lua scripts of a context
- script-package add add a lua package to the scripts allowlist
- script-package rm remove a lua package from the scripts allowlist
- script-package list get the lua packages allowlist
+ script put upload a Lua script to a context
+ script get get the Lua script of a context
+ script rm remove the Lua scripts of a context
+ script-package add add a Lua package to the scripts allowlist
+ script-package rm remove a Lua package from the scripts allowlist
+ script-package list get the Lua packages allowlist
+ script-package reload install/remove Lua packages according to allowlist
notification list list bucket notifications configuration
notification get get a bucket notifications configuration
notification rm remove a bucket notifications configuration
Script options:
--context context in which the script runs. one of: prerequest, postrequest, background, getdata, putdata
- --package name of the lua package that should be added/removed to/from the allowlist
+ --package name of the Lua package that should be added/removed to/from the allowlist
--allow-compilation package is allowed to compile C code as part of its installation
Bucket check olh/unlinked options:
tracing::Tracer tracer;
-#define DEFINE_REQ_STATE RGWProcessEnv pe; RGWEnv e; req_state s(g_cct, pe, &e, 0);
+#define MAKE_STORE auto store = std::unique_ptr<sal::RadosStore>(new sal::RadosStore); \
+ store->setRados(new RGWRados);
+
+#define DEFINE_REQ_STATE RGWProcessEnv pe; \
+ MAKE_STORE; \
+ pe.lua.manager = store->get_lua_manager(""); \
+ RGWEnv e; \
+ req_state s(g_cct, pe, &e, 0);
+
#define INIT_TRACE tracer.init(g_cct, "test"); \
s.trace = tracer.start_trace("test", true);
ASSERT_NE(rc, 0);
}
-#define MAKE_STORE auto store = std::unique_ptr<sal::RadosStore>(new sal::RadosStore); \
- store->setRados(new RGWRados);
-
TEST(TestRGWLua, OpsLog)
{
const std::string script = R"(
end
)";
- MAKE_STORE;
-
struct MockOpsLogSink : OpsLogSink {
bool logged = false;
int log(req_state*, rgw_log_entry&) override { logged = true; return 0; }
}
public:
- TestBackground(sal::RadosStore* store, const std::string& script, unsigned read_time = 0) :
- rgw::lua::Background(store, g_cct, "", /* luarocks path */ 1 /* run every second */),
+ TestBackground(sal::RadosStore* store, const std::string& script, rgw::sal::LuaManager* manager, unsigned read_time = 0) :
+ rgw::lua::Background(store,
+ g_cct,
+ manager,
+ 1 /* run every second */),
read_time(read_time) {
// the script is passed in the constructor
rgw_script = script;
TEST(TestRGWLuaBackground, Start)
{
MAKE_STORE;
+ auto manager = store->get_lua_manager("");
{
// ctr and dtor without running
- TestBackground lua_background(store.get(), "");
+ TestBackground lua_background(store.get(), "", manager.get());
}
{
// ctr and dtor with running
- TestBackground lua_background(store.get(), "");
+ TestBackground lua_background(store.get(), "", manager.get());
lua_background.start();
}
}
)";
MAKE_STORE;
- TestBackground lua_background(store.get(), script);
+ auto manager = store->get_lua_manager("");
+ TestBackground lua_background(store.get(), script, manager.get());
lua_background.start();
std::this_thread::sleep_for(wait_time);
EXPECT_EQ(get_table_value<std::string>(lua_background, "hello"), "world");
RGW[key] = value
)";
- MAKE_STORE;
- TestBackground lua_background(store.get(), background_script);
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), background_script, pe.lua.manager.get());
lua_background.start();
std::this_thread::sleep_for(wait_time);
RGW[key] = value
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
// to make sure test is consistent we have to puase the background
)";
MAKE_STORE;
- TestBackground lua_background(store.get(), script);
+ auto manager = store->get_lua_manager("");
+ TestBackground lua_background(store.get(), script, manager.get());
lua_background.start();
std::this_thread::sleep_for(wait_time);
const auto value_len = get_table_value<std::string>(lua_background, "hello").size();
)";
MAKE_STORE;
- constexpr auto long_wait_time = std::chrono::seconds(6);
- TestBackground lua_background(store.get(), script, 2);
+ auto manager = store->get_lua_manager("");
+ TestBackground lua_background(store.get(), script, manager.get(), 2);
lua_background.start();
+ constexpr auto long_wait_time = std::chrono::seconds(6);
std::this_thread::sleep_for(long_wait_time);
const auto value_len = get_table_value<std::string>(lua_background, "hello").size();
EXPECT_GT(value_len, 0);
)";
MAKE_STORE;
- TestBackground lua_background(store.get(), script);
+ auto manager = store->get_lua_manager("");
+ TestBackground lua_background(store.get(), script, manager.get());
lua_background.pause();
lua_background.start();
std::this_thread::sleep_for(wait_time);
)";
MAKE_STORE;
- TestBackground lua_background(store.get(), script);
+ auto manager = store->get_lua_manager("");
+ TestBackground lua_background(store.get(), script, manager.get());
lua_background.start();
std::this_thread::sleep_for(wait_time);
const auto value_len = get_table_value<std::string>(lua_background, "hello").size();
)";
MAKE_STORE;
- TestBackground lua_background(store.get(), script);
+ auto manager = store->get_lua_manager("");
+ TestBackground lua_background(store.get(), script, manager.get());
lua_background.start();
std::this_thread::sleep_for(wait_time);
const auto value_len = get_table_value<std::string>(lua_background, "hello").size();
TEST(TestRGWLuaBackground, TableValues)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
const std::string request_script = R"(
RGW["key1"] = "string value"
RGW["key4"] = true
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TablePersist)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
std::string request_script = R"(
RGW["key1"] = "string value"
RGW["key2"] = 42
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TableValuesFromRequest)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
lua_background.start();
const std::string request_script = R"(
RGW["key4"] = Request.Tags["key1"] == Request.Tags["key2"]
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
s.tagset.add_tag("key1", "val1");
TEST(TestRGWLuaBackground, TableInvalidValue)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
lua_background.start();
const std::string request_script = R"(
RGW["key5"] = Request.Tags
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
s.tagset.add_tag("key1", "val1");
s.tagset.add_tag("key2", "val2");
TEST(TestRGWLuaBackground, TableErase)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
std::string request_script = R"(
RGW["size"] = 0
RGW["size"] = #RGW
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TableIterate)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
const std::string request_script = R"(
RGW["key1"] = "string value"
end
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TableIterateWrite)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
const std::string request_script = R"(
RGW["a"] = 1
assert(counter == 4)
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TableIncrement)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
const std::string request_script = R"(
RGW["key1"] = 42
assert(RGW["key2"] == 43.2)
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TableIncrementBy)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
const std::string request_script = R"(
RGW["key1"] = 42
assert(RGW["key1"] == 52.2)
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TableDecrement)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
const std::string request_script = R"(
RGW["key1"] = 42
assert(RGW["key2"] == 41.2)
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TableDecrementBy)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
const std::string request_script = R"(
RGW["key1"] = 42
assert(RGW["key1"] == 31.2)
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TableIncrementValueError)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
std::string request_script = R"(
-- cannot increment string values
RGW.increment("key1")
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
TEST(TestRGWLuaBackground, TableIncrementError)
{
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
+ DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
std::string request_script = R"(
-- missing argument
RGW.increment()
)";
- DEFINE_REQ_STATE;
pe.lua.background = &lua_background;
auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
assert(Offset == 12345678)
)";
- MAKE_STORE;
- TestBackground lua_background(store.get(), "");
DEFINE_REQ_STATE;
+ TestBackground lua_background(store.get(), "", pe.lua.manager.get());
s.host_id = "foo";
pe.lua.background = &lua_background;
lua::RGWObjFilter filter(&s, script);