Use ActiveRecord::Migrator multiple migrations paths support

[#44034071]

ActiveRecord::Migrator has a class attribute, migrations_paths,
specificially for storing a list of different directories that have
migrations in them.  ActiveRecord::Migrator.migrations_paths is used in
rake db:load_config, which is a dependency of db:migrate, etc. that is
passed to ActiveRecord::Migrator.migrate.  Since migrate supports an
array of directories, and not just a single directory, there is no need
to merge all the migrations paths into one temporary directory as was
previously done.
bug/bundler_fix
Luke Imhoff 2013-03-02 20:33:48 -06:00
parent 2e4760c486
commit af4b3fa287
2 changed files with 31 additions and 48 deletions

View File

@ -56,9 +56,6 @@ class DBManager
# Flag to indicate database migration has completed
attr_accessor :migrated
# Array of additional migration paths
attr_accessor :migration_paths
# Flag to indicate that modules are cached
attr_accessor :modules_cached
@ -69,7 +66,6 @@ class DBManager
self.framework = framework
self.migrated = false
self.migration_paths = []
self.modules_cached = false
self.modules_caching = false
@ -82,17 +78,17 @@ class DBManager
end
initialize_database_support
# have to set migration paths after initialize_database_support as it loads
# MetasploitDataModels.
self.migration_paths << MetasploitDataModels.root.join('db', 'migrate').to_s
end
#
# Add additional migration paths
#
def add_migration_path(path)
self.migration_paths.push(path)
def initialize_metasploit_data_models
# Provide access to ActiveRecord models shared w/ commercial versions
require "metasploit_data_models"
metasploit_data_model_migrations_pathname = MetasploitDataModels.root.join(
'db',
'migrate'
)
ActiveRecord::Migrator.migrations_paths << metasploit_data_model_migrations_pathname.to_s
end
#
@ -105,8 +101,7 @@ class DBManager
require "active_record"
# Provide access to ActiveRecord models shared w/ commercial versions
require "metasploit_data_models"
initialize_metasploit_data_models
# Patches issues with ActiveRecord
require "msf/core/patches/active_record"
@ -283,45 +278,31 @@ class DBManager
end
end
# Migrate database to latest schema version.
#
# Migrate database to latest schema version
# @param verbose [Boolean] see ActiveRecord::Migration.verbose
# @return [Array<ActiveRecord::Migration>] List of migrations that ran.
#
# @see ActiveRecord::Migrator.migrate
def migrate(verbose=false)
ran = []
ActiveRecord::Migration.verbose = verbose
temp_dir = ::File.expand_path(::File.join( Msf::Config.config_directory, "schema", "#{Time.now.to_i}_#{$$}" ))
::FileUtils.rm_rf(temp_dir)
::FileUtils.mkdir_p(temp_dir)
self.migration_paths.each do |mpath|
dir = Dir.new(mpath) rescue nil
if not dir
elog("Could not access migration path #{mpath}")
next
end
dir.entries.each do |ent|
next unless ent =~ /^\d+.*\.rb$/
::FileUtils.cp( ::File.join(mpath, ent), ::File.join(temp_dir, ent) )
ActiveRecord::Base.connection_pool.with_connection do
begin
ran = ActiveRecord::Migrator.migrate(
ActiveRecord::Migrator.migrations_paths
)
# ActiveRecord::Migrator#migrate rescues all errors and re-raises them as
# StandardError
rescue StandardError => error
self.error = error
elog("DB.migrate threw an exception: #{error}")
dlog("Call stack:\n#{error.backtrace.join "\n"}")
end
end
success = true
begin
::ActiveRecord::Base.connection_pool.with_connection {
ActiveRecord::Migration.verbose = verbose
ActiveRecord::Migrator.migrate(temp_dir, nil)
}
rescue ::Exception => e
self.error = e
elog("DB.migrate threw an exception: #{e}")
dlog("Call stack:\n#{e.backtrace.join "\n"}")
success = false
end
::FileUtils.rm_rf(temp_dir)
return true
return ran
end
def workspace=(workspace)

View File

@ -171,7 +171,9 @@ class Driver < Msf::Ui::Driver
# Append any migration paths necessary to bring the database online
if opts['DatabaseMigrationPaths']
opts['DatabaseMigrationPaths'].each {|m| framework.db.add_migration_path(m) }
opts['DatabaseMigrationPaths'].each do |migrations_path|
ActiveRecord::Migrator.migrations_paths << migrations_path
end
end
# Look for our database configuration in the following places, in order: