diff --git a/src/onedb/4.4.1_to_4.5.80.rb b/src/onedb/4.4.1_to_4.5.80.rb index 6baa114b75..4feb260ff2 100644 --- a/src/onedb/4.4.1_to_4.5.80.rb +++ b/src/onedb/4.4.1_to_4.5.80.rb @@ -121,6 +121,10 @@ module Migrator @db.run "INSERT INTO pool_control VALUES('zone_pool',99);" + # New versioning table + @db.run "CREATE TABLE local_db_versioning (oid INTEGER PRIMARY KEY, version VARCHAR(256), timestamp INTEGER, comment VARCHAR(256), is_slave BOOLEAN);" + @db.run "INSERT INTO local_db_versioning VALUES(0,'#{db_version()}',#{Time.now.to_i},'Database migrated from 4.4.1 to 4.5.80 (OpenNebula 4.5.80) by onedb command.',0);" + return true end diff --git a/src/onedb/fsck.rb b/src/onedb/fsck.rb index 00a8ee8ede..07d1b533e3 100644 --- a/src/onedb/fsck.rb +++ b/src/onedb/fsck.rb @@ -22,10 +22,23 @@ require 'set' require 'nokogiri' module OneDBFsck - VERSION = "4.5.80" + VERSION = "4.5.0" + LOCAL_VERSION = "4.5.0" - def db_version - VERSION + def check_db_version() + db_version = read_db_version() + + if ( db_version[:version] != VERSION || + db_version[:local_version] != LOCAL_VERSION ) + + raise <<-EOT +Version mismatch: fsck file is for version +Shared: #{VERSION}, Local: #{LOCAL_VERSION} + +Current database is version +Shared: #{db_version[:version]}, Local: #{db_version[:local_version]} +EOT + end end def one_version @@ -36,6 +49,8 @@ module OneDBFsck def fsck + # TODO: different behaviour for slave/master database + ######################################################################## # Acl ######################################################################## diff --git a/src/onedb/import_slave.rb b/src/onedb/import_slave.rb index a6cbb603b5..5f01d80fea 100644 --- a/src/onedb/import_slave.rb +++ b/src/onedb/import_slave.rb @@ -31,9 +31,32 @@ include OpenNebula module OneDBImportSlave VERSION = "4.5.0" + LOCAL_VERSION = "4.5.0" - def db_version - VERSION + def check_db_version(master_db_version, slave_db_version) + if ( master_db_version[:version] != VERSION || + master_db_version[:local_version] != LOCAL_VERSION ) + + raise <<-EOT +Version mismatch: import slave file is for version +Shared: #{VERSION}, Local: #{LOCAL_VERSION} + +Current master database is version +Shared: #{master_db_version[:version]}, Local: #{master_db_version[:local_version]} +EOT + elsif ( slave_db_version[:version] != VERSION || + slave_db_version[:local_version] != LOCAL_VERSION ) + + raise <<-EOT +Version mismatch: import slave file is for version +Shared: #{VERSION}, Local: #{LOCAL_VERSION} + +Current slave database is version +Shared: #{master_db_version[:version]}, Local: #{master_db_version[:local_version]} +EOT + elsif master_db_version[:is_slave] + raise "Master database is an OpenNebula federation slave" + end end def one_version @@ -538,8 +561,8 @@ EOT # Init slave_db_versioning table ######################################################################## - @slave_db.run "CREATE TABLE slave_db_versioning (oid INTEGER PRIMARY KEY, version VARCHAR(256), timestamp INTEGER, comment VARCHAR(256));" - @slave_db.run "INSERT INTO slave_db_versioning (oid, version, timestamp, comment) VALUES (0, '#{VERSION}', #{Time.now.to_i}, 'onedb import tool');" + @slave_db.run "CREATE TABLE local_db_versioning (oid INTEGER PRIMARY KEY, version VARCHAR(256), timestamp INTEGER, comment VARCHAR(256), is_slave BOOLEAN);" + @slave_db.run "INSERT INTO local_db_versioning VALUES(0,'#{LOCAL_VERSION}',#{Time.now.to_i},'onedb import tool',1);" @slave_db.run "DROP TABLE old_document_pool;" @slave_db.run "DROP TABLE old_image_pool;" diff --git a/src/onedb/onedb.rb b/src/onedb/onedb.rb index fdef7f41cb..b8e686dce5 100644 --- a/src/onedb/onedb.rb +++ b/src/onedb/onedb.rb @@ -94,16 +94,32 @@ class OneDB end def version(ops) - version, timestamp, comment = @backend.read_db_version + ret = @backend.read_db_version if(ops[:verbose]) - puts "Version: #{version}" + puts "Shared tables version: #{ret[:version]}" - time = version == "2.0" ? Time.now : Time.at(timestamp) + time = ret[:version] == "2.0" ? Time.now : Time.at(ret[:timestamp]) puts "Timestamp: #{time.strftime("%m/%d %H:%M:%S")}" - puts "Comment: #{comment}" + puts "Comment: #{ret[:comment]}" + + if ret[:local_version] + puts + puts "Local tables version: #{ret[:local_version]}" + + time = Time.at(ret[:local_timestamp]) + puts "Timestamp: #{time.strftime("%m/%d %H:%M:%S")}" + puts "Comment: #{ret[:local_comment]}" + + if ret[:is_slave] + puts + puts "This database is a federation slave" + end + end + else - puts version + puts "Shared: #{ret[:version]}" + puts "Local: #{ret[:version]}" end return 0 @@ -117,15 +133,17 @@ class OneDB # max_version is ignored for now, as this is the first onedb release. # May be used in next releases def upgrade(max_version, ops) - version, timestamp, comment = @backend.read_db_version + ret = @backend.read_db_version if ops[:verbose] - puts "Version read:" - puts "#{version} : #{comment}" + pretty_print_db_version(ret) + puts "" end - matches = Dir.glob("#{RUBY_LIB_LOCATION}/onedb/#{version}_to_*.rb") + # TODO: different upgrade path for slave/master database tables + + matches = Dir.glob("#{RUBY_LIB_LOCATION}/onedb/#{ret[:version]}_to_*.rb") if ( matches.size > 0 ) # At least one upgrade will be executed, make DB backup @@ -141,7 +159,7 @@ class OneDB while ( matches.size > 0 ) if ( matches.size > 1 ) raise "There are more than one file that match \ - \"#{RUBY_LIB_LOCATION}/onedb/#{version}_to_*.rb\"" + \"#{RUBY_LIB_LOCATION}/onedb/#{ret[:version]}_to_*.rb\"" end file = matches[0] @@ -157,7 +175,7 @@ class OneDB time1 = Time.now if !result - raise "Error while upgrading from #{version} to " << + raise "Error while upgrading from #{ret[:version]} to " << " #{@backend.db_version}" end @@ -170,9 +188,9 @@ class OneDB # Modify db_versioning table if result != nil - @backend.update_db_version(version) + @backend.update_db_version(ret[:version]) else - puts "Database already uses version #{version}" + puts "Database already uses version #{ret[:version]}" end timeb = Time.now @@ -196,11 +214,10 @@ class OneDB end def fsck(ops) - version, timestamp, comment = @backend.read_db_version + ret = @backend.read_db_version if ops[:verbose] - puts "Version read:" - puts "#{version} : #{comment}" + pretty_print_db_version(ret) puts "" end @@ -213,10 +230,7 @@ class OneDB load(file) @backend.extend OneDBFsck - if ( version != @backend.db_version ) - raise "Version mismatch: fsck file is for version "<< - "#{@backend.db_version}, current database version is #{version}" - end + @backend.check_db_version() # FSCK will be executed, make DB backup backup(ops[:backup], ops) @@ -229,7 +243,7 @@ class OneDB result = @backend.fsck if !result - raise "Error running fsck version #{version}" + raise "Error running fsck version #{ret[:version]}" end puts " > Done" if ops[:verbose] @@ -245,7 +259,7 @@ class OneDB rescue Exception => e puts e.message - puts "Error running fsck version #{version}" + puts "Error running fsck version #{ret[:version]}" puts "The database will be restored" ops[:force] = true @@ -277,17 +291,17 @@ class OneDB :db_name => ops[:slave_db_name] ) - version, timestamp, comment = @backend.read_db_version + db_version = @backend.read_db_version - slave_version, slave_timestamp, slave_comment = - slave_backend.read_db_version + slave_db_version = slave_backend.read_db_version if ops[:verbose] - puts "Master version read:" - puts "#{version} : #{comment}" + puts "Master database information:" + pretty_print_db_version(db_version) puts "" - puts "Slave version read:" - puts "#{slave_version} : #{slave_comment}" + puts "" + puts "Slave database information:" + pretty_print_db_version(slave_db_version) puts "" end @@ -300,19 +314,7 @@ class OneDB load(file) @backend.extend OneDBImportSlave - if ( version != @backend.db_version ) - raise "Version mismatch: import slave file is for version "<< - "#{@backend.db_version}, current master database version is #{version}" - end - - if ( slave_version != @backend.db_version ) - raise "Version mismatch: import slave file is for version "<< - "#{@backend.db_version}, current slave database version is #{version}" - end - - # Import will be executed, make DB backup - backup(ops[:backup], ops) - backup(ops[:"slave-backup"], ops, slave_backend) + @backend.check_db_version(db_version, slave_db_version) puts <<-EOT Before running this tool, it is required to create a new Zone in the @@ -364,6 +366,10 @@ is preserved. merge_groups = input == "Y" + # Import will be executed, make DB backup + backup(ops[:backup], ops) + backup(ops[:"slave-backup"], ops, slave_backend) + begin puts " > Running slave import" if ops[:verbose] @@ -371,7 +377,7 @@ is preserved. merge_groups, zone_id) if !result - raise "Error running slave import version #{version}" + raise "Error running slave import" end puts " > Done" if ops[:verbose] @@ -381,7 +387,7 @@ is preserved. rescue Exception => e puts e.message - puts "Error running slave import version #{version}" + puts "Error running slave import" puts "The databases will be restored" ops[:force] = true @@ -404,4 +410,18 @@ is preserved. raise "First stop OpenNebula. Lock file found: #{LOCK_FILE}" end end + + def pretty_print_db_version(db_version) + puts "Version read:" + puts "Shared tables #{db_version[:version]} : #{db_version[:comment]}" + + if db_version[:local_version] + puts "Local tables #{db_version[:local_version]} : #{db_version[:local_comment]}" + end + + if db_version[:is_slave] + puts + puts "This database is a federation slave" + end + end end diff --git a/src/onedb/onedb_backend.rb b/src/onedb/onedb_backend.rb index 315251597e..ca7b1a7519 100644 --- a/src/onedb/onedb_backend.rb +++ b/src/onedb/onedb_backend.rb @@ -28,19 +28,36 @@ class OneDBBacKEnd def read_db_version connect_db + ret = {} + begin - version = "2.0" - timestamp = 0 - comment = "" + ret[:version] = "2.0" + ret[:timestamp] = 0 + ret[:comment] = "" @db.fetch("SELECT version, timestamp, comment FROM db_versioning " + "WHERE oid=(SELECT MAX(oid) FROM db_versioning)") do |row| - version = row[:version] - timestamp = row[:timestamp] - comment = row[:comment] + ret[:version] = row[:version] + ret[:timestamp] = row[:timestamp] + ret[:comment] = row[:comment] end - return [version, timestamp, comment] + begin + @db.fetch("SELECT version, timestamp, comment, is_slave FROM "+ + "local_db_versioning WHERE oid=(SELECT MAX(oid) "+ + "FROM local_db_versioning)") do |row| + ret[:local_version] = row[:version] + ret[:local_timestamp] = row[:timestamp] + ret[:local_comment] = row[:comment] + ret[:is_slave] = row[:is_slave] + end + rescue Exception => e + if e.class == Sequel::DatabaseConnectionError + raise e + end + end + + return ret rescue Exception => e if e.class == Sequel::DatabaseConnectionError @@ -62,7 +79,7 @@ class OneDBBacKEnd comment = "Could not read any previous db_versioning data, " << "assuming it is an OpenNebula 2.0 or 2.2 DB." - return [version, timestamp, comment] + return ret end end