MT#58395 add --db-scripts-dir command line option

* --db-scripts-dir option enables override of the
  default database scripts directory location
* docstring a bit more compact formatting
* apply_revisions(): improve non-existing directory
  detection and error output

Change-Id: Ic1d74244244df6406fb9a9258b7c36b971497513
mr12.2
Kirill Solomko 1 year ago
parent 554e3e393f
commit 7928836d0d

@ -50,37 +50,41 @@ class Config:
db_file (str): node db config file db_file (str): node db config file
ngcp_sync_db_script: (str) = ngcp sync db script ngcp_sync_db_script: (str) = ngcp sync db script
scripts_dir (str): directory containing .up/.down scripts
scripts_dir_order (List[str]): order to apply scripts
from the subdirectories
automated (bool): wether the script is run in the automated mode automated (bool): wether the script is run in the automated mode
that automatically init the db schema if it's empty. that automatically init the db schema if it's empty.
this option is taken from either this option is taken from either
AUTOMATED_INSTALL_MODE os.environ AUTOMATED_INSTALL_MODE os.environ
(backward compatibility) or from the args (backward compatibility) or from the args
skip_ro_db_sync (bool): skip db synchronisation (if applicable) skip_ro_db_sync (bool): skip db synchronisation (if applicable)
this option is taken from either SKIP_SYNC_DB this option is taken from either SKIP_SYNC_DB
os.environ (backward compatibility) os.environ (backward compatibility) or from the args
or from the args
debug (bool): debug/verbose mode debug (bool): debug/verbose mode
mode (str): 'up' mode or 'down' mode mode (str): 'up' mode or 'down' mode
to_revision (int): if the script must apply/remove up to to_revision (int): if the script must apply/remove up to
(and including) a certain revision (and including) a certain revision
force (bool): run this script on the active node force (bool): run this script on the active node
batch_mode (bool): instead of applying scripts one by one, collects
them all and builds a single sql file that is applied in one go
db_scripts_dir (str): directory containing .up/.down scripts
supported_args (List[str]): a list of the attributes described above supported_args (List[str]): a list of the attributes described above
that can be also passed args, that can be also passed args, to automate the code
to automate the code
_args (Any): parsed argspare result (usually Namespace()) _args (Any): parsed argspare result (usually Namespace())
_subproc (Popen): Popen handler to an opened subprocess, if any _subproc (Popen): Popen handler to an opened subprocess, if any
_prompt_is_shown (bool): if the prompt is shown, a helper _prompt_is_shown (bool): if the prompt is shown,
to handle SIGINT a helper to handle SIGINT
_interrupted (bool): if the script was interrupted with SIGINT _interrupted (bool): if the script was interrupted with SIGINT
_not_replicated_was_applied (bool): if at least one not_replicated _not_replicated_was_applied (bool): if at least one not_replicated
script was applied/removed script was applied/removed
_temp_sql_file (BufferedRandom): used to accumulate the sql scripts _temp_sql_file (BufferedRandom): used to accumulate the sql scripts
data when batch mode is enabled data when batch mode is enabled
_run_cmd_mysql_options (List[str]) = extra options that are passed
to every invokation of run_cmd() that calls the 'mysql' console
command. needed to use same connection (socket/config/user, etc.)
as the pymysql db connection
_scripts_dir_order (List[str]): order to apply scripts
from the subdirectories
node_name (str): current node name node_name (str): current node name
node_roles (ConfigDict): current node roles node_roles (ConfigDict): current node roles
@ -89,13 +93,12 @@ class Config:
db_conn (Connection): database connection handler db_conn (Connection): database connection handler
db_schema (DBSchema): database schema revisions state db_schema (DBSchema): database schema revisions state
revisions (Revisions): revisions that are read from revisions (Revisions): revisions that are read from
the scripts directory the scripts directory
sync_db_databases (str): a string containing a space separated list sync_db_databases (str): a string containing a space separated list
of databases that ngcp-sync-db of databases that ngcp-sync-db will synchronise
needs to synchronise
sync_db_ignore_tables (str): a string containing a space separated list sync_db_ignore_tables (str): a string containing a space separated list
of tables that ngcp-sync-db needs to ignore of tables that ngcp-sync-db should ignore
""" """
# db options # db options
@ -111,10 +114,6 @@ class Config:
db_file: str = '/etc/default/ngcp-db' db_file: str = '/etc/default/ngcp-db'
ngcp_sync_db_script: str = '/usr/sbin/ngcp-sync-db' ngcp_sync_db_script: str = '/usr/sbin/ngcp-sync-db'
# scripts dir location
scripts_dir: str = '/usr/share/ngcp-db-schema/db_scripts'
scripts_dir_order: List[str] = ['init', 'base', 'diff']
# default config options # default config options
automated: bool = False automated: bool = False
skip_ro_db_sync: bool = False skip_ro_db_sync: bool = False
@ -123,9 +122,11 @@ class Config:
to_revision: int = 0 to_revision: int = 0
force: bool = False force: bool = False
batch_mode: bool = False batch_mode: bool = False
db_scripts_dir: str = '/usr/share/ngcp-db-schema/db_scripts'
supported_args: List[str] = ['automated', 'batch_mode', supported_args: List[str] = ['automated', 'batch_mode',
'db_socket', 'db_connect_method', 'db_socket', 'db_connect_method',
'db_defaults_conf_file', 'db_defaults_conf_file',
'db_scripts_dir',
'debug', 'force', 'debug', 'force',
'mode', 'skip_ro_db_sync', 'mode', 'skip_ro_db_sync',
'to_revision'] 'to_revision']
@ -139,6 +140,7 @@ class Config:
_temp_sql_file: BufferedRandom = \ _temp_sql_file: BufferedRandom = \
tempfile.NamedTemporaryFile() # type: ignore tempfile.NamedTemporaryFile() # type: ignore
_run_cmd_mysql_options: List[str] = [] _run_cmd_mysql_options: List[str] = []
_scripts_dir_order: List[str] = ['init', 'base', 'diff']
# attributes that are initialised in __init__() # attributes that are initialised in __init__()
node_name: str node_name: str
@ -516,6 +518,15 @@ def parse_args() -> None:
({config.db_connect_method}) ({config.db_connect_method})
""") """)
parser.add_argument(
'--db-scripts-dir',
dest='db_scripts_dir',
type=str,
help=f"""
Override database .up/.down scripts directory instead of the
default one ({config.db_scripts_dir})
""")
args = parser.parse_args() args = parser.parse_args()
for arg in config.supported_args: for arg in config.supported_args:
if hasattr(args, arg): if hasattr(args, arg):
@ -774,14 +785,15 @@ def get_revisions() -> Revisions:
debug('fetching db scripts...') debug('fetching db scripts...')
mode = config.mode mode = config.mode
revisions: Revisions = {} revisions: Revisions = {}
for spec in config.scripts_dir_order: for spec in config._scripts_dir_order:
rev_dir = f'{config.db_scripts_dir}/{spec}'
if not os.access(rev_dir, os.R_OK):
error(f'non-existing or empty scripts dir {rev_dir}')
shutdown(1)
revisions[spec] = {} revisions[spec] = {}
for path in Path(f'{config.scripts_dir}/{spec}').glob(f'*.{mode}'): for path in Path(f'{config.db_scripts_dir}/{spec}').glob(f'*.{mode}'):
revision = int(path.stem.split('_')[0]) revision = int(path.stem.split('_')[0])
revisions[spec][revision] = path.name revisions[spec][revision] = path.name
if not revisions[spec]:
error(f'empty dir {config.scripts_dir}/{config.scripts_dir_order}')
shutdown(1)
return revisions return revisions
@ -802,7 +814,7 @@ def apply_revisions(revisions: Revisions) -> None:
""" """
mode = config.mode mode = config.mode
dir_specs = config.scripts_dir_order dir_specs = config._scripts_dir_order
max_schema_revision = 0 max_schema_revision = 0
if config.db_schema: if config.db_schema:
@ -905,7 +917,7 @@ def apply_up_script(script_name: str, revision: int) -> int:
debug(f'skip already applied revision {script_name}') debug(f'skip already applied revision {script_name}')
return 1 return 1
script_filename = f'{config.scripts_dir}/{script_name}' script_filename = f'{config.db_scripts_dir}/{script_name}'
if not config.batch_mode: if not config.batch_mode:
log(f'applying revision {script_name}') log(f'applying revision {script_name}')
@ -1005,7 +1017,7 @@ def apply_down_script(script_name: str, revision: int) -> int:
debug(f'skip already removed revision {script_name}') debug(f'skip already removed revision {script_name}')
return 1 return 1
script_filename = f'{config.scripts_dir}/{script_name}' script_filename = f'{config.db_scripts_dir}/{script_name}'
if not config.batch_mode: if not config.batch_mode:
log(f'Removing revision {script_name}') log(f'Removing revision {script_name}')

Loading…
Cancel
Save