Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate evm dba #195

Closed
wants to merge 19 commits into from
Closed
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9fbfdaa
Reroot vmdb to be the new root
Fryguy Jul 6, 2015
c8cb04e
Replace EvmDba.run_cmd_with_open4 with AwesomeSpawn
Fryguy Sep 3, 2015
dca25cf
explicitly state the legacy miq key version
kbrock Oct 5, 2015
24abe37
AwesomeSpawn::CommandResultError has no :error method
carbonin Feb 22, 2016
30a98de
Hack: Teach db:migrate to clear the schema cache after it runs.
jrafanie Mar 22, 2016
d9a6618
Revert "Hack: Teach db:migrate to clear the schema cache after it runs."
chrisarcand Mar 25, 2016
f15c47c
Fix Rails 5 issue where the temporary connection pools were not removed.
Fryguy Apr 13, 2016
463fee8
Add rake tasks to run schema verification
carbonin Apr 29, 2016
fbc7659
allow passwords to be passed to tasks
kbrock Jul 11, 2016
b45f00a
Remove the verify_local rake task
carbonin Jul 25, 2016
2fd0f11
Use evm:db:reset, not db:reset
jrafanie Sep 6, 2016
82c0b81
raise failover event by invoking task evm:db::raise_failover_executed…
yrudman Oct 19, 2016
17c822f
renamed rake task to 'raise_server_event' and move it to evm.rake
yrudman Oct 24, 2016
e382996
move .extract_command_options method from EvmDba to EvmRakeHelper
yrudman Oct 25, 2016
db9b348
Extract migrations to manageiq-schema repo
Fryguy Jun 3, 2017
ea6d562
Don't use the .start/.stop methods in PostgresAdmin
carbonin Jul 11, 2017
0b2311e
Add :environment as a prerequisate rake task for restore
carbonin Feb 2, 2018
299c72e
Use ENV instead of REGION file when creating db
kbrock Apr 5, 2018
d8dacc4
Merge branch 'move_evm_dba_rake' into migrate_evm_dba
Apr 27, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 260 additions & 0 deletions lib/tasks/evm_dba.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
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
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
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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EvmDatabaseOps should probably come over as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a handful of places where we use models in that file. Are we okay with those being in this repo?


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 => 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
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 => :environment 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 => :environment 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