Skip to content

Commit

Permalink
storage: introduce schema upgrade context
Browse files Browse the repository at this point in the history
Storage schema upgrade functions used to take all arguments
positionally. It gets harder to extend in a next commit, where the
automatic user management becomes optional.

The commit replaces the positional arguments with a context object
which can be enriched effortlessly, without forwarding each
attribute everywhere explicitly.

Needed for #435

NO_DOC=refactoring
NO_TEST=refactoring
  • Loading branch information
Gerold103 committed Nov 20, 2023
1 parent 97752bf commit 8281ca8
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 29 deletions.
19 changes: 12 additions & 7 deletions test/unit/upgrade.result
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ password = 'storage'
| ---
| ...

schema_bootstrap(user, password)
schema_bootstrap({username = user, password = password})
| ---
| ...

Expand Down Expand Up @@ -169,20 +169,25 @@ for _, handler in pairs(handlers) do

table.insert(upgrade_trace, 'Errinj in begin')
errinj.ERRINJ_UPGRADE = 'begin'
table.insert(upgrade_trace,
{util.check_error(upgrade, handler.version, user, password)})
table.insert(upgrade_trace, {
util.check_error(upgrade, handler.version,
{username = user, password = password})
})
table.insert(upgrade_trace, {diff = stat_update()})

table.insert(upgrade_trace, 'Errinj in end')
errinj.ERRINJ_UPGRADE = 'end'
table.insert(upgrade_trace,
{util.check_error(upgrade, handler.version, user, password)})
table.insert(upgrade_trace, {
util.check_error(upgrade, handler.version,
{usernme = user, password = password})
})
table.insert(upgrade_trace, {diff = stat_update()})

table.insert(upgrade_trace, 'No errinj')
errinj.ERRINJ_UPGRADE = nil
table.insert(upgrade_trace,
{pcall(upgrade, handler.version, user, password)})
table.insert(upgrade_trace, {
pcall(upgrade, handler.version, {username = user, password = password})
})
table.insert(upgrade_trace, {diff = stat_update()})
end;
| ---
Expand Down
19 changes: 12 additions & 7 deletions test/unit/upgrade.test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ schema_bootstrap = vshard.storage.internal.schema_bootstrap
user = 'storage'
password = 'storage'

schema_bootstrap(user, password)
schema_bootstrap({username = user, password = password})

version_make({0, 1, 16, 0})

Expand Down Expand Up @@ -107,20 +107,25 @@ for _, handler in pairs(handlers) do

table.insert(upgrade_trace, 'Errinj in begin')
errinj.ERRINJ_UPGRADE = 'begin'
table.insert(upgrade_trace,
{util.check_error(upgrade, handler.version, user, password)})
table.insert(upgrade_trace, {
util.check_error(upgrade, handler.version,
{username = user, password = password})
})
table.insert(upgrade_trace, {diff = stat_update()})

table.insert(upgrade_trace, 'Errinj in end')
errinj.ERRINJ_UPGRADE = 'end'
table.insert(upgrade_trace,
{util.check_error(upgrade, handler.version, user, password)})
table.insert(upgrade_trace, {
util.check_error(upgrade, handler.version,
{usernme = user, password = password})
})
table.insert(upgrade_trace, {diff = stat_update()})

table.insert(upgrade_trace, 'No errinj')
errinj.ERRINJ_UPGRADE = nil
table.insert(upgrade_trace,
{pcall(upgrade, handler.version, user, password)})
table.insert(upgrade_trace, {
pcall(upgrade, handler.version, {username = user, password = password})
})
table.insert(upgrade_trace, {diff = stat_update()})
end;

Expand Down
36 changes: 21 additions & 15 deletions vshard/storage/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -800,14 +800,14 @@ end

-- The schema first time appeared with 0.1.16. So this function
-- describes schema before that - 0.1.15.
local function schema_init_0_1_15_0(username, password)
local function schema_init_0_1_15_0(ctx)
log.info("Initializing schema %s", schema_version_make({0, 1, 15, 0}))
box.schema.user.create(username, {
password = password,
box.schema.user.create(ctx.username, {
password = ctx.password,
if_not_exists = true,
})
-- Replication may has not been granted, if user exists.
box.schema.user.grant(username, 'replication', nil, nil,
box.schema.user.grant(ctx.username, 'replication', nil, nil,
{if_not_exists = true})

local bucket = box.schema.space.create('_bucket')
Expand Down Expand Up @@ -837,13 +837,13 @@ local function schema_init_0_1_15_0(username, password)

for _, name in ipairs(storage_api) do
box.schema.func.create(name, {setuid = true})
box.schema.user.grant(username, 'execute', 'function', name)
box.schema.user.grant(ctx.username, 'execute', 'function', name)
end

box.space._schema:replace({'vshard_version', 0, 1, 15, 0})
end

local function schema_upgrade_to_0_1_16_0(username)
local function schema_upgrade_to_0_1_16_0(ctx)
-- Since 0.1.16.0 the old versioning by
-- 'oncevshard:storage:<number>' is dropped because it is not
-- really extendible nor understandable.
Expand All @@ -858,7 +858,7 @@ local function schema_upgrade_to_0_1_16_0(username)
local func = 'vshard.storage._call'
log.info('Create function %s()', func)
box.schema.func.create(func, {setuid = true})
box.schema.user.grant(username, 'execute', 'function', func)
box.schema.user.grant(ctx.username, 'execute', 'function', func)
-- Don't drop old functions in the same version. Removal can
-- happen only after 0.1.16. Or there should appear support of
-- rebalancing from too old versions. Drop of these functions
Expand Down Expand Up @@ -993,14 +993,14 @@ local schema_upgrade_handlers = {
},
}

local function schema_upgrade_master(target_version, username, password)
local function schema_upgrade_master(target_version, ctx)
local _schema = box.space._schema
local is_old_versioning = _schema:get({'oncevshard:storage:1'}) ~= nil
local version = schema_current_version()
local is_bootstrap = not box.space._bucket

if is_bootstrap then
schema_init_0_1_15_0(username, password)
schema_init_0_1_15_0(ctx)
elseif is_old_versioning then
log.info("The instance does not have 'vshard_version' record. "..
"It is 0.1.15.0.")
Expand All @@ -1020,7 +1020,7 @@ local function schema_upgrade_master(target_version, username, password)
if errinj == 'begin' then
ok, err1 = false, 'Errinj in begin'
else
ok, err1 = pcall(handler.upgrade, username)
ok, err1 = pcall(handler.upgrade, ctx)
if ok and errinj == 'end' then
ok, err1 = false, 'Errinj in end'
end
Expand Down Expand Up @@ -1053,13 +1053,13 @@ local function schema_upgrade_master(target_version, username, password)
end
end

local function schema_upgrade(is_first_cfg, is_master, username, password)
if is_master then
schema_upgrade_master(schema_latest_version, username, password)
local function schema_upgrade(ctx)
if ctx.is_master then
schema_upgrade_master(schema_latest_version, ctx)
-- Core features can only change with Tarantool exe update, which means
-- it won't happen on reconfig nor on hot reload. Enough to do it when
-- configured first time.
if is_first_cfg then
if ctx.is_first_cfg then
schema_upgrade_core_features()
end
else
Expand Down Expand Up @@ -3912,7 +3912,13 @@ local function storage_cfg_xc(cfgctx)
storage_cfg_services_update()

local uri = luri.parse(M.this_replica.uri)
schema_upgrade(is_first_cfg, this_is_master(), uri.login, uri.password)
local upgrade_ctx = {
is_first_cfg = is_first_cfg,
is_master = this_is_master(),
username = uri.login,
password = uri.password,
}
schema_upgrade(upgrade_ctx)

-- Check for master specifically. On master _bucket space must exist.
-- Because it should have done the schema bootstrap. Shall not ever try to
Expand Down

0 comments on commit 8281ca8

Please sign in to comment.