add resource groups
This commit is contained in:
		@@ -1,3 +1,4 @@
 | 
			
		||||
require File.expand_path('pacemaker/resource/primitive', File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('pacemaker/resource/clone', File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('pacemaker/resource/group', File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('pacemaker/constraint/colocation', File.dirname(__FILE__))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								libraries/pacemaker/resource/group.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								libraries/pacemaker/resource/group.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
require File.expand_path('../resource', File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('../mixins/resource_meta', File.dirname(__FILE__))
 | 
			
		||||
 | 
			
		||||
class Pacemaker::Resource::Group < Pacemaker::Resource
 | 
			
		||||
  TYPE = 'group'
 | 
			
		||||
  register_type TYPE
 | 
			
		||||
 | 
			
		||||
  include Pacemaker::Resource::Meta
 | 
			
		||||
 | 
			
		||||
  attr_accessor :members
 | 
			
		||||
 | 
			
		||||
  def self.from_chef_resource(resource)
 | 
			
		||||
    attrs = %w(members meta)
 | 
			
		||||
    new(resource.name).copy_attrs_from_chef_resource(resource, *attrs)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def parse_definition
 | 
			
		||||
    rsc_re = /(\S+?)(?::(Started|Stopped))?/
 | 
			
		||||
    unless definition =~ /^#{TYPE} (\S+) (.+?)(\s+\\)?$/
 | 
			
		||||
      raise Pacemaker::CIBObject::DefinitionParseError, \
 | 
			
		||||
        "Couldn't parse definition '#{definition}'"
 | 
			
		||||
    end
 | 
			
		||||
    self.name    = $1
 | 
			
		||||
    members = $2.split
 | 
			
		||||
    trim_from = members.find_index('meta')
 | 
			
		||||
    members = members[0..trim_from-1] if trim_from
 | 
			
		||||
    self.members = members
 | 
			
		||||
    self.meta    = self.class.extract_hash(definition, 'meta')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def definition_string
 | 
			
		||||
    str = "#{TYPE} #{name} " + members.join(' ')
 | 
			
		||||
    unless meta.empty?
 | 
			
		||||
      str << continuation_line(meta_string)
 | 
			
		||||
    end
 | 
			
		||||
    str
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def crm_configure_command
 | 
			
		||||
    "crm configure " + definition_string
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										78
									
								
								providers/group.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								providers/group.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
# Cookbook Name:: pacemaker
 | 
			
		||||
# Provider:: group
 | 
			
		||||
#
 | 
			
		||||
# Copyright:: 2014, SUSE
 | 
			
		||||
#
 | 
			
		||||
# 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 ::File.expand_path('../libraries/pacemaker', ::File.dirname(__FILE__))
 | 
			
		||||
require ::File.expand_path('../libraries/chef/mixin/pacemaker',
 | 
			
		||||
                           ::File.dirname(__FILE__))
 | 
			
		||||
 | 
			
		||||
include Chef::Mixin::Pacemaker::RunnableResource
 | 
			
		||||
 | 
			
		||||
action :create do
 | 
			
		||||
  name = new_resource.name
 | 
			
		||||
 | 
			
		||||
  if @current_resource_definition.nil?
 | 
			
		||||
    create_resource(name)
 | 
			
		||||
  else
 | 
			
		||||
    maybe_modify_resource(name)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
action :delete do
 | 
			
		||||
  delete_runnable_resource
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
action :start do
 | 
			
		||||
  start_runnable_resource
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
action :stop do
 | 
			
		||||
  stop_runnable_resource
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
def cib_object_class
 | 
			
		||||
  ::Pacemaker::Resource::Group
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
def load_current_resource
 | 
			
		||||
  standard_load_current_resource
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
def init_current_resource
 | 
			
		||||
  name = @new_resource.name
 | 
			
		||||
  @current_resource = Chef::Resource::PacemakerGroup.new(name)
 | 
			
		||||
  attrs = [:members]
 | 
			
		||||
  @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_group = cib_object_class.from_chef_resource(new_resource)
 | 
			
		||||
  if desired_group.definition_string != @current_cib_object.definition_string
 | 
			
		||||
    Chef::Log.debug "changed from [#{@current_cib_object.definition_string}] to [#{desired_group.definition_string}]"
 | 
			
		||||
    cmd = desired_group.reconfigure_command
 | 
			
		||||
    execute cmd do
 | 
			
		||||
      action :nothing
 | 
			
		||||
    end.run_action(:run)
 | 
			
		||||
    new_resource.updated_by_last_action(true)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										25
									
								
								resources/group.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								resources/group.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
# Cookbook Name:: pacemaker
 | 
			
		||||
# Resource:: group
 | 
			
		||||
#
 | 
			
		||||
# Copyright:: 2014, SUSE
 | 
			
		||||
#
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
actions :create, :delete, :start, :stop
 | 
			
		||||
 | 
			
		||||
default_action :create
 | 
			
		||||
 | 
			
		||||
attribute :name, :kind_of => String, :name_attribute => true
 | 
			
		||||
attribute :members, :kind_of => Array
 | 
			
		||||
attribute :meta, :kind_of => Hash
 | 
			
		||||
							
								
								
									
										20
									
								
								spec/fixtures/resource_group.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								spec/fixtures/resource_group.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
require File.expand_path('../../libraries/pacemaker/resource/group',
 | 
			
		||||
                         File.dirname(__FILE__))
 | 
			
		||||
 | 
			
		||||
module Chef::RSpec
 | 
			
		||||
  module Pacemaker
 | 
			
		||||
    module Config
 | 
			
		||||
      RESOURCE_GROUP = \
 | 
			
		||||
        ::Pacemaker::Resource::Group.new('group1')
 | 
			
		||||
      RESOURCE_GROUP.members = ['resource1', 'resource2']
 | 
			
		||||
      RESOURCE_GROUP.meta = [
 | 
			
		||||
        [ "target-role", "Started" ],
 | 
			
		||||
        [ "is-managed", "true" ]
 | 
			
		||||
      ]
 | 
			
		||||
      RESOURCE_GROUP_DEFINITION = <<'EOF'.chomp
 | 
			
		||||
group group1 resource1 resource2 \
 | 
			
		||||
         meta is-managed="true" target-role="Started"
 | 
			
		||||
EOF
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										63
									
								
								spec/libraries/pacemaker/resource/group_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								spec/libraries/pacemaker/resource/group_spec.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
require 'spec_helper'
 | 
			
		||||
require File.expand_path('../../../../libraries/pacemaker/resource/group',
 | 
			
		||||
                         File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('../../../fixtures/resource_group', File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('../../../helpers/cib_object', File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('../../../helpers/meta_examples',
 | 
			
		||||
                         File.dirname(__FILE__))
 | 
			
		||||
 | 
			
		||||
describe Pacemaker::Resource::Group do
 | 
			
		||||
  let(:fixture) { Chef::RSpec::Pacemaker::Config::RESOURCE_GROUP.dup }
 | 
			
		||||
  let(:fixture_definition) {
 | 
			
		||||
    Chef::RSpec::Pacemaker::Config::RESOURCE_GROUP_DEFINITION
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  before(:each) do
 | 
			
		||||
    Mixlib::ShellOut.any_instance.stub(:run_command)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def object_type
 | 
			
		||||
    'group'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pacemaker_object_class
 | 
			
		||||
    Pacemaker::Resource::Group
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def fields
 | 
			
		||||
    %w(name members)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it_should_behave_like "a CIB object"
 | 
			
		||||
 | 
			
		||||
  it_should_behave_like "with meta attributes"
 | 
			
		||||
 | 
			
		||||
  describe "#definition_string" do
 | 
			
		||||
    it "should return the definition string" do
 | 
			
		||||
      expect(fixture.definition_string).to eq(fixture_definition)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should return a short definition string" do
 | 
			
		||||
      primitive = Pacemaker::Resource::Group.new('foo')
 | 
			
		||||
      primitive.definition = \
 | 
			
		||||
        %!group foo member1 member2 meta target-role="Started"!
 | 
			
		||||
      primitive.parse_definition
 | 
			
		||||
      expect(primitive.definition_string).to eq(<<'EOF'.chomp)
 | 
			
		||||
group foo member1 member2 \
 | 
			
		||||
         meta target-role="Started"
 | 
			
		||||
EOF
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#parse_definition" do
 | 
			
		||||
    before(:each) do
 | 
			
		||||
      @parsed = Pacemaker::Resource::Group.new(fixture.name)
 | 
			
		||||
      @parsed.definition = fixture_definition
 | 
			
		||||
      @parsed.parse_definition
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should parse the members" do
 | 
			
		||||
      expect(@parsed.members).to eq(fixture.members)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										70
									
								
								spec/providers/group_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								spec/providers/group_spec.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
require 'chef/application'
 | 
			
		||||
require File.expand_path('../spec_helper', File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('../helpers/cib_object', File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('../helpers/runnable_resource', File.dirname(__FILE__))
 | 
			
		||||
require File.expand_path('../fixtures/resource_group', File.dirname(__FILE__))
 | 
			
		||||
 | 
			
		||||
describe "Chef::Provider::PacemakerGroup" do
 | 
			
		||||
  # for use inside examples:
 | 
			
		||||
  let(:fixture) { Chef::RSpec::Pacemaker::Config::RESOURCE_GROUP.dup }
 | 
			
		||||
  # for use outside examples (e.g. when invoking shared_examples)
 | 
			
		||||
  fixture = Chef::RSpec::Pacemaker::Config::RESOURCE_GROUP.dup
 | 
			
		||||
 | 
			
		||||
  before(:each) do
 | 
			
		||||
    runner_opts = {
 | 
			
		||||
      :step_into => ['pacemaker_group']
 | 
			
		||||
    }
 | 
			
		||||
    @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::PacemakerGroup.new(fixture.name, @run_context)
 | 
			
		||||
    @resource.members fixture.members.dup
 | 
			
		||||
    @resource.meta    Hash[fixture.meta.dup]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  let (:provider) { Chef::Provider::PacemakerGroup.new(@resource, @run_context) }
 | 
			
		||||
 | 
			
		||||
  def cib_object_class
 | 
			
		||||
    Pacemaker::Resource::Group
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  include Chef::RSpec::Pacemaker::CIBObject
 | 
			
		||||
 | 
			
		||||
  describe ":create action" do
 | 
			
		||||
    def test_modify(expected_cmds)
 | 
			
		||||
      yield
 | 
			
		||||
 | 
			
		||||
      expect_definition(fixture.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 group if it has a member resource added" do
 | 
			
		||||
      expected = fixture.dup
 | 
			
		||||
      expected.members = expected.members.dup + %w(resource3)
 | 
			
		||||
      expected_configure_cmd_args = [expected.reconfigure_command]
 | 
			
		||||
      test_modify(expected_configure_cmd_args) do
 | 
			
		||||
        @resource.members expected.members
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should modify the group if it has different member resources" do
 | 
			
		||||
      fixture.members = %w(resource1 resource3)
 | 
			
		||||
      expected_configure_cmd_args = [fixture.reconfigure_command]
 | 
			
		||||
      test_modify(expected_configure_cmd_args) do
 | 
			
		||||
        @resource.members fixture.members
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it_should_behave_like "a runnable resource", fixture
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
		Reference in New Issue
	
	Block a user