def clear_database(client): """ Clearing the database by dropping all tables https://www.techawaken.com/drop-tables-mysql-database/ { mysql -hHOSTNAME -uUSERNAME -pPASSWORD -Nse 'show tables' DB_NAME; } | ( while read table; do if [ -z ${i+x} ]; then echo 'SET FOREIGN_KEY_CHECKS = 0;'; fi; i=1; echo "drop table \`$table\`;"; done; echo 'SET FOREIGN_KEY_CHECKS = 1;' ) | awk '{print}' ORS=' ' | mysql -hHOSTNAME -uUSERNAME -pPASSWORD DB_NAME; :param client: String :return: """ mode.run_command( '{ ' + helper.get_command(client, 'mysql') + ' ' + database_utility.generate_mysql_credentials(client) + ' -Nse \'show tables\' \'' + system.config[client]['db']['name'] + '\'; }' + ' | ( while read table; do if [ -z ${i+x} ]; then echo \'SET FOREIGN_KEY_CHECKS = 0;\'; fi; i=1; ' + 'echo "drop table \\`$table\\`;"; done; echo \'SET FOREIGN_KEY_CHECKS = 1;\' ) | awk \'{print}\' ORS=' ' | ' + helper.get_command(client, 'mysql') + ' ' + database_utility.generate_mysql_credentials(client) + ' ' + system.config[client]['db']['name'], client, skip_dry_run=True )
def check_configuration(client): """ Checking remote Symfony database configuration :param client: String :return: """ _path = system.config[client]['path'] # Check for symfony 2.8 if 'parameters.yml' in _path: _db_config = { 'name': get_database_parameter(client, 'database_name', _path), 'host': get_database_parameter(client, 'database_host', _path), 'password': get_database_parameter(client, 'database_password', _path), 'port': get_database_parameter(client, 'database_port', _path), 'user': get_database_parameter(client, 'database_user', _path), } # Using for symfony >=3.4 else: stdout = mode.run_command( helper.get_command(client, 'grep') + ' -v "^#" ' + system.config[client][ 'path'] + ' | ' + helper.get_command(client, 'grep') + ' DATABASE_URL', client, True ) _db_config = parse_database_credentials(stdout) system.config[client]['db'] = _db_config
def check_database_dump(client, filepath): """ Checking the last line of the dump file if it contains "-- Dump completed on" :param client: String :param filepath: String :return: """ if system.config['check_dump']: _line = mode.run_command( helper.get_command(client, 'tail') + ' -n 1 ' + filepath, client, True, skip_dry_run=True ) if not _line: return if "-- Dump completed on" not in _line: sys.exit( output.message( output.Subject.ERROR, 'Dump file is corrupted', do_print=False ) ) else: output.message( output.host_to_subject(client), 'Dump file is valid', verbose_only=True )
def check_configuration(client): """ Checking remote TYPO3 database configuration :param client: String :return: """ _path = system.config[client]['path'] if 'LocalConfiguration' in _path: stdout = mode.run_command( helper.get_command(client, 'php') + ' -r "echo json_encode(include \'' + system.config[client][ 'path'] + '\');"', client, True ) _db_config = parse_database_credentials(json.loads(stdout)['DB']) else: # Try to parse settings from AdditionalConfiguration.php file _db_config = { 'name': get_database_setting(client, 'dbname', system.config[client]['path']), 'host': get_database_setting(client, 'host', system.config[client]['path']), 'password': get_database_setting(client, 'password', system.config[client]['path']), 'port': get_database_setting(client, 'port', system.config[client]['path']) if get_database_setting(client, 'port', system.config[client]['path']) != '' else 3306, 'user': get_database_setting(client, 'user', system.config[client]['path']), } system.config[client]['db'] = _db_config
def prepare_target_database_dump(): """ Preparing the target database dump by the unpacked .tar.gz file :return: """ output.message(output.Subject.TARGET, 'Extracting database dump', True) mode.run_command( helper.get_command('target', 'tar') + ' xzf ' + helper.get_dump_dir(mode.Client.TARGET) + database_utility.database_dump_file_name + '.tar.gz -C ' + helper.get_dump_dir(mode.Client.TARGET) + ' > /dev/null', mode.Client.TARGET, skip_dry_run=True )
def get_database_parameter(client, name, file): """ Parsing a single database variable from the .env file https://gist.github.com/judy2k/7656bfe3b322d669ef75364a46327836 :param client: String :param name: String :param file: String :return: """ return mode.run_command( helper.get_command(client, 'grep') + f' {name} {file} | cut -d \'=\' -f2', client, True ).replace('\n', '')
def run_database_command(client, command, force_database_name=False): """ Run a database command using the "mysql -e" command :param client: String :param command: String database command :param force_database_name: Bool forces the database name :return: """ _database_name = ' ' + system.config[client]['db']['name'] if force_database_name else '' return mode.run_command( helper.get_command(client, 'mysql') + ' ' + generate_mysql_credentials( client) + _database_name + ' -e "' + command + '"', client, True)
def get_database_parameter(client, name, file): """ Parsing a single database variable from the parameters.yml file hhttps://unix.stackexchange.com/questions/84922/extract-a-part-of-one-line-from-a-file-with-sed :param client: String :param name: String :param file: String :return: """ return mode.run_command( helper.get_command(client, 'sed') + f' -n -e \'/{name}/ s/.*\\: *//p\' {file}', client, True ).replace('\n', '')
def get_database_setting(client, name, file): """ Get database setting try to regex from AdditionalConfiguration sed -nE "s/'dbname'.*=>.*'(.*)'.*$/\1/p" /var/www/html/tests/files/www1/AdditionalConfiguration.php :param client: String :param name: String :param file: String :return: """ return mode.run_command( helper.get_command(client, 'sed') + f' -nE "s/\'{name}\'.*=>.*\'(.*)\'.*$/\\1/p" {file}', client, True ).replace('\n', '').strip()
def import_database_dump_file(client, filepath): """ Import a database dump file :param client: String :param filepath: String :return: """ if helper.check_file_exists(client, filepath): mode.run_command( helper.get_command(client, 'mysql') + ' ' + database_utility.generate_mysql_credentials(client) + ' \'' + system.config[client]['db']['name'] + '\' < ' + filepath, client, skip_dry_run=True )
def get_database_setting(client, name, file): """ Parsing a single database variable from the wp-config.php file https://stackoverflow.com/questions/63493645/extract-database-name-from-a-wp-config-php-file :param client: String :param name: String :param file: String :return: """ return mode.run_command( helper.get_command(client, 'sed') + f' -n "s/define( *\'{name}\', *\'\([^\']*\)\'.*/\\1/p" {file}', client, True ).replace('\n', '')
def remove_target_database_dump(): """ Removing the target database dump files :return: """ _file_path = helper.get_dump_dir(mode.Client.TARGET) + database_utility.database_dump_file_name # # Move dump to specified directory # if system.config['keep_dump']: helper.create_local_temporary_data_dir() _keep_dump_path = system.default_local_sync_path + database_utility.database_dump_file_name mode.run_command( helper.get_command('target', 'cp') + ' ' + _file_path + ' ' + _keep_dump_path, mode.Client.TARGET ) output.message( output.Subject.INFO, f'Database dump file is saved to: {_keep_dump_path}', True, True ) # # Clean up # if not mode.is_dump() and not mode.is_import(): output.message( output.Subject.TARGET, 'Cleaning up', True ) if system.config['dry_run']: return if mode.is_target_remote(): sftp = remote_client.ssh_client_target.open_sftp() sftp.remove(_file_path) sftp.remove(f'{_file_path}.tar.gz') sftp.close() else: if os.path.isfile(_file_path): os.remove(_file_path) if os.path.isfile(f'{_file_path}.tar.gz'): os.remove(f'{_file_path}.tar.gz')
def create_origin_database_dump(): """ Creating the origin database dump file :return: """ if not mode.is_import(): parser.get_database_configuration(mode.Client.ORIGIN) database_utility.generate_database_dump_filename() helper.check_and_create_dump_dir(mode.Client.ORIGIN, helper.get_dump_dir(mode.Client.ORIGIN)) _dump_file_path = helper.get_dump_dir( mode.Client.ORIGIN) + database_utility.database_dump_file_name _database_version = database_utility.get_database_version(mode.Client.ORIGIN) output.message( output.Subject.ORIGIN, f'Creating database dump {output.CliFormat.BLACK}{_dump_file_path}{output.CliFormat.ENDC}', True ) _mysqldump_options = '--no-tablespaces ' # Remove --no-tablespaces option for mysql < 5.6 # @ToDo: Better option handling if not _database_version is None: if _database_version[0] == database_utility.DatabaseSystem.MYSQL and \ semantic_version.Version(_database_version[1]) < semantic_version.Version('5.6.0'): _mysqldump_options = '' # Run mysql dump command, e.g. # mysqldump --no-tablespaces -u'db' -p'db' -h'db1' -P'3306' 'db' > /tmp/_db_08-10-2021_07-00.sql mode.run_command( helper.get_command(mode.Client.ORIGIN, 'mysqldump') + ' ' + _mysqldump_options + database_utility.generate_mysql_credentials(mode.Client.ORIGIN) + ' \'' + system.config[mode.Client.ORIGIN]['db']['name'] + '\' ' + database_utility.generate_ignore_database_tables() + database_utility.get_database_tables() + ' > ' + _dump_file_path, mode.Client.ORIGIN, skip_dry_run=True ) database_utility.check_database_dump(mode.Client.ORIGIN, _dump_file_path) database_utility.count_tables(mode.Client.ORIGIN, _dump_file_path) prepare_origin_database_dump()
def prepare_origin_database_dump(): """ Preparing the origin database dump file by compressing them as .tar.gz :return: """ output.message( output.Subject.ORIGIN, 'Compressing database dump', True ) mode.run_command( helper.get_command(mode.Client.ORIGIN, 'tar') + ' cfvz ' + helper.get_dump_dir( mode.Client.ORIGIN) + database_utility.database_dump_file_name + '.tar.gz -C ' + helper.get_dump_dir(mode.Client.ORIGIN) + ' ' + database_utility.database_dump_file_name + ' > /dev/null', mode.Client.ORIGIN, skip_dry_run=True )