// Copyright 2022, DragonflyDB authors. All rights reserved. // See LICENSE for licensing terms. // #include "server/script_mgr.h" #include #include #include #include #include #include #include #include #include "base/flags.h" #include "base/logging.h" #include "core/interpreter.h" #include "facade/error.h" #include "server/engine_shard_set.h" #include "server/server_state.h" #include "server/transaction.h" ABSL_FLAG(std::string, default_lua_flags, "", "Configure default flags for running Lua scripts: \n - Use 'allow-undeclared-keys' to " "allow accessing undeclared keys, \n - Use 'disable-atomicity' to allow " "running scripts non-atomically. \nSpecify multiple values " "separated by space, for example 'allow-undeclared-keys disable-atomicity' runs scripts " "non-atomically and allows accessing undeclared keys"); ABSL_FLAG( bool, lua_auto_async, false, "If enabled, call/pcall with discarded values are automatically replaced with acall/apcall."); ABSL_FLAG(bool, lua_allow_undeclared_auto_correct, false, "If enabled, when a script that is not allowed to run with undeclared keys is trying to " "access undeclared keys, automaticaly set the script flag to be able to run with " "undeclared key."); ABSL_FLAG( std::vector, lua_undeclared_keys_shas, std::vector({ "351130589c64523cb98978dc32c64173a31244f3", // Sidekiq, see #2442 "6ae15ef4678593dc61f991c9953722d67d822776", // Sidekiq, see #2442 }), "Comma-separated list of Lua script SHAs which are allowed to access undeclared keys. SHAs are " "only looked at when loading the script, and new values do not affect already-loaded script."); namespace dfly { using namespace std; using namespace facade; using namespace util; ScriptMgr::ScriptMgr() { // Build default script flags string flags = absl::GetFlag(FLAGS_default_lua_flags); static_assert(ScriptParams{}.atomic && !ScriptParams{}.undeclared_keys); auto err = ScriptParams::ApplyFlags(flags, &default_params_); CHECK(!err) << err.Format(); } ScriptMgr::ScriptKey::ScriptKey(string_view sha) : array{} { DCHECK_EQ(sha.size(), size()); memcpy(data(), sha.data(), size()); } void ScriptMgr::Run(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder, ConnectionContext* cntx) { string subcmd = absl::AsciiStrToUpper(ArgS(args, 0)); if (subcmd == "HELP") { string_view kHelp[] = { "SCRIPT [ [value] [opt] ...]", "Subcommands are:", "EXISTS [ ...]", " Return information about the existence of the scripts in the script cache.", "FLUSH", " Flush the Lua scripts cache. Very dangerous on replicas.", "LOAD