backupper 0.5.2 → 0.6.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +27 -19
- data/README.md +24 -6
- data/Rakefile +0 -1
- data/backupper.gemspec +7 -7
- data/lib/backupper/backupper.rb +73 -28
- data/lib/backupper/dump_command.rb +18 -7
- data/lib/backupper/mailer.rb +2 -2
- data/lib/backupper/sshkit.rb +23 -0
- data/lib/backupper/version.rb +1 -1
- metadata +19 -35
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a381517df098479aaa0237669fe34e93eb27616af160d6b2d60ea055d70c1835
|
|
4
|
+
data.tar.gz: 45d9d097401c396d046646003876f0a4078f25ec77cde66d84450e4f02eb3e96
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4c4ebcb074e0f30928d4952b0c80f0617d3bbe7bfe0277d1ef0cb26dbad0f6bc1c14bd012dff0aec880bcf35db2c09267e5087de56432e94221dfc8adc3aa7fb
|
|
7
|
+
data.tar.gz: 3bb3d1486bf4cc093175aa5fd28cb6afe5f6f7691d72d116dc730e333904b0a61b7637abd687d8e90609e5a9d76824f938f837949e122c790dec61ad33528504
|
data/Gemfile.lock
CHANGED
|
@@ -1,38 +1,47 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
backupper (0.
|
|
5
|
-
mail (~> 2.
|
|
6
|
-
sshkit (~> 1.
|
|
4
|
+
backupper (0.6.0)
|
|
5
|
+
mail (~> 2.9)
|
|
6
|
+
sshkit (~> 1.25)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
10
10
|
specs:
|
|
11
|
-
|
|
12
|
-
date (3.
|
|
13
|
-
|
|
11
|
+
base64 (0.3.0)
|
|
12
|
+
date (3.5.1)
|
|
13
|
+
logger (1.7.0)
|
|
14
|
+
mail (2.9.1)
|
|
15
|
+
logger
|
|
14
16
|
mini_mime (>= 0.1.1)
|
|
15
17
|
net-imap
|
|
16
18
|
net-pop
|
|
17
19
|
net-smtp
|
|
18
|
-
mini_mime (1.1.
|
|
19
|
-
net-imap (0.
|
|
20
|
+
mini_mime (1.1.5)
|
|
21
|
+
net-imap (0.6.4.1)
|
|
20
22
|
date
|
|
21
23
|
net-protocol
|
|
22
24
|
net-pop (0.1.2)
|
|
23
25
|
net-protocol
|
|
24
|
-
net-protocol (0.2.
|
|
26
|
+
net-protocol (0.2.2)
|
|
25
27
|
timeout
|
|
26
|
-
net-scp (4.
|
|
28
|
+
net-scp (4.1.0)
|
|
27
29
|
net-ssh (>= 2.6.5, < 8.0.0)
|
|
28
|
-
net-
|
|
30
|
+
net-sftp (4.0.0)
|
|
31
|
+
net-ssh (>= 5.0.0, < 8.0.0)
|
|
32
|
+
net-smtp (0.5.1)
|
|
29
33
|
net-protocol
|
|
30
|
-
net-ssh (7.
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
net-ssh (7.3.3)
|
|
35
|
+
ostruct (0.6.3)
|
|
36
|
+
rake (13.4.2)
|
|
37
|
+
sshkit (1.25.0)
|
|
38
|
+
base64
|
|
39
|
+
logger
|
|
33
40
|
net-scp (>= 1.1.2)
|
|
41
|
+
net-sftp (>= 2.1.2)
|
|
34
42
|
net-ssh (>= 2.8.0)
|
|
35
|
-
|
|
43
|
+
ostruct
|
|
44
|
+
timeout (0.6.1)
|
|
36
45
|
|
|
37
46
|
PLATFORMS
|
|
38
47
|
ruby
|
|
@@ -40,9 +49,8 @@ PLATFORMS
|
|
|
40
49
|
|
|
41
50
|
DEPENDENCIES
|
|
42
51
|
backupper!
|
|
43
|
-
bundler
|
|
44
|
-
|
|
45
|
-
rake (~> 10.0)
|
|
52
|
+
bundler
|
|
53
|
+
rake
|
|
46
54
|
|
|
47
55
|
BUNDLED WITH
|
|
48
|
-
|
|
56
|
+
4.0.15
|
data/README.md
CHANGED
|
@@ -20,6 +20,10 @@ mailer:
|
|
|
20
20
|
to: pioz@email.com # Send report email to this address
|
|
21
21
|
password: Pa$$w0rD # Gmail account password
|
|
22
22
|
|
|
23
|
+
default: # options here are merged into all database configurations below
|
|
24
|
+
port: 22
|
|
25
|
+
db_username: backup
|
|
26
|
+
|
|
23
27
|
db1:
|
|
24
28
|
disabled: false # true to disable this backup
|
|
25
29
|
dump: '/home/backup/db1' # path where to save the dump of the database
|
|
@@ -27,12 +31,13 @@ db1:
|
|
|
27
31
|
username: user # server ssh username
|
|
28
32
|
host: '1.2.3.4' # server ssh ip
|
|
29
33
|
port: 22 # server ssh port
|
|
30
|
-
password: Pa$$w0rD # server ssh password
|
|
31
|
-
|
|
34
|
+
password: Pa$$w0rD # server ssh password (also used as sudo password when sudo is true)
|
|
35
|
+
sudo: false # true to run the dump command with sudo
|
|
36
|
+
adapter: mysql # adapter to use to perform the backup (mysql, postgresql or mydumper)
|
|
32
37
|
database: db_name # database name
|
|
33
38
|
db_username: db_user # database username
|
|
34
39
|
db_password: db_Pa$$w0rD # database password
|
|
35
|
-
dump_options: '--single-transaction --quick' # dump command extra options
|
|
40
|
+
dump_options: '--single-transaction --quick' # dump command extra options (shell-style quoted or YAML array)
|
|
36
41
|
|
|
37
42
|
db2:
|
|
38
43
|
disabled: false
|
|
@@ -55,12 +60,25 @@ After done all backups a report email is sent to you using gmail smtp service (r
|
|
|
55
60
|
To backup only specific databases you can pass the option `-o db1,db3`. In this way only databases under the key `db1` and `db3` will be backupped,
|
|
56
61
|
ignoring the others configuration keys.
|
|
57
62
|
|
|
58
|
-
##
|
|
59
|
-
|
|
63
|
+
## Custom adapters
|
|
64
|
+
|
|
65
|
+
An adapter is just a module method of `DumpCommand` that returns the shell command used to dump the database:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
def self.myadapter(database:, username: 'root', password: nil, dump_options: nil, working_dir: nil, outfile:)
|
|
69
|
+
return "mydump #{database} -u #{username} > #{outfile}"
|
|
70
|
+
end
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
All the values arrive already shell-escaped: interpolate them as they are, without wrapping them in quotes. `dump_options` is parsed as shell-style arguments, then each argument is escaped before it reaches the adapter. The command must write the dump to `outfile`; `working_dir` is an empty temporary directory you can use as scratch space (both are removed from the server after the download). If your adapter produces a file format different from `.sql.bz2`, add its extension to `DumpCommand::EXTENSIONS`.
|
|
60
74
|
|
|
61
75
|
## Contributing
|
|
62
76
|
|
|
63
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
|
77
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/pioz/backupper.
|
|
78
|
+
|
|
79
|
+
## Resources
|
|
80
|
+
* [Blog post about Backupper](https://tech.uqido.com/2018/07/16/backupper-tool-backup-database/) (italian only).
|
|
81
|
+
|
|
64
82
|
|
|
65
83
|
## License
|
|
66
84
|
|
data/Rakefile
CHANGED
data/backupper.gemspec
CHANGED
|
@@ -6,11 +6,11 @@ Gem::Specification.new do |spec|
|
|
|
6
6
|
spec.name = 'backupper'
|
|
7
7
|
spec.version = Backupper::VERSION
|
|
8
8
|
spec.authors = ['pioz']
|
|
9
|
-
spec.email = ['
|
|
9
|
+
spec.email = ['epilotto@gmx.com']
|
|
10
10
|
|
|
11
11
|
spec.summary = 'Tool to backup databases'
|
|
12
12
|
spec.description = 'Backupper is a tool to backup all your databases spread all over the world'
|
|
13
|
-
spec.homepage = 'https://github.com/
|
|
13
|
+
spec.homepage = 'https://github.com/pioz/backupper'
|
|
14
14
|
spec.license = 'MIT'
|
|
15
15
|
|
|
16
16
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
@@ -28,10 +28,10 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
|
29
29
|
spec.require_paths = ['lib']
|
|
30
30
|
|
|
31
|
-
spec.
|
|
32
|
-
spec.add_runtime_dependency '
|
|
31
|
+
spec.required_ruby_version = '>= 2.5'
|
|
32
|
+
spec.add_runtime_dependency 'mail', '~> 2.9'
|
|
33
|
+
spec.add_runtime_dependency 'sshkit', '~> 1.25'
|
|
33
34
|
|
|
34
|
-
spec.add_development_dependency 'bundler'
|
|
35
|
-
spec.add_development_dependency '
|
|
36
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
|
35
|
+
spec.add_development_dependency 'bundler'
|
|
36
|
+
spec.add_development_dependency 'rake'
|
|
37
37
|
end
|
data/lib/backupper/backupper.rb
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
require 'fileutils'
|
|
2
|
+
require 'shellwords'
|
|
2
3
|
require 'sshkit'
|
|
3
4
|
require 'sshkit/dsl'
|
|
4
5
|
require 'yaml'
|
|
5
6
|
|
|
6
7
|
require_relative 'dump_command'
|
|
7
8
|
require_relative 'mailer'
|
|
9
|
+
require_relative 'sshkit'
|
|
8
10
|
|
|
9
11
|
class Backupper
|
|
10
12
|
include SSHKit::DSL
|
|
@@ -28,7 +30,14 @@ class Backupper
|
|
|
28
30
|
|
|
29
31
|
def backup!(only_these_keys = nil)
|
|
30
32
|
filtered_conf = @conf
|
|
31
|
-
|
|
33
|
+
if only_these_keys
|
|
34
|
+
filtered_conf = @conf.slice(*only_these_keys)
|
|
35
|
+
(only_these_keys - @conf.keys).each do |k|
|
|
36
|
+
err = "Configuration key '#{k}' not found or disabled!"
|
|
37
|
+
error(k, err)
|
|
38
|
+
@logger.error err
|
|
39
|
+
end
|
|
40
|
+
end
|
|
32
41
|
filtered_conf.each do |k, options|
|
|
33
42
|
@logger.info "[#{Time.now}] ⬇️ backing up #{k}..."
|
|
34
43
|
o, err = setup_options(options)
|
|
@@ -38,7 +47,7 @@ class Backupper
|
|
|
38
47
|
next
|
|
39
48
|
end
|
|
40
49
|
begin
|
|
41
|
-
|
|
50
|
+
do_and_download_dump(
|
|
42
51
|
key: k,
|
|
43
52
|
adapter: o['adapter'],
|
|
44
53
|
url: o['url'],
|
|
@@ -47,6 +56,7 @@ class Backupper
|
|
|
47
56
|
db_username: o['db_username'],
|
|
48
57
|
db_password: o['db_password'],
|
|
49
58
|
dump_options: o['dump_options'],
|
|
59
|
+
sudo: o['sudo'],
|
|
50
60
|
outdir: o['outdir'],
|
|
51
61
|
extra_copy: o['extra_copy']
|
|
52
62
|
)
|
|
@@ -58,31 +68,45 @@ class Backupper
|
|
|
58
68
|
send_report_email!
|
|
59
69
|
end
|
|
60
70
|
|
|
61
|
-
def download_dump(key:, adapter: 'mysql', url:, password: nil, database:, db_username: 'root', db_password: nil, dump_options: nil, outdir:, extra_copy: nil)
|
|
62
|
-
t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
63
|
-
path = nil
|
|
64
|
-
filename = "#{key}__#{database}.sql.bz2"
|
|
65
|
-
tempfile = File.join('/tmp', filename)
|
|
66
|
-
dumpname = "#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}__#{filename}"
|
|
67
|
-
path = File.join(outdir, dumpname)
|
|
68
|
-
on(url) do |client|
|
|
69
|
-
client.password = password
|
|
70
|
-
execute 'set -o pipefail; ' + DumpCommand.send(adapter, database: database, username: db_username, password: db_password, dump_options: dump_options, outfile: tempfile)
|
|
71
|
-
download! tempfile, path
|
|
72
|
-
execute :rm, tempfile
|
|
73
|
-
end
|
|
74
|
-
extra_copy = check_dir(extra_copy)
|
|
75
|
-
FileUtils.cp(path, extra_copy) if extra_copy
|
|
76
|
-
@report[key] = {
|
|
77
|
-
path: File.absolute_path(path),
|
|
78
|
-
size: (File.size(path).to_f / 2**20).round(2),
|
|
79
|
-
time: (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t).round(2)
|
|
80
|
-
}
|
|
81
|
-
@report[key].merge!({ extra_copy: File.absolute_path(File.join(extra_copy, dumpname)) }) if extra_copy
|
|
82
|
-
end
|
|
83
|
-
|
|
84
71
|
private
|
|
85
72
|
|
|
73
|
+
def do_and_download_dump(key:, adapter: 'mysql', url:, password: nil, database:, db_username: 'root', db_password: nil, dump_options: nil, sudo: false, outdir:, extra_copy: nil)
|
|
74
|
+
t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
75
|
+
filename = "#{key}__#{database}#{DumpCommand::EXTENSIONS[adapter]}"
|
|
76
|
+
temp_file = File.join('/tmp', filename)
|
|
77
|
+
working_dirname = "#{key}__#{database}"
|
|
78
|
+
temp_working_dir = File.join('/tmp', working_dirname)
|
|
79
|
+
dump_name = "#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}__#{filename}"
|
|
80
|
+
path = File.join(outdir, dump_name)
|
|
81
|
+
outfile = Shellwords.escape(temp_file)
|
|
82
|
+
working_dir = Shellwords.escape(temp_working_dir)
|
|
83
|
+
on(url) do |host|
|
|
84
|
+
host.password = password
|
|
85
|
+
sudo_execute :mkdir, '-p', working_dir, password: password, sudo: sudo
|
|
86
|
+
command = DumpCommand.public_send(
|
|
87
|
+
adapter,
|
|
88
|
+
database: Shellwords.escape(database),
|
|
89
|
+
username: Shellwords.escape(db_username),
|
|
90
|
+
password: db_password && Shellwords.escape(db_password),
|
|
91
|
+
dump_options: dump_options,
|
|
92
|
+
working_dir: working_dir,
|
|
93
|
+
outfile: outfile
|
|
94
|
+
)
|
|
95
|
+
sudo_execute 'set -o pipefail; ' + command, password: password, sudo: sudo
|
|
96
|
+
download! temp_file, path
|
|
97
|
+
sudo_execute :rm, outfile, password: password, sudo: sudo
|
|
98
|
+
sudo_execute :rm, '-r', working_dir, password: password, sudo: sudo
|
|
99
|
+
end
|
|
100
|
+
extra_copy = check_dir(extra_copy)
|
|
101
|
+
FileUtils.cp(path, extra_copy) if extra_copy
|
|
102
|
+
@report[key] = {
|
|
103
|
+
path: File.absolute_path(path),
|
|
104
|
+
size: (File.size(path).to_f / 2**20).round(2),
|
|
105
|
+
time: (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t).round(2)
|
|
106
|
+
}
|
|
107
|
+
@report[key][:extra_copy] = File.absolute_path(File.join(extra_copy, dump_name)) if extra_copy
|
|
108
|
+
end
|
|
109
|
+
|
|
86
110
|
def setup_options(options)
|
|
87
111
|
o = @default.merge(options)
|
|
88
112
|
o['outdir'] = check_dir(o['dump'].to_s)
|
|
@@ -94,17 +118,38 @@ class Backupper
|
|
|
94
118
|
o['url'] = "#{o['username']}@#{o['url']}" if o['username']
|
|
95
119
|
o['url'] = "#{o['url']}:#{o['port']}" if o['port']
|
|
96
120
|
o['adapter'] ||= 'mysql'
|
|
97
|
-
unless DumpCommand.
|
|
98
|
-
return nil, "Cannot handle adapter '#{o['adapter']}'"
|
|
121
|
+
unless DumpCommand.singleton_methods(false).map(&:to_s).include?(o['adapter'])
|
|
122
|
+
return nil, "Cannot handle adapter '#{o['adapter']}' (supported: #{DumpCommand.singleton_methods(false).join(', ')})"
|
|
123
|
+
end
|
|
124
|
+
begin
|
|
125
|
+
shellescape_dump_options(o['dump_options'])
|
|
126
|
+
rescue ArgumentError => e
|
|
127
|
+
return nil, e.message
|
|
99
128
|
end
|
|
100
129
|
|
|
101
130
|
return o, nil
|
|
102
131
|
end
|
|
103
132
|
|
|
133
|
+
def shellescape_dump_options(dump_options)
|
|
134
|
+
return nil if dump_options.nil?
|
|
135
|
+
|
|
136
|
+
options =
|
|
137
|
+
if dump_options.is_a?(Array)
|
|
138
|
+
dump_options.map(&:to_s)
|
|
139
|
+
else
|
|
140
|
+
Shellwords.split(dump_options.to_s)
|
|
141
|
+
end
|
|
142
|
+
return nil if options.empty?
|
|
143
|
+
|
|
144
|
+
return options.map { |option| Shellwords.escape(option) }.join(' ')
|
|
145
|
+
rescue ArgumentError => e
|
|
146
|
+
raise ArgumentError, "Invalid dump_options: #{e.message}"
|
|
147
|
+
end
|
|
148
|
+
|
|
104
149
|
def send_report_email!
|
|
105
150
|
if @report.any? && @mailer['from'] && @mailer['to'] && @mailer['password']
|
|
106
151
|
begin
|
|
107
|
-
Mailer.
|
|
152
|
+
Mailer.deliver(@report, from: @mailer['from'], to: @mailer['to'], password: @mailer['password'], address: @mailer['address'] || 'smtp.gmail.com', port: @mailer['port'] || 587, authentication: @mailer['authentication'] || 'plain')
|
|
108
153
|
rescue Net::SMTPAuthenticationError => e
|
|
109
154
|
@logger.error e
|
|
110
155
|
end
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
module DumpCommand
|
|
2
|
-
|
|
2
|
+
# Extension of the file produced by each adapter ('.sql.bz2' if not listed here)
|
|
3
|
+
EXTENSIONS = Hash.new('.sql.bz2').update('mydumper' => '.tar.bz2').freeze
|
|
4
|
+
|
|
5
|
+
def self.mysql(database:, username: 'root', password: nil, dump_options: nil, working_dir: nil, outfile:)
|
|
6
|
+
params = []
|
|
7
|
+
params << "-u#{username}"
|
|
8
|
+
params << "-p#{password}" if password
|
|
9
|
+
params << dump_options if dump_options
|
|
10
|
+
return "mysqldump #{database} #{params.join(' ')} | bzip2 > #{outfile}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.postgresql(database:, username: 'root', password: nil, dump_options: nil, working_dir: nil, outfile:)
|
|
3
14
|
params = []
|
|
4
|
-
params << "-
|
|
5
|
-
params << "-p'#{password}'" if password
|
|
15
|
+
params << "-U #{username}"
|
|
6
16
|
params << dump_options if dump_options
|
|
7
|
-
return "
|
|
17
|
+
return "PGPASSWORD=#{password} pg_dump #{database} #{params.join(' ')} | bzip2 > #{outfile}"
|
|
8
18
|
end
|
|
9
19
|
|
|
10
|
-
def self.
|
|
20
|
+
def self.mydumper(database:, username: 'root', password: nil, dump_options: nil, working_dir: nil, outfile:)
|
|
11
21
|
params = []
|
|
12
|
-
params << "
|
|
22
|
+
params << "--user #{username}"
|
|
23
|
+
params << "--password #{password}" if password
|
|
13
24
|
params << dump_options if dump_options
|
|
14
|
-
return "
|
|
25
|
+
return "mydumper --database #{database} #{params.join(' ')} --outputdir #{working_dir} && tar -cjf #{outfile} -C #{File.dirname(working_dir)} #{File.basename(working_dir)}"
|
|
15
26
|
end
|
|
16
27
|
end
|
data/lib/backupper/mailer.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'mail'
|
|
2
2
|
|
|
3
3
|
class Mailer
|
|
4
|
-
def self.
|
|
4
|
+
def self.deliver(report, from:, to:, password:, address:, port:, authentication:)
|
|
5
5
|
Mail.defaults do
|
|
6
6
|
delivery_method :smtp, {
|
|
7
7
|
address: address,
|
|
@@ -12,7 +12,7 @@ class Mailer
|
|
|
12
12
|
enable_starttls_auto: true
|
|
13
13
|
}
|
|
14
14
|
end
|
|
15
|
-
Mail.deliver(to: to, from: from, subject: generate_subject(report), body: generate_body(report))
|
|
15
|
+
Mail.deliver(to: to, from: from, subject: generate_subject(report), body: generate_body(report), charset: 'UTF-8')
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
class << self
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
require 'sshkit'
|
|
3
|
+
|
|
4
|
+
module SSHKitSudoExecute
|
|
5
|
+
def sudo_execute(*command, password: nil, sudo: false, **options)
|
|
6
|
+
return execute(*command, options) unless sudo
|
|
7
|
+
|
|
8
|
+
prompt = 'SSHKitSudoPassword'
|
|
9
|
+
execute(
|
|
10
|
+
:sudo,
|
|
11
|
+
'-S',
|
|
12
|
+
'-p', prompt,
|
|
13
|
+
'--',
|
|
14
|
+
'bash', '-c', command.map(&:to_s).join(' ').shellescape,
|
|
15
|
+
options.merge(
|
|
16
|
+
interaction_handler: {
|
|
17
|
+
/#{Regexp.escape(prompt)}/ => "#{password}\n"
|
|
18
|
+
}
|
|
19
|
+
)
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
SSHKit::Backend::Abstract.include(SSHKitSudoExecute)
|
data/lib/backupper/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: backupper
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- pioz
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: mail
|
|
@@ -16,74 +15,60 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '2.
|
|
18
|
+
version: '2.9'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '2.
|
|
25
|
+
version: '2.9'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: sshkit
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - "~>"
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '1.
|
|
32
|
+
version: '1.25'
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - "~>"
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '1.
|
|
39
|
+
version: '1.25'
|
|
41
40
|
- !ruby/object:Gem::Dependency
|
|
42
41
|
name: bundler
|
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
|
44
43
|
requirements:
|
|
45
|
-
- - "
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '2'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - "~>"
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '2'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: byebug
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
44
|
+
- - ">="
|
|
60
45
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
46
|
+
version: '0'
|
|
62
47
|
type: :development
|
|
63
48
|
prerelease: false
|
|
64
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
50
|
requirements:
|
|
66
|
-
- - "
|
|
51
|
+
- - ">="
|
|
67
52
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
53
|
+
version: '0'
|
|
69
54
|
- !ruby/object:Gem::Dependency
|
|
70
55
|
name: rake
|
|
71
56
|
requirement: !ruby/object:Gem::Requirement
|
|
72
57
|
requirements:
|
|
73
|
-
- - "
|
|
58
|
+
- - ">="
|
|
74
59
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
60
|
+
version: '0'
|
|
76
61
|
type: :development
|
|
77
62
|
prerelease: false
|
|
78
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
64
|
requirements:
|
|
80
|
-
- - "
|
|
65
|
+
- - ">="
|
|
81
66
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
67
|
+
version: '0'
|
|
83
68
|
description: Backupper is a tool to backup all your databases spread all over the
|
|
84
69
|
world
|
|
85
70
|
email:
|
|
86
|
-
-
|
|
71
|
+
- epilotto@gmx.com
|
|
87
72
|
executables:
|
|
88
73
|
- backupper
|
|
89
74
|
extensions: []
|
|
@@ -101,13 +86,13 @@ files:
|
|
|
101
86
|
- lib/backupper/backupper.rb
|
|
102
87
|
- lib/backupper/dump_command.rb
|
|
103
88
|
- lib/backupper/mailer.rb
|
|
89
|
+
- lib/backupper/sshkit.rb
|
|
104
90
|
- lib/backupper/version.rb
|
|
105
|
-
homepage: https://github.com/
|
|
91
|
+
homepage: https://github.com/pioz/backupper
|
|
106
92
|
licenses:
|
|
107
93
|
- MIT
|
|
108
94
|
metadata:
|
|
109
95
|
allowed_push_host: https://rubygems.org
|
|
110
|
-
post_install_message:
|
|
111
96
|
rdoc_options: []
|
|
112
97
|
require_paths:
|
|
113
98
|
- lib
|
|
@@ -115,15 +100,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
115
100
|
requirements:
|
|
116
101
|
- - ">="
|
|
117
102
|
- !ruby/object:Gem::Version
|
|
118
|
-
version: '
|
|
103
|
+
version: '2.5'
|
|
119
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
105
|
requirements:
|
|
121
106
|
- - ">="
|
|
122
107
|
- !ruby/object:Gem::Version
|
|
123
108
|
version: '0'
|
|
124
109
|
requirements: []
|
|
125
|
-
rubygems_version:
|
|
126
|
-
signing_key:
|
|
110
|
+
rubygems_version: 4.0.15
|
|
127
111
|
specification_version: 4
|
|
128
112
|
summary: Tool to backup databases
|
|
129
113
|
test_files: []
|