forked from ManageIQ/manageiq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevm_dba.rake
281 lines (227 loc) · 10.8 KB
/
evm_dba.rake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
require 'awesome_spawn'
require 'evm_rake_helper'
# TODO: move into DatabaseYml
# TODO: can we use EvmDatabseOps directly?
module EvmDba
def self.database_configuration_file
File.expand_path(File.join(Rails.root, 'config', 'database.yml'))
end
def self.load_config
require 'yaml'
YAML::load((IO.read(self.database_configuration_file)))
end
def self.local?
config = self.load_config[Rails.env]
return false unless config['adapter'] == 'postgresql'
return %w( 127.0.0.1 localhost ).include?(config['host']) || config['host'].blank?
end
def self.with_options(*option_types, &block)
require 'trollop'
Trollop.options(EvmRakeHelper.extract_command_options) do
option_types.each do |type|
case type
when :db_credentials
opt :username, "Username", :type => :string
opt :password, "Password", :type => :string
opt :hostname, "Hostname", :type => :string
opt :port, "Port", :type => :string
opt :dbname, "Database name", :type => :string
when :local_file
opt :local_file, "Destination file", :type => :string, :required => true
when :remote_file
opt :skip_directory, "Don't add backup directory", :type => :boolean, :default => false
opt :remote_file_name, "Destination depot filename", :type => :string
when :splitable
opt :byte_count, "Size to split files into", :type => :string
when :remote_uri
opt :uri, "Destination depot URI", :type => :string, :required => true
opt :uri_username, "Destination depot username", :type => :string
opt :uri_password, "Destination depot password", :type => :string
when :aws
opt :aws_region, "Destination depot AWS region", :type => :string
when :exclude_table_data
opt :exclude_table_data, "Tables to exclude data", :type => :strings
end
end
instance_exec(&block) if block_given?
end.delete_nils
end
DB_OPT_KEYS = [:dbname, :username, :password, :hostname, :port, :exclude_table_data, :byte_count].freeze
def self.collect_db_opts(opts)
db_opts = {}
DB_OPT_KEYS.each { |k| db_opts[k] = opts[k] if opts[k] }
db_opts
end
CONNECT_OPT_KEYS = %i(uri uri_username uri_password aws_region remote_file_name skip_directory).freeze
def self.collect_connect_opts(opts)
connect_opts = {}
CONNECT_OPT_KEYS.each { |k| connect_opts[k] = opts[k] if opts[k] }
connect_opts[:username] = connect_opts.delete(:uri_username) if connect_opts[:uri_username]
connect_opts[:password] = connect_opts.delete(:uri_password) if connect_opts[:uri_password]
connect_opts
end
end
namespace :evm do
namespace :db do
desc 'Start the local ManageIQ EVM Database (VMDB)'
task :start do
LinuxAdmin::Service.new(PostgresAdmin.service_name).start
end
desc 'Stop the local ManageIQ EVM Database (VMDB)'
task :stop do
LinuxAdmin::Service.new(PostgresAdmin.service_name).stop
end
# Start the EVM Database silently - not to be a visible rake task
task :silent_start do
begin
LinuxAdmin::Service.new(PostgresAdmin.service_name).start
rescue AwesomeSpawn::CommandResultError
# ignore issues (ala silent)
end
end
# Stop the EVM Database silently - not to be a visible rake task
task :silent_stop do
begin
LinuxAdmin::Service.new(PostgresAdmin.service_name).stop
rescue AwesomeSpawn::CommandResultError
# ignore issues (ala silent)
end
end
desc "Seed the ManageIQ EVM Database (VMDB) with defaults"
task :seed do
Rake::Task['db:seed'].invoke
end
desc "clean up database"
task :gc do
opts = EvmDba.with_options(:db_credentials) do
opt :aggressive, "Aggressive gc: vaccume with all options and reindexing"
opt :vacuum, "Vacuum database"
opt :reindex, "Reindex database (or table if --table specified)"
opt :analyze, "Vacuum with analyze"
opt :full, "Vacuum full"
opt :verbose, "Vacuum with verbose information printed"
opt :table, "Tablename to reindex (if only perorm on one)", :type => :string
end
opts = opts.delete_if { |_, v| v == false }
EvmDatabaseOps.gc(opts)
exit # exit so that parameters to the first rake task are not run as rake tasks
end
desc "Destroys the ManageIQ EVM Database (VMDB) of all tables, views and indices"
task :destroy do
begin
Rake::Task['environment'].invoke
rescue => err
# Allow "destroying" a database that doesn't exist
raise unless err.message =~ /does not exist$/
end
Rake::Task['db:drop'].invoke
Rake::Task['db:create'].invoke
# db:create creates a temporary connection to the default database, but doesn't
# remove the connection in the event of a failed create, so we drop the connection
# and reestablish it to the environment's database.
ActiveRecord::Base.remove_connection
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[Rails.env])
end
desc "Resets the ManageIQ EVM Database (VMDB) of all tables, views and indices"
task :reset => [:destroy, 'db:migrate']
# Example usage:
# RAILS_ENV=production bin/rake evm:db:region -- --region 99
desc 'Set the region of the current ManageIQ EVM Database (VMDB)'
task :region do
opts = EvmDba.with_options do
opt :region, "Region number", :type => :integer, :required => ENV["REGION"].blank?
end
Dir.chdir(Rails.root)
begin
#TODO: Raise an error if region is not valid
ENV["REGION"] = opts[:region].to_s if opts[:region]
region = ENV["REGION"]
region_file = Rails.root.join("REGION")
if File.exist?(region_file)
old_region = File.read(region_file)
File.delete(region_file)
end
puts "Resetting #{Rails.env} database to region #{region}..."
ENV['VERBOSE'] = 'false' # Do not flood the output with migration details
Rake::Task['evm:db:reset'].invoke
puts "Initializing region and database..."
# Create the region from our REGION file, initialize a new miq_database row for this region
AwesomeSpawn.run!("bin/rails runner", :params => ["MiqDatabase.seed; MiqRegion.seed"])
rescue => err
message = err.kind_of?(AwesomeSpawn::CommandResultError) ? err.result.error : err.message
STDERR.puts "Encountered issue setting up Database using region #{region}: #{message}\n"
File.write(region_file, old_region) if old_region
raise
end
exit # exit so that parameters to the first rake task are not run as rake tasks
end
# Example usage:
# bin/rake evm:db:backup:local -- --local-file /tmp/db_backup_test --dbname vmdb_production
# bin/rake evm:db:backup:remote -- --uri smb://dev005.manageiq.com/share1 --uri-username samba_one --uri-password "abc" --remote-file-name region1
# bin/rake evm:db:restore:local -- --local-file /tmp/db_backup_test
# bin/rake evm:db:restore:remote -- --uri smb://dev005.manageiq.com/share1/db_backup/region1 --uri-username samba_one --uri-password "abc"
namespace :backup do
require File.expand_path(File.join(Rails.root, "lib", "evm_database_ops"))
desc 'Backup the local ManageIQ EVM Database (VMDB) to a local file'
task :local do
opts = EvmDba.with_options(:local_file, :splitable, :db_credentials)
EvmDatabaseOps.backup(opts)
exit # exit so that parameters to the first rake task are not run as rake tasks
end
desc 'Backup the local ManageIQ EVM Database (VMDB) to a remote file'
task :remote do
opts = EvmDba.with_options(:remote_uri, :aws, :remote_file, :splitable, :db_credentials)
db_opts = EvmDba.collect_db_opts(opts)
connect_opts = EvmDba.collect_connect_opts(opts)
EvmDatabaseOps.backup(db_opts, connect_opts)
exit # exit so that parameters to the first rake task are not run as rake tasks
end
end
namespace :dump do
require Rails.root.join("lib", "evm_database_ops").expand_path.to_s
desc 'Dump the local ManageIQ EVM Database (VMDB) to a local file'
task :local do
opts = EvmDba.with_options(:local_file, :splitable, :db_credentials, :exclude_table_data)
EvmDatabaseOps.dump(opts)
exit # exit so that parameters to the first rake task are not run as rake tasks
end
desc 'Dump the local ManageIQ EVM Database (VMDB) to a remote file'
task :remote do
opts = EvmDba.with_options(:remote_uri, :aws, :remote_file, :splitable, :db_credentials, :exclude_table_data)
db_opts = EvmDba.collect_db_opts(opts)
connect_opts = EvmDba.collect_connect_opts(opts)
EvmDatabaseOps.dump(db_opts, connect_opts)
exit # exit so that parameters to the first rake task are not run as rake tasks
end
end
namespace :restore do
desc 'Restore the local ManageIQ EVM Database (VMDB) from a local backup file'
task :local => :environment do
opts = EvmDba.with_options(:local_file, :db_credentials)
# If running through runner, disconnect any local connections
ActiveRecord::Base.clear_all_connections! if ActiveRecord && ActiveRecord::Base
EvmDatabaseOps.restore(opts)
exit # exit so that parameters to the first rake task are not run as rake tasks
end
desc 'Restore the local ManageIQ EVM Database (VMDB) from a remote backup file'
task :remote => :environment do
opts = EvmDba.with_options(:remote_uri, :aws, :db_credentials)
db_opts = EvmDba.collect_db_opts(opts)
connect_opts = EvmDba.collect_connect_opts(opts)
# If running through runner, disconnect any local connections
ActiveRecord::Base.clear_all_connections! if ActiveRecord && ActiveRecord::Base
EvmDatabaseOps.restore(db_opts, connect_opts)
exit # exit so that parameters to the first rake task are not run as rake tasks
end
end
# loads the v1 key into the enviroment
task :environmentlegacykey => :environment do
MiqPassword.add_legacy_key('v0_key', :v0)
MiqPassword.add_legacy_key('v1_key', :v1)
end
end
end
Rake::Task["db:migrate"].enhance(["evm:db:environmentlegacykey"])
Rake::Task["db:reset"].enhance do
warn "Caution: You ran db:reset which resets the DB from schema.rb. You probably want to re-run all the migrations with the current ruby/rails versions, so run bin/rake evm:db:reset instead."
end