Add provider for managing policy-rc.d

This commits aims to add the policy-rcd provider to stable/mitaka
The stable/mitaka for puppet-nova need the provider see [1]

(cherry picked from commit Ic54b9707b6ef36032d71fe9dc04a7e310293f127)
(cherry picked from commit Ie6d4dd1e5406acd097969a9ff7fccd5dfa7f8632)
(cherry picked from commit I1bad3301729fa6310d9d1a50c22c621ffe44e24a)

[1] https://review.openstack.org/#/c/364620/

Change-Id: Ifed6e4bc79e757ff4aa7a38349e0ebef5d38ac87
This commit is contained in:
Denis Egorenko
2016-06-17 13:20:52 +03:00
committed by Iury Gregory Melo Ferreira
parent 1497ef3a26
commit fef24a2ea4
5 changed files with 277 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
Puppet::Type.type(:policy_rcd).provide(:policy_rcd) do
desc 'Provider for managing policy-rc.d for Ubuntu'
mk_resource_methods
def check_os
Facter.value(:osfamily) == 'Debian'
end
def check_policy_rcd
return File.exist? policy_rcd
end
def file_lines
@file_lines ||= File.open(policy_rcd).readlines
end
def policy_rcd
'/usr/sbin/policy-rc.d'
end
def service
@resource[:service]
end
def set_code
@resource[:set_code]
end
def self.write_to_file(file, content, truncate=false)
File.truncate(file, 0) if truncate
policy = File.open(file, 'a+')
policy.puts(content)
policy.close
File.chmod(0744, file)
end
def exists?
# we won't do anything if os family is not debian
return true unless check_os
if check_policy_rcd
file_lines.each do |line|
unless line =~ /"#{@resource[:service]}"/
next
end
return true
end
end
false
end
def create
unless check_policy_rcd
header = "#!/bin/bash\n# THIS FILE MANAGED BY PUPPET\n"
else
header = ""
end
content = "#{header}[[ \"$1\" == \"#{@resource[:service]}\" ]] && exit #{@resource[:set_code]}\n"
self.class.write_to_file(policy_rcd, content)
end
def destroy
if check_policy_rcd
file_lines.delete_if { |l| l =~ /"#{@resource[:service]}"/ }
self.class.write_to_file(policy_rcd, file_lines, true)
end
end
def flush
if @resource[:ensure] == :present and ! file_lines.nil?
new_line = nil
outdated_line = nil
file_lines.each do |line|
unless line =~ /"#{@resource[:service]}"/
next
end
code = line.match(/exit\s(\d+)/)[1]
if code != @resource[:set_code]
new_line = "[[ \"$1\" == \"#{@resource[:service]}\" ]] && exit #{@resource[:set_code]}\n"
outdated_line = line
end
end
unless new_line.nil?
file_lines.delete(outdated_line)
file_lines.push(new_line)
self.class.write_to_file(policy_rcd, file_lines, true)
end
end
end
end

View File

@@ -0,0 +1,21 @@
Puppet::Type.newtype(:policy_rcd) do
ensurable
newparam(:name, :namevar => true) do
newvalues(/\S+/)
end
newproperty(:service) do
defaultto { @resource[:name] }
newvalues(/\S+/)
end
newproperty(:set_code) do
defaultto('101')
validate do |value|
# validate codes according to https://people.debian.org/~hmh/invokerc.d-policyrc.d-specification.txt
allowed_codes = [ '0', '1', '100', '101', '102', '103', '104', '105', '106' ]
raise ArgumentError, 'Unknown exit status code is set' unless allowed_codes.include?(value)
end
end
end

View File

@@ -0,0 +1,3 @@
---
features:
- Added policy_rcd provider for managing policy-rc.d for Debian family.

View File

@@ -0,0 +1,137 @@
require 'puppet'
require 'spec_helper'
require 'puppet/provider/policy_rcd/policy_rcd'
require 'tempfile'
provider_class = Puppet::Type.type(:policy_rcd).provider(:policy_rcd)
describe provider_class do
let(:attributes) do {
:name => 'service',
:set_code => '101'
}
end
let(:resource) do
Puppet::Type::Policy_rcd.new(attributes)
end
let(:provider) do
resource.provider
end
let(:header) do
"#!/bin/bash\n# THIS FILE MANAGED BY PUPPET\n"
end
describe 'managing policy' do
describe '#create' do
it 'creates a policy when policy-rc.d doesnt exist' do
file = mock('file')
provider.stubs(:policy_rcd).returns(file)
File.expects(:exist?).with(file).returns(false)
content = "#{header}[[ \"$1\" == \"service\" ]] && exit 101\n"
provider.class.expects(:write_to_file).with(file, content)
provider.create
end
it 'creates a policy when policy-rc.d exists' do
file = mock('file')
provider.stubs(:policy_rcd).returns(file)
File.expects(:exist?).with(file).returns(true)
content = "[[ \"$1\" == \"service\" ]] && exit 101\n"
provider.class.expects(:write_to_file).with(file, content)
provider.create
end
end
describe '#destroy' do
it 'destroy a policy' do
file = mock('file')
file_content = "#{header}[[ \"$1\" == \"service\" ]] && exit 101\n"
provider.stubs(:policy_rcd).returns(file)
File.expects(:exist?).with(file).returns(true)
provider.stubs(:file_lines).returns(file_content.split("\n"))
provider.class.expects(:write_to_file).with(file, ['#!/bin/bash', '# THIS FILE MANAGED BY PUPPET'], true)
provider.destroy
end
end
describe '#flush' do
it 'update a policy' do
file = mock('file')
provider.stubs(:policy_rcd).returns(file)
file_content = "#{header}[[ \"$1\" == \"service\" ]] && exit 102\n"
provider.stubs(:file_lines).returns(file_content.split("\n"))
provider.class.expects(:write_to_file).with(file, ['#!/bin/bash', "# THIS FILE MANAGED BY PUPPET", "[[ \"$1\" == \"service\" ]] && exit 101\n"], true)
provider.flush
end
it 'dont update a policy' do
file = mock('file')
file_content = "#{header}[[ \"$1\" == \"service\" ]] && exit 101\n"
provider.stubs(:policy_rcd).returns(file)
provider.stubs(:file_lines).returns(file_content.split("\n"))
provider.flush
end
end
describe '#exists?' do
it 'should exists on Debian family' do
provider.stubs(:check_os).returns(true)
file = mock('file')
file_content = "#{header}[[ \"$1\" == \"service\" ]] && exit 101\n"
provider.stubs(:policy_rcd).returns(file)
provider.stubs(:check_policy_rcd).returns(true)
provider.stubs(:file_lines).returns(file_content.split("\n"))
expect(provider.exists?).to be_truthy
end
it 'should not exists on Debian family when file is present' do
provider.stubs(:check_os).returns(true)
file = mock('file')
file_content = "#{header}[[ \"$1\" == \"new-service\" ]] && exit 101\n"
provider.stubs(:policy_rcd).returns(file)
provider.stubs(:check_policy_rcd).returns(true)
provider.stubs(:file_lines).returns(file_content.split("\n"))
expect(provider.exists?).to be_falsey
end
it 'should not exists on Debian family when file is not present' do
provider.stubs(:check_os).returns(true)
provider.stubs(:check_policy_rcd).returns(false)
expect(provider.exists?).to be_falsey
end
it 'should exists on non-Debian family' do
provider.stubs(:check_os).returns(false)
expect(provider.exists?).to be_truthy
end
end
describe 'write_to_file' do
it 'should write to file' do
file = mock
policy = mock
content = 'some_content'
File.expects(:open).with(file, 'a+').returns(policy)
policy.expects(:puts).with(content)
policy.expects(:close)
File.expects(:chmod).with(0744, file)
provider.class.write_to_file(file, content)
end
it 'should truncate file' do
file = mock
policy = mock
content = 'some_content'
File.expects(:truncate).with(file, 0)
File.expects(:open).with(file, 'a+').returns(policy)
policy.expects(:puts).with(content)
policy.expects(:close)
File.expects(:chmod).with(0744, file)
provider.class.write_to_file(file, content, true)
end
end
end
end

View File

@@ -0,0 +1,25 @@
require 'puppet'
require 'puppet/type/policy_rcd'
describe Puppet::Type.type(:policy_rcd) do
before :each do
Puppet::Type.rmtype(:policy_rcd)
end
it 'should fail with wrong status code' do
incorrect_input = {
:name => 'test_type',
:set_code => '356'
}
expect { Puppet::Type.type(:policy_rcd).new(incorrect_input) }.to raise_error(Puppet::ResourceError, /Unknown exit status code is set/)
end
it 'should be compiled withour errors' do
correct_input = {
:name => 'test_type',
:set_code => '0'
}
expect { Puppet::Type.type(:policy_rcd).new(correct_input) }.to_not raise_error
end
end