mirror of
https://github.com/OpenNebula/one.git
synced 2026-11-10 14:35:43 +09:00
Migrate VN_MAD from the Host to the Network
This commit is contained in:
1 parent
be59195bf8
commit
fc3ab2d7ab
3 files changed
+403
-1
No files matched your search
+2
-1
@@ -1217,7 +1217,8 @@ ONEDB_LOCAL_MIGRATOR_FILES="src/onedb/local/4.5.80_to_4.7.80.rb \
|
||||
src/onedb/local/4.13.85_to_4.90.0.rb"
|
||||
|
||||
ONEDB_PATCH_FILES="src/onedb/patches/4.14_monitoring.rb \
|
||||
src/onedb/patches/history_times.rb"
|
||||
src/onedb/patches/history_times.rb \
|
||||
src/onedb/patches/vnmad.rb"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configuration files for OpenNebula, to be installed under $ETC_LOCATION
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'set'
|
||||
|
||||
require 'opennebula'
|
||||
|
||||
include OpenNebula
|
||||
@@ -471,6 +473,211 @@ module Migrator
|
||||
|
||||
log_time()
|
||||
|
||||
# Move HOST/VN_MAD --> VNET/VN_MAD
|
||||
|
||||
log_time()
|
||||
|
||||
# Build net_vnmad
|
||||
net_vnmad = {}
|
||||
@db.transaction do
|
||||
@db.fetch("SELECT * FROM vm_pool") do |row|
|
||||
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
|
||||
state = row[:state].to_i
|
||||
|
||||
if state != 6
|
||||
vnmads = Set.new
|
||||
doc.root.xpath("HISTORY_RECORDS/HISTORY/VNMMAD").collect{|v| vnmads << v.text }
|
||||
|
||||
doc.root.xpath("TEMPLATE/NIC/NETWORK_ID").each do |net_id|
|
||||
net_id = net_id.text.to_i
|
||||
|
||||
net_vnmad[net_id] ||= Set.new
|
||||
net_vnmad[net_id] += vnmads
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Build cluster_vnmad and fix hosts
|
||||
@db.run "ALTER TABLE host_pool RENAME TO old_host_pool;"
|
||||
@db.run "CREATE TABLE host_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, state INTEGER, last_mon_time INTEGER, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, cid INTEGER);"
|
||||
|
||||
cluster_vnmad = {}
|
||||
@db.transaction do
|
||||
@db.fetch("SELECT * FROM old_host_pool") do |row|
|
||||
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
|
||||
|
||||
# Get cluster
|
||||
cluster_id = doc.root.xpath('CLUSTER_ID').text.to_i
|
||||
|
||||
# Store VN_MAD
|
||||
vnmad = doc.root.xpath('VN_MAD').text
|
||||
|
||||
cluster_vnmad[cluster_id] ||= Set.new
|
||||
cluster_vnmad[cluster_id] << vnmad
|
||||
|
||||
# Remove VN_MAD
|
||||
doc.root.xpath('//VN_MAD').remove
|
||||
|
||||
row[:body] = doc.root.to_s
|
||||
@db[:host_pool].insert(row)
|
||||
end
|
||||
end
|
||||
@db.run "DROP TABLE old_host_pool;"
|
||||
|
||||
# Fix Networks
|
||||
|
||||
# So far we have two hashes: net_vnmad, which lists the specific vnmad found
|
||||
# for each network, based on the nics of the VMs, and cluster_vnmad, with
|
||||
# the vnmad found in the hosts.
|
||||
#
|
||||
# We will report a warning if either the cluster or the network has more
|
||||
# than one vnmad. We will automatically choose one vnmad from the network
|
||||
# list, or if empty from the cluster list.
|
||||
#
|
||||
# That vnmad may be changed through onedb patch.
|
||||
#
|
||||
# It could happen that no network is found in the net or in the cluster, in
|
||||
# which case the admin **must** run the onedb patch, it's not optional any
|
||||
# more.
|
||||
|
||||
@db.run "ALTER TABLE network_pool RENAME TO old_network_pool;"
|
||||
@db.run "CREATE TABLE network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, pid INTEGER, UNIQUE(name,uid));"
|
||||
|
||||
suggest_patch = false
|
||||
final_net_vnmad = {}
|
||||
@db.transaction do
|
||||
@db.fetch("SELECT * FROM old_network_pool") do |row|
|
||||
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
|
||||
|
||||
net_id = row[:oid]
|
||||
cluster_id = doc.root.xpath('CLUSTERS/ID').first.text.to_i
|
||||
|
||||
net_vnmad_len = net_vnmad[net_id].length rescue 0
|
||||
cluster_vnmad_len = cluster_vnmad[cluster_id].length rescue 0
|
||||
|
||||
if (vlan = doc.root.xpath('VLAN'))
|
||||
vlan = vlan.text
|
||||
if !vlan.empty? && vlan.to_i == 0
|
||||
dummy_net = true
|
||||
end
|
||||
end
|
||||
|
||||
doc.root.xpath('//VLAN').remove
|
||||
|
||||
if dummy_net
|
||||
vnmad = "fw"
|
||||
else
|
||||
vnmad = nil
|
||||
other_vnmads = nil
|
||||
|
||||
# net_vnmad_len == 1 => that one
|
||||
# net_vnmad_len > 1 => get first one and show warning
|
||||
# net_vnmad_len == 0 && cluster_vnmad_len == 1 => that one
|
||||
# net_vnmad_len == 0 && cluster_vnmad_len > 1 => first one and show warning
|
||||
# net_vnmad_len == 0 && cluster_vnmad_len == 0 => force onedb patch
|
||||
|
||||
if net_vnmad_len == 1
|
||||
vnmad = net_vnmad[net_id].first
|
||||
elsif net_vnmad_len > 1
|
||||
vnmad = net_vnmad[net_id].first
|
||||
other_vnmads = net_vnmad[net_id] - Set[vnmad]
|
||||
elsif net_vnmad_len == 0 && cluster_vnmad_len == 1
|
||||
vnmad = cluster_vnmad[cluster_id].first
|
||||
elsif net_vnmad_len == 0 && cluster_vnmad_len > 1
|
||||
vnmad = cluster_vnmad[cluster_id].first
|
||||
other_vnmads = cluster_vnmad[cluster_id] - Set[vnmad]
|
||||
end
|
||||
|
||||
if vnmad && other_vnmads
|
||||
if !suggest_patch
|
||||
puts
|
||||
puts "**************************************************************"
|
||||
puts "* WARNING WARNING WARNING WARNING WARNING WARNING WARNING *"
|
||||
puts "**************************************************************"
|
||||
end
|
||||
|
||||
suggest_patch = true
|
||||
puts "* Net ##{net_id} assigned VN_MAD=#{vnmad}. " <<
|
||||
"Other options: #{other_vnmads.to_a.join(', ')}"
|
||||
end
|
||||
end
|
||||
|
||||
final_net_vnmad[net_id] = vnmad
|
||||
|
||||
if vnmad
|
||||
doc.root.add_child(doc.create_element("VN_MAD")).content = vnmad
|
||||
end
|
||||
|
||||
row[:body] = doc.root.to_s
|
||||
@db[:network_pool].insert(row)
|
||||
end
|
||||
end
|
||||
|
||||
patch_cmd = "onedb patch [opts] /usr/lib/one/ruby/onedb/patches/vnmad.rb"
|
||||
if suggest_patch
|
||||
puts
|
||||
puts "If you want to change the above assignments, please run:"
|
||||
puts patch_cmd
|
||||
end
|
||||
|
||||
net_unassigned = final_net_vnmad.select{|k,v| v.nil?}.keys
|
||||
if !net_unassigned.empty?
|
||||
puts
|
||||
puts "**************************************************************"
|
||||
puts "* ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR *"
|
||||
puts "**************************************************************"
|
||||
puts
|
||||
puts "You **must** run:"
|
||||
puts patch_cmd
|
||||
puts
|
||||
puts "to assign a vnmad to the following networks:"
|
||||
net_unassigned.each{|n| puts " - #{n}"}
|
||||
puts
|
||||
end
|
||||
|
||||
@db.run "DROP TABLE old_network_pool;"
|
||||
|
||||
# Fix VMs
|
||||
|
||||
@db.run "ALTER TABLE vm_pool RENAME TO old_vm_pool;"
|
||||
@db.run "CREATE TABLE IF NOT EXISTS vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER)"
|
||||
|
||||
@db.transaction do
|
||||
@db.fetch("SELECT * FROM old_vm_pool") do |row|2
|
||||
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
|
||||
state = row[:state].to_i
|
||||
|
||||
if state != 6
|
||||
# Remove vnmad from the history records
|
||||
doc.root.xpath("HISTORY_RECORDS//VNMMAD").remove
|
||||
doc.root.xpath("HISTORY_RECORDS//DS_LOCATION").remove
|
||||
|
||||
# Rename VMMMAD -> VM_MAD and TMMAD -> TM_MAD
|
||||
doc.root.xpath("HISTORY_RECORDS//VMMMAD").each {|e| e.name = "VM_MAD"}
|
||||
doc.root.xpath("HISTORY_RECORDS//TMMAD").each {|e| e.name = "TM_MAD"}
|
||||
|
||||
# Add vnmad to the nics
|
||||
doc.root.xpath('TEMPLATE/NIC').each do |nic|
|
||||
net_id = nic.xpath("NETWORK_ID").text.to_i rescue nil # NICs without network may exist
|
||||
|
||||
next unless net_id
|
||||
|
||||
vnmad = final_net_vnmad[net_id]
|
||||
|
||||
if vnmad
|
||||
nic.add_child(doc.create_element("VN_MAD")).content = vnmad
|
||||
end
|
||||
end
|
||||
|
||||
row[:body] = doc.root.to_s
|
||||
end
|
||||
|
||||
@db[:vm_pool].insert(row)
|
||||
end
|
||||
end
|
||||
@db.run "DROP TABLE old_vm_pool;"
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||
# not use this file except in compliance with the License. You may obtain #
|
||||
# a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
if !ONE_LOCATION
|
||||
LOG_LOCATION = "/var/log/one"
|
||||
else
|
||||
LOG_LOCATION = ONE_LOCATION + "/var"
|
||||
end
|
||||
|
||||
LOG = LOG_LOCATION + "/onedb-fsck.log"
|
||||
|
||||
require 'nokogiri'
|
||||
|
||||
module OneDBPatch
|
||||
VERSION = "4.90.0"
|
||||
LOCAL_VERSION = "4.90.0"
|
||||
|
||||
def is_hot_patch(ops)
|
||||
return false
|
||||
end
|
||||
|
||||
def check_db_version(ops)
|
||||
db_version = read_db_version()
|
||||
|
||||
if ( db_version[:version] != VERSION ||
|
||||
db_version[:local_version] != LOCAL_VERSION )
|
||||
|
||||
raise <<-EOT
|
||||
Version mismatch: patch 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 patch(ops)
|
||||
init_log_time()
|
||||
|
||||
all_nets = {}
|
||||
fix_nets = {}
|
||||
|
||||
@db.transaction do
|
||||
@db.fetch("SELECT * FROM network_pool") do |row|
|
||||
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
|
||||
vnmad = doc.root.xpath("VN_MAD").text rescue ""
|
||||
all_nets[row[:oid]] = {:name => row[:name], :vnmad => vnmad}
|
||||
|
||||
if vnmad.empty?
|
||||
fix_nets[row[:oid]] = ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !fix_nets.empty?
|
||||
puts "You need to input a VN_MAD for the following networks:"
|
||||
fix_nets.each do |net_id, vnmad|
|
||||
input = ""
|
||||
while ( input.empty? ) do
|
||||
name = all_nets[net_id][:name]
|
||||
puts "##{net_id} (#{name}) => VN_MAD:"
|
||||
input = STDIN.gets.chomp.strip
|
||||
end
|
||||
fix_nets[net_id] = input
|
||||
end
|
||||
end
|
||||
|
||||
puts
|
||||
puts "Change additional networks:"
|
||||
|
||||
input = ""
|
||||
while (input != "c")
|
||||
puts
|
||||
puts "Input the ID of the network to change or 'c' to continue"
|
||||
|
||||
input = STDIN.gets.chomp.strip
|
||||
|
||||
if input.match(/^\d+$/)
|
||||
net_id = input.to_i
|
||||
|
||||
if all_nets[net_id].nil?
|
||||
puts "Error: Net ##{net_id} not found."
|
||||
next
|
||||
end
|
||||
|
||||
input_vnmad = ""
|
||||
while ( input_vnmad.empty? ) do
|
||||
name = all_nets[net_id][:name]
|
||||
current_vnmad = all_nets[net_id][:vnmad]
|
||||
puts "##{net_id} (#{name}) (current VN_MAD='#{current_vnmad}') => VN_MAD:"
|
||||
input_vnmad = STDIN.gets.chomp.strip
|
||||
end
|
||||
fix_nets[net_id] = input_vnmad
|
||||
end
|
||||
end
|
||||
|
||||
puts "Review these assignemnts:"
|
||||
|
||||
fix_nets.keys.sort.each do |net_id|
|
||||
name = all_nets[net_id][:name]
|
||||
vnmad = fix_nets[net_id]
|
||||
|
||||
current_vnmad = all_nets[net_id][:vnmad]
|
||||
|
||||
msg = "* ##{net_id} (#{name}) => VN_MAD='#{vnmad}'"
|
||||
|
||||
if !current_vnmad.empty?
|
||||
msg << " (current VN_MAD='#{current_vnmad}')"
|
||||
end
|
||||
|
||||
puts msg
|
||||
end
|
||||
|
||||
puts
|
||||
|
||||
input = ""
|
||||
while ( !input.match(/^(y|n)$/)) do
|
||||
puts "Do you wish to apply the above? (y/n)"
|
||||
input = STDIN.gets.chomp.strip.downcase
|
||||
end
|
||||
|
||||
if input == "n"
|
||||
puts "Quitting without changing anything."
|
||||
raise "Execution canceled by user"
|
||||
end
|
||||
|
||||
@db.run "ALTER TABLE network_pool RENAME TO old_network_pool;"
|
||||
@db.run "CREATE TABLE network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, pid INTEGER, UNIQUE(name,uid));"
|
||||
|
||||
@db.transaction do
|
||||
@db.fetch("SELECT * FROM old_network_pool") do |row|
|
||||
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
|
||||
|
||||
net_id = row[:oid]
|
||||
vnmad = fix_nets[net_id]
|
||||
|
||||
if vnmad
|
||||
doc.root.add_child(doc.create_element("VN_MAD")).content = vnmad
|
||||
end
|
||||
|
||||
row[:body] = doc.root.to_s
|
||||
@db[:network_pool].insert(row)
|
||||
end
|
||||
end
|
||||
|
||||
@db.run "DROP TABLE old_network_pool;"
|
||||
|
||||
@db.run "ALTER TABLE vm_pool RENAME TO old_vm_pool;"
|
||||
@db.run "CREATE TABLE IF NOT EXISTS vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER)"
|
||||
|
||||
@db.transaction do
|
||||
@db.fetch("SELECT * FROM old_vm_pool") do |row|
|
||||
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
|
||||
state = row[:state].to_i
|
||||
|
||||
if state != 6
|
||||
doc.root.xpath('TEMPLATE/NIC').each do |nic|
|
||||
net_id = nic.xpath("NETWORK_ID").text.to_i rescue nil # NICs without network may exist
|
||||
next unless net_id
|
||||
|
||||
vnmad = fix_nets[net_id]
|
||||
|
||||
if vnmad
|
||||
nic.add_child(doc.create_element("VN_MAD")).content = vnmad
|
||||
end
|
||||
end
|
||||
|
||||
row[:body] = doc.root.to_s
|
||||
end
|
||||
|
||||
@db[:vm_pool].insert(row)
|
||||
end
|
||||
end
|
||||
@db.run "DROP TABLE old_vm_pool;"
|
||||
|
||||
log_time()
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user