c08013d004
* Improve missing cib sections filters * Change is_online? to use dc-version to determine if CIB is ready * Cleanup primitives by their full names * Change node id references to node name as 'id' does not represent node name for new pacemaker versions (related change: Id84994df3bf2a990d2925b595aa448746db45383 * Switch location add implementation from pcs to cibadmin --patch as this provder claims to be crmsh/pcs agnostic and to solve problems with cib changes not being synced to other nodes then has been applied concurrently. * Add missing debug info * Update rspecs Author: Dmitry Ilyin <dilyin@mirantis.com> Closes-bug: #1416378 Change-Id: I2185b17286e46086674abe985bfc48260e7c397b Signed-off-by: Bogdan Dobrelya <bdobrelia@mirantis.com>
213 lines
6.6 KiB
Ruby
213 lines
6.6 KiB
Ruby
require File.join File.dirname(__FILE__), '../pacemaker_common.rb'
|
|
|
|
Puppet::Type.type(:service).provide :pacemaker, :parent => Puppet::Provider::Pacemaker_common do
|
|
|
|
has_feature :enableable
|
|
has_feature :refreshable
|
|
|
|
commands :uname => 'uname'
|
|
commands :pcs => 'pcs'
|
|
commands :crm_resource => 'crm_resource'
|
|
commands :crm_attribute => 'crm_attribute'
|
|
commands :cibadmin => 'cibadmin'
|
|
|
|
# hostname of the current node
|
|
# @return [String]
|
|
def hostname
|
|
return @hostname if @hostname
|
|
@hostname = (uname '-n').chomp.strip
|
|
end
|
|
|
|
# original name passed from the type
|
|
# @return [String]
|
|
def title
|
|
@resource[:name]
|
|
end
|
|
|
|
# primitive name with 'p_' added if needed
|
|
# @return [String]
|
|
def name
|
|
return @name if @name
|
|
primitive_name = title
|
|
if primitive_exists? primitive_name
|
|
Puppet.debug "Primitive with title '#{primitive_name}' was found in CIB"
|
|
@name = primitive_name
|
|
return @name
|
|
end
|
|
primitive_name = "p_#{primitive_name}"
|
|
if primitive_exists? primitive_name
|
|
Puppet.debug "Using '#{primitive_name}' name instead of '#{title}'"
|
|
@name = primitive_name
|
|
return @name
|
|
end
|
|
fail "Primitive '#{title}' was not found in CIB!"
|
|
end
|
|
|
|
# full name of the primitive
|
|
# if resource is complex use group name
|
|
# @return [String]
|
|
def full_name
|
|
return @full_name if @full_name
|
|
if primitive_is_complex? name
|
|
full_name = primitives[name]['name']
|
|
Puppet.debug "Using full name '#{full_name}' for complex primitive '#{name}'"
|
|
@full_name = full_name
|
|
else
|
|
@full_name = name
|
|
end
|
|
end
|
|
|
|
# name of the basic service without 'p_' prefix
|
|
# used to disable the basic service
|
|
# @return [String]
|
|
def basic_service_name
|
|
return @basic_service_name if @basic_service_name
|
|
if name.start_with? 'p_'
|
|
basic_service_name = name.gsub /^p_/, ''
|
|
Puppet.debug "Using '#{basic_service_name}' as the basic service name for primitive '#{name}'"
|
|
@basic_service_name = basic_service_name
|
|
else
|
|
@basic_service_name = name
|
|
end
|
|
end
|
|
|
|
# cleanup a primitive and
|
|
# wait for cleanup to finish
|
|
def cleanup
|
|
cleanup_primitive full_name, hostname
|
|
wait_for_status name
|
|
end
|
|
|
|
# called by Puppet to determine if the service
|
|
# is running on the local node
|
|
# @return [:running,:stopped]
|
|
def status
|
|
wait_for_online
|
|
Puppet.debug "Call: 'status' for Pacemaker service '#{name}' on node '#{hostname}'"
|
|
cib_reset
|
|
out = get_primitive_puppet_status name, hostname
|
|
Puppet.debug get_cluster_debug_report
|
|
Puppet.debug "Return: '#{out}' (#{out.class})"
|
|
out
|
|
end
|
|
|
|
# called by Puppet to start the service
|
|
def start
|
|
Puppet.debug "Call 'start' for Pacemaker service '#{name}' on node '#{hostname}'"
|
|
enable unless primitive_is_managed? name
|
|
disable_basic_service
|
|
constraint_location_add full_name, hostname
|
|
cleanup
|
|
unban_primitive name, hostname
|
|
start_primitive full_name
|
|
start_primitive name
|
|
|
|
if primitive_is_multistate? name
|
|
Puppet.debug "Choose master start for Pacemaker service '#{name}'"
|
|
wait_for_master name
|
|
else
|
|
Puppet.debug "Choose global start for Pacemaker service '#{name}'"
|
|
wait_for_start name
|
|
end
|
|
end
|
|
|
|
# called by Puppet to stop the service
|
|
def stop
|
|
Puppet.debug "Call 'stop' for Pacemaker service '#{name}' on node '#{hostname}'"
|
|
cleanup
|
|
enable unless primitive_is_managed? name
|
|
|
|
if primitive_is_complex? name
|
|
Puppet.debug "Choose local stop for Pacemaker service '#{name}' on node '#{hostname}'"
|
|
ban_primitive name, hostname
|
|
wait_for_stop name, hostname
|
|
else
|
|
Puppet.debug "Choose global stop for Pacemaker service '#{name}'"
|
|
stop_primitive name
|
|
wait_for_stop name
|
|
end
|
|
end
|
|
|
|
# called by Puppet to restart the service
|
|
def restart
|
|
Puppet.debug "Call 'restart' for Pacemaker service '#{name}' on node '#{hostname}'"
|
|
unless primitive_is_running? name, hostname
|
|
Puppet.info "Pacemaker service '#{name}' is not running on node '#{hostname}'. Skipping restart!"
|
|
return
|
|
end
|
|
|
|
begin
|
|
stop
|
|
rescue
|
|
nil
|
|
ensure
|
|
start
|
|
end
|
|
end
|
|
|
|
# called by Puppet to enable the service
|
|
def enable
|
|
Puppet.debug "Call 'enable' for Pacemaker service '#{name}' on node '#{hostname}'"
|
|
manage_primitive name
|
|
end
|
|
|
|
# called by Puppet to disable the service
|
|
def disable
|
|
Puppet.debug "Call 'disable' for Pacemaker service '#{name}' on node '#{hostname}'"
|
|
unmanage_primitive name
|
|
end
|
|
alias :manual_start :disable
|
|
|
|
# called by Puppet to determine if the service is enabled
|
|
# @return [:true,:false]
|
|
def enabled?
|
|
Puppet.debug "Call 'enabled?' for Pacemaker service '#{name}' on node '#{hostname}'"
|
|
out = get_primitive_puppet_enable name
|
|
Puppet.debug "Return: '#{out}' (#{out.class})"
|
|
out
|
|
end
|
|
|
|
# create an extra provider instance to deal with the basic service
|
|
# the provider will be chosen to match the current system
|
|
# @return [Puppet::Type::Service::Provider]
|
|
def extra_provider(provider_name = nil)
|
|
return @extra_provider if @extra_provider
|
|
begin
|
|
param_hash = {}
|
|
param_hash.store :name, basic_service_name
|
|
param_hash.store :provider, provider_name if provider_name
|
|
type = Puppet::Type::Service.new param_hash
|
|
@extra_provider = type.provider
|
|
rescue => e
|
|
Puppet.warning "Could not get extra provider for Pacemaker primitive '#{name}': #{e.message}"
|
|
@extra_provider = nil
|
|
end
|
|
end
|
|
|
|
# disable and stop the basic service
|
|
def disable_basic_service
|
|
return unless extra_provider
|
|
begin
|
|
if extra_provider.enableable? and extra_provider.enabled? == :true
|
|
Puppet.info "Disable basic service '#{extra_provider.name}' using provider '#{extra_provider.class.name}'"
|
|
extra_provider.disable
|
|
else
|
|
Puppet.info "Basic service '#{extra_provider.name}' is disabled as reported by '#{extra_provider.class.name}' provider"
|
|
end
|
|
if extra_provider.status == :running
|
|
if not ['lsb','systemd','upstart'].include?(primitive_class name)
|
|
Puppet.info "Stop basic service '#{extra_provider.name}' using provider '#{extra_provider.class.name}'"
|
|
extra_provider.stop
|
|
else
|
|
Puppet.info "Not stopping basic service '#{extra_provider.name}', since its Pacemaker primitive is using primitive_class '#{extra_provider.class.name}'"
|
|
end
|
|
else
|
|
Puppet.info "Basic service '#{extra_provider.name}' is stopped as reported by '#{extra_provider.class.name}' provider"
|
|
end
|
|
rescue => e
|
|
Puppet.warning "Could not disable basic service for Pacemaker primitive '#{name}' using '#{extra_provider.class.name}' provider: #{e.message}"
|
|
end
|
|
end
|
|
|
|
end
|