backup 1.3.4 → 2.0.0
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.
- data/README.rdoc +121 -53
- data/Rakefile +3 -8
- data/VERSION +1 -1
- data/backup.gemspec +20 -34
- data/generators/backup/backup_generator.rb +31 -0
- data/generators/backup/templates/config/backup.rb +60 -0
- data/generators/backup/templates/migrations/create_backup_tables.rb +24 -0
- data/generators/backup/templates/tasks/backup.rake +42 -0
- data/lib/backup.rb +64 -12
- data/lib/backup/adapters/archive.rb +53 -0
- data/lib/backup/adapters/base.rb +65 -0
- data/lib/backup/adapters/mysql.rb +48 -0
- data/lib/backup/configuration/adapter.rb +17 -0
- data/lib/backup/configuration/base.rb +38 -0
- data/lib/backup/configuration/helpers.rb +12 -0
- data/lib/backup/configuration/storage.rb +17 -0
- data/lib/backup/connection/s3.rb +28 -13
- data/lib/backup/record/s3.rb +90 -0
- data/lib/backup/record/scp.rb +92 -0
- data/lib/backup/storage/s3.rb +14 -0
- data/lib/backup/storage/scp.rb +28 -0
- metadata +18 -35
- data/generators/backup_files/backup_files_generator.rb +0 -72
- data/generators/backup_files/templates/backup.sqlite3 +0 -0
- data/generators/backup_files/templates/config.rake +0 -20
- data/generators/backup_files/templates/db.rake +0 -62
- data/generators/backup_files/templates/s3.rake +0 -231
- data/generators/backup_files/templates/s3.yml +0 -120
- data/generators/backup_files/templates/setup.rake +0 -28
- data/generators/backup_files/templates/ssh.rake +0 -226
- data/generators/backup_files/templates/ssh.yml +0 -119
- data/lib/backup/adapter/assets.rb +0 -57
- data/lib/backup/adapter/custom.rb +0 -91
- data/lib/backup/adapter/mysql.rb +0 -65
- data/lib/backup/adapter/sqlite3.rb +0 -49
- data/lib/backup/backup_record/s3.rb +0 -90
- data/lib/backup/backup_record/ssh.rb +0 -90
- data/lib/backup/base.rb +0 -92
- data/lib/backup/connection/base.rb +0 -13
- data/lib/backup/connection/ssh.rb +0 -19
- data/lib/backup/encrypt.rb +0 -18
- data/lib/backup/transfer/base.rb +0 -13
- data/lib/backup/transfer/s3.rb +0 -36
- data/lib/backup/transfer/ssh.rb +0 -30
@@ -0,0 +1,90 @@
|
|
1
|
+
module Backup
|
2
|
+
module Record
|
3
|
+
class S3 < ActiveRecord::Base
|
4
|
+
|
5
|
+
# Establishes a connection with the SQLite3
|
6
|
+
# local database to avoid conflict with users
|
7
|
+
# Production database.
|
8
|
+
# establish_connection(
|
9
|
+
# :adapter => "sqlite3",
|
10
|
+
# :database => "db/backup.sqlite3",
|
11
|
+
# :pool => 5,
|
12
|
+
# :timeout => 5000 )
|
13
|
+
|
14
|
+
set_table_name 'backup_s3'
|
15
|
+
|
16
|
+
# Scopes
|
17
|
+
default_scope :order => 'created_at desc'
|
18
|
+
|
19
|
+
# Callbacks
|
20
|
+
after_save :clean_backups
|
21
|
+
|
22
|
+
# Attributes
|
23
|
+
attr_accessor :adapter_config, :keep_backups
|
24
|
+
|
25
|
+
# Receives the options hash and stores it
|
26
|
+
# Sets the S3 values
|
27
|
+
def load_adapter(adapter)
|
28
|
+
self.adapter_config = adapter
|
29
|
+
self.trigger = adapter.procedure.trigger
|
30
|
+
self.adapter = adapter.procedure.adapter_name
|
31
|
+
self.filename = adapter.final_file
|
32
|
+
self.bucket = adapter.procedure.get_storage_configuration.attributes['bucket']
|
33
|
+
self.keep_backups = adapter.procedure.attributes['keep_backups']
|
34
|
+
end
|
35
|
+
|
36
|
+
# Destroys all backups for the specified trigger from Amazon S3
|
37
|
+
def self.destroy_all_backups(procedure, trigger)
|
38
|
+
backups = Backup::Record::S3.all(:conditions => {:trigger => trigger})
|
39
|
+
unless backups.empty?
|
40
|
+
s3 = Backup::Connection::S3.new
|
41
|
+
s3.static_initialize(procedure)
|
42
|
+
s3.connect
|
43
|
+
backups.each do |backup|
|
44
|
+
puts "\nDestroying backup \"#{backup.filename}\" from bucket \"#{backup.bucket}\"."
|
45
|
+
s3.destroy(backup.filename, backup.bucket)
|
46
|
+
backup.destroy
|
47
|
+
end
|
48
|
+
puts "\nAll \"#{trigger}\" backups destroyed.\n\n"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Maintains the backup file amount on S3
|
55
|
+
# This is invoked after a successful record save
|
56
|
+
# This deletes the oldest files when the backup limit has been exceeded
|
57
|
+
def clean_backups
|
58
|
+
if keep_backups.is_a?(Integer)
|
59
|
+
backups = Backup::Record::S3.all(:conditions => {:trigger => trigger})
|
60
|
+
backups_to_destroy = Array.new
|
61
|
+
backups.each_with_index do |backup, index|
|
62
|
+
if index >= keep_backups then
|
63
|
+
backups_to_destroy << backup
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
unless backups_to_destroy.empty?
|
68
|
+
|
69
|
+
# Create a new Amazon S3 Object
|
70
|
+
s3 = Backup::Connection::S3.new(adapter_config)
|
71
|
+
|
72
|
+
# Connect to Amazon S3 with provided credentials
|
73
|
+
s3.connect
|
74
|
+
|
75
|
+
# Loop through all backups that should be destroyed and remove them from S3.
|
76
|
+
backups_to_destroy.each do |backup|
|
77
|
+
puts "\nDestroying backup \"#{backup.filename}\" from bucket \"#{backup.bucket}\"."
|
78
|
+
s3.destroy(backup.filename, backup.bucket)
|
79
|
+
backup.destroy
|
80
|
+
end
|
81
|
+
|
82
|
+
puts "\nBackup storage for \"#{trigger}\" is limited to #{keep_backups} backups."
|
83
|
+
puts "\nThe #{keep_backups} most recent backups are now stored on S3.\n\n"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Backup
|
2
|
+
module Record
|
3
|
+
class SCP < ActiveRecord::Base
|
4
|
+
|
5
|
+
# Establishes a connection with the SQLite3
|
6
|
+
# local database to avoid conflict with users
|
7
|
+
# Production database.
|
8
|
+
# establish_connection(
|
9
|
+
# :adapter => "sqlite3",
|
10
|
+
# :database => "db/backup.sqlite3",
|
11
|
+
# :pool => 5,
|
12
|
+
# :timeout => 5000 )
|
13
|
+
|
14
|
+
set_table_name 'backup_scp'
|
15
|
+
|
16
|
+
# Scopes
|
17
|
+
default_scope :order => 'created_at desc'
|
18
|
+
|
19
|
+
# Callbacks
|
20
|
+
after_save :clean_backups
|
21
|
+
|
22
|
+
# Attributes
|
23
|
+
attr_accessor :adapter_config, :keep_backups, :ip, :user, :password
|
24
|
+
|
25
|
+
# Receives the options hash and stores it
|
26
|
+
# Sets the SCP values
|
27
|
+
def load_adapter(adapter)
|
28
|
+
self.adapter_config = adapter
|
29
|
+
self.trigger = adapter.procedure.trigger
|
30
|
+
self.adapter = adapter.procedure.adapter_name
|
31
|
+
self.filename = adapter.final_file
|
32
|
+
self.keep_backups = adapter.procedure.attributes['keep_backups']
|
33
|
+
|
34
|
+
%w(ip user password path).each do |method|
|
35
|
+
send(:"#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Destroys all backups for the specified trigger from Remote Server (SCP)
|
40
|
+
def self.destroy_all_backups(procedure, trigger)
|
41
|
+
backups = Backup::Record::SCP.all(:conditions => {:trigger => trigger})
|
42
|
+
unless backups.empty?
|
43
|
+
ip = procedure.get_storage_configuration.attributes['ip']
|
44
|
+
user = procedure.get_storage_configuration.attributes['user']
|
45
|
+
password = procedure.get_storage_configuration.attributes['password']
|
46
|
+
|
47
|
+
Net::SSH.start(ip, user, :password => password) do |ssh|
|
48
|
+
backups.each do |backup|
|
49
|
+
puts "\nDestroying backup \"#{backup.filename}\" from path \"#{backup.path}\"."
|
50
|
+
ssh.exec("rm #{File.join(backup.path, backup.filename)}")
|
51
|
+
backup.destroy
|
52
|
+
end
|
53
|
+
end
|
54
|
+
puts "\nAll \"#{trigger}\" backups destroyed.\n\n"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# Maintains the backup file amount on the remote server
|
61
|
+
# This is invoked after a successful record save
|
62
|
+
# This deletes the oldest files when the backup limit has been exceeded
|
63
|
+
def clean_backups
|
64
|
+
if keep_backups.is_a?(Integer)
|
65
|
+
backups = Backup::Record::SCP.all(:conditions => {:trigger => trigger})
|
66
|
+
backups_to_destroy = Array.new
|
67
|
+
backups.each_with_index do |backup, index|
|
68
|
+
if index >= keep_backups then
|
69
|
+
backups_to_destroy << backup
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
unless backups_to_destroy.empty?
|
74
|
+
|
75
|
+
Net::SSH.start(ip, user, :password => password) do |ssh|
|
76
|
+
backups_to_destroy.each do |backup|
|
77
|
+
puts "\nDestroying backup \"#{backup.filename}\" from path \"#{backup.path}\"."
|
78
|
+
ssh.exec("rm #{File.join(backup.path, backup.filename)}")
|
79
|
+
backup.destroy
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
puts "\nBackup storage for \"#{trigger}\" is limited to #{keep_backups} backups."
|
84
|
+
puts "\nThe #{keep_backups} most recent backups are now stored on the remote server.\n\n"
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Backup
|
2
|
+
module Storage
|
3
|
+
class SCP
|
4
|
+
|
5
|
+
attr_accessor :user, :password, :ip, :path, :tmp_path, :final_file
|
6
|
+
|
7
|
+
# Stores the file on the remote server using SCP
|
8
|
+
def initialize(adapter)
|
9
|
+
%w(ip user password path).each do |method|
|
10
|
+
send(:"#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
|
11
|
+
end
|
12
|
+
|
13
|
+
final_file = adapter.final_file
|
14
|
+
tmp_path = adapter.tmp_path
|
15
|
+
|
16
|
+
Net::SSH.start(ip, user, :password => password) do |ssh|
|
17
|
+
ssh.exec "mkdir -p #{path}"
|
18
|
+
end
|
19
|
+
|
20
|
+
puts "Storing \"#{final_file}\" to path \"#{path}\" on remote server (#{ip})."
|
21
|
+
Net::SCP.start(ip, user, :password => password) do |scp|
|
22
|
+
scp.upload! File.join(tmp_path, final_file).gsub('\ ', ' '), path
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael van Rooijen
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-12-01 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -42,17 +42,7 @@ dependencies:
|
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: 1.0.2
|
44
44
|
version:
|
45
|
-
|
46
|
-
name: sqlite3-ruby
|
47
|
-
type: :runtime
|
48
|
-
version_requirement:
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - ">="
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 1.2.5
|
54
|
-
version:
|
55
|
-
description: "\n \xE2\x80\x9CBackup\xE2\x80\x9D is a RubyGem, written for Ruby on Rails. It's main purpose is to Backup any\n files to Amazon S3 or any remotely accessible server through SSH (SCP). It supports database\n and regular file backups. On top of that, it's extremely easy to set up. Backup will provide\n a generator script that will place all necessary files inside your Rails application.\n Two of which, are \xE2\x80\x9Cyaml\xE2\x80\x9D configuration files. Using just these two files to configure a\n backup for database formats such as a MySQL, SQLite3 or any Assets folder.\n Setting up \xE2\x80\x9CBackup\xE2\x80\x9D takes only about a minute or two!\n "
|
45
|
+
description: "\n Backup is a Ruby Gem, written specifically for Ruby on Rails applications. This gem offers a quick and easy way\n to configure and run backups of your MySQL database (soon PostgreSQL and possibly more) and Archives (any files or folders)\n to \"Amazon S3\" or \"any remotely accessible server using SCP\". Backup handles: Compression, Archiving, Encryption and Backup Cleaning.\n "
|
56
46
|
email: meskyan@gmail.com
|
57
47
|
executables: []
|
58
48
|
|
@@ -69,30 +59,23 @@ files:
|
|
69
59
|
- Rakefile
|
70
60
|
- VERSION
|
71
61
|
- backup.gemspec
|
72
|
-
- generators/
|
73
|
-
- generators/
|
74
|
-
- generators/
|
75
|
-
- generators/
|
76
|
-
- generators/backup_files/templates/s3.rake
|
77
|
-
- generators/backup_files/templates/s3.yml
|
78
|
-
- generators/backup_files/templates/setup.rake
|
79
|
-
- generators/backup_files/templates/ssh.rake
|
80
|
-
- generators/backup_files/templates/ssh.yml
|
62
|
+
- generators/backup/backup_generator.rb
|
63
|
+
- generators/backup/templates/config/backup.rb
|
64
|
+
- generators/backup/templates/migrations/create_backup_tables.rb
|
65
|
+
- generators/backup/templates/tasks/backup.rake
|
81
66
|
- lib/backup.rb
|
82
|
-
- lib/backup/
|
83
|
-
- lib/backup/
|
84
|
-
- lib/backup/
|
85
|
-
- lib/backup/adapter
|
86
|
-
- lib/backup/
|
87
|
-
- lib/backup/
|
88
|
-
- lib/backup/
|
89
|
-
- lib/backup/connection/base.rb
|
67
|
+
- lib/backup/adapters/archive.rb
|
68
|
+
- lib/backup/adapters/base.rb
|
69
|
+
- lib/backup/adapters/mysql.rb
|
70
|
+
- lib/backup/configuration/adapter.rb
|
71
|
+
- lib/backup/configuration/base.rb
|
72
|
+
- lib/backup/configuration/helpers.rb
|
73
|
+
- lib/backup/configuration/storage.rb
|
90
74
|
- lib/backup/connection/s3.rb
|
91
|
-
- lib/backup/
|
92
|
-
- lib/backup/
|
93
|
-
- lib/backup/
|
94
|
-
- lib/backup/
|
95
|
-
- lib/backup/transfer/ssh.rb
|
75
|
+
- lib/backup/record/s3.rb
|
76
|
+
- lib/backup/record/scp.rb
|
77
|
+
- lib/backup/storage/s3.rb
|
78
|
+
- lib/backup/storage/scp.rb
|
96
79
|
has_rdoc: true
|
97
80
|
homepage: ""
|
98
81
|
licenses: []
|
@@ -1,72 +0,0 @@
|
|
1
|
-
class BackupFilesGenerator < Rails::Generator::Base
|
2
|
-
|
3
|
-
# This method gets initialized when the generator gets run.
|
4
|
-
# It will receive an array of arguments inside @args
|
5
|
-
def initialize(runtime_args, runtime_options = {})
|
6
|
-
super
|
7
|
-
extract_args
|
8
|
-
set_defaults
|
9
|
-
confirm_input
|
10
|
-
end
|
11
|
-
|
12
|
-
# Processes the file generation/templating
|
13
|
-
# This will automatically be run after the initialize method
|
14
|
-
def manifest
|
15
|
-
record do |m|
|
16
|
-
|
17
|
-
# Generate the Rake Tasks
|
18
|
-
m.directory "lib/tasks"
|
19
|
-
m.directory "lib/tasks/backup"
|
20
|
-
m.directory "lib/tasks/backup/files"
|
21
|
-
m.file "config.rake", "lib/tasks/backup/config.rake"
|
22
|
-
m.file "s3.rake", "lib/tasks/backup/s3.rake"
|
23
|
-
m.file "ssh.rake", "lib/tasks/backup/ssh.rake"
|
24
|
-
m.file "db.rake", "lib/tasks/backup/db.rake"
|
25
|
-
m.file "setup.rake", "lib/tasks/backup/setup.rake"
|
26
|
-
m.file "backup.sqlite3", "lib/tasks/backup/files/backup.sqlite3"
|
27
|
-
|
28
|
-
# Generate the YAML files
|
29
|
-
m.directory "config/backup"
|
30
|
-
m.file "s3.yml", "config/backup/s3.yml"
|
31
|
-
m.file "ssh.yml", "config/backup/ssh.yml"
|
32
|
-
|
33
|
-
# Generates the backup.sqlite3 database
|
34
|
-
m.directory "db"
|
35
|
-
m.file "backup.sqlite3", "db/backup.sqlite3"
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Creates a new Hash Object containing the user input
|
41
|
-
# The user input will be available through @input and input
|
42
|
-
def extract_args
|
43
|
-
@input = Hash.new
|
44
|
-
@args.each do |arg|
|
45
|
-
if arg.include?(":") then
|
46
|
-
@input[:"#{arg.slice(0, arg.index(":"))}"] = arg.slice((arg.index(":") + 1)..-1)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# Input Method that's available inside the generated templates
|
52
|
-
# because instance variable are not available, so we access them through methods
|
53
|
-
def input
|
54
|
-
@input
|
55
|
-
end
|
56
|
-
|
57
|
-
# Sets defaults for user input when left blank by the user
|
58
|
-
# for each parameter
|
59
|
-
def set_defaults
|
60
|
-
end
|
61
|
-
|
62
|
-
# Confirms whether the model and attachment arguments were passed in
|
63
|
-
# Raises an error if not
|
64
|
-
def confirm_input
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def input_error
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
Binary file
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# Opens and Reads the Backup YAML File from the RAILS_ROOT/config/backup path
|
2
|
-
# Replaces all the :rails_root tokens with the actual RAILS_ROOT path
|
3
|
-
# Returns the content of the file in YAML format
|
4
|
-
def read_backup_yaml_file(config_file)
|
5
|
-
YAML.load File.open(File.join(RAILS_ROOT, 'config', 'backup', config_file), 'r').read.gsub(/:rails_root/, RAILS_ROOT)
|
6
|
-
end
|
7
|
-
|
8
|
-
namespace :backup do
|
9
|
-
|
10
|
-
task :s3_config => :environment do
|
11
|
-
@config = read_backup_yaml_file('s3.yml')
|
12
|
-
@adapters = ['mysql', 'sqlite3', 'assets', 'custom']
|
13
|
-
end
|
14
|
-
|
15
|
-
task :ssh_config => :environment do
|
16
|
-
@config = read_backup_yaml_file('ssh.yml')
|
17
|
-
@adapters = ['mysql', 'sqlite3', 'assets', 'custom']
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
namespace :backup do
|
2
|
-
namespace :db do
|
3
|
-
namespace :truncate do
|
4
|
-
|
5
|
-
desc 'Truncates the S3 Backup database records; Physical files WILL NOT be deleted from S3.'
|
6
|
-
task :s3 => :environment do
|
7
|
-
puts "Truncating S3 Backup database records!"
|
8
|
-
Backup::BackupRecord::S3.destroy_all
|
9
|
-
end
|
10
|
-
|
11
|
-
desc 'Truncates the SHH database records; Physical files WILL NOT be deleted from remote server.'
|
12
|
-
task :ssh => :environment do
|
13
|
-
puts "Truncating SSH database records!"
|
14
|
-
Backup::BackupRecord::SSH.destroy_all
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
|
-
namespace :destroy do
|
21
|
-
|
22
|
-
desc 'Destroys S3 Backup database records; Physical files WILL be deleted as well.'
|
23
|
-
task :s3 => :s3_config do
|
24
|
-
puts "Removing all backups from S3.."
|
25
|
-
@adapters.each do |adapter|
|
26
|
-
if @config[adapter]
|
27
|
-
unless @config[adapter].is_a?(Array)
|
28
|
-
puts "\n\n-- Processing #{adapter} backups --"
|
29
|
-
Backup::BackupRecord::S3.destroy_all_backups(adapter, @config[adapter], 0)
|
30
|
-
else
|
31
|
-
puts "\n\n-- Processing #{adapter} backups --"
|
32
|
-
@config[adapter].each_with_index do |config, index|
|
33
|
-
Backup::BackupRecord::S3.destroy_all_backups(adapter, config, index)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
puts "\n\nAll S3 backups destroyed!\n\n"
|
39
|
-
end
|
40
|
-
|
41
|
-
desc 'Destroys SSH Backup database records; Physical files WILL be deleted as well.'
|
42
|
-
task :ssh => :ssh_config do
|
43
|
-
puts "Removing all backups from remote server through SSH.."
|
44
|
-
@adapters.each do |adapter|
|
45
|
-
if @config[adapter]
|
46
|
-
unless @config[adapter].is_a?(Array)
|
47
|
-
puts "\n\n-- Processing #{adapter} backups --"
|
48
|
-
Backup::BackupRecord::SSH.destroy_all_backups(adapter, @config[adapter], 0)
|
49
|
-
else
|
50
|
-
puts "\n\n-- Processing #{adapter} backups --"
|
51
|
-
@config[adapter].each_with_index do |config, index|
|
52
|
-
Backup::BackupRecord::SSH.destroy_all_backups(adapter, config, index)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
puts "\n\nAll backups from remote server destroyed!\n\n"
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|