Apply CIB changes using patch method
Generate XML diff patch and apply it. 1) generate config changes in shadow 2) generate diff only for specific scope 3) apply it This will not touch cluster attributes and other stuff it should not touch, thus not breaking functionality of OCF scripts using CIB attributes. Change-Id: Ibcfaa82707d1aed01b79c8307d17f4e71fd60906 Closes-bug: #1338594
This commit is contained in:
parent
fd5fd0d3f7
commit
03342f53fa
@ -70,4 +70,72 @@ class Puppet::Provider::Corosync < Puppet::Provider
|
||||
debug(@property_hash.inspect)
|
||||
!(@property_hash[:ensure] == :absent or @property_hash.empty?)
|
||||
end
|
||||
|
||||
def get_scope(type)
|
||||
case type
|
||||
when 'resource'
|
||||
scope='resources'
|
||||
when /^(colocation|order|location)$/
|
||||
scope='constraints'
|
||||
when 'rsc_defaults'
|
||||
scope='rsc_defaults'
|
||||
else
|
||||
fail('unknown resource type')
|
||||
scope=nil
|
||||
end
|
||||
return scope
|
||||
end
|
||||
|
||||
def apply_changes(res_name,tmpfile,res_type)
|
||||
env={}
|
||||
shadow_name="#{res_type}_#{res_name}"
|
||||
original_cib="/tmp/#{shadow_name}_orig.xml"
|
||||
new_cib="/tmp/#{shadow_name}_new.xml"
|
||||
begin
|
||||
debug('trying to delete old shadow if exists')
|
||||
crm_shadow("-b","-f","-D",shadow_name)
|
||||
rescue Puppet::ExecutionFailure
|
||||
debug('delete failed but proceeding anyway')
|
||||
end
|
||||
crm_shadow("-b","-c",shadow_name)
|
||||
env["CIB_shadow"] = shadow_name
|
||||
exec_withenv("#{command(:crm)} configure load update #{tmpfile.path.to_s}",env)
|
||||
if !get_scope(res_type).nil?
|
||||
cibadmin_scope = "-o #{get_scope(res_type)}"
|
||||
else
|
||||
cibadmin_scope = nil
|
||||
end
|
||||
orig_status = exec_withenv("#{command(:cibadmin)} #{cibadmin_scope} -Q > /tmp/#{shadow_name}_orig.xml")
|
||||
#cibadmin returns code 6 if scope is empty
|
||||
#in this case write empty file
|
||||
if orig_status == 6 or File.open("/tmp/#{shadow_name}_orig.xml").read.empty?
|
||||
cur_scope=REXML::Element.new(get_scope(res_type)).to_s
|
||||
emptydoc=REXML::Document.new(cur_scope)
|
||||
emptydoc.write(File.new("/tmp/#{shadow_name}_orig.xml",'w'))
|
||||
end
|
||||
exec_withenv("#{command(:cibadmin)} #{cibadmin_scope} -Q > /tmp/#{shadow_name}_new.xml",env)
|
||||
patch = Open3.popen3("#{command(:crm_diff)} --original #{original_cib} --new #{new_cib}")[1].read
|
||||
if patch.empty?
|
||||
debug("no difference - nothing to apply")
|
||||
return
|
||||
end
|
||||
xml_patch = REXML::Document.new(patch)
|
||||
wrap_cib=REXML::Element.new('cib')
|
||||
wrap_configuration=REXML::Element.new('configuration')
|
||||
wrap_cib.add_element(wrap_configuration)
|
||||
wrap_cib_a=Marshal.load(Marshal.dump(wrap_cib))
|
||||
wrap_cib_r=Marshal.load(Marshal.dump(wrap_cib))
|
||||
diff_a=REXML::XPath.first(xml_patch,'//diff-added')
|
||||
diff_r=REXML::XPath.first(xml_patch,'//diff-removed')
|
||||
diff_a_elements=diff_a.elements
|
||||
diff_r_elements=diff_r.elements
|
||||
wrap_configuration_a=REXML::XPath.first(wrap_cib_a,'//configuration')
|
||||
wrap_configuration_r=REXML::XPath.first(wrap_cib_r,'//configuration')
|
||||
diff_a_elements.each {|element| wrap_configuration_a.add_element(element)}
|
||||
diff_r_elements.each {|element| wrap_configuration_r.add_element(element)}
|
||||
diff_a.add_element(wrap_cib_a)
|
||||
diff_r.add_element(wrap_cib_r)
|
||||
cibadmin '--patch', '--sync-call', '--xml-text', xml_patch
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -9,8 +9,13 @@ Puppet::Type.type(:cs_colocation).provide(:crm, :parent => Puppet::Provider::Cor
|
||||
|
||||
# Path to the crm binary for interacting with the cluster configuration.
|
||||
# Decided to just go with relative.
|
||||
|
||||
commands :cibadmin => 'cibadmin'
|
||||
commands :crm_shadow => 'crm_shadow'
|
||||
commands :crm => 'crm'
|
||||
commands :crm_diff => 'crm_diff'
|
||||
commands :crm_attribute => 'crm_attribute'
|
||||
|
||||
def self.instances
|
||||
|
||||
block_until_ready
|
||||
@ -103,9 +108,7 @@ Puppet::Type.type(:cs_colocation).provide(:crm, :parent => Puppet::Provider::Cor
|
||||
Tempfile.open('puppet_crm_update') do |tmpfile|
|
||||
tmpfile.write(updated.rstrip)
|
||||
tmpfile.flush
|
||||
env = {}
|
||||
env["CIB_shadow"] = @resource[:cib].to_s if !@resource[:cib].nil?
|
||||
exec_withenv("#{command(:crm)} configure load update #{tmpfile.path.to_s}",env)
|
||||
apply_changes(@resource[:name],tmpfile,'colocation')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -9,8 +9,13 @@ Puppet::Type.type(:cs_location).provide(:crm, :parent => Puppet::Provider::Coros
|
||||
|
||||
# Path to the crm binary for interacting with the cluster configuration.
|
||||
# Decided to just go with relative.
|
||||
|
||||
commands :cibadmin => 'cibadmin'
|
||||
commands :crm_shadow => 'crm_shadow'
|
||||
commands :crm => 'crm'
|
||||
commands :crm_diff => 'crm_diff'
|
||||
commands :crm_attribute => 'crm_attribute'
|
||||
|
||||
def self.instances
|
||||
|
||||
block_until_ready
|
||||
@ -199,9 +204,7 @@ Puppet::Type.type(:cs_location).provide(:crm, :parent => Puppet::Provider::Coros
|
||||
Tempfile.open('puppet_crm_update') do |tmpfile|
|
||||
tmpfile.write(updated.rstrip)
|
||||
tmpfile.flush
|
||||
env = {}
|
||||
env["CIB_shadow"] = @resource[:cib].to_s if !@resource[:cib].nil?
|
||||
exec_withenv("#{command(:crm)} configure load update #{tmpfile.path.to_s}",env)
|
||||
apply_changes(@resource[:name],tmpfile,'location')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -8,8 +8,13 @@ Puppet::Type.type(:cs_order).provide(:crm, :parent => Puppet::Provider::Corosync
|
||||
aspects.'
|
||||
|
||||
# Path to the crm binary for interacting with the cluster configuration.
|
||||
|
||||
commands :cibadmin => 'cibadmin'
|
||||
commands :crm_shadow => 'crm_shadow'
|
||||
commands :crm => 'crm'
|
||||
commands :crm_diff => 'crm_diff'
|
||||
commands :crm_attribute => 'crm_attribute'
|
||||
|
||||
def self.instances
|
||||
|
||||
block_until_ready
|
||||
@ -111,9 +116,7 @@ Puppet::Type.type(:cs_order).provide(:crm, :parent => Puppet::Provider::Corosync
|
||||
Tempfile.open('puppet_crm_update') do |tmpfile|
|
||||
tmpfile.write(updated.rstrip)
|
||||
tmpfile.flush
|
||||
env = {}
|
||||
env["CIB_shadow"] = @resource[:cib].to_s if !@resource[:cib].nil?
|
||||
exec_withenv("#{command(:crm)} configure load update #{tmpfile.path.to_s}",env)
|
||||
apply_changes(@resource[:name],tmpfile,'order')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -11,8 +11,14 @@ Puppet::Type.type(:cs_resource).provide(:crm, :parent => Puppet::Provider::Coros
|
||||
better model since these values can be almost anything.'
|
||||
|
||||
# Path to the crm binary for interacting with the cluster configuration.
|
||||
|
||||
|
||||
commands :cibadmin => 'cibadmin'
|
||||
commands :crm_shadow => 'crm_shadow'
|
||||
commands :crm => 'crm'
|
||||
commands :crm_diff => 'crm_diff'
|
||||
commands :crm_attribute => 'crm_attribute'
|
||||
|
||||
def self.instances
|
||||
|
||||
block_until_ready
|
||||
@ -125,6 +131,8 @@ Puppet::Type.type(:cs_resource).provide(:crm, :parent => Puppet::Provider::Coros
|
||||
debug('Stopping primitive before removing it')
|
||||
crm('resource', 'stop', @resource[:name])
|
||||
debug('Removing primitive')
|
||||
## FIXME(aglarendil): may be we need to apply crm_diff related approach
|
||||
## FIXME(aglarendil): due to 1338594 bug and do this in flush section
|
||||
try_command("delete",@resource[:name])
|
||||
@property_hash.clear
|
||||
end
|
||||
@ -258,9 +266,9 @@ Puppet::Type.type(:cs_resource).provide(:crm, :parent => Puppet::Provider::Coros
|
||||
Tempfile.open('puppet_crm_update') do |tmpfile|
|
||||
tmpfile.write(updated)
|
||||
tmpfile.flush
|
||||
env = {}
|
||||
env["CIB_shadow"] = @resource[:cib].to_s if !@resource[:cib].nil?
|
||||
exec_withenv("#{command(:crm)} configure load update #{tmpfile.path.to_s}",env)
|
||||
#env["CIB_shadow"] = @resource[:cib].to_s if !@resource[:cib].nil?
|
||||
##LP1338594 part: should be put into separate method, I guess
|
||||
apply_changes(@resource[:name],tmpfile,'resource')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user