Add function for parsing services cgroups settings
Current function was introduced to convert cgroups settings in JSON format to the HASH what will be processed by main cgroups puppet module. Change-Id: I580207f26d672df87b20aa10468ed062be135f46 Implements: blueprint cgroups
This commit is contained in:
parent
7f9b8f648b
commit
20752a7974
|
@ -0,0 +1,19 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
group :development, :test do
|
||||
gem 'rake', :require => false
|
||||
gem 'pry', :require => false
|
||||
gem 'rspec', '~>3.3', :require => false
|
||||
gem 'rspec-puppet', '~>2.2.0', :require => false
|
||||
gem 'puppetlabs_spec_helper', :require => false
|
||||
gem 'puppet-lint', '~> 0.3.2'
|
||||
gem 'json', :require => false
|
||||
end
|
||||
|
||||
if puppetversion = ENV['PUPPET_GEM_VERSION']
|
||||
gem 'puppet', puppetversion, :require => false
|
||||
else
|
||||
gem 'puppet', '<4.0', :require => false
|
||||
end
|
||||
|
||||
# vim:ft=ruby
|
|
@ -0,0 +1,8 @@
|
|||
require 'rubygems'
|
||||
require 'puppetlabs_spec_helper/rake_tasks'
|
||||
require 'puppet-lint/tasks/puppet-lint'
|
||||
|
||||
PuppetLint.configuration.fail_on_warnings = false
|
||||
PuppetLint.configuration.send('disable_80chars')
|
||||
PuppetLint.configuration.send('disable_class_parameter_defaults')
|
||||
PuppetLint.configuration.send('disable_class_inherits_from_params_class')
|
|
@ -0,0 +1,72 @@
|
|||
require 'json'
|
||||
|
||||
module CgroupsSettings
|
||||
require 'facter'
|
||||
# value is valid if value has integer type or
|
||||
# matches with pattern: %percent, min_value, max_value
|
||||
def self.handle_value(group, value)
|
||||
return value if value.is_a?(Numeric)
|
||||
if group == 'memory' and value.match(/%(\d+), (\d+), (\d+)/)
|
||||
percent, min, max = value.scan(/%(\d+), (\d+), (\d+)/).flatten.map { |i| i.to_i }
|
||||
total_memory = Facter.value(:memorysize_mb)
|
||||
res = (total_memory.to_f / 100.0) * percent.to_f
|
||||
return [min, max, res].sort[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Puppet::Parser::Functions::newfunction(:prepare_cgroups_hash, :type => :rvalue, :arity => 1, :doc => <<-EOS
|
||||
This function get hash contains service and its cgroups settings(in JSON format) and serialize it.
|
||||
|
||||
ex: prepare_cgroups_hash(hiera('cgroups'))
|
||||
|
||||
Following input:
|
||||
{
|
||||
'metadata' => {
|
||||
'always_editable' => true,
|
||||
'group' => 'general',
|
||||
'label' => 'Cgroups',
|
||||
'weight' => 50
|
||||
},
|
||||
cinder-api: {"blkio":{"blkio.weight":500}}
|
||||
}
|
||||
|
||||
will be transformed to:
|
||||
[{"cinder-api"=>{"blkio"=>{"blkio.weight"=>500}}}]
|
||||
|
||||
Pattern for value field:
|
||||
{
|
||||
group1 => {
|
||||
param1 => value1,
|
||||
param2 => value2
|
||||
},
|
||||
group2 => {
|
||||
param3 => value3,
|
||||
param4 => value4
|
||||
}
|
||||
}
|
||||
|
||||
EOS
|
||||
) do |argv|
|
||||
raise(Puppet::ParseError, "prepare_cgroups_hash(...): Wrong type of argument. Hash is expected.") unless argv[0].is_a?(Hash)
|
||||
|
||||
# wipe out UI metadata
|
||||
cgroups = argv[0].tap { |el| el.delete('metadata') }
|
||||
|
||||
serialized_data = {}
|
||||
|
||||
cgroups.each do |service, settings|
|
||||
hash_settings = JSON.parse(settings) rescue raise("'#{service}': JSON parsing error for : #{settings}")
|
||||
hash_settings.each do |group, options|
|
||||
raise("'#{service}': group '#{group}' options is not a HASH instance") unless options.is_a?(Hash)
|
||||
options.each do |option, value|
|
||||
options[option] = CgroupsSettings.handle_value(group, value)
|
||||
raise("'#{service}': group '#{group}': option '#{option}' has wrong value") if options[option].nil?
|
||||
end
|
||||
end
|
||||
serialized_data[service] = hash_settings
|
||||
end
|
||||
serialized_data
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,133 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Puppet::Parser::Functions.function(:prepare_cgroups_hash) do
|
||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||
|
||||
subject do
|
||||
function_name = Puppet::Parser::Functions.function(:prepare_cgroups_hash)
|
||||
scope.method(function_name)
|
||||
end
|
||||
|
||||
it 'should exist' do
|
||||
subject == Puppet::Parser::Functions.function(:prepare_cgroups_hash)
|
||||
end
|
||||
|
||||
Facter.stubs(:fact).with(:memorysize_mb).returns Facter.add(:memorysize_mb) { setcode { 1024 } }
|
||||
|
||||
context "transform simple hash" do
|
||||
let(:sample) {
|
||||
{
|
||||
'metadata' => {
|
||||
'always_editable' => true,
|
||||
'group' => 'general',
|
||||
'label' => 'Cgroups',
|
||||
'weight' => 50
|
||||
},
|
||||
'cinder' => '{"blkio":{"blkio.weight":500, "blkio.test":800}, "memory":{"memory.soft_limit_in_bytes":700}}',
|
||||
'keystone' => '{"cpu":{"cpu.shares":70}}'
|
||||
}
|
||||
}
|
||||
|
||||
let(:result) {
|
||||
{
|
||||
'cinder' => {
|
||||
'blkio' => {
|
||||
'blkio.weight' => 500,
|
||||
'blkio.test' => 800
|
||||
},
|
||||
'memory' => {
|
||||
'memory.soft_limit_in_bytes' => 700
|
||||
},
|
||||
},
|
||||
'keystone' => {
|
||||
'cpu' => {
|
||||
'cpu.shares' => 70
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it 'should transform hash with simple values' do
|
||||
should run.with_params(sample).and_return(result)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
context "transform hash with expression" do
|
||||
|
||||
let(:sample) {
|
||||
{
|
||||
'metadata' => {
|
||||
'always_editable' => true,
|
||||
'group' => 'general',
|
||||
'label' => 'Cgroups',
|
||||
'weight' => 50
|
||||
},
|
||||
'neutron' => '{"memory":{"memory.soft_limit_in_bytes":"%50, 300, 700"}}'
|
||||
}
|
||||
}
|
||||
|
||||
let(:result) {
|
||||
{
|
||||
'neutron' => {
|
||||
'memory' => {
|
||||
'memory.soft_limit_in_bytes' => 512
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it 'should transform hash including expression to compute' do
|
||||
should run.with_params(sample).and_return(result)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "wrong JSON format" do
|
||||
|
||||
let(:sample) {
|
||||
{
|
||||
'neutron' => '{"memory":{"memory.soft_limit_in_bytes":"%50, 300, 700"}}}}'
|
||||
}
|
||||
}
|
||||
|
||||
let(:result) {
|
||||
{}
|
||||
}
|
||||
|
||||
it 'should raise if settings have wrong JSON format' do
|
||||
is_expected.to run.with_params(sample).and_raise_error(RuntimeError, /JSON parsing error/)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "service's cgroup settings are not a HASH" do
|
||||
|
||||
let(:sample) {
|
||||
{
|
||||
'neutron' => '{"memory": 28}'
|
||||
}
|
||||
}
|
||||
|
||||
it 'should raise if group option is not a Hash' do
|
||||
is_expected.to run.with_params(sample).and_raise_error(RuntimeError, /options is not a HASH instance/)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "cgroup limit is not an integer" do
|
||||
|
||||
let(:sample) {
|
||||
{
|
||||
'neutron' => '{"memory":{"memory.soft_limit_in_bytes":"test"}}'
|
||||
}
|
||||
}
|
||||
|
||||
it 'should raise if limit value is not an integer or template' do
|
||||
is_expected.to run.with_params(sample).and_raise_error(RuntimeError, /has wrong value/)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
require 'rubygems'
|
||||
require 'puppetlabs_spec_helper/module_spec_helper'
|
||||
|
||||
fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures'))
|
||||
|
||||
PROJECT_ROOT = File.expand_path('..', File.dirname(__FILE__))
|
||||
$LOAD_PATH.unshift(File.join(PROJECT_ROOT, "lib"))
|
||||
|
||||
# Add fixture lib dirs to LOAD_PATH. Work-around for PUP-3336
|
||||
if Puppet.version < '4.0.0'
|
||||
Dir["#{fixture_path}/modules/*/lib"].entries.each do |lib_dir|
|
||||
$LOAD_PATH << lib_dir
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.module_path = File.join(fixture_path, 'modules')
|
||||
c.manifest_dir = File.join(fixture_path, 'manifests')
|
||||
c.mock_with(:mocha)
|
||||
c.alias_it_should_behave_like_to :it_configures, 'configures'
|
||||
end
|
||||
|
||||
def puppet_debug_override
|
||||
if ENV['SPEC_PUPPET_DEBUG']
|
||||
Puppet::Util::Log.level = :debug
|
||||
Puppet::Util::Log.newdestination(:console)
|
||||
end
|
||||
end
|
||||
|
||||
###
|
Loading…
Reference in New Issue