db-sync-tool-kmi 2.11.6__py3-none-any.whl → 3.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- db_sync_tool/__main__.py +7 -252
- db_sync_tool/cli.py +733 -0
- db_sync_tool/database/process.py +94 -111
- db_sync_tool/database/utility.py +339 -121
- db_sync_tool/info.py +1 -1
- db_sync_tool/recipes/drupal.py +87 -12
- db_sync_tool/recipes/laravel.py +7 -6
- db_sync_tool/recipes/parsing.py +102 -0
- db_sync_tool/recipes/symfony.py +17 -28
- db_sync_tool/recipes/typo3.py +33 -54
- db_sync_tool/recipes/wordpress.py +13 -12
- db_sync_tool/remote/client.py +206 -71
- db_sync_tool/remote/file_transfer.py +303 -0
- db_sync_tool/remote/rsync.py +18 -15
- db_sync_tool/remote/system.py +2 -3
- db_sync_tool/remote/transfer.py +51 -47
- db_sync_tool/remote/utility.py +29 -30
- db_sync_tool/sync.py +52 -28
- db_sync_tool/utility/config.py +367 -0
- db_sync_tool/utility/config_resolver.py +573 -0
- db_sync_tool/utility/console.py +779 -0
- db_sync_tool/utility/exceptions.py +32 -0
- db_sync_tool/utility/helper.py +155 -148
- db_sync_tool/utility/info.py +53 -20
- db_sync_tool/utility/log.py +55 -31
- db_sync_tool/utility/logging_config.py +410 -0
- db_sync_tool/utility/mode.py +85 -150
- db_sync_tool/utility/output.py +122 -51
- db_sync_tool/utility/parser.py +33 -53
- db_sync_tool/utility/pure.py +93 -0
- db_sync_tool/utility/security.py +79 -0
- db_sync_tool/utility/system.py +277 -194
- db_sync_tool/utility/validation.py +2 -9
- db_sync_tool_kmi-3.0.2.dist-info/METADATA +99 -0
- db_sync_tool_kmi-3.0.2.dist-info/RECORD +44 -0
- {db_sync_tool_kmi-2.11.6.dist-info → db_sync_tool_kmi-3.0.2.dist-info}/WHEEL +1 -1
- db_sync_tool_kmi-2.11.6.dist-info/METADATA +0 -276
- db_sync_tool_kmi-2.11.6.dist-info/RECORD +0 -34
- {db_sync_tool_kmi-2.11.6.dist-info → db_sync_tool_kmi-3.0.2.dist-info}/entry_points.txt +0 -0
- {db_sync_tool_kmi-2.11.6.dist-info → db_sync_tool_kmi-3.0.2.dist-info/licenses}/LICENSE +0 -0
- {db_sync_tool_kmi-2.11.6.dist-info → db_sync_tool_kmi-3.0.2.dist-info}/top_level.txt +0 -0
db_sync_tool/remote/rsync.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: future_fstrings -*-
|
|
3
2
|
|
|
4
3
|
"""
|
|
5
4
|
rsync script
|
|
@@ -7,6 +6,7 @@ rsync script
|
|
|
7
6
|
|
|
8
7
|
import re
|
|
9
8
|
from db_sync_tool.utility import mode, system, output
|
|
9
|
+
from db_sync_tool.utility.console import get_output_manager
|
|
10
10
|
|
|
11
11
|
# Default options for rsync command
|
|
12
12
|
# https://wiki.ubuntuusers.de/rsync/
|
|
@@ -31,8 +31,10 @@ def get_password_environment(client):
|
|
|
31
31
|
if not client:
|
|
32
32
|
return ''
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
cfg = system.get_typed_config()
|
|
35
|
+
client_cfg = cfg.get_client(client)
|
|
36
|
+
if cfg.use_sshpass and not client_cfg.ssh_key and client_cfg.password:
|
|
37
|
+
return f'SSHPASS=\'{client_cfg.password}\' '
|
|
36
38
|
return ''
|
|
37
39
|
|
|
38
40
|
|
|
@@ -42,20 +44,19 @@ def get_authorization(client):
|
|
|
42
44
|
:param client: String
|
|
43
45
|
:return: String
|
|
44
46
|
"""
|
|
45
|
-
_ssh_key = None
|
|
46
47
|
if not client:
|
|
47
48
|
return ''
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
_ssh_port =
|
|
50
|
+
cfg = system.get_typed_config()
|
|
51
|
+
client_cfg = cfg.get_client(client)
|
|
52
|
+
_ssh_key = client_cfg.ssh_key
|
|
53
|
+
_ssh_port = client_cfg.port
|
|
53
54
|
|
|
54
55
|
if _ssh_key is None:
|
|
55
|
-
if
|
|
56
|
+
if cfg.use_sshpass and get_password_environment(client):
|
|
56
57
|
# In combination with SSHPASS environment variable
|
|
57
58
|
# https://www.redhat.com/sysadmin/ssh-automation-sshpass
|
|
58
|
-
return f'--rsh="sshpass -e ssh -p{_ssh_port} -o StrictHostKeyChecking=no -l {
|
|
59
|
+
return f'--rsh="sshpass -e ssh -p{_ssh_port} -o StrictHostKeyChecking=no -l {client_cfg.user}"'
|
|
59
60
|
else:
|
|
60
61
|
return f'-e "ssh -p{_ssh_port} -o StrictHostKeyChecking=no"'
|
|
61
62
|
else:
|
|
@@ -70,7 +71,9 @@ def get_host(client):
|
|
|
70
71
|
:return: String
|
|
71
72
|
"""
|
|
72
73
|
if mode.is_remote(client):
|
|
73
|
-
|
|
74
|
+
cfg = system.get_typed_config()
|
|
75
|
+
client_cfg = cfg.get_client(client)
|
|
76
|
+
return f'{client_cfg.user}@{client_cfg.host}:'
|
|
74
77
|
return ''
|
|
75
78
|
|
|
76
79
|
|
|
@@ -79,9 +82,10 @@ def get_options():
|
|
|
79
82
|
Prepare rsync options with stored default options and provided addtional options
|
|
80
83
|
:return: String
|
|
81
84
|
"""
|
|
85
|
+
cfg = system.get_typed_config()
|
|
82
86
|
_options = f'{" ".join(default_options)}'
|
|
83
|
-
if
|
|
84
|
-
_options += f'{
|
|
87
|
+
if cfg.use_rsync_options is not None:
|
|
88
|
+
_options += f'{cfg.use_rsync_options}'
|
|
85
89
|
return _options
|
|
86
90
|
|
|
87
91
|
|
|
@@ -91,8 +95,7 @@ def read_stats(stats):
|
|
|
91
95
|
:param stats: String
|
|
92
96
|
:return:
|
|
93
97
|
"""
|
|
94
|
-
|
|
95
|
-
print(f'{output.Subject.DEBUG}{output.CliFormat.BLACK}{stats}{output.CliFormat.ENDC}')
|
|
98
|
+
get_output_manager().debug(stats)
|
|
96
99
|
|
|
97
100
|
_file_size = parse_string(stats, r'Total transferred file size:\s*([\d.]+[MKG]?)')
|
|
98
101
|
|
db_sync_tool/remote/system.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: future_fstrings -*-
|
|
3
2
|
|
|
4
3
|
"""
|
|
5
4
|
System script
|
|
6
5
|
"""
|
|
7
6
|
|
|
8
|
-
import sys
|
|
9
7
|
from db_sync_tool.utility import mode, output, helper
|
|
8
|
+
from db_sync_tool.utility.exceptions import DbSyncError
|
|
10
9
|
from db_sync_tool.remote import client as remote_client
|
|
11
10
|
|
|
12
11
|
|
|
@@ -38,7 +37,7 @@ def run_ssh_command(command, ssh_client=remote_client.ssh_client_origin, client=
|
|
|
38
37
|
|
|
39
38
|
if err and exit_status != 0:
|
|
40
39
|
helper.run_script(client=client, script='error')
|
|
41
|
-
|
|
40
|
+
raise DbSyncError(err)
|
|
42
41
|
elif err:
|
|
43
42
|
output.message(output.Subject.WARNING, err, True)
|
|
44
43
|
|
db_sync_tool/remote/transfer.py
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: future_fstrings -*-
|
|
3
2
|
|
|
4
3
|
"""
|
|
5
4
|
Transfer script
|
|
6
5
|
"""
|
|
7
6
|
|
|
8
|
-
import sys
|
|
9
7
|
from db_sync_tool.utility import mode, system, helper, output
|
|
10
8
|
from db_sync_tool.database import utility as database_utility
|
|
11
9
|
from db_sync_tool.remote import utility, client, rsync
|
|
@@ -16,6 +14,7 @@ def transfer_origin_database_dump():
|
|
|
16
14
|
Transfer the origin database dump files
|
|
17
15
|
:return:
|
|
18
16
|
"""
|
|
17
|
+
cfg = system.get_typed_config()
|
|
19
18
|
if not mode.is_import():
|
|
20
19
|
if mode.get_sync_mode() == mode.SyncMode.RECEIVER:
|
|
21
20
|
get_origin_database_dump(helper.get_dump_dir(mode.Client.TARGET))
|
|
@@ -31,7 +30,7 @@ def transfer_origin_database_dump():
|
|
|
31
30
|
put_origin_database_dump(system.default_local_sync_path)
|
|
32
31
|
elif mode.get_sync_mode() == mode.SyncMode.SYNC_REMOTE or mode.get_sync_mode() == mode.SyncMode.SYNC_LOCAL:
|
|
33
32
|
system.check_target_configuration()
|
|
34
|
-
elif
|
|
33
|
+
elif cfg.is_same_client:
|
|
35
34
|
utility.remove_origin_database_dump(True)
|
|
36
35
|
else:
|
|
37
36
|
system.check_target_configuration()
|
|
@@ -43,6 +42,7 @@ def get_origin_database_dump(target_path):
|
|
|
43
42
|
:param target_path: String
|
|
44
43
|
:return:
|
|
45
44
|
"""
|
|
45
|
+
cfg = system.get_typed_config()
|
|
46
46
|
output.message(
|
|
47
47
|
output.Subject.ORIGIN,
|
|
48
48
|
'Downloading database dump',
|
|
@@ -51,16 +51,16 @@ def get_origin_database_dump(target_path):
|
|
|
51
51
|
if mode.get_sync_mode() != mode.SyncMode.PROXY:
|
|
52
52
|
helper.check_and_create_dump_dir(mode.Client.TARGET, target_path)
|
|
53
53
|
|
|
54
|
-
if not
|
|
55
|
-
_remotepath =
|
|
54
|
+
if not cfg.dry_run:
|
|
55
|
+
_remotepath = database_utility.get_dump_gz_path(mode.Client.ORIGIN)
|
|
56
56
|
_localpath = target_path
|
|
57
57
|
|
|
58
|
-
if
|
|
58
|
+
if cfg.use_rsync:
|
|
59
59
|
rsync.run_rsync_command(
|
|
60
60
|
remote_client=mode.Client.ORIGIN,
|
|
61
61
|
origin_path=_remotepath,
|
|
62
62
|
target_path=_localpath,
|
|
63
|
-
origin_ssh=
|
|
63
|
+
origin_ssh=cfg.origin.user + '@' + cfg.origin.host
|
|
64
64
|
)
|
|
65
65
|
else:
|
|
66
66
|
#
|
|
@@ -68,29 +68,46 @@ def get_origin_database_dump(target_path):
|
|
|
68
68
|
# https://github.com/paramiko/paramiko/issues/60
|
|
69
69
|
#
|
|
70
70
|
sftp = get_sftp_client(client.ssh_client_origin)
|
|
71
|
-
sftp.get(
|
|
72
|
-
target_path + database_utility.database_dump_file_name + '.
|
|
71
|
+
sftp.get(database_utility.get_dump_gz_path(mode.Client.ORIGIN),
|
|
72
|
+
target_path + database_utility.database_dump_file_name + '.gz', download_status)
|
|
73
73
|
sftp.close()
|
|
74
|
-
if not system.config['mute']:
|
|
75
|
-
print('')
|
|
76
74
|
|
|
77
75
|
utility.remove_origin_database_dump()
|
|
78
76
|
|
|
79
77
|
|
|
78
|
+
def _transfer_status(sent, size, direction, subject_override=None):
|
|
79
|
+
"""
|
|
80
|
+
Print transfer progress status.
|
|
81
|
+
|
|
82
|
+
:param sent: Bytes transferred
|
|
83
|
+
:param size: Total bytes
|
|
84
|
+
:param direction: 'downloaded' or 'uploaded'
|
|
85
|
+
:param subject_override: Optional subject prefix override
|
|
86
|
+
"""
|
|
87
|
+
cfg = system.get_typed_config()
|
|
88
|
+
if cfg.mute:
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
from db_sync_tool.utility.console import get_output_manager
|
|
92
|
+
output_manager = get_output_manager()
|
|
93
|
+
|
|
94
|
+
# Track transfer size for final summary
|
|
95
|
+
if sent == size:
|
|
96
|
+
output_manager.track_stat("size", size)
|
|
97
|
+
|
|
98
|
+
# Use OutputManager for progress display
|
|
99
|
+
msg = "Downloading" if direction == "downloaded" else "Uploading"
|
|
100
|
+
output_manager.progress(sent, size, msg)
|
|
101
|
+
|
|
102
|
+
|
|
80
103
|
def download_status(sent, size):
|
|
81
104
|
"""
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
:param
|
|
85
|
-
:
|
|
105
|
+
Callback for SFTP download progress.
|
|
106
|
+
|
|
107
|
+
:param sent: Bytes transferred
|
|
108
|
+
:param size: Total bytes
|
|
86
109
|
"""
|
|
87
|
-
|
|
88
|
-
sent_mb = round(float(sent) / 1024 / 1024, 1)
|
|
89
|
-
size = round(float(size) / 1024 / 1024, 1)
|
|
90
|
-
sys.stdout.write(
|
|
91
|
-
output.Subject.ORIGIN + output.CliFormat.BLACK + '[REMOTE]' + output.CliFormat.ENDC + " Status: {0} MB of {1} MB downloaded".
|
|
92
|
-
format(sent_mb, size, ))
|
|
93
|
-
sys.stdout.write('\r')
|
|
110
|
+
_transfer_status(sent, size, 'downloaded')
|
|
94
111
|
|
|
95
112
|
|
|
96
113
|
def put_origin_database_dump(origin_path):
|
|
@@ -99,6 +116,7 @@ def put_origin_database_dump(origin_path):
|
|
|
99
116
|
:param origin_path: String
|
|
100
117
|
:return:
|
|
101
118
|
"""
|
|
119
|
+
cfg = system.get_typed_config()
|
|
102
120
|
if mode.get_sync_mode() == mode.SyncMode.PROXY:
|
|
103
121
|
_subject = output.Subject.LOCAL
|
|
104
122
|
else:
|
|
@@ -111,16 +129,16 @@ def put_origin_database_dump(origin_path):
|
|
|
111
129
|
)
|
|
112
130
|
helper.check_and_create_dump_dir(mode.Client.TARGET, helper.get_dump_dir(mode.Client.TARGET))
|
|
113
131
|
|
|
114
|
-
if not
|
|
115
|
-
_localpath = origin_path + database_utility.database_dump_file_name + '.
|
|
132
|
+
if not cfg.dry_run:
|
|
133
|
+
_localpath = origin_path + database_utility.database_dump_file_name + '.gz'
|
|
116
134
|
_remotepath = helper.get_dump_dir(mode.Client.TARGET) + '/'
|
|
117
135
|
|
|
118
|
-
if
|
|
136
|
+
if cfg.use_rsync:
|
|
119
137
|
rsync.run_rsync_command(
|
|
120
138
|
remote_client=mode.Client.TARGET,
|
|
121
139
|
origin_path=_localpath,
|
|
122
140
|
target_path=_remotepath,
|
|
123
|
-
target_ssh=
|
|
141
|
+
target_ssh=cfg.target.user + '@' + cfg.target.host
|
|
124
142
|
)
|
|
125
143
|
else:
|
|
126
144
|
#
|
|
@@ -128,35 +146,21 @@ def put_origin_database_dump(origin_path):
|
|
|
128
146
|
# https://github.com/paramiko/paramiko/issues/60
|
|
129
147
|
#
|
|
130
148
|
sftp = get_sftp_client(client.ssh_client_target)
|
|
131
|
-
sftp.put(origin_path + database_utility.database_dump_file_name + '.
|
|
132
|
-
|
|
149
|
+
sftp.put(origin_path + database_utility.database_dump_file_name + '.gz',
|
|
150
|
+
database_utility.get_dump_gz_path(mode.Client.TARGET),
|
|
133
151
|
upload_status)
|
|
134
152
|
sftp.close()
|
|
135
|
-
if not system.config['mute']:
|
|
136
|
-
print('')
|
|
137
153
|
|
|
138
154
|
|
|
139
155
|
|
|
140
156
|
def upload_status(sent, size):
|
|
141
157
|
"""
|
|
142
|
-
|
|
143
|
-
:param sent: Float
|
|
144
|
-
:param size: Float
|
|
145
|
-
:return:
|
|
146
|
-
"""
|
|
147
|
-
if not system.config['mute']:
|
|
148
|
-
sent_mb = round(float(sent) / 1024 / 1024, 1)
|
|
149
|
-
size = round(float(size) / 1024 / 1024, 1)
|
|
158
|
+
Callback for SFTP upload progress.
|
|
150
159
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
sys.stdout.write(
|
|
157
|
-
_subject + " Status: {0} MB of {1} MB uploaded".
|
|
158
|
-
format(sent_mb, size, ))
|
|
159
|
-
sys.stdout.write('\r')
|
|
160
|
+
:param sent: Bytes transferred
|
|
161
|
+
:param size: Total bytes
|
|
162
|
+
"""
|
|
163
|
+
_transfer_status(sent, size, 'uploaded')
|
|
160
164
|
|
|
161
165
|
|
|
162
166
|
def get_sftp_client(ssh_client):
|
db_sync_tool/remote/utility.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: future_fstrings -*-
|
|
3
2
|
|
|
4
3
|
"""
|
|
5
4
|
Utility script
|
|
@@ -9,7 +8,6 @@ import os
|
|
|
9
8
|
import paramiko
|
|
10
9
|
from db_sync_tool.utility import mode, system, helper, output
|
|
11
10
|
from db_sync_tool.database import utility as database_utility
|
|
12
|
-
from db_sync_tool.remote import client as remote_client
|
|
13
11
|
|
|
14
12
|
|
|
15
13
|
def remove_origin_database_dump(keep_compressed_file=False):
|
|
@@ -24,34 +22,33 @@ def remove_origin_database_dump(keep_compressed_file=False):
|
|
|
24
22
|
True
|
|
25
23
|
)
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
cfg = system.get_typed_config()
|
|
26
|
+
if cfg.dry_run:
|
|
28
27
|
return
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
)
|
|
36
|
-
if not keep_compressed_file:
|
|
29
|
+
_gz_path = database_utility.get_dump_gz_path(mode.Client.ORIGIN)
|
|
30
|
+
|
|
31
|
+
# With streaming compression, only .gz file exists on origin (no separate .sql)
|
|
32
|
+
if not keep_compressed_file:
|
|
33
|
+
if mode.is_origin_remote():
|
|
37
34
|
mode.run_command(
|
|
38
|
-
helper.get_command(mode.Client.ORIGIN, 'rm') + ' ' +
|
|
35
|
+
helper.get_command(mode.Client.ORIGIN, 'rm') + ' ' + _gz_path,
|
|
39
36
|
mode.Client.ORIGIN
|
|
40
37
|
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
os.remove(f'{_file_path}.tar.gz')
|
|
38
|
+
else:
|
|
39
|
+
if os.path.isfile(_gz_path):
|
|
40
|
+
os.remove(_gz_path)
|
|
45
41
|
|
|
46
42
|
if keep_compressed_file:
|
|
47
|
-
|
|
43
|
+
origin_cfg = cfg.origin
|
|
44
|
+
if origin_cfg.keep_dumps is not None:
|
|
48
45
|
helper.clean_up_dump_dir(mode.Client.ORIGIN,
|
|
49
46
|
helper.get_dump_dir(mode.Client.ORIGIN) + '*',
|
|
50
|
-
|
|
47
|
+
origin_cfg.keep_dumps)
|
|
51
48
|
|
|
52
49
|
output.message(
|
|
53
50
|
output.Subject.INFO,
|
|
54
|
-
f'Database dump file is saved to: {
|
|
51
|
+
f'Database dump file is saved to: {_gz_path}',
|
|
55
52
|
True,
|
|
56
53
|
True
|
|
57
54
|
)
|
|
@@ -62,17 +59,22 @@ def remove_target_database_dump():
|
|
|
62
59
|
Removing the target database dump files
|
|
63
60
|
:return:
|
|
64
61
|
"""
|
|
65
|
-
|
|
62
|
+
cfg = system.get_typed_config()
|
|
63
|
+
_file_path = database_utility.get_dump_file_path(mode.Client.TARGET)
|
|
64
|
+
_gz_file_path = database_utility.get_dump_gz_path(mode.Client.TARGET)
|
|
66
65
|
|
|
67
66
|
#
|
|
68
67
|
# Move dump to specified directory
|
|
69
68
|
#
|
|
70
|
-
if
|
|
69
|
+
if cfg.keep_dump:
|
|
71
70
|
helper.create_local_temporary_data_dir()
|
|
72
|
-
|
|
71
|
+
# Copy the .gz file (streaming compression means only .gz exists)
|
|
72
|
+
# database_dump_file_name is guaranteed to be set at this point
|
|
73
|
+
_dump_name = database_utility.database_dump_file_name or ''
|
|
74
|
+
_keep_dump_path = system.default_local_sync_path + _dump_name + '.gz'
|
|
73
75
|
mode.run_command(
|
|
74
76
|
helper.get_command('target',
|
|
75
|
-
'cp') + ' ' +
|
|
77
|
+
'cp') + ' ' + _gz_file_path + ' ' + _keep_dump_path,
|
|
76
78
|
mode.Client.TARGET
|
|
77
79
|
)
|
|
78
80
|
output.message(
|
|
@@ -92,23 +94,20 @@ def remove_target_database_dump():
|
|
|
92
94
|
True
|
|
93
95
|
)
|
|
94
96
|
|
|
95
|
-
if
|
|
97
|
+
if cfg.dry_run:
|
|
96
98
|
return
|
|
97
99
|
|
|
98
100
|
if mode.is_target_remote():
|
|
101
|
+
# Remove both decompressed .sql and compressed .gz
|
|
99
102
|
mode.run_command(
|
|
100
|
-
helper.get_command(mode.Client.TARGET, 'rm') + ' ' + _file_path,
|
|
101
|
-
mode.Client.TARGET
|
|
102
|
-
)
|
|
103
|
-
mode.run_command(
|
|
104
|
-
helper.get_command(mode.Client.TARGET, 'rm') + ' ' + _file_path + '.tar.gz',
|
|
103
|
+
helper.get_command(mode.Client.TARGET, 'rm') + ' -f ' + _file_path + ' ' + _gz_file_path,
|
|
105
104
|
mode.Client.TARGET
|
|
106
105
|
)
|
|
107
106
|
else:
|
|
108
107
|
if os.path.isfile(_file_path):
|
|
109
108
|
os.remove(_file_path)
|
|
110
|
-
if os.path.isfile(
|
|
111
|
-
os.remove(
|
|
109
|
+
if os.path.isfile(_gz_file_path):
|
|
110
|
+
os.remove(_gz_file_path)
|
|
112
111
|
|
|
113
112
|
|
|
114
113
|
def check_keys_from_ssh_agent():
|
db_sync_tool/sync.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: future_fstrings -*-
|
|
3
2
|
"""
|
|
4
3
|
Sync script
|
|
5
4
|
"""
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
from db_sync_tool.
|
|
9
|
-
from db_sync_tool.
|
|
6
|
+
import sys
|
|
7
|
+
from db_sync_tool.utility import system, helper, info, output
|
|
8
|
+
from db_sync_tool.utility.exceptions import DbSyncError
|
|
9
|
+
from db_sync_tool.database import process, utility as database_utility
|
|
10
|
+
from db_sync_tool.remote import transfer, client as remote_client, file_transfer
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class Sync:
|
|
@@ -29,6 +30,8 @@ class Sync:
|
|
|
29
30
|
use_rsync=False,
|
|
30
31
|
use_rsync_options=None,
|
|
31
32
|
reverse=False,
|
|
33
|
+
with_files=False,
|
|
34
|
+
files_only=False,
|
|
32
35
|
config=None,
|
|
33
36
|
args=None):
|
|
34
37
|
"""
|
|
@@ -47,34 +50,55 @@ class Sync:
|
|
|
47
50
|
:param use_rsync:
|
|
48
51
|
:param use_rsync_options:
|
|
49
52
|
:param reverse:
|
|
53
|
+
:param with_files:
|
|
54
|
+
:param files_only:
|
|
50
55
|
:param config:
|
|
51
56
|
:param args:
|
|
52
57
|
"""
|
|
53
58
|
if config is None:
|
|
54
59
|
config = {}
|
|
55
60
|
|
|
56
|
-
info.print_header(mute)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
info.print_header(mute, verbose)
|
|
62
|
+
try:
|
|
63
|
+
system.check_args_options(
|
|
64
|
+
config_file,
|
|
65
|
+
verbose,
|
|
66
|
+
yes,
|
|
67
|
+
mute,
|
|
68
|
+
dry_run,
|
|
69
|
+
import_file,
|
|
70
|
+
dump_name,
|
|
71
|
+
keep_dump,
|
|
72
|
+
host_file,
|
|
73
|
+
clear,
|
|
74
|
+
force_password,
|
|
75
|
+
use_rsync,
|
|
76
|
+
use_rsync_options,
|
|
77
|
+
reverse,
|
|
78
|
+
with_files,
|
|
79
|
+
files_only
|
|
80
|
+
)
|
|
81
|
+
system.get_configuration(config, args)
|
|
82
|
+
system.check_authorizations()
|
|
83
|
+
|
|
84
|
+
cfg = system.get_typed_config()
|
|
85
|
+
|
|
86
|
+
# Database sync (skip if --files-only)
|
|
87
|
+
if not cfg.files_only:
|
|
88
|
+
process.create_origin_database_dump()
|
|
89
|
+
transfer.transfer_origin_database_dump()
|
|
90
|
+
process.import_database_dump()
|
|
91
|
+
|
|
92
|
+
# File sync (only if --with-files or --files-only)
|
|
93
|
+
file_transfer.transfer_files()
|
|
94
|
+
|
|
95
|
+
helper.clean_up()
|
|
96
|
+
except DbSyncError as e:
|
|
97
|
+
output.message(output.Subject.ERROR, str(e), do_print=True)
|
|
98
|
+
sys.exit(1)
|
|
99
|
+
finally:
|
|
100
|
+
# Always clean up sensitive credential files, even on error
|
|
101
|
+
database_utility.cleanup_mysql_config_files()
|
|
102
|
+
remote_client.close_ssh_clients()
|
|
103
|
+
file_transfer.cleanup()
|
|
80
104
|
info.print_footer()
|