()
| 405 | backup_db_file() |
| 406 | |
| 407 | def run_migration_for_sqlite(): |
| 408 | # Tighten the process umask while we may be creating the SQLite |
| 409 | # DB file. The post-hoc chmod below sets 0o600, but only AFTER |
| 410 | # SQLAlchemy/SQLite has already created the file with the |
| 411 | # umask-default mode (0o644 on a typical 0o022 umask). That's a |
| 412 | # TOCTOU window — small in practice because the parent dir is |
| 413 | # 0o700, but easy to close. With umask 0o077 in effect during |
| 414 | # creation, the file is born 0o600. |
| 415 | _saved_umask = os.umask(0o077) |
| 416 | try: |
| 417 | # Run migration for the first time i.e. create database |
| 418 | # If version not available, user must have aborted. Tables |
| 419 | # are not created and so its an empty db |
| 420 | if not os.path.exists(SQLITE_PATH) or get_version() == -1: |
| 421 | # If running in cli mode then don't try to upgrade, just |
| 422 | # raise the exception |
| 423 | if not cli_mode: |
| 424 | upgrade_db() |
| 425 | else: |
| 426 | if not os.path.exists(SQLITE_PATH): |
| 427 | raise FileNotFoundError( |
| 428 | 'SQLite database file "' + SQLITE_PATH + |
| 429 | '" does not exists.') |
| 430 | raise RuntimeError( |
| 431 | 'The configuration database file is not valid.') |
| 432 | else: |
| 433 | schema_version = get_version() |
| 434 | |
| 435 | # Run migration if current schema version is greater than |
| 436 | # the schema version stored in version table |
| 437 | if CURRENT_SCHEMA_VERSION > schema_version: |
| 438 | # Take a backup of the old database file. |
| 439 | try: |
| 440 | prev_database_file_name = \ |
| 441 | "{0}.prev.bak".format(SQLITE_PATH) |
| 442 | shutil.copyfile( |
| 443 | SQLITE_PATH, prev_database_file_name) |
| 444 | except Exception as e: |
| 445 | app.logger.error(e) |
| 446 | |
| 447 | upgrade_db() |
| 448 | else: |
| 449 | # check all tables are present in the db. |
| 450 | is_db_error, invalid_tb_names = check_db_tables() |
| 451 | if is_db_error: |
| 452 | app.logger.error( |
| 453 | 'Table(s) {0} are missing in the' |
| 454 | ' database'.format(invalid_tb_names)) |
| 455 | backup_db_file() |
| 456 | |
| 457 | # Update schema version to the latest |
| 458 | if CURRENT_SCHEMA_VERSION > schema_version: |
| 459 | set_version(CURRENT_SCHEMA_VERSION) |
| 460 | db.session.commit() |
| 461 | finally: |
| 462 | # Always restore the prior umask — including the exception |
| 463 | # paths above, so a migration failure doesn't leave the |
| 464 | # whole process running with 0o077. |
no test coverage detected