Skip to content

Commit

Permalink
config: expand config:info()
Browse files Browse the repository at this point in the history
Closes #9780

@TarantoolBot document
Title: Expansion of `config:info()`

Before this patch, the `meta` field of the `config:info()` function
contained the meta data of the last load, even if it was unsuccessful
reload. This can be inconvenient because if the reload fails, we expect
that the last configuration that was successfully applied is used, but
its metadata was lost.

Now `config:info()` can take one argument — the version of the
information that should be returned by the function. If no arguments are
specified or the argument is the string `v1`, the return value has the
same structure as before. If the argument is the string `v2`, the `meta`
field in the return value has fields - `active` (meta for the last
successfully applied configuration) and `last` (meta of the last loaded
configuration). Currently only these values are accepted.
  • Loading branch information
ImeevMA authored and Totktonada committed Mar 15, 2024
1 parent 5040fba commit 699775b
Show file tree
Hide file tree
Showing 3 changed files with 271 additions and 3 deletions.
4 changes: 4 additions & 0 deletions changelogs/unreleased/gh-9780-show-active-meta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## feature/config

* `config:info()` can now display source metadata from the last successful
load along with source metadata from the very last load attempt (gh-9780).
35 changes: 32 additions & 3 deletions src/box/lua/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ function methods._startup(self, instance_name, config_file)

self:_post_apply()
self:_set_status_based_on_alerts()
if self._status == 'ready' or self._status == 'check_warnings' then
self._active_metadata = self._metadata
end
if extras ~= nil then
extras.post_apply(self)
end
Expand Down Expand Up @@ -457,6 +460,9 @@ function methods._reload_noexc(self, opts)
end

self:_set_status_based_on_alerts()
if self._status == 'ready' or self._status == 'check_warnings' then
self._active_metadata = self._metadata
end
if extras ~= nil then
extras.post_apply(self)
end
Expand All @@ -472,13 +478,36 @@ function methods.reload(self)
end
end

function methods.info(self)
function methods.info(self, version)
selfcheck(self, 'info')
return {
alerts = self._aboard:alerts(),
version = version == nil and 'v1' or version
local info = {}
local alerts = self._aboard:alerts()
info['v1'] = {
alerts = alerts,
meta = self._metadata,
status = self._status,
}
info['v2'] = {
alerts = alerts,
meta = {
active = self._active_metadata,
last = self._metadata,
},
status = self._status,
}
if info[version] ~= nil then
return info[version]
end

local supported_versions = {}
for key in pairs(info) do
table.insert(supported_versions, key)
end
table.sort(supported_versions)

error(('config:info() expects %s or nil as an argument, got %q'):format(
table.concat(supported_versions, ', '), version), 0)
end

-- The object is a singleton. The constructor should be called
Expand Down
235 changes: 235 additions & 0 deletions test/config-luatest/config_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1433,3 +1433,238 @@ g.test_post_apply_status = function(cg)
verify_2 = verify_2,
})
end

-- Check that config:info('v2') works properly.
g.test_info_new_version = function(g)
local dir = treegen.prepare_directory(g, {}, {})

local config = [[
credentials:
users:
guest:
roles:
- super
iproto:
listen:
- uri: unix/:./{{ instance_name }}.iproto
groups:
group-001:
replicasets:
replicaset-001:
instances:
instance-001: {}
]]
treegen.write_script(dir, 'config.yaml', config)

-- New source that sets meta.
local script = string.dump(function()
local yaml = require('yaml')
local file = require('internal.config.utils.file')

local methods = {}
local mt = {
__index = methods,
}

function methods.sync(self, config)
local data = file.universal_read('myconf.yaml', 'my config file')
local ok, res = pcall(yaml.decode, data)
if not ok then
error('Unable to parse my config file')
end
self._values = res
config:_meta('mysource', 'revision', self._revision)
self._revision = self._revision + 1
end

function methods.get(self)
return self._values
end

local function new()
return setmetatable({
name = 'mysource',
type = 'instance',
_values = {},
_revision = 1,
}, mt)
end

return {
new = new,
}
end)
treegen.write_script(dir, 'mysource.lua', script)

local myconf = [[
sql:
cache_size: 12345
]]
treegen.write_script(dir, 'myconf.yaml', myconf)

local opts = {
config_file = 'config.yaml',
alias = 'instance-001',
chdir = dir,
}
g.server = server:new(opts)
g.server:start()

-- Make sure the new source is loaded properly and the meta is set.
g.server:exec(function()
local config = require('config')
t.assert_equals(config:get('sql.cache_size'), 5242880)

config:_register_source(require('mysource').new())
config:reload()
t.assert_equals(config:get('sql.cache_size'), 12345)
local exp = {
mysource = {
revision = 1,
},
}
t.assert_equals(config:info().meta, exp)
t.assert_equals(config:info('v1').meta, exp)
exp = {
active = {
mysource = {
revision = 1,
},
},
last = {
mysource = {
revision = 1,
},
},
}
t.assert_equals(config:info('v2').meta, exp)
end)

-- Make sure the meta for config:info() is new and that config:info('v2')
-- contains both applied meta and unapplied new meta when reload failed
-- in apply phase.
myconf = [[
sql:
cache_size: true
]]
treegen.write_script(dir, 'myconf.yaml', myconf)
g.server:exec(function()
local config = require('config')
t.assert_equals(config:get('sql.cache_size'), 12345)
pcall(config.reload, config)
t.assert_equals(config:get('sql.cache_size'), 12345)
local exp = {
mysource = {
revision = 2,
},
}
t.assert_equals(config:info().meta, exp)
t.assert_equals(config:info('v1').meta, exp)
exp = {
active = {
mysource = {
revision = 1,
},
},
last = {
mysource = {
revision = 2,
},
},
}
t.assert_equals(config:info('v2').meta, exp)
end)

-- Make sure the meta for config:info() is new and that config:info('v2')
-- contains both applied meta and unapplied new meta when reload failed
-- in post_apply phase.
myconf = [[
sql:
cache_size: 123
roles: [myrole]
]]
treegen.write_script(dir, 'myconf.yaml', myconf)
g.server:exec(function()
local config = require('config')
t.assert_equals(config:get('sql.cache_size'), 12345)
t.assert_equals(config:get('roles'), nil)
local ok, err = pcall(config.reload, config)
t.assert(not ok)
t.assert_str_contains(err, "module 'myrole' not found")
-- If error in post_apply phase get() returns config of failed load.
t.assert_equals(config:get('sql.cache_size'), 123)
t.assert_equals(config:get('roles'), {'myrole'})
local exp = {
mysource = {
revision = 3,
},
}
t.assert_equals(config:info().meta, exp)
t.assert_equals(config:info('v1').meta, exp)
exp = {
active = {
mysource = {
revision = 1,
},
},
last = {
mysource = {
revision = 3,
},
},
}
t.assert_equals(config:info('v2').meta, exp)
end)

-- Make sure that in config:info('v2') both applied meta and unapplied new
-- meta are equal when reload is successful.
myconf = [[
sql:
cache_size: 100000
]]
treegen.write_script(dir, 'myconf.yaml', myconf)
g.server:exec(function()
local config = require('config')
t.assert_equals(config:get('sql.cache_size'), 123)
t.assert_equals(config:get('roles'), {'myrole'})
config:reload()
t.assert_equals(config:get('sql.cache_size'), 100000)
t.assert_equals(config:get('roles'), nil)
local exp = {
mysource = {
revision = 4,
},
}
t.assert_equals(config:info().meta, exp)
t.assert_equals(config:info('v1').meta, exp)
exp = {
active = {
mysource = {
revision = 4,
},
},
last = {
mysource = {
revision = 4,
},
},
}
t.assert_equals(config:info('v2').meta, exp)
end)
end

-- Check that config:info() throws an error on unexpected argument.
g.test_info_version_error = function(g)
local verify = function()
local config = require('config')
local exp = 'config:info() expects v1, v2 or nil as an argument, ' ..
'got "1"'
t.assert_error_msg_equals(exp, config.info, config, 1)
end

helpers.success_case(g, {
verify = verify,
})
end

0 comments on commit 699775b

Please sign in to comment.