]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/lua/doc: support reloading lua packages on all RGWs 52326/head
authorYuval Lifshitz <ylifshit@ibm.com>
Wed, 5 Jul 2023 18:33:55 +0000 (18:33 +0000)
committerYuval Lifshitz <ylifshit@redhat.com>
Fri, 6 Oct 2023 09:54:56 +0000 (12:54 +0300)
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>
25 files changed:
doc/radosgw/lua-scripting.rst
src/rgw/driver/daos/rgw_sal_daos.cc
src/rgw/driver/daos/rgw_sal_daos.h
src/rgw/driver/motr/rgw_sal_motr.cc
src/rgw/driver/motr/rgw_sal_motr.h
src/rgw/driver/rados/rgw_sal_rados.cc
src/rgw/driver/rados/rgw_sal_rados.h
src/rgw/rgw_admin.cc
src/rgw/rgw_appmain.cc
src/rgw/rgw_lua.cc
src/rgw/rgw_lua.h
src/rgw/rgw_lua_background.cc
src/rgw/rgw_lua_background.h
src/rgw/rgw_lua_request.cc
src/rgw/rgw_perf_counters.cc
src/rgw/rgw_process_env.h
src/rgw/rgw_realm_reloader.cc
src/rgw/rgw_sal.h
src/rgw/rgw_sal_dbstore.cc
src/rgw/rgw_sal_dbstore.h
src/rgw/rgw_sal_filter.cc
src/rgw/rgw_sal_filter.h
src/rgw/rgw_sal_store.h
src/test/cli/radosgw-admin/help.t
src/test/rgw/test_rgw_lua.cc

index 9f32dac1a49717cfe960c463b27f30a8c1f34d98..29cba258efecc87ae92f6b518fc18b20f2924e1d 100644 (file)
@@ -23,7 +23,8 @@ To change this default value, use the ``rgw_lua_max_memory_per_state`` configura
 
 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. 
@@ -116,6 +117,13 @@ To print the list of packages in the allowlist:
   # radosgw-admin script-package list
 
 
+To apply changes from the allowlist to all RGWs:
+
+::
+
+  # radosgw-admin script-package reload
+
+
 Context Free Functions
 ----------------------
 Debug Log
index ebd6957d884b222ac95a36d6f1232345acd03eb3..46db3dd654ca1d2c9d7d0e78af90fdf5a5e900cd 100644 (file)
@@ -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,
index d8f1d276da2d12fde021fd05157839c205543b47..0eaf495d2e2beeeaceffa1e9e0ed63c7e74bdc58 100644 (file)
@@ -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 = "",
index c0dff1c1f9f25dccdc508554ef1b4c2a62fa7a73..06df127594e76a6bbe6998458b35ac0abb799ac4 100644 (file)
@@ -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" {
index c9e6fab6a0f4fa773f6fe320b1aca9bb40b066f7..eee843d7effacb14a9b973bbb28722aba7f9170b 100644 (file)
@@ -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="",
index ffbfb65dacdbc0cade5da86c91d44b7e6c93f0a2..0c24a36a0a5866b91a28db4a290464c783adc542 100644 (file)
@@ -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;
index 75d4be843debc9c06a0242a4800bab7fbbdbbcd3..228ba532869c0e98e7d353b4055e9ef8e844d262 100644 (file)
@@ -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 {
index 0b82da7774fe8bd32143cbca7bc34fb88c5b579a..a4e17b8895ae80619947fc2ddb239ec1c8c76b82 100644 (file)
@@ -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;
 }
 
index 5eaf03e5793e91dbd6c8e040a96b882ef4520bad..57a1a16783a9ff862637c153a8cd01c802d94fd5 100644 (file)
@@ -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) {
index 505c5fc25cd61a58a6ceda263a52d0a50f715e2d..6a5780a3eb1c59c16676ac18c4a84449e317369d 100644 (file)
@@ -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 DoutPrefixProviderdpp, 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
 
 }
index e8962aba6c44d614a11316cac2559c5c7a99e64b..30b3272c4e48a2e113f5c08f39a35efbcc9f7940 100644 (file)
@@ -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
 }
 
index 16a6ca5b4d81ea356c4d28d2c38524959ea63c19..93c509a78cc78d873d52752d51612da0adea30d7 100644 (file)
@@ -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
 
index dbca399a6957d6a7a328f441f3cbdc0f9c84b970..e2f290213b5cfdb1d52d92bf12584f22f87f9fd9 100644 (file)
@@ -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
index cfbf511aac24a39ad2dedbb0f1f756d97c77ec00..058384929b3cb5bf93cede6639a0f34f37bc46e4 100644 (file)
@@ -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);  
   
index fd058ab00a9f226eb44ecaabbb0303ee62301047..6757dd8913cf3c6a46f9762f7b9bd1dc9548a9f9 100644 (file)
@@ -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();
index 905c0a5411c1b8759e18cf028a5cd90d4ffe466d..710340f0a259b6ca3558c8de0b86960d5acffcde 100644 (file)
@@ -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;
 };
index 4973ec14080d272b3bc67f6d04cb8a71043382c3..745dac7fefe477e060bcca185e7110a29de3104a 100644 (file)
@@ -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;
 
index 6b54067fb4c214fe65208a2d2946edee8b5923f4..84731f333d72b3c0ccf7e277df5c1feeb94e519d 100644 (file)
@@ -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 */
index c640c5bfe8cb67eb938d393c93c2a11302c16c23..aa1243fe59825d69d55df2ca3078ba701ee8e0a8 100644 (file)
@@ -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" {
index ed56e8c114969c3f352a1f61cd0d267f64e54320..65ffd9091093486663ad4551b56201a8359bebb4 100644 (file)
@@ -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="",
index 6980cd01cd19ccdbb7ee6f9c1d99bac5e1b25323..13e9155c524b063df6e15cf146124687a0913ab7 100644 (file)
@@ -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" {
index 5011b89df61a3fde6fb8302df600e9019987ec30..6db44a191003f653198b295c6c874ceea461f47f 100644 (file)
@@ -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
index 124debdb7b433fe11ea97141875beb0ceaa6f473..f5efdc3494fe8e678832b21490343ad7f5b71e00 100644 (file)
@@ -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;
 };
 
index 8762c43c5c98bc90cab1092b8d79e36c33c8d824..179094dc4b548bee41f9094829d16008e341df65 100644 (file)
     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:
index 9eca926e30f2d0c793ede698149f5810368f8bb8..e8656ac8e39e6f3ccad4e3c5ba9582f960e4b7a7 100644 (file)
@@ -163,7 +163,15 @@ CctCleaner cleaner(g_cct);
 
 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);
 
@@ -775,9 +783,6 @@ TEST(TestRGWLua, NotAllowedInLib)
   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"(
@@ -789,8 +794,6 @@ TEST(TestRGWLua, OpsLog)
                end
   )";
 
-  MAKE_STORE;
-
   struct MockOpsLogSink : OpsLogSink {
     bool logged = false;
     int log(req_state*, rgw_log_entry&) override { logged = true; return 0; }
@@ -840,8 +843,11 @@ protected:
   }
 
 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;
@@ -855,13 +861,14 @@ public:
 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();
   }
 }
@@ -888,7 +895,8 @@ TEST(TestRGWLuaBackground, Script)
   )";
 
   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");
@@ -902,8 +910,8 @@ TEST(TestRGWLuaBackground, RequestScript)
     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);
 
@@ -914,7 +922,6 @@ TEST(TestRGWLuaBackground, RequestScript)
     RGW[key] = value
   )";
 
-  DEFINE_REQ_STATE;
   pe.lua.background = &lua_background;
 
   // to make sure test is consistent we have to puase the background
@@ -941,7 +948,8 @@ TEST(TestRGWLuaBackground, Pause)
   )";
 
   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();
@@ -966,9 +974,10 @@ TEST(TestRGWLuaBackground, PauseWhileReading)
   )";
 
   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);
@@ -987,7 +996,8 @@ TEST(TestRGWLuaBackground, ReadWhilePaused)
   )";
 
   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);
@@ -1010,7 +1020,8 @@ TEST(TestRGWLuaBackground, PauseResume)
   )";
 
   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();
@@ -1038,7 +1049,8 @@ TEST(TestRGWLuaBackground, MultipleStarts)
   )";
 
   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();
@@ -1055,8 +1067,8 @@ TEST(TestRGWLuaBackground, MultipleStarts)
 
 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"
@@ -1065,7 +1077,6 @@ TEST(TestRGWLuaBackground, TableValues)
     RGW["key4"] = true
   )";
 
-  DEFINE_REQ_STATE;
   pe.lua.background = &lua_background;
 
   const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
@@ -1078,15 +1089,14 @@ TEST(TestRGWLuaBackground, TableValues)
 
 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);
@@ -1109,8 +1119,8 @@ TEST(TestRGWLuaBackground, TablePersist)
 
 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"(
@@ -1120,7 +1130,6 @@ TEST(TestRGWLuaBackground, TableValuesFromRequest)
     RGW["key4"] = Request.Tags["key1"] == Request.Tags["key2"] 
   )";
 
-  DEFINE_REQ_STATE;
   pe.lua.background = &lua_background;
 
   s.tagset.add_tag("key1", "val1");
@@ -1138,8 +1147,8 @@ TEST(TestRGWLuaBackground, TableValuesFromRequest)
 
 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"(
@@ -1150,7 +1159,6 @@ TEST(TestRGWLuaBackground, TableInvalidValue)
     RGW["key5"] = Request.Tags
   )";
 
-  DEFINE_REQ_STATE;
   pe.lua.background = &lua_background;
   s.tagset.add_tag("key1", "val1");
   s.tagset.add_tag("key2", "val2");
@@ -1165,8 +1173,8 @@ TEST(TestRGWLuaBackground, TableInvalidValue)
 
 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
@@ -1176,7 +1184,6 @@ TEST(TestRGWLuaBackground, TableErase)
     RGW["size"] = #RGW
   )";
 
-  DEFINE_REQ_STATE;
   pe.lua.background = &lua_background;
 
   auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
@@ -1204,8 +1211,8 @@ TEST(TestRGWLuaBackground, TableErase)
 
 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"
@@ -1218,7 +1225,6 @@ TEST(TestRGWLuaBackground, TableIterate)
     end
   )";
 
-  DEFINE_REQ_STATE;
   pe.lua.background = &lua_background;
 
   const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
@@ -1232,8 +1238,8 @@ TEST(TestRGWLuaBackground, TableIterate)
 
 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
@@ -1253,7 +1259,6 @@ TEST(TestRGWLuaBackground, TableIterateWrite)
     assert(counter == 4)
   )";
 
-  DEFINE_REQ_STATE;
   pe.lua.background = &lua_background;
 
   const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
@@ -1263,8 +1268,8 @@ TEST(TestRGWLuaBackground, TableIterateWrite)
 
 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
@@ -1275,7 +1280,6 @@ TEST(TestRGWLuaBackground, TableIncrement)
     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);
@@ -1284,8 +1288,8 @@ TEST(TestRGWLuaBackground, TableIncrement)
 
 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
@@ -1298,7 +1302,6 @@ TEST(TestRGWLuaBackground, TableIncrementBy)
     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);
@@ -1307,8 +1310,8 @@ TEST(TestRGWLuaBackground, TableIncrementBy)
 
 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
@@ -1319,7 +1322,6 @@ TEST(TestRGWLuaBackground, TableDecrement)
     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);
@@ -1328,8 +1330,8 @@ TEST(TestRGWLuaBackground, TableDecrement)
 
 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
@@ -1342,7 +1344,6 @@ TEST(TestRGWLuaBackground, TableDecrementBy)
     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);
@@ -1351,8 +1352,8 @@ TEST(TestRGWLuaBackground, TableDecrementBy)
 
 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
@@ -1360,7 +1361,6 @@ TEST(TestRGWLuaBackground, TableIncrementValueError)
     RGW.increment("key1")
   )";
 
-  DEFINE_REQ_STATE;
   pe.lua.background = &lua_background;
 
   auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
@@ -1387,8 +1387,8 @@ TEST(TestRGWLuaBackground, TableIncrementValueError)
 
 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
@@ -1396,7 +1396,6 @@ TEST(TestRGWLuaBackground, TableIncrementError)
     RGW.increment()
   )";
 
-  DEFINE_REQ_STATE;
   pe.lua.background = &lua_background;
 
   auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, request_script);
@@ -1477,9 +1476,8 @@ TEST(TestRGWLua, Data)
     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);