backup_minister 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/bin/backup_minister +28 -2
- data/lib/backup_minister.rb +11 -0
- data/lib/backup_minister/agent.rb +64 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b944e992d64bd98fe8c5843d9a061a063ce2d159
|
4
|
+
data.tar.gz: e2c999388a8ce746da8be7398fc81d9c4f8c85b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 788d174df306e30204ac0535aab390d815c14b8946473d8d8bf1eef9de322a6156bc75a7ec2a2a67d85baa5370b960db1019295833e117c9b6107cbfb9b50500
|
7
|
+
data.tar.gz: 0a1eef9e35f4b30d3ba6e9f058d412baa7f5e98ec7348ba64feb45e51b5f3c5da9fba7da1560fd5b2a7d98300efc47dda0b1552f7402e1d61aaca2a757fadeb3
|
data/bin/backup_minister
CHANGED
@@ -3,12 +3,38 @@ require 'backup_minister'
|
|
3
3
|
require 'thor'
|
4
4
|
|
5
5
|
class CLI < Thor
|
6
|
+
desc 'backup_database', 'Backup DB and place it one remote server.'
|
7
|
+
option :project_name, type: :string, required: true, aliases: :name
|
8
|
+
def backup_database
|
9
|
+
agent = BackupMinister::Agent.new
|
10
|
+
backup_file_path = agent.backup_database(options[:project_name])
|
11
|
+
if backup_file_path
|
12
|
+
digest = agent.file_sha256_hash(backup_file_path)
|
13
|
+
placed_file_path = agent.place_database_backup(backup_file_path)
|
14
|
+
if agent.process_remote_database_backup(options[:project_name], placed_file_path, digest)
|
15
|
+
LOGGER.info "Database for project #{options[:project_name]} placed on remote server."
|
16
|
+
else
|
17
|
+
LOGGER.error "Could not place database backup for project #{options[:project_name]} on remote server."
|
18
|
+
exit!(true)
|
19
|
+
end
|
20
|
+
else
|
21
|
+
LOGGER.error "Could not create database backup for project #{options[:project_name]}."
|
22
|
+
exit!(true)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
6
26
|
desc 'backup_database', 'Move database TAR GZ archive to destination directory'
|
7
27
|
option :project_name, type: :string, required: true, aliases: :name
|
8
28
|
option :file, type: :string, required: true, banner: '</Path/to/database/backup.tar.gz>'
|
9
|
-
|
29
|
+
option :sha256, type: :string, banner: 'Hash of uploaded file'
|
30
|
+
def store_database_backup
|
10
31
|
server = BackupMinister::Server.new
|
11
|
-
server.place_database_backup(options[:project_name], options[:file])
|
32
|
+
if server.place_database_backup(options[:project_name], options[:file])
|
33
|
+
LOGGER.info "Database for project #{options[:project_name]} backed up."
|
34
|
+
else
|
35
|
+
LOGGER.error "Could not complete backup #{options[:project_name]}."
|
36
|
+
exit!(true)
|
37
|
+
end
|
12
38
|
end
|
13
39
|
|
14
40
|
desc 'sync_path', 'Server\'s path for files'
|
data/lib/backup_minister.rb
CHANGED
@@ -2,6 +2,7 @@ require 'net/ssh'
|
|
2
2
|
require 'open3'
|
3
3
|
require 'logger'
|
4
4
|
require 'fileutils'
|
5
|
+
require 'digest'
|
5
6
|
|
6
7
|
LOGGER = Logger.new(STDOUT)
|
7
8
|
APP_NAME = 'backup_minister'
|
@@ -87,6 +88,16 @@ class BackupMinister
|
|
87
88
|
out
|
88
89
|
end
|
89
90
|
|
91
|
+
# Get SHA256 Hash of file
|
92
|
+
#
|
93
|
+
# @param file_path [String] path to file
|
94
|
+
#
|
95
|
+
# @return [String, nil]
|
96
|
+
def file_sha256_hash(file_path)
|
97
|
+
file = File.read(file_path)
|
98
|
+
Digest::SHA256.hexdigest(file) if file
|
99
|
+
end
|
100
|
+
|
90
101
|
private
|
91
102
|
|
92
103
|
attr_accessor :config
|
@@ -8,6 +8,7 @@ DATABASE_DRIVERS = %i(docker)
|
|
8
8
|
class BackupMinister::Agent < BackupMinister
|
9
9
|
@projects = nil
|
10
10
|
@config_file_name = nil
|
11
|
+
@remote_server_connection = nil
|
11
12
|
|
12
13
|
def initialize(file_name = nil)
|
13
14
|
super
|
@@ -68,7 +69,7 @@ class BackupMinister::Agent < BackupMinister
|
|
68
69
|
LOGGER.info "Connection with server #{user}@#{host} established."
|
69
70
|
|
70
71
|
remote_install = connection.exec!("gem list -i #{APP_NAME}")
|
71
|
-
if remote_install == 'true'
|
72
|
+
if remote_install.to_s.strip == 'true'
|
72
73
|
LOGGER.debug "#{APP_NAME} installed on remote server."
|
73
74
|
result = true
|
74
75
|
else
|
@@ -150,6 +151,45 @@ class BackupMinister::Agent < BackupMinister
|
|
150
151
|
result
|
151
152
|
end
|
152
153
|
|
154
|
+
# Move database backup to server
|
155
|
+
#
|
156
|
+
# @return [String, nil] path to backup on remote server
|
157
|
+
def place_database_backup(file_path)
|
158
|
+
result = nil
|
159
|
+
destination_directory = '/tmp/'
|
160
|
+
scp_command = "scp #{file_path} #{system_config('server', 'user')}@#{system_config('server', 'host')}:#{destination_directory}"
|
161
|
+
if execute(scp_command)
|
162
|
+
LOGGER.debug "Backup #{file_path} placed remotely to #{destination_directory}."
|
163
|
+
|
164
|
+
FileUtils.rm(file_path)
|
165
|
+
LOGGER.debug "Local file #{file_path} removed."
|
166
|
+
|
167
|
+
result = destination_directory + File.basename(file_path)
|
168
|
+
else
|
169
|
+
LOGGER.error "Could not move #{file_path} to server."
|
170
|
+
end
|
171
|
+
result
|
172
|
+
end
|
173
|
+
|
174
|
+
# Execute command on remote server for processing database backup
|
175
|
+
#
|
176
|
+
# @param project_name [String]
|
177
|
+
# @param remote_file_path [String]
|
178
|
+
# @param sha256 [String, nil]
|
179
|
+
#
|
180
|
+
# @return [Bool] is operation success?
|
181
|
+
def process_remote_database_backup(project_name, remote_file_path, sha256 = nil)
|
182
|
+
result = false
|
183
|
+
command = "#{APP_NAME} store_database_backup"
|
184
|
+
command += " --project_name=#{project_name}"
|
185
|
+
command += " --file=#{remote_file_path}"
|
186
|
+
command += " --sha256=#{sha256}" unless sha256.nil?
|
187
|
+
|
188
|
+
execute_remotely { result = (@remote_server_connection.exec!(command).exitstatus == 0) }
|
189
|
+
|
190
|
+
result
|
191
|
+
end
|
192
|
+
|
153
193
|
# Create TAR GZ single file archive
|
154
194
|
#
|
155
195
|
# @param file_name [String] file name for new archive (including extension)
|
@@ -195,4 +235,27 @@ class BackupMinister::Agent < BackupMinister
|
|
195
235
|
nil
|
196
236
|
end
|
197
237
|
end
|
238
|
+
|
239
|
+
def remote_server_connect
|
240
|
+
if check_server_requirements
|
241
|
+
begin
|
242
|
+
host = system_config('server', 'host')
|
243
|
+
user = system_config('server', 'user')
|
244
|
+
|
245
|
+
@remote_server_connection = Net::SSH.start(host, user)
|
246
|
+
rescue Exception => error
|
247
|
+
LOGGER.error "Could not establish connection: #{error.message}"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def remote_server_close_connection
|
253
|
+
@remote_server_connection.close if !@remote_server_connection.nil? and !@remote_server_connection.closed?
|
254
|
+
end
|
255
|
+
|
256
|
+
def execute_remotely
|
257
|
+
remote_server_connect
|
258
|
+
yield if block_given?
|
259
|
+
remote_server_close_connection
|
260
|
+
end
|
198
261
|
end
|