-
Notifications
You must be signed in to change notification settings - Fork 900
/
Copy pathevm_dba.rake
284 lines (233 loc) · 11.2 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
282
283
284
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.start
require File.expand_path(File.join(Rails.root, 'lib/evm_database_ops'))
Dir.chdir(Rails.root)
EvmDatabaseOps.start
end
def self.stop
require File.expand_path(File.join(Rails.root, 'lib/evm_database_ops'))
Dir.chdir(Rails.root)
EvmDatabaseOps.stop
end
end
namespace :evm do
namespace :db do
desc 'Start the local ManageIQ EVM Database (VMDB)'
task :start do
EvmDba.start
end
desc 'Stop the local ManageIQ EVM Database (VMDB)'
task :stop do
EvmDba.stop
end
# Start the EVM Database silently - not to be a visible rake task
task :silent_start do
begin
EvmDba.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
EvmDba.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
require 'trollop'
opts = Trollop.options(EvmRakeHelper.extract_command_options) do
opt :username, "Username", :type => :string
opt :password, "Password", :type => :string
opt :hostname, "Hostname", :type => :string
opt :dbname, "Database name", :type => :string
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 { |_k, v| v.nil? || 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
require 'trollop'
opts = Trollop.options(EvmRakeHelper.extract_command_options) do
opt :region, "Region number", :type => :integer, :required => true
end
Dir.chdir(Rails.root)
begin
#TODO: Raise an error if region is not valid
region = opts[:region]
region_file = Rails.root.join("REGION")
puts "Writing region: #{region} in #{region_file}..."
old_region = File.exist?(region_file) ? File.read(region_file) : 0
File.write(region_file, region)
puts "Resetting #{Rails.env} database..."
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
desc 'Check the current schema against the schema.yml file for inconsistencies'
task :check_schema => :environment do
message = EvmDatabase.check_schema
raise message if message
puts "The local schema is consistent with schema.yml"
end
desc 'Write the current schema to the schema.yml file'
task :write_schema => :environment do
EvmDatabase.write_expected_schema
puts "Wrote configured schema to schema.yml"
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
require 'trollop'
opts = Trollop.options(EvmRakeHelper.extract_command_options) do
opt :local_file, "Destination file", :type => :string, :required => true
opt :username, "Username", :type => :string
opt :password, "Password", :type => :string
opt :hostname, "Hostname", :type => :string
opt :dbname, "Database name", :type => :string
end
opts.delete_if { |k,v| v.nil? }
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
require 'trollop'
opts = Trollop.options(EvmRakeHelper.extract_command_options) do
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
opt :remote_file_name, "Destination depot filename", :type => :string
opt :username, "Username", :type => :string
opt :password, "Password", :type => :string
opt :hostname, "Hostname", :type => :string
opt :dbname, "Database name", :type => :string
end
db_opts = {}
[:dbname, :username, :password, :hostname].each { |k| db_opts[k] = opts[k] if opts[k] }
connect_opts = {}
[:uri, :uri_username, :uri_password, :remote_file_name].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]
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 :restore do
desc 'Restore the local ManageIQ EVM Database (VMDB) from a local backup file'
task :local do
require 'trollop'
opts = Trollop.options(EvmRakeHelper.extract_command_options) do
opt :local_file, "Destination file", :type => :string, :required => true
opt :username, "Username", :type => :string
opt :password, "Password", :type => :string
opt :hostname, "Hostname", :type => :string
opt :dbname, "Database name", :type => :string
end
opts.delete_if { |k,v| v.nil? }
# 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 do
require 'trollop'
opts = Trollop.options(EvmRakeHelper.extract_command_options) do
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
opt :username, "Username", :type => :string
opt :password, "Password", :type => :string
opt :hostname, "Hostname", :type => :string
opt :dbname, "Database name", :type => :string
end
db_opts = {}
[:dbname, :username, :password, :hostname].each { |k| db_opts[k] = opts[k] if opts[k] }
connect_opts = {}
[:uri, :uri_username, :uri_password].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]
# 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