summaryrefslogtreecommitdiffstats
path: root/src/rgw
diff options
context:
space:
mode:
authorYuval Lifshitz <ylifshit@ibm.com>2023-07-05 20:33:55 +0200
committerYuval Lifshitz <ylifshit@redhat.com>2023-10-06 11:54:56 +0200
commit7a11f1d574266d66239c7ea6b49130606ed810a0 (patch)
treed6a7049a2caa14c8343e71a02c1873e58333a90b /src/rgw
parentrgw/lua: install lua packages in temp directory (diff)
downloadceph-7a11f1d574266d66239c7ea6b49130606ed810a0.tar.xz
ceph-7a11f1d574266d66239c7ea6b49130606ed810a0.zip
rgw/lua/doc: support reloading lua packages on all RGWs
without requiring a restart of the RGWs test instructions: https://gist.github.com/yuvalif/95b8ed9ea73ab4591c59644a050e01e2 also use capitalized "Lua" in logs/doc Signed-off-by: Yuval Lifshitz <ylifshit@ibm.com>
Diffstat (limited to 'src/rgw')
-rw-r--r--src/rgw/driver/daos/rgw_sal_daos.cc4
-rw-r--r--src/rgw/driver/daos/rgw_sal_daos.h2
-rw-r--r--src/rgw/driver/motr/rgw_sal_motr.cc9
-rw-r--r--src/rgw/driver/motr/rgw_sal_motr.h4
-rw-r--r--src/rgw/driver/rados/rgw_sal_rados.cc226
-rw-r--r--src/rgw/driver/rados/rgw_sal_rados.h44
-rw-r--r--src/rgw/rgw_admin.cc55
-rw-r--r--src/rgw/rgw_appmain.cc17
-rw-r--r--src/rgw/rgw_lua.cc44
-rw-r--r--src/rgw/rgw_lua.h4
-rw-r--r--src/rgw/rgw_lua_background.cc28
-rw-r--r--src/rgw/rgw_lua_background.h42
-rw-r--r--src/rgw/rgw_lua_request.cc2
-rw-r--r--src/rgw/rgw_perf_counters.cc4
-rw-r--r--src/rgw/rgw_process_env.h1
-rw-r--r--src/rgw/rgw_realm_reloader.cc5
-rw-r--r--src/rgw/rgw_sal.h10
-rw-r--r--src/rgw/rgw_sal_dbstore.cc8
-rw-r--r--src/rgw/rgw_sal_dbstore.h4
-rw-r--r--src/rgw/rgw_sal_filter.cc17
-rw-r--r--src/rgw/rgw_sal_filter.h6
-rw-r--r--src/rgw/rgw_sal_store.h11
22 files changed, 394 insertions, 153 deletions
diff --git a/src/rgw/driver/daos/rgw_sal_daos.cc b/src/rgw/driver/daos/rgw_sal_daos.cc
index ebd6957d884..46db3dd654c 100644
--- a/src/rgw/driver/daos/rgw_sal_daos.cc
+++ b/src/rgw/driver/daos/rgw_sal_daos.cc
@@ -880,8 +880,8 @@ const std::string& DaosZone::get_current_period_id() {
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,
diff --git a/src/rgw/driver/daos/rgw_sal_daos.h b/src/rgw/driver/daos/rgw_sal_daos.h
index d8f1d276da2..0eaf495d2e2 100644
--- a/src/rgw/driver/daos/rgw_sal_daos.h
+++ b/src/rgw/driver/daos/rgw_sal_daos.h
@@ -997,7 +997,7 @@ class DaosStore : public StoreDriver {
}
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 = "",
diff --git a/src/rgw/driver/motr/rgw_sal_motr.cc b/src/rgw/driver/motr/rgw_sal_motr.cc
index c0dff1c1f9f..06df127594e 100644
--- a/src/rgw/driver/motr/rgw_sal_motr.cc
+++ b/src/rgw/driver/motr/rgw_sal_motr.cc
@@ -1151,9 +1151,9 @@ const std::string& MotrZone::get_current_period_id()
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)
@@ -3901,6 +3901,11 @@ int MotrStore::init_metadata_cache(const DoutPrefixProvider *dpp,
{
return -ENOENT;
}
+
+ int MotrLuaManager::reload_packages(const DoutPrefixProvider* dpp, optional_yield y)
+ {
+ return -ENOENT;
+ }
} // namespace rgw::sal
extern "C" {
diff --git a/src/rgw/driver/motr/rgw_sal_motr.h b/src/rgw/driver/motr/rgw_sal_motr.h
index c9e6fab6a0f..eee843d7eff 100644
--- a/src/rgw/driver/motr/rgw_sal_motr.h
+++ b/src/rgw/driver/motr/rgw_sal_motr.h
@@ -559,6 +559,8 @@ class MotrLuaManager : public StoreLuaManager {
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 {
@@ -1047,7 +1049,7 @@ class MotrStore : public StoreDriver {
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="",
diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc
index ffbfb65dacd..0c24a36a0a5 100644
--- a/src/rgw/driver/rados/rgw_sal_rados.cc
+++ b/src/rgw/driver/rados/rgw_sal_rados.cc
@@ -853,7 +853,7 @@ int RadosBucket::set_acl(const DoutPrefixProvider* dpp, RGWAccessControlPolicy &
cerr << "ERROR: failed to set bucket owner: " << cpp_strerror(-r) << std::endl;
return r;
}
-
+
return 0;
}
@@ -1003,8 +1003,8 @@ std::string RadosBucket::topics_oid() const {
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();
@@ -1030,7 +1030,7 @@ int RadosBucket::read_topics(rgw_pubsub_bucket_topics& notifications,
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;
}
@@ -1049,14 +1049,14 @@ int RadosBucket::write_topics(const rgw_pubsub_bucket_topics& notifications,
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);
@@ -1337,7 +1337,7 @@ int RadosStore::read_topics(const std::string& tenant, rgw_pubsub_topics& topics
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;
}
@@ -1351,14 +1351,14 @@ int RadosStore::write_topics(const std::string& tenant, const rgw_pubsub_topics&
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);
@@ -1515,9 +1515,9 @@ void RadosStore::register_admin_apis(RGWRESTMgr* mgr)
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,
@@ -2479,7 +2479,7 @@ int RadosMultipartUpload::abort(const DoutPrefixProvider *dpp, CephContext *cct,
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;
@@ -2748,9 +2748,9 @@ int RadosMultipartUpload::complete(const DoutPrefixProvider *dpp,
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)
@@ -2764,7 +2764,7 @@ int RadosMultipartUpload::complete(const DoutPrefixProvider *dpp,
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;
@@ -3318,15 +3318,18 @@ RGWBucketSyncPolicyHandlerRef RadosZone::get_sync_policy_handler()
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;
@@ -3349,7 +3352,7 @@ int RadosLuaManager::get_script(const DoutPrefixProvider* dpp, optional_yield y,
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;
@@ -3366,7 +3369,7 @@ int RadosLuaManager::put_script(const DoutPrefixProvider* dpp, optional_yield y,
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);
@@ -3381,28 +3384,31 @@ const std::string PACKAGE_LIST_OBJECT_NAME = "lua_package_allowlist";
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;
@@ -3419,7 +3425,7 @@ int RadosLuaManager::remove_package(const DoutPrefixProvider *dpp, optional_yiel
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;
@@ -3431,6 +3437,10 @@ int RadosLuaManager::remove_package(const DoutPrefixProvider *dpp, optional_yiel
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;
@@ -3439,7 +3449,7 @@ int RadosLuaManager::list_packages(const DoutPrefixProvider *dpp, optional_yield
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) {
@@ -3452,6 +3462,162 @@ int RadosLuaManager::list_packages(const DoutPrefixProvider *dpp, optional_yield
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;
diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h
index 75d4be843de..228ba532869 100644
--- a/src/rgw/driver/rados/rgw_sal_rados.h
+++ b/src/rgw/driver/rados/rgw_sal_rados.h
@@ -198,7 +198,7 @@ class RadosStore : public StoreDriver {
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="",
@@ -889,19 +889,43 @@ public:
};
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 {
diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc
index 0b82da7774f..a4e17b8895a 100644
--- a/src/rgw/rgw_admin.cc
+++ b/src/rgw/rgw_admin.cc
@@ -316,12 +316,13 @@ void usage()
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";
@@ -493,7 +494,7 @@ void usage()
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";
@@ -857,7 +858,8 @@ enum class OPT {
SCRIPT_RM,
SCRIPT_PACKAGE_ADD,
SCRIPT_PACKAGE_RM,
- SCRIPT_PACKAGE_LIST
+ SCRIPT_PACKAGE_LIST,
+ SCRIPT_PACKAGE_RELOAD
};
}
@@ -1096,6 +1098,7 @@ static SimpleCmd::Commands all_cmds = {
{ "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 = {
@@ -10732,7 +10735,7 @@ next:
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;
@@ -10750,7 +10753,7 @@ next:
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) {
@@ -10774,7 +10777,7 @@ next:
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;
@@ -10785,16 +10788,16 @@ next:
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
}
@@ -10802,7 +10805,7 @@ next:
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);
@@ -10811,11 +10814,11 @@ next:
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
}
@@ -10825,9 +10828,9 @@ next:
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) {
@@ -10835,11 +10838,23 @@ next:
}
}
#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;
}
diff --git a/src/rgw/rgw_appmain.cc b/src/rgw/rgw_appmain.cc
index 5eaf03e5793..57a1a16783a 100644
--- a/src/rgw/rgw_appmain.cc
+++ b/src/rgw/rgw_appmain.cc
@@ -550,29 +550,29 @@ void rgw::AppMain::init_lua()
{
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 */
@@ -580,6 +580,7 @@ void rgw::AppMain::shutdown(std::function<void(void)> finalize_async_signals)
{
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) {
diff --git a/src/rgw/rgw_lua.cc b/src/rgw/rgw_lua.cc
index 505c5fc25cd..6a5780a3eb1 100644
--- a/src/rgw/rgw_lua.cc
+++ b/src/rgw/rgw_lua.cc
@@ -97,7 +97,7 @@ int delete_script(const DoutPrefixProvider *dpp, sal::LuaManager* manager, const
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");
@@ -133,25 +133,19 @@ int add_package(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, optiona
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;
@@ -244,34 +238,14 @@ int install_packages(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver,
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
}
diff --git a/src/rgw/rgw_lua.h b/src/rgw/rgw_lua.h
index e8962aba6c4..30b3272c4e4 100644
--- a/src/rgw/rgw_lua.h
+++ b/src/rgw/rgw_lua.h
@@ -57,6 +57,9 @@ int remove_package(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, opti
// 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
@@ -64,6 +67,7 @@ int install_packages(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver,
optional_yield y, const std::string& luarocks_path,
packages_t& failed_packages,
std::string& install_dir);
+
#endif
}
diff --git a/src/rgw/rgw_lua_background.cc b/src/rgw/rgw_lua_background.cc
index 16a6ca5b4d8..93c509a78cc 100644
--- a/src/rgw/rgw_lua_background.cc
+++ b/src/rgw/rgw_lua_background.cc
@@ -56,15 +56,15 @@ int RGWTable::increment_by(lua_State* L) {
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;
@@ -97,7 +97,6 @@ void Background::pause() {
}
void Background::resume(rgw::sal::Driver* driver) {
- lua_manager = driver->get_lua_manager();
paused = false;
cond.notify_all();
}
@@ -108,7 +107,7 @@ int Background::read_script() {
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;
@@ -135,7 +134,7 @@ void Background::run() {
}
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) {
@@ -155,6 +154,7 @@ void Background::run() {
}
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
@@ -190,5 +190,9 @@ void Background::create_background_metatable(lua_State* L) {
ceph_assert(lua_istable(L, -1));
}
+void Background::set_manager(rgw::sal::LuaManager* _lua_manager) {
+ lua_manager = _lua_manager;
+}
+
} //namespace rgw::lua
diff --git a/src/rgw/rgw_lua_background.h b/src/rgw/rgw_lua_background.h
index dbca399a695..e2f290213b5 100644
--- a/src/rgw/rgw_lua_background.h
+++ b/src/rgw/rgw_lua_background.h
@@ -135,6 +135,7 @@ struct RGWTable : EmptyMetaTable {
class Background : public RGWRealmReloader::Pauser {
public:
static const BackgroundMapValue empty_table_value;
+
private:
BackgroundMap rgw_map;
bool stopped = false;
@@ -142,9 +143,8 @@ private:
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;
@@ -158,24 +158,26 @@ protected:
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
diff --git a/src/rgw/rgw_lua_request.cc b/src/rgw/rgw_lua_request.cc
index cfbf511aac2..058384929b3 100644
--- a/src/rgw/rgw_lua_request.cc
+++ b/src/rgw/rgw_lua_request.cc
@@ -784,7 +784,7 @@ int execute(
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);
diff --git a/src/rgw/rgw_perf_counters.cc b/src/rgw/rgw_perf_counters.cc
index fd058ab00a9..6757dd8913c 100644
--- a/src/rgw/rgw_perf_counters.cc
+++ b/src/rgw/rgw_perf_counters.cc
@@ -60,8 +60,8 @@ int rgw_perf_start(CephContext *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();
diff --git a/src/rgw/rgw_process_env.h b/src/rgw/rgw_process_env.h
index 905c0a5411c..710340f0a25 100644
--- a/src/rgw/rgw_process_env.h
+++ b/src/rgw/rgw_process_env.h
@@ -32,7 +32,6 @@ namespace rgw::flight {
#endif
struct RGWLuaProcessEnv {
- std::string luarocks_path;
rgw::lua::Background* background = nullptr;
std::unique_ptr<rgw::sal::LuaManager> manager;
};
diff --git a/src/rgw/rgw_realm_reloader.cc b/src/rgw/rgw_realm_reloader.cc
index 4973ec14080..745dac7fefe 100644
--- a/src/rgw/rgw_realm_reloader.cc
+++ b/src/rgw/rgw_realm_reloader.cc
@@ -183,7 +183,10 @@ void RGWRealmReloader::reload()
* 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;
diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h
index 6b54067fb4c..84731f333d7 100644
--- a/src/rgw/rgw_sal.h
+++ b/src/rgw/rgw_sal.h
@@ -396,8 +396,8 @@ class Driver {
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,
@@ -1514,6 +1514,12 @@ public:
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 */
diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc
index c640c5bfe8c..aa1243fe598 100644
--- a/src/rgw/rgw_sal_dbstore.cc
+++ b/src/rgw/rgw_sal_dbstore.cc
@@ -596,7 +596,7 @@ namespace rgw::sal {
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);
}
@@ -1986,6 +1986,12 @@ namespace rgw::sal {
{
return -ENOENT;
}
+
+ int DBLuaManager::reload_packages(const DoutPrefixProvider* dpp, optional_yield y)
+ {
+ return -ENOENT;
+ }
+
} // namespace rgw::sal
extern "C" {
diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h
index ed56e8c1149..65ffd909109 100644
--- a/src/rgw/rgw_sal_dbstore.h
+++ b/src/rgw/rgw_sal_dbstore.h
@@ -368,6 +368,8 @@ protected:
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 {
@@ -843,7 +845,7 @@ public:
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="",
diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc
index 6980cd01cd1..13e9155c524 100644
--- a/src/rgw/rgw_sal_filter.cc
+++ b/src/rgw/rgw_sal_filter.cc
@@ -432,9 +432,9 @@ const RGWSyncModuleInstanceRef& FilterDriver::get_sync_module()
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));
}
@@ -1319,6 +1319,19 @@ int FilterLuaManager::list_packages(const DoutPrefixProvider* dpp, optional_yiel
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" {
diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h
index 5011b89df61..6db44a19100 100644
--- a/src/rgw/rgw_sal_filter.h
+++ b/src/rgw/rgw_sal_filter.h
@@ -264,7 +264,7 @@ public:
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="",
@@ -896,6 +896,10 @@ public:
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
diff --git a/src/rgw/rgw_sal_store.h b/src/rgw/rgw_sal_store.h
index 124debdb7b4..f5efdc3494f 100644
--- a/src/rgw/rgw_sal_store.h
+++ b/src/rgw/rgw_sal_store.h
@@ -410,7 +410,18 @@ class StoreZone : public Zone {
};
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;
};