add Pacemaker::Constraint::Colocation
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
require File.join(File.dirname(__FILE__), %w(pacemaker resource primitive))
|
||||
require File.join(File.dirname(__FILE__), %w(pacemaker resource clone))
|
||||
require File.join(File.dirname(__FILE__), %w(pacemaker constraint colocation))
|
||||
|
10
libraries/pacemaker/constraint.rb
Normal file
10
libraries/pacemaker/constraint.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
require File.join(File.dirname(__FILE__), 'cib_object')
|
||||
|
||||
module Pacemaker
|
||||
class Constraint < Pacemaker::CIBObject
|
||||
def self.description
|
||||
type = self.to_s.split('::').last
|
||||
"#{type} constraint"
|
||||
end
|
||||
end
|
||||
end
|
33
libraries/pacemaker/constraint/colocation.rb
Normal file
33
libraries/pacemaker/constraint/colocation.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
require File::join(File.dirname(__FILE__), %w(.. constraint))
|
||||
|
||||
class Pacemaker::Constraint::Colocation < Pacemaker::Constraint
|
||||
TYPE = 'colocation'
|
||||
register_type TYPE
|
||||
|
||||
attr_accessor :score, :resources
|
||||
|
||||
def self.from_chef_resource(resource)
|
||||
attrs = %w(score resources)
|
||||
new(resource.name).copy_attrs_from_chef_resource(resource, *attrs)
|
||||
end
|
||||
|
||||
def parse_definition
|
||||
rsc_re = /(\S+?)(?::(Started|Stopped))?/
|
||||
unless definition =~ /^#{TYPE} (\S+) (\d+|[-+]?inf): (.+?)\s*$/
|
||||
raise Pacemaker::CIBObject::DefinitionParseError, \
|
||||
"Couldn't parse definition '#{definition}'"
|
||||
end
|
||||
self.name = $1
|
||||
self.score = $2
|
||||
self.resources = $3.split
|
||||
end
|
||||
|
||||
def definition_string
|
||||
"colocation #{name} #{score}: " + resources.join(' ')
|
||||
end
|
||||
|
||||
def crm_configure_command
|
||||
"crm configure " + definition_string
|
||||
end
|
||||
|
||||
end
|
@@ -17,55 +17,60 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require ::File.join(::File.dirname(__FILE__),
|
||||
*%w(.. libraries pacemaker cib_object))
|
||||
require ::File.join(::File.dirname(__FILE__), *%w(.. libraries pacemaker))
|
||||
require ::File.join(::File.dirname(__FILE__), 'common')
|
||||
|
||||
include Chef::Mixin::PacemakerCommon
|
||||
|
||||
action :create do
|
||||
name = new_resource.name
|
||||
priority = new_resource.priority
|
||||
multiple = new_resource.multiple
|
||||
|
||||
unless resource_exists?(name)
|
||||
if multiple
|
||||
multiple_rscs = new_resource.multiple_rscs
|
||||
|
||||
cmd = "crm configure colocation #{name} #{priority}:"
|
||||
multiple_rscs.each do |rsc|
|
||||
cmd << " #{rsc}"
|
||||
end
|
||||
else
|
||||
rsc = new_resource.rsc
|
||||
with_rsc = new_resource.with_rsc
|
||||
|
||||
cmd = "crm configure colocation #{name} #{priority}: #{rsc} #{with_rsc}"
|
||||
end
|
||||
|
||||
cmd_ = Mixlib::ShellOut.new(cmd)
|
||||
cmd_.environment['HOME'] = ENV.fetch('HOME', '/root')
|
||||
cmd_.run_command
|
||||
begin
|
||||
cmd_.error!
|
||||
if resource_exists?(name)
|
||||
new_resource.updated_by_last_action(true)
|
||||
Chef::Log.info "Successfully configured colocation '#{name}'."
|
||||
else
|
||||
Chef::Log.error "Failed to configure colocation #{name}."
|
||||
end
|
||||
rescue
|
||||
Chef::Log.error "Failed to configure colocation #{name}."
|
||||
end
|
||||
if @current_resource_definition.nil?
|
||||
create_resource(name)
|
||||
else
|
||||
maybe_modify_resource(name)
|
||||
end
|
||||
end
|
||||
|
||||
action :delete do
|
||||
name = new_resource.name
|
||||
cmd = "crm resource stop #{name}; crm configure delete #{name}"
|
||||
|
||||
e = execute "delete colocation #{name}" do
|
||||
command cmd
|
||||
only_if { resource_exists?(name) }
|
||||
end
|
||||
|
||||
new_resource.updated_by_last_action(true)
|
||||
Chef::Log.info "Deleted colocation '#{name}'."
|
||||
next unless @current_resource
|
||||
rsc = cib_object_class.new(name)
|
||||
execute rsc.delete_command do
|
||||
action :nothing
|
||||
end.run_action(:run)
|
||||
new_resource.updated_by_last_action(true)
|
||||
Chef::Log.info "Deleted #{@current_cib_object}'."
|
||||
end
|
||||
|
||||
def cib_object_class
|
||||
Pacemaker::Constraint::Colocation
|
||||
end
|
||||
|
||||
def init_current_resource
|
||||
name = @new_resource.name
|
||||
@current_resource = Chef::Resource::PacemakerColocation.new(name)
|
||||
attrs = [:score, :resources]
|
||||
@current_cib_object.copy_attrs_to_chef_resource(@current_resource, *attrs)
|
||||
end
|
||||
|
||||
def create_resource(name)
|
||||
standard_create_resource
|
||||
end
|
||||
|
||||
def maybe_modify_resource(name)
|
||||
Chef::Log.info "Checking existing #{@current_cib_object} for modifications"
|
||||
|
||||
desired_colocation = cib_object_class.from_chef_resource(new_resource)
|
||||
if desired_colocation.definition_string != @current_cib_object.definition_string
|
||||
Chef::Log.debug "changed from [#{@current_cib_object.definition_string}] to [#{desired_colocation.definition_string}]"
|
||||
to_echo = desired_colocation.definition_string.chomp
|
||||
to_echo.gsub!('\\') { '\\\\' }
|
||||
to_echo.gsub!("'", "\\'")
|
||||
cmd = "echo '#{to_echo}' | crm configure load update -"
|
||||
execute cmd do
|
||||
action :nothing
|
||||
end.run_action(:run)
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
|
@@ -22,8 +22,5 @@ actions :create, :delete
|
||||
default_action :create
|
||||
|
||||
attribute :name, :kind_of => String, :name_attribute => true
|
||||
attribute :priority, :kind_of => String
|
||||
attribute :multiple, :default => false
|
||||
attribute :rsc, :kind_of => String
|
||||
attribute :with_rsc, :kind_of => String
|
||||
attribute :multiple_rscs, :kind_of => Array
|
||||
attribute :score, :kind_of => String
|
||||
attribute :resources, :kind_of => Array
|
||||
|
14
spec/fixtures/colocation_constraint.rb
vendored
Normal file
14
spec/fixtures/colocation_constraint.rb
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
require ::File.join(::File.dirname(__FILE__),
|
||||
*%w(.. .. libraries pacemaker constraint colocation))
|
||||
|
||||
module Chef::RSpec
|
||||
module Pacemaker
|
||||
module Config
|
||||
COLOCATION_CONSTRAINT = \
|
||||
::Pacemaker::Constraint::Colocation.new('colocation1')
|
||||
COLOCATION_CONSTRAINT.score = 'inf'
|
||||
COLOCATION_CONSTRAINT.resources = ['foo']
|
||||
COLOCATION_CONSTRAINT_DEFINITION = 'colocation colocation1 inf: foo'
|
||||
end
|
||||
end
|
||||
end
|
27
spec/libraries/pacemaker/constraint/colocation_spec.rb
Normal file
27
spec/libraries/pacemaker/constraint/colocation_spec.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
require 'spec_helper'
|
||||
require File.join(File.dirname(__FILE__), %w(.. .. .. ..
|
||||
libraries pacemaker constraint colocation))
|
||||
require File.join(File.dirname(__FILE__), %w(.. .. .. fixtures colocation_constraint))
|
||||
require File.join(File.dirname(__FILE__), %w(.. .. .. helpers common_object_examples))
|
||||
|
||||
describe Pacemaker::Constraint::Colocation do
|
||||
let(:fixture) { Chef::RSpec::Pacemaker::Config::COLOCATION_CONSTRAINT.dup }
|
||||
|
||||
before(:each) do
|
||||
Mixlib::ShellOut.any_instance.stub(:run_command)
|
||||
end
|
||||
|
||||
def object_type
|
||||
'colocation'
|
||||
end
|
||||
|
||||
def pacemaker_object_class
|
||||
Pacemaker::Constraint::Colocation
|
||||
end
|
||||
|
||||
def fields
|
||||
%w(name score resources)
|
||||
end
|
||||
|
||||
it_should_behave_like "a CIB object"
|
||||
end
|
93
spec/providers/colocation_spec.rb
Normal file
93
spec/providers/colocation_spec.rb
Normal file
@@ -0,0 +1,93 @@
|
||||
require 'chef/application'
|
||||
require File.join(File.dirname(__FILE__), %w(.. spec_helper))
|
||||
require File.join(File.dirname(__FILE__), %w(.. helpers common))
|
||||
require File.join(File.dirname(__FILE__), %w(.. fixtures colocation_constraint))
|
||||
|
||||
describe "Chef::Provider::PacemakerColocation" do
|
||||
# for use inside examples:
|
||||
let(:colo) { Chef::RSpec::Pacemaker::Config::COLOCATION_CONSTRAINT.dup }
|
||||
# for use outside examples (e.g. when invoking shared_examples)
|
||||
colo = Chef::RSpec::Pacemaker::Config::COLOCATION_CONSTRAINT.dup
|
||||
|
||||
before(:each) do
|
||||
runner_opts = {
|
||||
:step_into => ['pacemaker_colocation']
|
||||
}
|
||||
@chef_run = ::ChefSpec::Runner.new(runner_opts)
|
||||
@chef_run.converge "pacemaker::default"
|
||||
@node = @chef_run.node
|
||||
@run_context = @chef_run.run_context
|
||||
|
||||
@resource = Chef::Resource::PacemakerColocation.new(colo.name, @run_context)
|
||||
@resource.score colo.score
|
||||
@resource.resources colo.resources.dup
|
||||
end
|
||||
|
||||
let (:provider) { Chef::Provider::PacemakerColocation.new(@resource, @run_context) }
|
||||
|
||||
def cib_object_class
|
||||
Pacemaker::Constraint::Colocation
|
||||
end
|
||||
|
||||
include Chef::RSpec::Pacemaker::Common
|
||||
|
||||
describe ":create action" do
|
||||
def test_modify(expected_cmds)
|
||||
yield
|
||||
|
||||
expect_definition(colo.definition_string)
|
||||
|
||||
provider.run_action :create
|
||||
|
||||
expected_cmds.each do |cmd|
|
||||
expect(@chef_run).to run_execute(cmd)
|
||||
end
|
||||
expect(@resource).to be_updated
|
||||
end
|
||||
|
||||
it "should modify the constraint if it has a different score" do
|
||||
echo_string = colo.definition_string.chomp.gsub('inf', '100')
|
||||
echo_string.gsub!('\\') { '\\\\' }
|
||||
expected_configure_cmd_args = [
|
||||
"echo '#{echo_string}' | crm configure load update -"
|
||||
]
|
||||
test_modify(expected_configure_cmd_args) do
|
||||
@resource.score '100'
|
||||
end
|
||||
end
|
||||
|
||||
it "should modify the constraint if it has a resource added" do
|
||||
new_resource = 'bar:Stopped'
|
||||
expected = colo.dup
|
||||
expected.resources = expected.resources.dup + [new_resource]
|
||||
echo_string = expected.definition_string.chomp
|
||||
echo_string.gsub!('\\') { '\\\\' }
|
||||
expected_configure_cmd_args = [
|
||||
"echo '#{echo_string}' | crm configure load update -"
|
||||
]
|
||||
test_modify(expected_configure_cmd_args) do
|
||||
@resource.resources expected.resources
|
||||
end
|
||||
end
|
||||
|
||||
it "should modify the constraint if it has a different resource" do
|
||||
new_resources = ['bar:Started']
|
||||
colo.resources = new_resources
|
||||
echo_string = colo.definition_string.chomp
|
||||
echo_string.gsub!('\\') { '\\\\' }
|
||||
expected_configure_cmd_args = [
|
||||
"echo '#{echo_string}' | crm configure load update -"
|
||||
]
|
||||
test_modify(expected_configure_cmd_args) do
|
||||
@resource.resources new_resources
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe ":delete action" do
|
||||
it_should_behave_like "action on non-existent resource", \
|
||||
:delete, "crm configure delete #{colo.name}", nil
|
||||
end
|
||||
|
||||
end
|
Reference in New Issue
Block a user