File: //var/cache/puppet/lib/puppet/type/cs_colocation.rb
Puppet::Type.newtype(:cs_colocation) do
@doc = "Type for manipulating corosync/pacemaker colocation. Colocation
is the grouping together of a set of primitives so that they travel
together when one of them fails. For instance, if a web server vhost
is colocated with a specific ip address and the web server software
crashes, the ip address with migrate to the new host with the vhost.
More information on Corosync/Pacemaker colocation can be found here:
* http://www.clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Clusters_from_Scratch/_ensuring_resources_run_on_the_same_host.html"
ensurable
newparam(:name) do
desc "Identifier of the colocation entry. This value needs to be unique
across the entire Corosync/Pacemaker configuration since it doesn't have
the concept of name spaces per type."
isnamevar
end
newproperty(:primitives, array_matching: :all) do
desc "At least two Pacemaker primitives to be located together. Order of primitives
in colocation groups is important. In Pacemaker, a colocation of 2 primitives
behaves different than a colocation between more than 2 primitives. Here the
behavior is altered to be more consistent.
Examples on how to define colocations here:
- 2 primitives: [A, B] will cause A to be located first, and B will be located
with A. This is different than how crm configure colocation works, because
there [A, B] would mean colocate A with B, thus B should be located first.
- multiple primitives: [A, B, C] will cause A to be located first, B next, and
finally C. This is identical to how crm configure colocation works with
multiple resources, it will add a colocated set.
Property will raise an error if you do not provide an array containing at least
two values. Values can be either the name of the primitive, or primitive:role.
Notice, we can only interpret colocations of single sets, not multiple sets
combined. In Pacemaker speak, this means we can support 'A B C' but not e.g.
'A B (C D) E'. Feel free to contribute a patch for this."
# Do some validation: the way Pacemaker colocation works we need to only accept
# arrays with at least 2 values.
def should=(value)
super
raise Puppet::Error, 'Puppet::Type::Cs_Colocation: The primitives property must be an array.' unless value.is_a? Array
raise Puppet::Error, 'Puppet::Type::Cs_Colocation: The primitives property must be an array of at least one element.' if value.empty?
@should
end
end
newparam(:cib) do
desc "Corosync applies its configuration immediately. Using a CIB allows
you to group multiple primitives and relationships to be applied at
once. This can be necessary to insert complex configurations into
Corosync correctly.
This paramater sets the CIB this colocation should be created in. A
cs_shadow resource with a title of the same name as this value should
also be added to your manifest."
end
newproperty(:score) do
desc "The priority of this colocation. Primitives can be a part of
multiple colocation groups and so there is a way to control which
primitives get priority when forcing the move of other primitives.
This value can be an integer but is often defined as the string
INFINITY."
defaultto 'INFINITY'
end
autorequire(:cs_shadow) do
autos = []
autos << @parameters[:cib].value if @parameters[:cib]
autos
end
autorequire(:service) do
%w[corosync pacemaker]
end
def extract_primitives
result = []
unless @parameters[:primitives].should.nil?
if @parameters[:primitives].should.first.is_a?(Hash)
@parameters[:primitives].should.each do |colocation_set|
if colocation_set.key?('primitives')
result << colocation_set['primitives']
end
end
end
if @parameters[:primitives].should.first.is_a?(String)
@parameters[:primitives].should.each do |val|
result << unmunge_cs_primitive(val)
end
end
end
result.flatten
end
[:cs_clone, :cs_primitive].each do |resource_type|
autorequire(resource_type) do
extract_primitives
end
end
def unmunge_cs_primitive(name)
name = name.split(':')[0]
name = name[3..-1] if name.start_with? 'ms_'
name
end
end