def test__take_mysql_backup_retention(master1, docker_client, s3_client, config_content_mysql_only, client_my_cnf): twindb_config_dir = get_twindb_config_dir(docker_client, master1["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(twindb_config_host, "w") as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ["AWS_ACCESS_KEY_ID"], AWS_SECRET_ACCESS_KEY=os.environ["AWS_SECRET_ACCESS_KEY"], BUCKET=s3_client.bucket, daily_copies=1, hourly_copies=2, MY_CNF="/etc/twindb/my.cnf", ) fp.write(content) cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "daily", ] for i in range(0, 3): ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "hourly", ] for i in range(0, 3): ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["twindb-backup", "--config", twindb_config_guest, "status"] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) status = json.loads(cout) assert_and_pause((len(status["daily"].keys()) == 1, ), status) assert_and_pause((len(status["hourly"].keys()) == 2, ), status)
def test__s3_find_files_returns_sorted(master1, docker_client, s3_client, config_content_mysql_only, client_my_cnf): # cleanup the bucket first s3_client.delete_all_objects() twindb_config_dir = get_twindb_config_dir(docker_client, master1["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(twindb_config_host, "w") as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ["AWS_ACCESS_KEY_ID"], AWS_SECRET_ACCESS_KEY=os.environ["AWS_SECRET_ACCESS_KEY"], BUCKET=s3_client.bucket, daily_copies=5, hourly_copies=2, MY_CNF="/etc/twindb/my.cnf", ) fp.write(content) cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "daily", ] n_runs = 3 for x in range(n_runs): ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 hostname = "master1_1" dst = S3( bucket=s3_client.bucket, aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"], aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"], ) for x in range(10): result = dst.list_files(dst.remote_path, pattern="/daily/") assert len(result) == n_runs assert result == sorted(result) prefix = "{remote_path}/{hostname}/{run_type}/mysql/mysql-".format( remote_path=dst.remote_path, hostname=hostname, run_type="daily") files = dst.list_files(prefix) assert len(files) == n_runs assert files == sorted(files)
def test__s3_find_files_returns_sorted(master1, docker_client, s3_client, config_content_mysql_only, client_my_cnf): # cleanup the bucket first s3_client.delete_all_objects() twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(twindb_config_host, 'w') as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket, daily_copies=5, hourly_copies=2, MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily'] n_runs = 3 for x in xrange(n_runs): ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 hostname = 'master1_1' dst = S3( bucket=s3_client.bucket, aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'], aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'] ) for x in xrange(10): result = dst.list_files(dst.remote_path, pattern='/daily/') assert len(result) == n_runs assert result == sorted(result) prefix = "{remote_path}/{hostname}/{run_type}/mysql/mysql-".format( remote_path=dst.remote_path, hostname=hostname, run_type='daily' ) files = dst.list_files(prefix) assert len(files) == n_runs assert files == sorted(files)
def test__s3_find_files_returns_sorted(master1, docker_client, s3_client, config_content_mysql_only): # cleanup the bucket first s3_client.delete_all_objects() twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir contents = """ [client] user=dba password=qwerty """ with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) with open(twindb_config_host, 'w') as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket, daily_copies=5, hourly_copies=2, MY_CNF='/etc/twindb/my.cnf') fp.write(content) cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily' ] n_runs = 3 for x in xrange(n_runs): ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 hostname = 'master1_1' dst = S3( s3_client.bucket, AWSAuthOptions(os.environ['AWS_ACCESS_KEY_ID'], os.environ['AWS_SECRET_ACCESS_KEY'])) for x in xrange(10): result = dst.find_files(dst.remote_path, 'daily') assert len(result) == n_runs assert result == sorted(result) prefix = "{remote_path}/{hostname}/{run_type}/mysql/mysql-".format( remote_path=dst.remote_path, hostname=hostname, run_type='daily') files = dst.list_files(prefix) assert len(files) == n_runs assert files == sorted(files)
def test__take_mysql_backup_retention(master1, docker_client, s3_client, config_content_mysql_only): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir contents = """ [client] user=dba password=qwerty """ with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) with open(twindb_config_host, 'w') as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket, daily_copies=1, hourly_copies=2, MY_CNF='/etc/twindb/my.cnf') fp.write(content) cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily' ] for i in range(0, 3): ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly' ] for i in range(0, 3): ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--config', twindb_config_guest, 'status'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) assert ret == 0 print(cout) status = json.loads(cout) assert len(status['daily'].keys()) == 1 assert len(status['hourly'].keys()) == 2
def test__take_mysql_backup_retention(master1, docker_client, s3_client, config_content_mysql_only, client_my_cnf): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(twindb_config_host, 'w') as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket, daily_copies=1, hourly_copies=2, MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily'] pause_test(' '.join(cmd)) for i in range(0, 3): ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly'] for i in range(0, 3): ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--config', twindb_config_guest, 'status'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) assert ret == 0 print(cout) status = json.loads(cout) assert len(status['daily'].keys()) == 1 assert len(status['hourly'].keys()) == 2
def test__take_mysql_backup(master1, docker_client, s3_client, config_content_mysql_only, client_my_cnf): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(twindb_config_host, 'w') as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket, daily_copies=1, hourly_copies=2, MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly' ] pause_test(' '.join(cmd)) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--config', twindb_config_guest, 'status'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) key = json.loads(cout)['hourly'].keys()[0] assert key.endswith('.xbstream.gz')
def test__take_mysql_backup(master1, docker_client, s3_client, config_content_mysql_only, client_my_cnf): twindb_config_dir = get_twindb_config_dir(docker_client, master1["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(twindb_config_host, "w") as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ["AWS_ACCESS_KEY_ID"], AWS_SECRET_ACCESS_KEY=os.environ["AWS_SECRET_ACCESS_KEY"], BUCKET=s3_client.bucket, daily_copies=1, hourly_copies=2, MY_CNF="/etc/twindb/my.cnf", ) fp.write(content) cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "hourly", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = ["twindb-backup", "--config", twindb_config_guest, "status"] ret, cout = docker_execute(docker_client, master1["Id"], cmd) LOG.debug("STDOUT: %s", cout) key = list(json.loads(cout)["hourly"].keys())[0] assert_and_pause((key.endswith(".xbstream.gz"), ), key)
def test_clone(runner, master1, slave, docker_client, config_content_clone): twindb_config_dir = get_twindb_config_dir(docker_client, runner['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir private_key_host = "%s/private_key" % twindb_config_dir private_key_guest = "/etc/twindb/private_key" contents = """ [client] user=dba password=qwerty """ with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) private_key = """-----BEGIN RSA PRIVATE KEY----- MIIEoAIBAAKCAQEAyXxAjPShNGAedbaEtltFI6A7RlsyI+4evxTq6uQrgbJ6Hm+p HBXshXQYXDyVjvytaM+6GKF+r+6+C+6Wc5Xz4lLO/ZiSCdPbyEgqw1JoHrgPNpc6 wmCtjJExxjzvpwSVgbZg3xOdqW1y+TyqeUkXEg/Lm4VZhN1Q/KyGCgBlWuAXoOYR GhaNWqcnr/Wn5YzVHAx2yJNrurtKLVYVMIkGcN/6OUaPpWqKZLaXiK/28PSZ5GdT DmxRg4W0pdyGEYQndpPlpLF4w5gNUEhVZM8hWVE29+DIW3XXVYGYchxmkhU7wrGx xZR+k5AT+7g8VspVS8zNMXM9Z27w55EQuluNMQIBIwKCAQAzz35QIaXLo7APo/Y9 hS8JKTPQQ1YJPTsbMUO4vlRUjPrUoF6vc1oTsCOFbqoddCyXS1u9MNdvEYFThn51 flSn6WhtGJqU0BPxrChA2q0PNqTThfkqqyVQCBQdCFrhzfqPEaPhl1RtZUlzSh01 IWxVGgEn/bfu9xTTQk5aV9+MZQ2XKe4BGzpOZMI/B7ivRCcthEwMTx92opr52bre 4t7DahVLN/2Wu4lxajDzCaKXpjMuL76lFov0mZZN7S8whH5xSx1tpapHqsCAwfLL k49lDdR8aN6oqoeK0e9w//McIaKxN2FVxD4bcuXiQTjihx+QwQOLmlHSRDKhTsYg 4Q5bAoGBAOgVZM2eqC8hNl5UH//uuxOeBKqwz7L/FtGemNr9m0XG8N9yE/K7A5iX 6EDvDyVI51IlIXdxfK8re5yxfbJ4YevenwdEZZ2O8YRrVByJ53PV9CcVeWL4p6f/ I56sYyDfXcnDTEOVYY0mCfYUfUcSb1ExpuIU4RvuQJg6tvbdxD9FAoGBAN4/pVCT krRd6PJmt6Dbc2IF6N09OrAnLB3fivGztF5cp+RpyqZK4ve+akLoe1laTg7vNtnF l/PZtM9v/VT45hb70MFEHO+sKvGa5Yimxkb6YCriJOcLxTysSgFHKz7v+8BqqoHi qY4fORGwPVDv28I8jKRvcuNHendV/Rdcuk79AoGAd1t1q5NscAJzu3u4r4IXEWc1 mZzClpHROJq1AujTgviZInUu1JqxZGthgHrx2KkmggR3nIOB86/2bdefut7TRhq4 L5+Et24VzxKgSTD6sJnrR0zfV3iQvMxbdizFRBsaSoGyMWLEdHn2fo4xzMem9o6Q VwNsdMOsMQhA1rsxuiMCgYBr8wcnIxte68jqxC1OIXKOsmnKi3RG7nSDidXF2vE1 JbCiJMGD+Hzeu5KyyLDw4rgzI7uOWKjkJ+obnMuBCy3t6AZPPlcylXPxsaKwFn2Q MHfaUJWUyzPqRQ4AnukekdINAJv18cAR1Kaw0fHle9Ej1ERP3lxfw6HiMRSHsLJD nwKBgCIXVhXCDaXOOn8M4ky6k27bnGJrTkrRjHaq4qWiQhzizOBTb+7MjCrJIV28 8knW8+YtEOfl5R053SKQgVsmRjjDfvCirGgqC4kSAN4A6MD+GNVXZVUUjAUBVUbU 8Wt4BxW6kFA7+Su7n8o4DxCqhZYmK9ZUhNjE+uUhxJCJaGr4 -----END RSA PRIVATE KEY----- """ with open(private_key_host, "w") as key_fd: key_fd.write(private_key) with open(twindb_config_host, 'w') as fp: content = config_content_clone.format( PRIVATE_KEY=private_key_guest, MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = '/usr/sbin/sshd' # Run SSH daemon on master1_1 ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'clone', 'mysql', "%s:3306" % master1['ip'], "%s:3306" % slave['ip'] ] ret, cout = docker_execute(docker_client, runner['Id'], cmd) print(cout) assert ret == 0 sql_master_2 = RemoteMySQLSource({ "ssh_host": slave['ip'], "ssh_user": '******', "ssh_key": private_key_guest, "mysql_connect_info": MySQLConnectInfo( my_cnf_path, hostname=slave['ip'] ), "run_type": INTERVALS[0], "backup_type": 'full' }) timeout = time.time() + 30 while time.time() < timeout: with sql_master_2.get_connection() as conn: with conn.cursor() as cursor: cursor.execute('SHOW SLAVE STATUS') row = cursor.fetchone() if row['Slave_IO_Running'] == 'Yes' and row['Slave_SQL_Running'] == 'Yes': LOG.info('Relication is up and running') return LOG.error('Replication is not running after 30 seconds timeout') assert False
def test__take_file_backup(master1, docker_client, s3_client, config_content_files_only): twindb_config_dir = get_twindb_config_dir(docker_client, master1["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" backup_dir = "/etc/twindb" with open(twindb_config_host, "w") as fp: content = config_content_files_only.format( TEST_DIR=backup_dir, AWS_ACCESS_KEY_ID=os.environ["AWS_ACCESS_KEY_ID"], AWS_SECRET_ACCESS_KEY=os.environ["AWS_SECRET_ACCESS_KEY"], BUCKET=s3_client.bucket, ) fp.write(content) cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "hourly", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) # Check that backup copy is in "twindb-backup ls" output hostname = "master1_1" s3_backup_path = "s3://%s/%s/hourly/files/%s" % ( s3_client.bucket, hostname, backup_dir.replace("/", "_"), ) cmd = ["twindb-backup", "--debug", "--config", twindb_config_guest, "ls"] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) assert_and_pause((s3_backup_path in cout, ), "%s is not in %s" % (s3_backup_path, cout)) backup_to_restore = None for line in StringIO(cout): if line.startswith(s3_backup_path): backup_to_restore = line.strip() break cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "restore", "file", "--dst", "/tmp/restore", backup_to_restore, ] assert_and_pause((backup_to_restore is not None, ), s3_backup_path) ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) # Check that restored file exists path_to_file_restored = "/tmp/restore/etc/twindb/twindb-backup-1.cfg" cmd = ["ls", path_to_file_restored] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) # And content is same cmd = [ "diff", "/tmp/restore/etc/twindb/twindb-backup-1.cfg", twindb_config_guest ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) # empty output assert_and_pause((not cout, ), cout) # zero exit code if no differences assert_and_pause((ret == 0, ), "%s exited with %d" % (" ".join(cmd), ret))
def test__restore_mysql_inc_creates_log_files( master1, docker_client, s3_client, config_content_mysql_only, client_my_cnf ): twindb_config_dir = get_twindb_config_dir(docker_client, master1["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(twindb_config_host, "w") as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ["AWS_ACCESS_KEY_ID"], AWS_SECRET_ACCESS_KEY=os.environ["AWS_SECRET_ACCESS_KEY"], BUCKET=s3_client.bucket, daily_copies=1, hourly_copies=2, MY_CNF="/etc/twindb/my.cnf", ) fp.write(content) cmd = ["ls", "-la", "/var/lib/mysql"] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "hourly", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "daily", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["twindb-backup", "--config", twindb_config_guest, "status"] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 status = json.loads(cout) key = list(status["hourly"].keys())[0] backup_copy = "s3://" + s3_client.bucket + "/" + key dst_dir = "/tmp/dst_full_log_files" ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "restore", "mysql", backup_copy, "--dst", dst_dir, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["find", dst_dir] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["test", "-f", "/tmp/dst_full_log_files/backup-my.cnf"] print(cmd) ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["test", "-f", "/tmp/dst_full_log_files/ibdata1"] print(cmd) ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["test", "-f", "/tmp/dst_full_log_files/ib_logfile0"] print(cmd) ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["test", "-f", "/tmp/dst_full_log_files/ib_logfile1"] print(cmd) ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["test", "-f", "/tmp/dst_full_log_files/mysql/user.MYD"] print(cmd) ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["test", "-f", "/tmp/dst_full_log_files/xtrabackup_logfile"] print(cmd) ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "bash", "-c", "test -f /tmp/dst_full_log_files/_config/etc/my.cnf " "|| test -f /tmp/dst_full_log_files/_config/etc/mysql/my.cnf", ] print(cmd) ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0
def test_backup(master1, storage_server, config_content_ssh, docker_client): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir ssh_key_host = "%s/id_rsa" % twindb_config_dir ssh_key_guest = '/etc/twindb/id_rsa' contents = """ [client] user=dba password=qwerty """ with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) ssh_key = """-----BEGIN RSA PRIVATE KEY----- MIIEoAIBAAKCAQEAyXxAjPShNGAedbaEtltFI6A7RlsyI+4evxTq6uQrgbJ6Hm+p HBXshXQYXDyVjvytaM+6GKF+r+6+C+6Wc5Xz4lLO/ZiSCdPbyEgqw1JoHrgPNpc6 wmCtjJExxjzvpwSVgbZg3xOdqW1y+TyqeUkXEg/Lm4VZhN1Q/KyGCgBlWuAXoOYR GhaNWqcnr/Wn5YzVHAx2yJNrurtKLVYVMIkGcN/6OUaPpWqKZLaXiK/28PSZ5GdT DmxRg4W0pdyGEYQndpPlpLF4w5gNUEhVZM8hWVE29+DIW3XXVYGYchxmkhU7wrGx xZR+k5AT+7g8VspVS8zNMXM9Z27w55EQuluNMQIBIwKCAQAzz35QIaXLo7APo/Y9 hS8JKTPQQ1YJPTsbMUO4vlRUjPrUoF6vc1oTsCOFbqoddCyXS1u9MNdvEYFThn51 flSn6WhtGJqU0BPxrChA2q0PNqTThfkqqyVQCBQdCFrhzfqPEaPhl1RtZUlzSh01 IWxVGgEn/bfu9xTTQk5aV9+MZQ2XKe4BGzpOZMI/B7ivRCcthEwMTx92opr52bre 4t7DahVLN/2Wu4lxajDzCaKXpjMuL76lFov0mZZN7S8whH5xSx1tpapHqsCAwfLL k49lDdR8aN6oqoeK0e9w//McIaKxN2FVxD4bcuXiQTjihx+QwQOLmlHSRDKhTsYg 4Q5bAoGBAOgVZM2eqC8hNl5UH//uuxOeBKqwz7L/FtGemNr9m0XG8N9yE/K7A5iX 6EDvDyVI51IlIXdxfK8re5yxfbJ4YevenwdEZZ2O8YRrVByJ53PV9CcVeWL4p6f/ I56sYyDfXcnDTEOVYY0mCfYUfUcSb1ExpuIU4RvuQJg6tvbdxD9FAoGBAN4/pVCT krRd6PJmt6Dbc2IF6N09OrAnLB3fivGztF5cp+RpyqZK4ve+akLoe1laTg7vNtnF l/PZtM9v/VT45hb70MFEHO+sKvGa5Yimxkb6YCriJOcLxTysSgFHKz7v+8BqqoHi qY4fORGwPVDv28I8jKRvcuNHendV/Rdcuk79AoGAd1t1q5NscAJzu3u4r4IXEWc1 mZzClpHROJq1AujTgviZInUu1JqxZGthgHrx2KkmggR3nIOB86/2bdefut7TRhq4 L5+Et24VzxKgSTD6sJnrR0zfV3iQvMxbdizFRBsaSoGyMWLEdHn2fo4xzMem9o6Q VwNsdMOsMQhA1rsxuiMCgYBr8wcnIxte68jqxC1OIXKOsmnKi3RG7nSDidXF2vE1 JbCiJMGD+Hzeu5KyyLDw4rgzI7uOWKjkJ+obnMuBCy3t6AZPPlcylXPxsaKwFn2Q MHfaUJWUyzPqRQ4AnukekdINAJv18cAR1Kaw0fHle9Ej1ERP3lxfw6HiMRSHsLJD nwKBgCIXVhXCDaXOOn8M4ky6k27bnGJrTkrRjHaq4qWiQhzizOBTb+7MjCrJIV28 8knW8+YtEOfl5R053SKQgVsmRjjDfvCirGgqC4kSAN4A6MD+GNVXZVUUjAUBVUbU 8Wt4BxW6kFA7+Su7n8o4DxCqhZYmK9ZUhNjE+uUhxJCJaGr4 -----END RSA PRIVATE KEY----- """ with open(ssh_key_host, "w") as ssh_fd: ssh_fd.write(ssh_key) with open(twindb_config_host, 'w') as fp: content = config_content_ssh.format(PRIVATE_KEY=ssh_key_guest, HOST_IP=storage_server['ip'], MY_CNF='/etc/twindb/my.cnf') fp.write(content) cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly' ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly' ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['test', '-d', '/tmp/backup'] ret, cout = docker_execute(docker_client, storage_server['Id'], cmd) print(cout) assert ret == 0 dir_path = "/var/backup/local/master1_1/hourly/mysql" cmd = ["bash", "-c", "ls %s | wc -l" % dir_path] ret, cout = docker_execute(docker_client, master1['Id'], cmd, tty=True) print(cout) assert ret == 0 assert '1' in cout cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily' ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily' ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 dir_path = "/var/backup/local/master1_1/daily/mysql" cmd = ["bash", "-c", "ls %s | wc -l" % dir_path] ret, cout = docker_execute(docker_client, master1['Id'], cmd, tty=True) print(cout) assert ret == 0 assert '1' in cout
def test_take_mysql_backup_aenc_restores_inc( master1, docker_client, s3_client, config_content_mysql_aenc, gpg_public_key, gpg_private_key, tmpdir, client_my_cnf, ): twindb_config_dir = get_twindb_config_dir(docker_client, master1["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) gpg_public_key_path_host = "%s/public_key" % twindb_config_dir gpg_private_key_path_host = "%s/private_key" % twindb_config_dir gpg_private_key_path_guest = "/etc/twindb/private_key" gpg_keyring = "/etc/twindb/keyring" gpg_secret_keyring = "/etc/twindb/secret_keyring" with open(gpg_public_key_path_host, "w") as fd: fd.write(gpg_public_key) with open(gpg_private_key_path_host, "w") as fd: fd.write(gpg_private_key) cmd = ["rm", "-f", gpg_keyring, gpg_secret_keyring] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "gpg", "--no-default-keyring", "--keyring", gpg_keyring, "--secret-keyring", gpg_secret_keyring, "--yes", "--no-tty", "--batch", "--import", gpg_private_key_path_guest, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 with open(twindb_config_host, "w") as fp: content = config_content_mysql_aenc.format( AWS_ACCESS_KEY_ID=os.environ["AWS_ACCESS_KEY_ID"], AWS_SECRET_ACCESS_KEY=os.environ["AWS_SECRET_ACCESS_KEY"], BUCKET=s3_client.bucket, gpg_keyring=gpg_keyring, gpg_secret_keyring=gpg_secret_keyring, daily_copies=1, hourly_copies=2, MY_CNF="/etc/twindb/my.cnf", ) fp.write(content) cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "daily", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "hourly", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["twindb-backup", "--config", twindb_config_guest, "status"] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 key = list(json.loads(cout)["hourly"].keys())[0] backup_copy = "s3://" + s3_client.bucket + "/" + key dst_dir = str(tmpdir.mkdir("dst")) ret, cout = docker_execute(docker_client, master1["Id"], ["mkdir", "-p", str(dst_dir)]) print(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", str(twindb_config_guest), "restore", "mysql", backup_copy, "--dst", dst_dir, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 print("Files in restored datadir:") ret, cout = docker_execute(docker_client, master1["Id"], ["find", dst_dir]) print(cout) assert ret == 0 files_to_test = [] for datadir_file in [ "ibdata1", "ib_logfile0", "ib_logfile1", "mysql/user.MYD", "backup-my.cnf", "xtrabackup_logfile", ]: files_to_test += ["test -f %s/%s" % (dst_dir, datadir_file)] cmd = ["bash", "-c", " && ".join(files_to_test)] print(cmd) ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "bash", "-c", "test -f {datadir}/_config/etc/my.cnf " "|| test -f {datadir}/_config/etc/mysql/my.cnf".format( datadir=dst_dir), ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0
def test_restore(master1, storage_server, config_content_ssh, docker_client, rsa_private_key): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir ssh_key_host = "%s/id_rsa" % twindb_config_dir ssh_key_guest = '/etc/twindb/id_rsa' contents = """ [client] user=dba password=qwerty """ with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) with open(ssh_key_host, "w") as ssh_fd: ssh_fd.write(rsa_private_key) with open(twindb_config_host, 'w') as fp: content = config_content_ssh.format(PRIVATE_KEY=ssh_key_guest, HOST_IP=storage_server['ip'], MY_CNF='/etc/twindb/my.cnf') fp.write(content) cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily' ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = [ "bash", "-c", "twindb-backup --config %s ls | grep /tmp/backup " "| grep mysql | sort | tail -1" % twindb_config_guest ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) url = cout.strip() LOG.info(cout) assert ret == 0 dst_dir = "/tmp/ssh_dest_restore/" cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'restore', 'mysql', url, "--dst", dst_dir ] # print('Test paused') # print(' '.join(cmd)) # import time # time.sleep(36000) ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['find', dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/backup-my.cnf' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/ibdata1' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/ib_logfile0' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/ib_logfile1' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/mysql/user.MYD' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/xtrabackup_logfile' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = [ "bash", "-c", 'test -f %s/_config/etc/my.cnf || test -f %s/_config/etc/mysql/my.cnf' % (dst_dir, dst_dir) ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0
def test_take_mysql_backup_aenc_restores_inc( master1, docker_client, s3_client, config_content_mysql_aenc, gpg_public_key, gpg_private_key, tmpdir, client_my_cnf): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) gpg_public_key_path_host = "%s/public_key" % twindb_config_dir gpg_private_key_path_host = "%s/private_key" % twindb_config_dir gpg_private_key_path_guest = "/etc/twindb/private_key" gpg_keyring = "/etc/twindb/keyring" gpg_secret_keyring = "/etc/twindb/secret_keyring" with open(gpg_public_key_path_host, "w") as fd: fd.write(gpg_public_key) with open(gpg_private_key_path_host, "w") as fd: fd.write(gpg_private_key) cmd = ['rm', '-f', gpg_keyring, gpg_secret_keyring] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['gpg', '--no-default-keyring', '--keyring', gpg_keyring, '--secret-keyring', gpg_secret_keyring, '--yes', '--no-tty', '--batch', '--import', gpg_private_key_path_guest] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 with open(twindb_config_host, 'w') as fp: content = config_content_mysql_aenc.format( AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket, gpg_keyring=gpg_keyring, gpg_secret_keyring=gpg_secret_keyring, daily_copies=1, hourly_copies=2, MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--config', twindb_config_guest, 'status'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 key = json.loads(cout)['hourly'].keys()[0] backup_copy = 's3://' + s3_client.bucket + '/' + key dst_dir = str(tmpdir.mkdir('dst')) ret, cout = docker_execute( docker_client, master1['Id'], ["mkdir", "-p", str(dst_dir)] ) print(cout) assert ret == 0 cmd = [ 'twindb-backup', '--debug', '--config', str(twindb_config_guest), 'restore', 'mysql', backup_copy, '--dst', dst_dir ] # LOG.debug('Test paused') # LOG.debug(' '.join(cmd)) # import time # time.sleep(36000) ret, cout = docker_execute( docker_client, master1['Id'], cmd ) print(cout) assert ret == 0 print('Files in restored datadir:') ret, cout = docker_execute( docker_client, master1['Id'], ["find", dst_dir] ) print(cout) assert ret == 0 files_to_test = [] for datadir_file in ['ibdata1', 'ib_logfile0', 'ib_logfile1', 'mysql/user.MYD', 'backup-my.cnf', 'xtrabackup_logfile']: files_to_test += [ "test -f %s/%s" % (dst_dir, datadir_file) ] cmd = [ "bash", "-c", " && ".join(files_to_test) ] print(cmd) ret, cout = docker_execute( docker_client, master1['Id'], cmd ) print(cout) assert ret == 0 cmd = [ "bash", "-c", "test -f {datadir}/_config/etc/my.cnf " "|| test -f {datadir}/_config/etc/mysql/my.cnf".format( datadir=dst_dir ) ] ret, cout = docker_execute( docker_client, master1['Id'], cmd ) print(cout) assert ret == 0
def test_take_file_backup_with_aenc( master1, docker_client, s3_client, config_content_files_aenc, gpg_public_key, gpg_private_key, ): twindb_config_dir = get_twindb_config_dir(docker_client, master1["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" backup_dir = "/etc/twindb" gpg_public_key_path_host = "%s/public_key" % twindb_config_dir gpg_private_key_path_host = "%s/private_key" % twindb_config_dir gpg_private_key_path_guest = "/etc/twindb/private_key" gpg_keyring = "/etc/twindb/keyring" gpg_secret_keyring = "/etc/twindb/secret_keyring" with open(gpg_public_key_path_host, "w") as fd: fd.write(gpg_public_key) with open(gpg_private_key_path_host, "w") as fd: fd.write(gpg_private_key) cmd = ["rm", "-f", gpg_keyring, gpg_secret_keyring] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "gpg", "--no-default-keyring", "--keyring", gpg_keyring, "--secret-keyring", gpg_secret_keyring, "--yes", "--no-tty", "--batch", "--import", gpg_private_key_path_guest, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 with open(twindb_config_host, "w") as fp: content = config_content_files_aenc.format( TEST_DIR=backup_dir, AWS_ACCESS_KEY_ID=os.environ["AWS_ACCESS_KEY_ID"], AWS_SECRET_ACCESS_KEY=os.environ["AWS_SECRET_ACCESS_KEY"], BUCKET=s3_client.bucket, gpg_keyring=gpg_keyring, gpg_secret_keyring=gpg_secret_keyring, ) fp.write(content) # write some content to the directory with open(os.path.join(twindb_config_dir, "file"), "w") as f: f.write("Hello world.") hostname = "master1_1" s3_backup_path = "s3://%s/%s/hourly/files/%s" % ( s3_client.bucket, hostname, backup_dir.replace("/", "_"), ) cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "hourly", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["twindb-backup", "--debug", "--config", twindb_config_guest, "ls"] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 assert s3_backup_path in cout backup_to_restore = None for line in StringIO(cout): if line.startswith(s3_backup_path): backup_to_restore = line.strip() break assert backup_to_restore.endswith(".tar.gz.gpg") key = backup_to_restore.lstrip("s3://").lstrip( s3_client.bucket).lstrip("/") local_copy = "%s/backup_to_restore.tar.gz.gpg" % twindb_config_dir s3_client.s3_client.download_file(s3_client.bucket, key, local_copy) assert magic.from_file(local_copy) == "data" dest_dir = "/tmp/simple_backup_aenc" cmd = ["mkdir", "-p", "/tmp/simple_backup_aenc"] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "restore", "file", "--dst", dest_dir, backup_to_restore, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 path_to_file_restored = "%s%s/file" % (dest_dir, backup_dir) cmd = ["test", "-f", path_to_file_restored] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 # And content is same path_to_file_orig = "%s/file" % backup_dir cmd = ["diff", "-Nur", path_to_file_orig, path_to_file_restored] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 assert not cout
def test_take_file_backup_with_aenc(master1, docker_client, s3_client, config_content_files_aenc, gpg_public_key, gpg_private_key): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' backup_dir = "/etc/twindb" gpg_public_key_path_host = "%s/public_key" % twindb_config_dir gpg_private_key_path_host = "%s/private_key" % twindb_config_dir gpg_private_key_path_guest = "/etc/twindb/private_key" gpg_keyring = "/etc/twindb/keyring" gpg_secret_keyring = "/etc/twindb/secret_keyring" with open(gpg_public_key_path_host, "w") as fd: fd.write(gpg_public_key) with open(gpg_private_key_path_host, "w") as fd: fd.write(gpg_private_key) cmd = ['rm', '-f', gpg_keyring, gpg_secret_keyring] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['gpg', '--no-default-keyring', '--keyring', gpg_keyring, '--secret-keyring', gpg_secret_keyring, '--yes', '--no-tty', '--batch', '--import', gpg_private_key_path_guest] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 with open(twindb_config_host, 'w') as fp: content = config_content_files_aenc.format( TEST_DIR=backup_dir, AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket, gpg_keyring=gpg_keyring, gpg_secret_keyring=gpg_secret_keyring ) fp.write(content) # write some content to the directory with open(os.path.join(twindb_config_dir, 'file'), 'w') as f: f.write("Hello world.") hostname = 'master1_1' s3_backup_path = 's3://%s/%s/hourly/files/%s' % \ (s3_client.bucket, hostname, backup_dir.replace('/', '_')) cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'ls'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 assert s3_backup_path in cout backup_to_restore = None for line in StringIO.StringIO(cout): if line.startswith(s3_backup_path): backup_to_restore = line.strip() break assert backup_to_restore.endswith('.tar.gz.gpg') key = backup_to_restore.lstrip('s3://').lstrip(s3_client.bucket).lstrip('/') local_copy = '%s/backup_to_restore.tar.gz.gpg' % twindb_config_dir s3_client.s3_client.download_file( s3_client.bucket, key, local_copy ) assert magic.from_file(local_copy) == 'data' dest_dir = '/tmp/simple_backup_aenc' cmd = ['mkdir', '-p', '/tmp/simple_backup_aenc'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'restore', 'file', '--dst', dest_dir, backup_to_restore] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 path_to_file_restored = '%s%s/file' % (dest_dir, backup_dir) cmd = ['test', '-f', path_to_file_restored] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 # And content is same path_to_file_orig = "%s/file" % backup_dir cmd = ['diff', '-Nur', path_to_file_orig, path_to_file_restored] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 assert not cout
def test_restore(master1, storage_server, config_content_ssh, docker_client, rsa_private_key): twindb_config_dir = get_twindb_config_dir(docker_client, master1["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" my_cnf_path = "%s/my.cnf" % twindb_config_dir ssh_key_host = "%s/id_rsa" % twindb_config_dir ssh_key_guest = "/etc/twindb/id_rsa" contents = """ [client] user=dba password=qwerty """ with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) with open(ssh_key_host, "w") as ssh_fd: ssh_fd.write(rsa_private_key) os.chmod(ssh_key_host, 0o600) with open(twindb_config_host, "w") as fp: content = config_content_ssh.format( PRIVATE_KEY=ssh_key_guest, HOST_IP=storage_server["ip"], MY_CNF="/etc/twindb/my.cnf", ) fp.write(content) cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "daily", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = [ "bash", "-c", "twindb-backup --config %s ls | grep /tmp/backup " "| grep mysql | sort | tail -1" % twindb_config_guest, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) url = cout.strip() assert_and_pause((ret == 0, ), cout) dst_dir = "/tmp/ssh_dest_restore/" cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "restore", "mysql", url, "--dst", dst_dir, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = ["find", dst_dir] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = ["test", "-f", "%s/backup-my.cnf" % dst_dir] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = ["test", "-f", "%s/ibdata1" % dst_dir] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = ["test", "-f", "%s/ib_logfile0" % dst_dir] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = ["test", "-f", "%s/ib_logfile1" % dst_dir] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = ["test", "-f", "%s/mysql/user.MYD" % dst_dir] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = ["test", "-f", "%s/xtrabackup_logfile" % dst_dir] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = [ "bash", "-c", "test -f %s/_config/etc/my.cnf || test -f %s/_config/etc/mysql/my.cnf" % (dst_dir, dst_dir), ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout)
def test_verify_on_master(master1, slave, storage_server, config_content_ssh, docker_client, rsa_private_key): twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" for cont in master1, slave: twindb_config_dir = get_twindb_config_dir(docker_client, cont["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir my_cnf_path = "%s/my.cnf" % twindb_config_dir ssh_key_host = "%s/id_rsa" % twindb_config_dir ssh_key_guest = "/etc/twindb/id_rsa" contents = dedent(""" [client] user=dba password=qwerty """) with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) my_cnf.flush() with open(ssh_key_host, "w") as ssh_fd: ssh_fd.write(rsa_private_key) ssh_fd.flush() with open(twindb_config_host, "w") as fp: content = config_content_ssh.format( PRIVATE_KEY=ssh_key_guest, HOST_IP=storage_server["ip"], MY_CNF="/etc/twindb/my.cnf", ) fp.write(content) fp.flush() cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "daily", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) LOG.info(cout) assert ret == 0 cmd = [ "bash", "-c", "twindb-backup --config %s ls | grep /tmp/backup " "| grep mysql | sort | tail -1" % twindb_config_guest, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) url = cout.strip() LOG.info(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "verify", "mysql", url, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) LOG.info(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "verify", "mysql", "latest", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) LOG.info(cout) assert ret == 0 cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "verify", "mysql", "--hostname", "master1_1", "latest", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) LOG.info(cout) assert ret == 0
def test_clone(runner, master1, slave, docker_client, config_content_clone, client_my_cnf, rsa_private_key): twindb_config_dir = get_twindb_config_dir(docker_client, runner['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir private_key_host = "%s/private_key" % twindb_config_dir private_key_guest = "/etc/twindb/private_key" with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(private_key_host, "w") as key_fd: key_fd.write(rsa_private_key) with open(twindb_config_host, 'w') as fp: content = config_content_clone.format(PRIVATE_KEY=private_key_guest, MY_CNF='/etc/twindb/my.cnf') fp.write(content) cmd = '/usr/sbin/sshd' LOG.info('Run SSH daemon on master1_1') ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'clone', 'mysql', '%s:3306' % master1['ip'], '%s:3306' % slave['ip'] ] pause_test(' '.join(cmd)) ret, cout = docker_execute(docker_client, runner['Id'], cmd) print(cout) assert ret == 0 sql_master_2 = RemoteMySQLSource({ "ssh_host": slave['ip'], "ssh_user": '******', "ssh_key": private_key_guest, "mysql_connect_info": MySQLConnectInfo(my_cnf_path, hostname=slave['ip']), "run_type": INTERVALS[0], "backup_type": 'full' }) timeout = time.time() + 30 while time.time() < timeout: with sql_master_2.get_connection() as conn: with conn.cursor() as cursor: cursor.execute('SHOW SLAVE STATUS') row = cursor.fetchone() if row['Slave_IO_Running'] == 'Yes' \ and row['Slave_SQL_Running'] == 'Yes': LOG.info('Replication is up and running') return LOG.error('Replication is not running after 30 seconds timeout') assert False
def test__take_file_backup(master1, docker_client, s3_client, config_content_files_only): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' backup_dir = "/etc/twindb" with open(twindb_config_host, 'w') as fp: content = config_content_files_only.format( TEST_DIR=backup_dir, AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket ) fp.write(content) cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 # Check that backup copy is in "twindb-backup ls" output hostname = 'master1_1' s3_backup_path = 's3://%s/%s/hourly/files/%s' % ( s3_client.bucket, hostname, backup_dir.replace('/', '_') ) cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'ls'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 assert s3_backup_path in cout backup_to_restore = None for line in StringIO.StringIO(cout): if line.startswith(s3_backup_path): backup_to_restore = line.strip() break cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'restore', 'file', '--dst', '/tmp/restore', backup_to_restore] # print('test paused') # print(' '.join(cmd)) # from time import sleep # sleep(36000) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 # Check that restored file exists path_to_file_restored = '/tmp/restore/etc/twindb/twindb-backup-1.cfg' cmd = ['ls', path_to_file_restored] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 # And content is same cmd = ['diff', '/tmp/restore/etc/twindb/twindb-backup-1.cfg', twindb_config_guest] ret, cout = docker_execute(docker_client, master1['Id'], cmd) # empty output assert not cout # zero exit code if no differences assert ret == 0
def test_restore(master1, storage_server, config_content_ssh, docker_client, rsa_private_key): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir ssh_key_host = "%s/id_rsa" % twindb_config_dir ssh_key_guest = '/etc/twindb/id_rsa' contents = """ [client] user=dba password=qwerty """ with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) with open(ssh_key_host, "w") as ssh_fd: ssh_fd.write(rsa_private_key) with open(twindb_config_host, 'w') as fp: content = config_content_ssh.format( PRIVATE_KEY=ssh_key_guest, HOST_IP=storage_server['ip'], MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily' ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = [ "bash", "-c", "twindb-backup --config %s ls | grep /tmp/backup " "| grep mysql | sort | tail -1" % twindb_config_guest ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) url = cout.strip() LOG.info(cout) assert ret == 0 dst_dir = "/tmp/ssh_dest_restore/" cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'restore', 'mysql', url, "--dst", dst_dir] # print('Test paused') # print(' '.join(cmd)) # import time # time.sleep(36000) ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['find', dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/backup-my.cnf' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/ibdata1' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/ib_logfile0' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/ib_logfile1' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/mysql/user.MYD' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = ['test', '-f', '%s/xtrabackup_logfile' % dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = [ "bash", "-c", 'test -f %s/_config/etc/my.cnf || test -f %s/_config/etc/mysql/my.cnf' % (dst_dir, dst_dir) ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0
def test_verify_on_master( master1, slave, storage_server, config_content_ssh, docker_client, rsa_private_key): twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' for cont in master1, slave: twindb_config_dir = get_twindb_config_dir(docker_client, cont['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir my_cnf_path = "%s/my.cnf" % twindb_config_dir ssh_key_host = "%s/id_rsa" % twindb_config_dir ssh_key_guest = '/etc/twindb/id_rsa' contents = dedent( """ [client] user=dba password=qwerty """ ) with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) my_cnf.flush() with open(ssh_key_host, "w") as ssh_fd: ssh_fd.write(rsa_private_key) ssh_fd.flush() with open(twindb_config_host, 'w') as fp: content = config_content_ssh.format( PRIVATE_KEY=ssh_key_guest, HOST_IP=storage_server['ip'], MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) fp.flush() cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily' ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = [ "bash", "-c", "twindb-backup --config %s ls | grep /tmp/backup " "| grep mysql | sort | tail -1" % twindb_config_guest ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) url = cout.strip() LOG.info(cout) assert ret == 0 cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'verify', 'mysql', url, ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'verify', 'mysql', 'latest', ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0 cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'verify', 'mysql', '--hostname', 'master1_1', 'latest', ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) LOG.info(cout) assert ret == 0
def test_clone( runner, master1, slave, docker_client, config_content_clone, client_my_cnf, rsa_private_key): twindb_config_dir = get_twindb_config_dir(docker_client, runner['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir private_key_host = "%s/private_key" % twindb_config_dir private_key_guest = "/etc/twindb/private_key" with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(private_key_host, "w") as key_fd: key_fd.write(rsa_private_key) with open(twindb_config_host, 'w') as fp: content = config_content_clone.format( PRIVATE_KEY=private_key_guest, MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = '/usr/sbin/sshd' LOG.info('Run SSH daemon on master1_1') ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) cmd = [ 'twindb-backup', '--debug', '--config', twindb_config_guest, 'clone', 'mysql', '%s:3306' % master1['ip'], '%s:3306' % slave['ip'] ] pause_test(' '.join(cmd)) ret, cout = docker_execute(docker_client, runner['Id'], cmd) print(cout) assert ret == 0 sql_master_2 = RemoteMySQLSource({ "ssh_host": slave['ip'], "ssh_user": '******', "ssh_key": private_key_guest, "mysql_connect_info": MySQLConnectInfo( my_cnf_path, hostname=slave['ip'] ), "run_type": INTERVALS[0], "backup_type": 'full' }) timeout = time.time() + 30 while time.time() < timeout: with sql_master_2.get_connection() as conn: with conn.cursor() as cursor: cursor.execute('SHOW SLAVE STATUS') row = cursor.fetchone() if row['Slave_IO_Running'] == 'Yes' \ and row['Slave_SQL_Running'] == 'Yes': LOG.info('Replication is up and running') return LOG.error('Replication is not running after 30 seconds timeout') assert False
def test_backup(master1, storage_server, config_content_ssh, docker_client, rsa_private_key): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir ssh_key_host = "%s/id_rsa" % twindb_config_dir ssh_key_guest = '/etc/twindb/id_rsa' contents = """ [client] user=dba password=qwerty """ with open(my_cnf_path, "w") as my_cnf: my_cnf.write(contents) with open(ssh_key_host, "w") as ssh_fd: ssh_fd.write(rsa_private_key) with open(twindb_config_host, 'w') as fp: content = config_content_ssh.format( PRIVATE_KEY=ssh_key_guest, HOST_IP=storage_server['ip'], MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly'] # print('Test paused') # print(' '.join(cmd)) # import time # time.sleep(36000) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = [ 'twindb-backup', '--config', twindb_config_guest, 'status' ] ret, cout = docker_execute(docker_client, master1['Id'], cmd) assert ret == 0 status = json.loads(cout) assert len(status["hourly"]) == 1 cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['test', '-d', '/tmp/backup'] ret, cout = docker_execute(docker_client, storage_server['Id'], cmd) print(cout) assert ret == 0 dir_path = "/var/backup/local/master1_1/hourly/mysql" cmd = ["bash", "-c", "ls %s | wc -l" % dir_path] ret, cout = docker_execute(docker_client, master1['Id'], cmd, tty=True) print(cout) assert ret == 0 assert '1' in cout cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 dir_path = "/var/backup/local/master1_1/daily/mysql" cmd = ["bash", "-c", "ls %s | wc -l" % dir_path] ret, cout = docker_execute(docker_client, master1['Id'], cmd, tty=True) print(cout) assert ret == 0 assert '1' in cout
def test__take_mysql_backup_aenc_suffix_gpg( master1, docker_client, s3_client, config_content_mysql_aenc, gpg_public_key, gpg_private_key, client_my_cnf, ): twindb_config_dir = get_twindb_config_dir(docker_client, master1["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) gpg_public_key_path_host = "%s/public_key" % twindb_config_dir gpg_private_key_path_host = "%s/private_key" % twindb_config_dir gpg_private_key_path_guest = "/etc/twindb/private_key" gpg_keyring = "/etc/twindb/keyring" gpg_secret_keyring = "/etc/twindb/secret_keyring" with open(gpg_public_key_path_host, "w") as fd: fd.write(gpg_public_key) with open(gpg_private_key_path_host, "w") as fd: fd.write(gpg_private_key) cmd = ["rm", "-f", gpg_keyring, gpg_secret_keyring] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = [ "gpg", "--no-default-keyring", "--keyring", gpg_keyring, "--secret-keyring", gpg_secret_keyring, "--yes", "--no-tty", "--batch", "--import", gpg_private_key_path_guest, ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 with open(twindb_config_host, "w") as fp: content = config_content_mysql_aenc.format( AWS_ACCESS_KEY_ID=os.environ["AWS_ACCESS_KEY_ID"], AWS_SECRET_ACCESS_KEY=os.environ["AWS_SECRET_ACCESS_KEY"], BUCKET=s3_client.bucket, gpg_keyring=gpg_keyring, gpg_secret_keyring=gpg_secret_keyring, daily_copies=1, hourly_copies=2, MY_CNF="/etc/twindb/my.cnf", ) fp.write(content) cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "backup", "daily", ] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 cmd = ["twindb-backup", "--config", twindb_config_guest, "status"] ret, cout = docker_execute(docker_client, master1["Id"], cmd) print(cout) assert ret == 0 key = list(json.loads(cout)["daily"].keys())[0] assert key.endswith("xbstream.gz.gpg") local_copy = "%s/mysql_backup.tar.gz.gpg" % twindb_config_dir s3_client.s3_client.download_file(s3_client.bucket, key, local_copy) assert magic.from_file(local_copy) == "data"
def test__restore_mysql_inc_creates_log_files(master1, docker_client, s3_client, config_content_mysql_only, client_my_cnf): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(twindb_config_host, 'w') as fp: content = config_content_mysql_only.format( AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket, daily_copies=1, hourly_copies=2, MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = ['ls', '-la', '/var/lib/mysql'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'hourly'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--config', twindb_config_guest, 'status'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 status = json.loads(cout) key = status['hourly'].keys()[0] backup_copy = 's3://' + s3_client.bucket + '/' + key dst_dir = '/tmp/dst_full_log_files' ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'restore', 'mysql', backup_copy, '--dst', dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['find', dst_dir] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['test', '-f', '/tmp/dst_full_log_files/backup-my.cnf'] print(cmd) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['test', '-f', '/tmp/dst_full_log_files/ibdata1'] print(cmd) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['test', '-f', '/tmp/dst_full_log_files/ib_logfile0'] print(cmd) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['test', '-f', '/tmp/dst_full_log_files/ib_logfile1'] print(cmd) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['test', '-f', '/tmp/dst_full_log_files/mysql/user.MYD'] print(cmd) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['test', '-f', '/tmp/dst_full_log_files/xtrabackup_logfile'] print(cmd) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = [ "bash", "-c", 'test -f /tmp/dst_full_log_files/_config/etc/my.cnf ' '|| test -f /tmp/dst_full_log_files/_config/etc/mysql/my.cnf' ] print(cmd) ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0
def test__take_mysql_backup_aenc_suffix_gpg(master1, docker_client, s3_client, config_content_mysql_aenc, gpg_public_key, gpg_private_key, client_my_cnf): twindb_config_dir = get_twindb_config_dir(docker_client, master1['Id']) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = '/etc/twindb/twindb-backup-1.cfg' my_cnf_path = "%s/my.cnf" % twindb_config_dir with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) gpg_public_key_path_host = "%s/public_key" % twindb_config_dir gpg_private_key_path_host = "%s/private_key" % twindb_config_dir gpg_private_key_path_guest = "/etc/twindb/private_key" gpg_keyring = "/etc/twindb/keyring" gpg_secret_keyring = "/etc/twindb/secret_keyring" with open(gpg_public_key_path_host, "w") as fd: fd.write(gpg_public_key) with open(gpg_private_key_path_host, "w") as fd: fd.write(gpg_private_key) cmd = ['rm', '-f', gpg_keyring, gpg_secret_keyring] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['gpg', '--no-default-keyring', '--keyring', gpg_keyring, '--secret-keyring', gpg_secret_keyring, '--yes', '--no-tty', '--batch', '--import', gpg_private_key_path_guest] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 with open(twindb_config_host, 'w') as fp: content = config_content_mysql_aenc.format( AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY'], BUCKET=s3_client.bucket, gpg_keyring=gpg_keyring, gpg_secret_keyring=gpg_secret_keyring, daily_copies=1, hourly_copies=2, MY_CNF='/etc/twindb/my.cnf' ) fp.write(content) cmd = ['twindb-backup', '--debug', '--config', twindb_config_guest, 'backup', 'daily'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 cmd = ['twindb-backup', '--config', twindb_config_guest, 'status'] ret, cout = docker_execute(docker_client, master1['Id'], cmd) print(cout) assert ret == 0 key = json.loads(cout)['daily'].keys()[0] assert key.endswith('xbstream.gz.gpg') local_copy = '%s/mysql_backup.tar.gz.gpg' % twindb_config_dir s3_client.s3_client.download_file( s3_client.bucket, key, local_copy ) assert magic.from_file(local_copy) == 'data'
def test_clone( runner, master1, slave, docker_client, config_content_clone, client_my_cnf, rsa_private_key, ): twindb_config_dir = get_twindb_config_dir(docker_client, runner["Id"]) twindb_config_host = "%s/twindb-backup-1.cfg" % twindb_config_dir twindb_config_guest = "/etc/twindb/twindb-backup-1.cfg" my_cnf_path = "%s/my.cnf" % twindb_config_dir private_key_host = "%s/private_key" % twindb_config_dir private_key_guest = "/etc/twindb/private_key" with open(my_cnf_path, "w") as my_cnf: my_cnf.write(client_my_cnf) with open(private_key_host, "w") as key_fd: key_fd.write(rsa_private_key) with open(twindb_config_host, "w") as fp: content = config_content_clone.format(PRIVATE_KEY=private_key_guest, MY_CNF="/etc/twindb/my.cnf") fp.write(content) cmd = "/usr/sbin/sshd" LOG.info("Run SSH daemon on master1_1") ret, cout = docker_execute(docker_client, master1["Id"], cmd) assert_and_pause((ret == 0, ), cout) cmd = [ "twindb-backup", "--debug", "--config", twindb_config_guest, "clone", "mysql", "%s:3306" % master1["ip"], "%s:3306" % slave["ip"], ] ret, cout = docker_execute(docker_client, runner["Id"], cmd) assert_and_pause((ret == 0, ), cout) sql_master_2 = RemoteMySQLSource({ "ssh_host": slave["ip"], "ssh_user": "******", "ssh_key": private_key_guest, "mysql_connect_info": MySQLConnectInfo(my_cnf_path, hostname=slave["ip"]), "run_type": INTERVALS[0], "backup_type": "full", }) timeout = time.time() + 30 while time.time() < timeout: with sql_master_2.get_connection() as conn: with conn.cursor() as cursor: cursor.execute("SHOW SLAVE STATUS") row = cursor.fetchone() if (row["Slave_IO_Running"] == "Yes" and row["Slave_SQL_Running"] == "Yes"): LOG.info("Replication is up and running") return LOG.error("Replication is not running after 30 seconds timeout") assert False