Skip to content

Commit

Permalink
config: move snapshot related code into utils
Browse files Browse the repository at this point in the history
Config's box.cfg applier scans snapshot_dir in order to find out,
whether recovery is going to be done. It's needed in order to determine,
whether the instance should be started into ro mode firstly.

Let's move info about snapshot into separate file in utils. The commit
also introduces snapshot_path, which will be used in the following
commits in order to validate names.

Needed for #8978

NO_DOC=refactoring
NO_TEST=refactoring
NO_CHANGELOG=refactoring
  • Loading branch information
Serpentian authored and sergepetrenko committed Oct 27, 2023
1 parent e72e57b commit 21e9ef4
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 52 deletions.
1 change: 1 addition & 0 deletions src/box/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ lua_source(lua_sources lua/config/source/env.lua config_source_env_lua)
lua_source(lua_sources lua/config/source/file.lua config_source_file_lua)
lua_source(lua_sources lua/config/utils/log.lua config_utils_log_lua)
lua_source(lua_sources lua/config/utils/schema.lua config_utils_schema_lua)
lua_source(lua_sources lua/config/utils/snapshot.lua config_utils_snapshot_lua)
lua_source(lua_sources lua/config/utils/tabulate.lua config_utils_tabulate_lua)

if (ENABLE_CONFIG_EXTRAS)
Expand Down
56 changes: 4 additions & 52 deletions src/box/lua/config/applier/box_cfg.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
local fio = require('fio')
local fiber = require('fiber')
local log = require('internal.config.utils.log')
local instance_config = require('internal.config.instance_config')
local snapshot = require('internal.config.utils.snapshot')

local function peer_uri(configdata, peer_name)
local iconfig = configdata._peers[peer_name].iconfig_def
Expand Down Expand Up @@ -69,55 +69,6 @@ local function log_destination(log)
end
end

-- Determine where snapshot should reside based on the given
-- configuration.
--
-- To be called before first box.cfg().
local function effective_snapshot_dir(configdata)
-- The snapshot directory has a default value in the schema
-- (it is a string). So, it can't be nil or box.NULL.
local snap_dir = configdata:get('snapshot.dir', {use_default = true})
assert(snap_dir ~= nil)

-- If the path is absolute, just return it.
--
-- This check is necessary due to fio.pathjoin() peculiars,
-- see gh-8816.
if snap_dir:startswith('/') then
return snap_dir
end

-- We assume that the startup working directory is the current
-- working directory. IOW, that this function is called before
-- first box.cfg() call. Let's verify it.
assert(type(box.cfg) == 'function')

-- If the snapshot directory is not absolute, it is relative
-- to the working directory.
--
-- Determine an absolute path to the configured working
-- directory considering that it may be relative to the
-- working directory at the startup moment.
local work_dir = configdata:get('process.work_dir', {use_default = true})
if work_dir == nil then
work_dir = '.'
end
work_dir = fio.abspath(work_dir)

-- Now we know the absolute path to the configured working
-- directory. Let's determine the snapshot directory path.
return fio.abspath(fio.pathjoin(work_dir, snap_dir))
end

-- Determine whether the instance will be started from an existing
-- snapshot.
--
-- To be called before first box.cfg().
local function has_snapshot(configdata)
local pattern = fio.pathjoin(effective_snapshot_dir(configdata), '*.snap')
return #fio.glob(pattern) > 0
end

-- Returns nothing or {needs_retry = true}.
local function apply(config)
local configdata = config._configdata
Expand Down Expand Up @@ -266,7 +217,8 @@ local function apply(config)
local am_i_bootstrap_leader = false
if is_startup then
local instance_name = configdata:names().instance_name
am_i_bootstrap_leader = not has_snapshot(configdata) and
am_i_bootstrap_leader =
snapshot.get_path(configdata._iconfig_def) == nil and
instance_name == configdata:bootstrap_leader_name()
box_cfg.read_only = not am_i_bootstrap_leader
end
Expand Down Expand Up @@ -382,7 +334,7 @@ local function apply(config)
if is_startup and failover ~= 'election' and failover ~= 'supervised' then
local configured_as_rw = not box_cfg.read_only
local in_replicaset = #configdata:peers() > 1
local has_snap = has_snapshot(configdata)
local has_snap = snapshot.get_path(configdata._iconfig_def) ~= nil

-- Require at least one writable instance in the
-- replicaset if the instance is to be bootstrapped (has
Expand Down
67 changes: 67 additions & 0 deletions src/box/lua/config/utils/snapshot.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
local fio = require('fio')
local instance_config = require('internal.config.instance_config')

local snapshot_path = nil

-- Determine where snapshot should reside based on the given
-- configuration.
--
-- To be called before first box.cfg().
local function effective_snapshot_dir(iconfig)
assert(iconfig ~= nil)
-- The snapshot directory has a default value in the schema
-- (it is a string). So, it can't be nil or box.NULL.
local snap_dir = instance_config:get(iconfig, 'snapshot.dir')
assert(snap_dir ~= nil)

-- If the path is absolute, just return it.
--
-- This check is necessary due to fio.pathjoin() peculiars,
-- see gh-8816.
if snap_dir:startswith('/') then
return snap_dir
end

-- We assume that the startup working directory is the current
-- working directory. IOW, that this function is called before
-- first box.cfg() call. Let's verify it.
assert(type(box.cfg) == 'function')

-- If the snapshot directory is not absolute, it is relative
-- to the working directory.
--
-- Determine an absolute path to the configured working
-- directory considering that it may be relative to the
-- working directory at the startup moment.
local work_dir = instance_config:get(iconfig, 'process.work_dir')
if work_dir == nil then
work_dir = '.'
end
work_dir = fio.abspath(work_dir)

-- Now we know the absolute path to the configured working
-- directory. Let's determine the snapshot directory path.
return fio.abspath(fio.pathjoin(work_dir, snap_dir))
end

-- Determine whether the instance will be recovered from an existing
-- snapshot and return its path. Should be called before box.cfg.
--
-- To be called before first box.cfg().
local function get_snapshot_path(iconfig)
assert(type(box.cfg) == 'function')
if snapshot_path == nil then
local snap_dir = effective_snapshot_dir(iconfig)
local glob = fio.glob(fio.pathjoin(snap_dir, '*.snap'))
if #glob > 0 then
table.sort(glob)
snapshot_path = glob[#glob]
end
end

return snapshot_path
end

return {
get_path = get_snapshot_path,
}
5 changes: 5 additions & 0 deletions src/box/lua/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ extern char session_lua[],
config_source_file_lua[],
config_utils_log_lua[],
config_utils_schema_lua[],
config_utils_snapshot_lua[],
config_utils_tabulate_lua[]
#if ENABLE_CONFIG_EXTRAS
,
Expand Down Expand Up @@ -335,6 +336,10 @@ static const char *lua_sources[] = {
"internal.config.instance_config",
config_instance_config_lua,

"config/utils/snapshot",
"internal.config.utils.snapshot",
config_utils_snapshot_lua,

"config/cluster_config",
"internal.config.cluster_config",
config_cluster_config_lua,
Expand Down

0 comments on commit 21e9ef4

Please sign in to comment.