# -------------------------------------------------------------------------- # # Copyright 2002-2018, 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 = "5.6.0" LOCAL_VERSION = "5.6.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() puts "This patch updates images and VMs with missing NEXT_SNAPSHOT parameter." puts # BUG #2687: Disk snapshots dissapearing # https://github.com/OpenNebula/one/issues/2687 @db.transaction do @db.fetch("SELECT * FROM image_pool") do |row| doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){ |c| c.default_xml.noblanks } next_snapshot = doc.at_xpath("//SNAPSHOTS/NEXT_SNAPSHOT") next if next_snapshot max = doc.xpath("//SNAPSHOTS/SNAPSHOT/ID").max if max next_snapshot = max.text.to_i + 1 else next_snapshot = 0 end sxml = doc.xpath("//SNAPSHOTS") if sxml ns = doc.create_element("NEXT_SNAPSHOT") ns.content = next_snapshot sxml = sxml.first.add_child(ns) puts "Image #{row[:oid]} updated with NEXT_SNAPSHOT #{next_snapshot}" @db[:image_pool].where(:oid => row[:oid]).update( :body => doc.root.to_s) end end log_time() @db.fetch("SELECT * FROM vm_pool") do |row| doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){ |c| c.default_xml.noblanks } # evaluate each disk snapshot individually doc.xpath("//SNAPSHOTS").each do |disk| next_snapshot = disk.at_xpath("NEXT_SNAPSHOT") next if next_snapshot max = disk.xpath("SNAPSHOT/ID").max if max next_snapshot = max.text.to_i + 1 else next_snapshot = 0 end puts "VM #{row[:oid]}, DISK #{disk.at_xpath('DISK_ID').text} updated with NEXT_SNAPSHOT #{next_snapshot}" ns = doc.create_element("NEXT_SNAPSHOT") ns.content = next_snapshot disk.add_child(ns) end @db[:vm_pool].where(:oid => row[:oid]).update( :body => doc.root.to_s) end log_time() end log_time() return true end end