From 7dfecb9cc8f3ceffaf3a3077166807bfb8fff231 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 1 Apr 2019 14:22:17 +0100 Subject: [PATCH] [Fix] Another fix for Redis sentinel Issue: #2796 --- lualib/lua_redis.lua | 33 ++++++++++++++++++++++++-------- lualib/rspamadm/configwizard.lua | 12 +++++++----- lualib/rspamadm/stat_convert.lua | 4 ++-- src/libserver/cfg_rcl.c | 2 +- src/lua/lua_common.c | 14 ++++++-------- src/plugins/lua/bayes_expiry.lua | 11 +++++++---- src/plugins/lua/reputation.lua | 5 +++-- 7 files changed, 51 insertions(+), 30 deletions(-) diff --git a/lualib/lua_redis.lua b/lualib/lua_redis.lua index 4e30850d5..a93545f23 100644 --- a/lualib/lua_redis.lua +++ b/lualib/lua_redis.lua @@ -313,8 +313,10 @@ local function enrich_defaults(rspamd_config, module, redis_params) local opts = rspamd_config:get_all_opt('redis') if opts then - if opts[module] then - process_redis_opts(opts[module], redis_params) + if module then + if opts[module] then + process_redis_opts(opts[module], redis_params) + end end process_redis_opts(opts, redis_params) @@ -344,7 +346,7 @@ end -- @module lua_redis -- This module contains helper functions for working with Redis --]] -local function try_load_redis_servers(options, rspamd_config, result) +local function process_redis_options(options, rspamd_config, result) local default_port = 6379 local upstream_list = require "rspamd_upstream_list" local read_only = true @@ -427,7 +429,22 @@ local function try_load_redis_servers(options, rspamd_config, result) return false end -exports.try_load_redis_servers = try_load_redis_servers +--[[[ +@function try_load_redis_servers(options, rspamd_config, no_fallback) +Tries to load redis servers from the specified `options` object. +Returns `redis_params` table or nil in case of failure + +--]] +exports.try_load_redis_servers = function(options, rspamd_config, no_fallback, module_name) + local result = {} + + if process_redis_options(options, rspamd_config, result) then + if not no_fallback then + enrich_defaults(rspamd_config, module_name, result) + end + return maybe_return_cached(result) + end +end -- This function parses redis server definition using either -- specific server string for this module or global @@ -448,7 +465,7 @@ local function rspamd_parse_redis_server(module_name, module_opts, no_fallback) local ret if opts.redis then - ret = try_load_redis_servers(opts.redis, rspamd_config, result) + ret = process_redis_options(opts.redis, rspamd_config, result) if ret then if not no_fallback then @@ -458,7 +475,7 @@ local function rspamd_parse_redis_server(module_name, module_opts, no_fallback) end end - ret = try_load_redis_servers(opts, rspamd_config, result) + ret = process_redis_options(opts, rspamd_config, result) if ret then if not no_fallback then @@ -482,13 +499,13 @@ local function rspamd_parse_redis_server(module_name, module_opts, no_fallback) local ret if opts[module_name] then - ret = try_load_redis_servers(opts[module_name], rspamd_config, result) + ret = process_redis_options(opts[module_name], rspamd_config, result) if ret then return maybe_return_cached(result) end else - ret = try_load_redis_servers(opts, rspamd_config, result) + ret = process_redis_options(opts, rspamd_config, result) -- Exclude disabled if opts['disabled_modules'] then diff --git a/lualib/rspamadm/configwizard.lua b/lualib/rspamadm/configwizard.lua index 3a6ff3116..6de3e9c26 100644 --- a/lualib/rspamadm/configwizard.lua +++ b/lualib/rspamadm/configwizard.lua @@ -449,9 +449,11 @@ local function check_redis_classifier(cls, changes) return end - local parsed_redis = {} - if not lua_redis.try_load_redis_servers(cls, nil, parsed_redis) then - if not lua_redis.try_load_redis_servers(redis_params, nil, parsed_redis) then + local parsed_redis = lua_redis.try_load_redis_servers(cls, nil) + + if not parsed_redis then + parsed_redis = lua_redis.try_load_redis_servers(redis_params, nil) + if not parsed_redis then printf("Cannot parse Redis params") return end @@ -583,8 +585,8 @@ local function setup_statistic(cfg, changes) return false end - local parsed_redis = {} - if lua_redis.try_load_redis_servers(redis_params, nil, parsed_redis) then + local parsed_redis = lua_redis.try_load_redis_servers(redis_params, nil) + if parsed_redis then printf('You have %d sqlite classifiers', #sqlite_configs) local expire = readline_expire() diff --git a/lualib/rspamadm/stat_convert.lua b/lualib/rspamadm/stat_convert.lua index 230dc3f3f..3b54826aa 100644 --- a/lualib/rspamadm/stat_convert.lua +++ b/lualib/rspamadm/stat_convert.lua @@ -5,11 +5,11 @@ local logger = require "rspamd_logger" local lua_util = require "lua_util" return function (_, res) - local redis_params = {} + local redis_params = lua_redis.try_load_redis_servers(res.redis, nil) if res.expire then res.expire = lua_util.parse_time_interval(res.expire) end - if not lua_redis.try_load_redis_servers(res.redis, nil, redis_params) then + if not redis_params then logger.errx('cannot load redis server definition') return false diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index 5c99aed59..ed99ef8b6 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -3554,7 +3554,7 @@ rspamd_rcl_jinja_handler (struct ucl_parser *parser, GString *tb; tb = lua_touserdata (L, -1); - msg_err_config ("cannot call lua try_load_redis_servers script: %s", tb->str); + msg_err_config ("cannot call lua jinja_template script: %s", tb->str); g_string_free (tb, TRUE); lua_settop (L, err_idx - 1); diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index 5f1be424d..81fac3640 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -2500,12 +2500,9 @@ gboolean rspamd_lua_try_load_redis (lua_State *L, const ucl_object_t *obj, struct rspamd_config *cfg, gint *ref_id) { - gint res_pos, err_idx; + gint err_idx; struct rspamd_config **pcfg; - /* Create results table */ - lua_createtable (L, 0, 0); - res_pos = lua_gettop (L); lua_pushcfunction (L, &rspamd_lua_traceback); err_idx = lua_gettop (L); @@ -2522,7 +2519,7 @@ rspamd_lua_try_load_redis (lua_State *L, const ucl_object_t *obj, pcfg = lua_newuserdata (L, sizeof (*pcfg)); rspamd_lua_setclass (L, "rspamd{config}", -1); *pcfg = cfg; - lua_pushvalue (L, res_pos); + lua_pushboolean (L, false); /* no_fallback */ if (lua_pcall (L, 3, 1, err_idx) != 0) { GString *tb; @@ -2535,16 +2532,17 @@ rspamd_lua_try_load_redis (lua_State *L, const ucl_object_t *obj, return FALSE; } - if (lua_toboolean (L, -1)) { + if (lua_istable (L, -1)) { if (ref_id) { /* Ref table */ - lua_pushvalue (L, res_pos); + lua_pushvalue (L, -1); *ref_id = luaL_ref (L, LUA_REGISTRYINDEX); lua_settop (L, 0); } else { /* Leave it on the stack */ - lua_settop (L, res_pos); + lua_insert (L, err_idx); + lua_settop (L, err_idx); } return TRUE; diff --git a/src/plugins/lua/bayes_expiry.lua b/src/plugins/lua/bayes_expiry.lua index 9f5d7a68f..6e2c328dc 100644 --- a/src/plugins/lua/bayes_expiry.lua +++ b/src/plugins/lua/bayes_expiry.lua @@ -97,10 +97,13 @@ local function check_redis_classifier(cls, cfg) end -- Now try to load redis_params if needed - local redis_params = {} - if not lredis.try_load_redis_servers(cls, rspamd_config, redis_params) then - if not lredis.try_load_redis_servers(cfg[N] or E, rspamd_config, redis_params) then - if not lredis.try_load_redis_servers(cfg['redis'] or E, rspamd_config, redis_params) then + local redis_params + redis_params = lredis.try_load_redis_servers(cls, rspamd_config, false, 'bayes') + if not redis_params then + redis_params = lredis.try_load_redis_servers(cfg[N] or E, rspamd_config, false, 'bayes') + if not redis_params then + redis_params = lredis.try_load_redis_servers(cfg[N] or E, rspamd_config, true) + if not redis_params then return false end end diff --git a/src/plugins/lua/reputation.lua b/src/plugins/lua/reputation.lua index e91c6ebb7..b72c00719 100644 --- a/src/plugins/lua/reputation.lua +++ b/src/plugins/lua/reputation.lua @@ -897,8 +897,9 @@ end local function reputation_redis_init(rule, cfg, ev_base, worker) local our_redis_params = {} - if not lua_redis.try_load_redis_servers(rule.backend.config, - rspamd_config, our_redis_params) then + our_redis_params = lua_redis.try_load_redis_servers(rule.backend.config, rspamd_config, + true) + if not our_redis_params then our_redis_params = redis_params end if not our_redis_params then -- 2.39.5