ey_cloud_server 1.4.54 → 1.4.58
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/bin/eyrestore +182 -0
- data/lib/ey_cloud_server/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTRlYTdlMDYxN2UzYzI2MTNjM2Y1NGMzMmFjNmJkMWQzOTVkYWU4Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MGQ4M2EwYWVhMmY2OGU0ZGUxYmNhNDdkODdiMjBmN2MwNjdlZDRkZA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
N2M0ZGUzOWJhNDRlYTNiMzIxYzQ4YzcwZDY1MGI0OTY2NTVkZDQxZTA4YmQ2
|
10
|
+
OGY5NmUwNTg4ZDFiM2ZjMjNlNmExMjBmMWJhNjFhNGUxYTVlYzhmODlhYjc0
|
11
|
+
M2E2N2M5MWJjZDRlZWE3MGM2MDdkNGJlNDkzMjA2MGIxMDBkZjM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Mzc1YTczYzU1M2QyODA2NDgwZjE0MzJmNTVmOGEzOGZlNzJjYTc5NGRmYmEz
|
14
|
+
OWZjNjc0NjEyYWVhM2JkOGQxMmFkZTE0NWViNWQ2MDBlYzVjZGVmZTZkZTc2
|
15
|
+
NzgwYTI2NjcwZmQ0NWUwOWVmOTlkNTM3NjM2MzMxYjBlMGE4OTI=
|
data/bin/eyrestore
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'yaml'
|
5
|
+
require 'tempfile'
|
6
|
+
require 'timeout'
|
7
|
+
|
8
|
+
def opt_parse(argv)
|
9
|
+
options = {}
|
10
|
+
optparse = OptionParser.new do |opts|
|
11
|
+
opts.banner = "Usage: #{__FILE__} --env <environment name> --database <database_name> --action <action> [options]"
|
12
|
+
opts.separator ''
|
13
|
+
opts.separator "Wrapper for eybackup used for listing, downloading and restoring database backups. The main purpose for this tool is to"
|
14
|
+
opts.separator "simplify the process of accessing backups from one environment in a different environment (e.g. access Production backups"
|
15
|
+
opts.separator "from Staging). This can also be used for restoring backups within the current environment."
|
16
|
+
opts.separator ''
|
17
|
+
opts.on('-h', '--help', 'Displays this Help message') { puts opts; exit}
|
18
|
+
|
19
|
+
opts.separator ''
|
20
|
+
opts.separator 'Common Options:'
|
21
|
+
|
22
|
+
opts.on('-e', '--env environment_name', "Specifies the source environment name for the backups you will be working with.") { |env| options[:env] = env }
|
23
|
+
opts.on('-d', '--database database_name', "Name of the source database to get backups for.") { |dbname| options[:databases] = [dbname] }
|
24
|
+
actions=['list', 'restore', 'download']
|
25
|
+
opts.on('-a', '--action action_name', "The action you want to perform using the backup #{actions}.") do |action|
|
26
|
+
unless actions.include?(action)
|
27
|
+
puts "Invalid action: '#{action}' must be one of #{actions}\n\n"
|
28
|
+
puts opts
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
options[:action] = action
|
32
|
+
end
|
33
|
+
opts.on('-i', '--index BACKUP_INDEX', 'Download/Restore the backup specified by index','BACKUP_INDEX uses the format #{index_number}:#{db_name}',
|
34
|
+
"The string 'last' will automatically reference the most recent available backup.") do |index|
|
35
|
+
options[:index] = index
|
36
|
+
end
|
37
|
+
opts.on('-f', '--force', 'Force mode, skips all confirmation prompts for use with automated restores.') { options[:force] = true }
|
38
|
+
|
39
|
+
opts.separator ''
|
40
|
+
opts.separator 'Additional Options:'
|
41
|
+
|
42
|
+
opts.on('-u', '--aws_secret_id key', 'AWS S3 Key') { |key| options[:aws_key_id] = key }
|
43
|
+
opts.on('-p', '--aws_secret_key secret', 'AWS S3 Secret Key') { |secret| options[:aws_secret_key] = secret }
|
44
|
+
opts.on('-b', '--backup_bucket bucket', 'AWS S3 bucket identifier') { |bucket| options[:backup_bucket] = bucket }
|
45
|
+
opts.on('-v', '--verbose', "Enable debug info for this wrapper.") { $verbose = true }
|
46
|
+
opts.on('-c', '--config', "Alternate config file for eyrestore (default ~/.eyrestore.confg.yml)") do |path|
|
47
|
+
unless File.exists?(path)
|
48
|
+
puts "Invalid config file path '#{path}', no file at that location."
|
49
|
+
exit 1
|
50
|
+
end
|
51
|
+
options[:def_config] = path
|
52
|
+
end
|
53
|
+
opts.separator ''
|
54
|
+
opts.separator 'Examples:'
|
55
|
+
opts.separator '* List backups from an environment named production for a database named todo'
|
56
|
+
opts.separator " sudo -i #{__FILE__} --env production --database todo --action list"
|
57
|
+
opts.separator ''
|
58
|
+
opts.separator '* Download the most recent backup from an environment named production for a database named todo'
|
59
|
+
opts.separator " sudo -i #{__FILE__} --env production --database todo --action download --index last"
|
60
|
+
opts.separator ''
|
61
|
+
opts.separator "* Download a backup from an environment named production for a database named todo, prompt with a list of available backups"
|
62
|
+
opts.separator " sudo -i #{__FILE__} --env production --database todo --action download"
|
63
|
+
opts.separator ''
|
64
|
+
opts.separator '* Restore the most recent backup from an environment named production for a database named todo'
|
65
|
+
opts.separator " sudo -i #{__FILE__} --env production --database todo --action restore --index last"
|
66
|
+
opts.separator ''
|
67
|
+
end
|
68
|
+
optparse.parse!
|
69
|
+
options
|
70
|
+
end
|
71
|
+
|
72
|
+
def debug(msg)
|
73
|
+
puts '[' + Time.now.strftime("%D %T") + ']: DEBUG: ' + msg if $verbose
|
74
|
+
end
|
75
|
+
|
76
|
+
def find_engine
|
77
|
+
debug("Searching for database engine based on file '/etc/.*.backups.yml'")
|
78
|
+
main_config = Dir['/etc/.*.backups.yml'].first
|
79
|
+
abort "Failed to find eybackup config at '/etc/.*.backups.yml', this needs to run on a database instance." unless main_config
|
80
|
+
debug("Found file '#{main_config}'")
|
81
|
+
File.basename(main_config).split('.')[1]
|
82
|
+
end
|
83
|
+
|
84
|
+
def extra_validations(options)
|
85
|
+
mandatory = [:databases, :env, :action]
|
86
|
+
missing = mandatory.select{ |param| options[param].nil? }
|
87
|
+
raise OptionParser::MissingArgument, missing.join(',') unless missing.empty?
|
88
|
+
end
|
89
|
+
|
90
|
+
def list_backups(engine, db, path)
|
91
|
+
command = "eybackup -e #{engine} -l #{db} -c #{path}"
|
92
|
+
debug("Listing backups with command: #{command}")
|
93
|
+
res = %x{#{command}}
|
94
|
+
last = res.chomp.split("\n").last
|
95
|
+
abort "No Backups Found for that environment and database." if last.match(/0 backup\(s\) found/)
|
96
|
+
res
|
97
|
+
end
|
98
|
+
|
99
|
+
def gets_timeout( prompt, secs )
|
100
|
+
print prompt + "[timeout=#{secs}secs]: "
|
101
|
+
Timeout::timeout( secs ) { gets.chomp }
|
102
|
+
rescue Timeout::Error
|
103
|
+
puts "*timeout"
|
104
|
+
'' # return nil if timeout
|
105
|
+
end
|
106
|
+
|
107
|
+
def last_backup_idx(listing)
|
108
|
+
last = listing.chomp.split("\n").last
|
109
|
+
if last.split.first.match(/\d+:\w+/)
|
110
|
+
index = last.split.first
|
111
|
+
else
|
112
|
+
index = last.split[3]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
options = opt_parse(ARGV)
|
117
|
+
options[:def_config] = '~/.eyrestore.config.yml' unless options[:def_config]
|
118
|
+
|
119
|
+
# auto-detect the type of database running in the given environment
|
120
|
+
engine = find_engine
|
121
|
+
|
122
|
+
# parse eybackup config file
|
123
|
+
config = YAML.load_file("/etc/.#{engine}.backups.yml")
|
124
|
+
this_env = config[:env]
|
125
|
+
# delete these just in case
|
126
|
+
config.delete(:env)
|
127
|
+
config.delete(:databases)
|
128
|
+
|
129
|
+
# override config from eyrestore config file
|
130
|
+
eyrestore = YAML.load_file(options[:def_config]) if File.exists?(options[:def_config])
|
131
|
+
config.merge!(eyrestore) unless eyrestore.nil?
|
132
|
+
|
133
|
+
# override config from command line options
|
134
|
+
config.merge!(options)
|
135
|
+
extra_validations(config)
|
136
|
+
debug("Config Options: '#{config}'")
|
137
|
+
|
138
|
+
# create a temporary configuration file from ~/.eyrestore.config.yml
|
139
|
+
temp_config = Tempfile.new("eyrestore")
|
140
|
+
temp_config.write(config.to_yaml)
|
141
|
+
temp_config.rewind
|
142
|
+
debug("Generated temporary config file: '#{temp_config.path}'")
|
143
|
+
|
144
|
+
db = config[:databases].first
|
145
|
+
temp = temp_config.path
|
146
|
+
if config[:action] == 'list' or ! config[:index]
|
147
|
+
puts list_backups(engine, db, temp)
|
148
|
+
end
|
149
|
+
|
150
|
+
# confirm environment overwrite if restoring
|
151
|
+
if config[:action] == 'restore' and ! config[:force]
|
152
|
+
response = gets_timeout("You are restoring the backup for '#{db}' from '#{config[:env]}' into '#{this_env}', THIS MAY BE DESTRUCTIVE; are you sure you want to proceed (Y/n) ? ", 30)
|
153
|
+
exit unless response.downcase == 'y'
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
if ['download','restore'].include?(config[:action])
|
158
|
+
config[:index] = gets_timeout("Enter the backup index to use for #{config[:action]} (e.g. 9:#{db}) ", 30) unless config[:index]
|
159
|
+
config[:index] = last_backup_idx(list_backups(engine, db, temp)) if config[:index] == 'last'
|
160
|
+
abort "Invalid backup index '#{config[:index]}'." unless config[:index].match(/^\d+:\w+$/)
|
161
|
+
|
162
|
+
action = config[:action] == 'restore' ? '-r' : '-d'
|
163
|
+
debug("Set action flag for eybackup to '#{action}' based on action of '#{config[:action]}'")
|
164
|
+
|
165
|
+
# test eybackup version for force option
|
166
|
+
ey_cloud_server_version = Gem::Version.new(%x{/usr/local/ey_resin/ruby/bin/gem list ey_cloud_server}.split[1].gsub('(','').gsub(')','').gsub(',',''))
|
167
|
+
force = ey_cloud_server_version >= Gem::Version.new('1.4.51') ? '--force' : ''
|
168
|
+
debug("eybackup version '#{ey_cloud_server_version}' so force is set to '#{force}'")
|
169
|
+
|
170
|
+
command="eybackup -e #{engine} -c #{temp} #{action} #{config[:index]} #{force}"
|
171
|
+
|
172
|
+
puts "Running '#{config[:action]}' on index '#{config[:index]}'."
|
173
|
+
debug("Running command: #{command}")
|
174
|
+
|
175
|
+
res=%x{#{command}}
|
176
|
+
puts res
|
177
|
+
puts "Restore complete!" if res.split("\n").last.match(/^Filename/) and config[:action] == 'restore'
|
178
|
+
end
|
179
|
+
|
180
|
+
# cleanup temporary config file
|
181
|
+
temp_config.close
|
182
|
+
temp_config.unlink
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ey_cloud_server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.58
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- EngineYard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -238,6 +238,7 @@ email:
|
|
238
238
|
executables:
|
239
239
|
- ey-snapshots
|
240
240
|
- eybackup
|
241
|
+
- eyrestore
|
241
242
|
extensions: []
|
242
243
|
extra_rdoc_files: []
|
243
244
|
files:
|
@@ -247,6 +248,7 @@ files:
|
|
247
248
|
- TODO
|
248
249
|
- bin/ey-snapshots
|
249
250
|
- bin/eybackup
|
251
|
+
- bin/eyrestore
|
250
252
|
- features/downloading_a_mysql_backup.feature
|
251
253
|
- features/making_a_postgresql_backup.feature
|
252
254
|
- features/restoring_postgres_backup.feature
|
@@ -312,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
312
314
|
version: '0'
|
313
315
|
requirements: []
|
314
316
|
rubyforge_project:
|
315
|
-
rubygems_version: 2.
|
317
|
+
rubygems_version: 2.4.5
|
316
318
|
signing_key:
|
317
319
|
specification_version: 4
|
318
320
|
summary: Server side components for Engine Yard's cloud
|