Skip to content
Snippets Groups Projects
Commit fb734be0 authored by Alexander Turenko's avatar Alexander Turenko Committed by Alexander Turenko
Browse files

config: create dirs relative to process.work_dir

The current working directory of a tarantool process is changed during
startup to `process.work_dir`.

The mkdir applier works before and after this point, so it should take
into account both situations.

Before first box.cfg() call (in the box_cfg applier) it should prepend
directories with `process.work_dir`. However, it shouldn't do that after
the current wordking directory change.

Part of #8862

NO_DOC=It is bugfix.
parent f1a09989
No related branches found
No related tags found
No related merge requests found
......@@ -4,3 +4,5 @@
file (gh-8862).
* Create parent directories for `console.socket` and `log.file` (gh-8862).
* Create the `process.work_dir` directory (gh-8862).
* Consider all the paths as relative to `process.work_dir` when creating
necessary directories (gh-8862).
......@@ -2,7 +2,21 @@ local fio = require('fio')
local log = require('internal.config.utils.log')
-- Create a directory if it doesn't exist.
local function safe_mkdir(prefix, dir)
local function safe_mkdir(prefix, dir, work_dir)
-- All the directories are interpreted as relative to
-- `process.work_dir`. The first box.cfg() call sets a
-- current working directory to this path.
--
-- However, we should prepend paths manually before the first
-- box.cfg() call.
--
-- The absolute path is checked explicitly due to gh-8816.
local needs_prepending = type(box.cfg) == 'function' and
work_dir ~= nil and not dir:startswith('/')
if needs_prepending then
dir = fio.pathjoin(work_dir, dir)
end
local stat = fio.stat(dir)
if stat == nil then
......@@ -24,16 +38,13 @@ end
local function apply(config)
local configdata = config._configdata
local work_dir = configdata:get('process.work_dir', {use_default = true})
-- Create process.work_dir directory if box.cfg() is not
-- called yet.
if type(box.cfg) == 'function' then
local work_dir = configdata:get('process.work_dir',
{use_default = true})
if work_dir ~= nil then
local prefix = ('mkdir.apply[%s]'):format('process.work_dir')
safe_mkdir(prefix, work_dir)
end
if type(box.cfg) == 'function' and work_dir ~= nil then
local prefix = ('mkdir.apply[%s]'):format('process.work_dir')
safe_mkdir(prefix, work_dir)
end
configdata:filter(function(w)
......@@ -43,7 +54,7 @@ local function apply(config)
return
end
local prefix = ('mkdir.apply[%s]'):format(table.concat(w.path, '.'))
safe_mkdir(prefix, w.data)
safe_mkdir(prefix, w.data, work_dir)
end)
configdata:filter(function(w)
......@@ -53,19 +64,19 @@ local function apply(config)
return
end
local prefix = ('mkdir.apply[%s]'):format(table.concat(w.path, '.'))
safe_mkdir(prefix, fio.dirname(w.data))
safe_mkdir(prefix, fio.dirname(w.data), work_dir)
end)
local console = configdata:get('console', {use_default = true})
if console.enabled then
local prefix = ('mkdir.apply[%s]'):format('console.socket')
safe_mkdir(prefix, fio.dirname(console.socket))
safe_mkdir(prefix, fio.dirname(console.socket), work_dir)
end
local log = configdata:get('log', {use_default = true})
if log.to == 'file' then
local prefix = ('mkdir.apply[%s]'):format('log.file')
safe_mkdir(prefix, fio.dirname(log.file))
safe_mkdir(prefix, fio.dirname(log.file), work_dir)
end
end
......
......@@ -71,3 +71,60 @@ g.test_work_dir = function(g)
verify_2 = verify,
})
end
-- Verify the logic of directories calculation relative to
-- process.work_dir at startup and reload.
--
-- See the comments in the verify() function in the test
-- for details what exactly is verified.
g.test_dirs_are_relative_to_work_dir = function(g)
local dir = treegen.prepare_directory(g, {}, {})
local verify = loadstring(([[
local fio = require('fio')
local dirs = {'d', 'e', 'f', 'g', 'h', 'i'}
-- The requested directories are NOT created in the
-- startup dir.
local startup_dir = '%s'
for _, dir in ipairs(dirs) do
assert(not fio.path.exists(fio.pathjoin(startup_dir, dir)))
end
-- The requested directories are created in the work_dir.
local work_dir = fio.pathjoin(startup_dir, 'a/b/c')
for _, dir in ipairs(dirs) do
assert(fio.path.is_dir(dir))
end
-- The process.work_dir value should be used as a prefix
-- for requested directories only at startup. After this,
-- on reload, it would be harmful, because the process
-- has already changed the current working directory to
-- the work_dir.
assert(not fio.path.exists(fio.pathjoin(work_dir, 'a')))
]]):format(dir))
helpers.reload_success_case(g, {
dir = dir,
options = {
['process.work_dir'] = 'a/b/c',
['process.pid_file'] = 'd/{{ instance_name }}.pid',
['vinyl.dir'] = 'e',
['wal.dir'] = 'f',
['snapshot.dir'] = 'g',
['console.socket'] = 'h/{{ instance_name }}.control',
['log.to'] = 'file',
['log.file'] = 'i/{{ instance_name }}.log',
-- Set the binary protocol socket as an absolute path
-- to don't confuse the testing helpers and allows
-- them to connect to the instance and execute
-- necessary commands (such as `config:reload()`).
['iproto.listen'] = fio.pathjoin(dir, '{{ instance_name }}.iproto'),
},
verify = verify,
verify_2 = verify,
})
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment