# -------------------------------------------------------------------------- # # Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # # # # 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. # #--------------------------------------------------------------------------- # require 'nokogiri' module Migrator def db_version "4.5.80" end def one_version "OpenNebula 4.5.80" end def up init_log_time() @db.run "ALTER TABLE acl RENAME TO old_acl;" @db.run "CREATE TABLE acl (oid INT PRIMARY KEY, user BIGINT, resource BIGINT, rights BIGINT, zone BIGINT, UNIQUE(user, resource, rights, zone));" @db.transaction do @db.fetch("SELECT * FROM old_acl") do |row| @db[:acl].insert( :oid => row[:oid], :user => row[:user], :resource => row[:resource], :rights => row[:rights], :zone => 4294967296) end end @db.run "DROP TABLE old_acl;" log_time() # Move USER/QUOTA to user_quotas table @db.run "ALTER TABLE user_pool RENAME TO old_user_pool;" @db.run "CREATE TABLE user_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" @db.run "CREATE TABLE user_quotas (user_oid INTEGER PRIMARY KEY, body MEDIUMTEXT);" @db.transaction do @db.fetch("SELECT * FROM old_user_pool") do |row| doc = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks} quotas_doc = extract_quotas(doc) @db[:user_pool].insert( :oid => row[:oid], :name => row[:name], :body => doc.root.to_s, :uid => row[:uid], :gid => row[:gid], :owner_u => row[:owner_u], :group_u => row[:group_u], :other_u => row[:other_u]) @db[:user_quotas].insert( :user_oid => row[:oid], :body => quotas_doc.root.to_s) end end @db.run "DROP TABLE old_user_pool;" log_time() # GROUP/RESOURCE_PROVIDER is not needed # Move GROUP/QUOTA to group_quotas table # Add GROUP/TEMPLATE @db.run "ALTER TABLE group_pool RENAME TO old_group_pool;" @db.run "CREATE TABLE group_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" @db.run "CREATE TABLE group_quotas (group_oid INTEGER PRIMARY KEY, body MEDIUMTEXT);" @db.transaction do @db.fetch("SELECT * FROM old_group_pool") do |row| doc = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks} quotas_doc = extract_quotas(doc) doc.root.add_child(doc.create_element("TEMPLATE")) @db[:group_pool].insert( :oid => row[:oid], :name => row[:name], :body => doc.root.to_s, :uid => row[:uid], :gid => row[:gid], :owner_u => row[:owner_u], :group_u => row[:group_u], :other_u => row[:other_u]) @db[:group_quotas].insert( :group_oid => row[:oid], :body => quotas_doc.root.to_s) end end @db.run "DROP TABLE old_group_pool;" log_time() # Copy VNet config variables to the template @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, cid INTEGER, UNIQUE(name,uid));" @db.transaction do @db.fetch("SELECT * FROM old_network_pool") do |row| doc = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks} template = doc.root.at_xpath("TEMPLATE") ["PHYDEV", "VLAN_ID", "BRIDGE"].each do |elem_name| elem = doc.root.at_xpath(elem_name) txt = elem.nil? ? "" : elem.text # The cleaner doc.create_cdata(txt) is not supported in # old versions of nokogiri template.add_child(doc.create_element(elem_name)). add_child(Nokogiri::XML::CDATA.new(doc,txt)) end vlan_text = doc.root.at_xpath("VLAN").text == "0" ? "NO" : "YES" template.add_child(doc.create_element("VLAN")). add_child(Nokogiri::XML::CDATA.new(doc,vlan_text)) @db[:network_pool].insert( :oid => row[:oid], :name => row[:name], :body => doc.root.to_s, :uid => row[:uid], :gid => row[:gid], :owner_u => row[:owner_u], :group_u => row[:group_u], :other_u => row[:other_u], :cid => row[:cid]) end end @db.run "DROP TABLE old_network_pool;" log_time() # Replace deprecated host attributes inside requirements/rank expressions @db.run "ALTER TABLE template_pool RENAME TO old_template_pool;" @db.run "CREATE TABLE template_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER);" @db.transaction do @db.fetch("SELECT * FROM old_template_pool") do |row| doc = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks} atts = ["SCHED_REQUIREMENTS", "SCHED_RANK", "REQUIREMENTS", "RANK"] atts.each do |att| elem = doc.root.at_xpath("TEMPLATE/#{att}") if !elem.nil? elem.content = elem.text. gsub("TOTALCPU", "MAX_CPU"). gsub("TOTALMEMORY","MAX_MEM"). gsub("FREECPU", "FREE_CPU"). gsub("FREEMEMORY", "FREE_MEM"). gsub("USEDCPU", "USED_CPU"). gsub("USEDMEMORY", "USED_MEM") end end @db[:template_pool].insert( :oid => row[:oid], :name => row[:name], :body => doc.root.to_s, :uid => row[:uid], :gid => row[:gid], :owner_u => row[:owner_u], :group_u => row[:group_u], :other_u => row[:other_u]) end end @db.run "DROP TABLE old_template_pool;" log_time() # Default ZONE @db.run "CREATE TABLE zone_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" @db.run "INSERT INTO zone_pool VALUES(0,'OpenNebula','0OpenNebula',0,0,1,0,0);" @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 def extract_quotas(doc) ds_quota = doc.root.at_xpath("DATASTORE_QUOTA") net_quota = doc.root.at_xpath("NETWORK_QUOTA") vm_quota = doc.root.at_xpath("VM_QUOTA") img_quota = doc.root.at_xpath("IMAGE_QUOTA") quotas_doc = Nokogiri::XML(""){|c| c.default_xml.noblanks} ds_quota = quotas_doc.create_element("DATASTORE_QUOTA") if ds_quota.nil? net_quota = quotas_doc.create_element("NETWORK_QUOTA") if net_quota.nil? vm_quota = quotas_doc.create_element("VM_QUOTA") if vm_quota.nil? img_quota = quotas_doc.create_element("IMAGE_QUOTA") if img_quota.nil? ds_quota.remove net_quota.remove vm_quota.remove img_quota.remove quotas_doc.root.add_child(quotas_doc.create_element("ID")). content = doc.root.at_xpath("ID").text quotas_doc.root.add_child(ds_quota) quotas_doc.root.add_child(net_quota) quotas_doc.root.add_child(vm_quota) quotas_doc.root.add_child(img_quota) return quotas_doc end end