backup_minister 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: af89f01465c72c52b25a8e609c50519a15fe6ab6
4
- data.tar.gz: 62c62db31e310a4e6b22abdab8bfb69c2732f69f
3
+ metadata.gz: b944e992d64bd98fe8c5843d9a061a063ce2d159
4
+ data.tar.gz: e2c999388a8ce746da8be7398fc81d9c4f8c85b4
5
5
  SHA512:
6
- metadata.gz: 411b3d4bcb3c1a841d7440f5bc8d3904fc26b7da9afce45feee939116c4e9b5b51259a79d16a95e1df3a39b0225e0bce8437470b53d9b3cde5557ea6dcd65204
7
- data.tar.gz: 1bd6a245ba4a09435506db87cf257251ebe873bdbd897a63136452d18114f480dc9219f10902f5fb11fcf0eed571928528bbe48436a7a71db7c2f841ec5d1185
6
+ metadata.gz: 788d174df306e30204ac0535aab390d815c14b8946473d8d8bf1eef9de322a6156bc75a7ec2a2a67d85baa5370b960db1019295833e117c9b6107cbfb9b50500
7
+ data.tar.gz: 0a1eef9e35f4b30d3ba6e9f058d412baa7f5e98ec7348ba64feb45e51b5f3c5da9fba7da1560fd5b2a7d98300efc47dda0b1552f7402e1d61aaca2a757fadeb3
@@ -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
- def backup_database
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'
@@ -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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backup_minister
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Krigouzov