...
 
Commits (12)
......@@ -146,6 +146,14 @@ suites:
- To boldly go where no one has gone before!
footer: Engage!
info: true
- name: sys_chef
run_list:
- recipe[sys::chef]
attributes:
sys:
chef:
server_url:
http://localhost:4000
- name: sys_mail
run_list:
- recipe[sys::mail]
......
......@@ -2,7 +2,6 @@
language: ruby
cache: bundler
sudo: required
dist: xenial
services: docker
......@@ -23,41 +22,21 @@ before_script:
env:
global:
- KITCHEN_LOCAL_YAML=.kitchen.docker.yml
matrix:
- CHEF_VERSION=12.3
- CHEF_VERSION=12.14
- CHEF_VERSION=13
- CHEF_VERSION=14
rvm:
# - system # does not work with `gem install bundler`
- 2.3
- 2.4
- 2.5
# - 2.1
# before_install:
# - gem install bundler -v ‘< 2’
# cf. https://travis-ci.com/chuhn/chef-install-test/
matrix:
exclude:
- rvm: 1.9
env: CHEF_VERSION=12
- rvm: 2.1
env: CHEF_VERSION=13
- rvm: 2.1
env: CHEF_VERSION=14
- rvm: 2.3
env: CHEF_VERSION=14
stages:
- rubocop
- foodcritic
- test
- chefspec
- kitchen
# this is the script for the test stage, where the matrix is expanded
script: bundle exec rake chefspec
jobs:
fast_finish: true
include:
......@@ -65,6 +44,20 @@ jobs:
script: bundle exec rake rubocop
- stage: foodcritic
script: bundle exec rake foodcritic
- stage: chefspec
script: bundle exec rake chefspec
env: CHEF_VERSION=12.3
- stage: chefspec
script: bundle exec rake chefspec
env: CHEF_VERSION=12.14
- stage: chefspec
script: bundle exec rake chefspec
env: CHEF_VERSION=13.8
- stage: chefspec
script: bundle exec rake chefspec
env: CHEF_VERSION=14
- stage: chefspec
script: bundle exec rake chefspec
- stage: kitchen
env: KITCHEN_PLATFORM=debian-stretch
script: bundle exec kitchen test $KITCHEN_PLATFORM
......@@ -79,9 +72,7 @@ jobs:
- env: KITCHEN_PLATFORM=centos-7
script: bundle exec kitchen test $KITCHEN_PLATFORM
allow_failures:
- rvm: 2.4
- rvm: 1.9
- env: CHEF_VERSION=14
- env: CHEF_VERSION=13
- env: CHEF_VERSION=13.8
- env: KITCHEN_PLATFORM=centos-7
- stage: test
......@@ -15,3 +15,7 @@ default_unless['sys']['chef']['verify_ssl'] = 'all'
default_unless['sys']['chef']['trusted_certs_dir'] = '/etc/ssl/certs'
default_unless['sys']['chef']['restart_via_cron'] = false
if node['platform_family'] == 'rhel'
default_unless['sys']['chef']['init_style'] = 'systemd'
end
......@@ -68,7 +68,7 @@ Ohai.plugin(:Dpkg) do
# Print a warning that this plugin is probably not usefule if
# platform_family != debian
Ohai::Log.warn("Not a debian derivative, #{__FILE__} only collects data for nodes with platform_family.eq? 'debian'.")
Ohai::Log.debug("Not a debian derivative, #{__FILE__} only collects data for nodes with platform_family.eq? 'debian'.")
end
......
#
# Copyright 2014 - 2020, GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
#
# Authors:
# Christopher Huhn <c.huhn@gsi.de>
# Dennis Klein <d.klein@gsi.de>
#
# 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.
#
use_inline_resources
action :add do
if new_resource.to.is_a?(String)
# single recipient
new_resource.to(escape_value(new_resource.to))
elsif new_resource.to.is_a?(Array)
# multiple recipients have been passed as an array:
new_resource.to(new_resource.to.map{|e| escape_value(e)}.join(', '))
end
new_line = "#{new_resource.name}: #{new_resource.to}"
if @current_resource.exists
unless @current_resource.to == new_resource.to
# Mail alias exists, but points to wrong value:
# * change alias value
ruby_block 'SysMailAlias action :add : change alias value' do
block do
aliases_file = Chef::Util::FileEdit.new(new_resource.aliases_file)
aliases_file.search_file_replace_line(alias_regexp, new_line)
aliases_file.write_file
end
end
new_resource.updated_by_last_action(true)
end
else
# Mail alias does not exist:
# * create new aliases file, if missing
# * insert mail alias
file "mail_alias #{new_resource.aliases_file}" do
path new_resource.aliases_file
action :create
not_if { ::File.exist?(new_resource.aliases_file) }
end
ruby_block 'SysMailAlias action :add : insert alias' do
block do
aliases_file = Chef::Util::FileEdit.new(new_resource.aliases_file)
aliases_file.insert_line_if_no_match(alias_regexp, new_line)
aliases_file.write_file
end
end
new_resource.updated_by_last_action(true)
end
end
action :remove do
if @current_resource.exists
# Mail alias exists:
# * delete the alias from aliases file
ruby_block 'SysMailAlias action :remove : remove alias' do
block do
aliases_file = Chef::Util::FileEdit.new(new_resource.aliases_file)
aliases_file.search_file_delete_line(alias_regexp)
aliases_file.write_file
end
end
# FIXME: should only be triggered something was removed:
new_resource.updated_by_last_action(true)
end
end
def load_current_resource
@current_resource = Chef::Resource::SysMailAlias.new(new_resource.name)
@current_resource.exists = false
if ::File.exist? new_resource.aliases_file
lines = ::File.readlines(new_resource.aliases_file).select { |line| line =~ /^#{@current_resource.name}:/ }
unless lines.empty?
@current_resource.to(lines.first.match(/:(.*)$/)[1].strip)
@current_resource.exists = true
end
end
@current_resource
end
def escape_value(value)
if value =~ /[:@#|]/
"\"#{value}\""
else
value
end
end
def alias_regexp
/^#{new_resource.name}:/
end
......@@ -5,21 +5,27 @@
#
# set's up the chef-client
#
# Copyright 2011-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH <hpc@gsi.de>
# Copyright 2011-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# All rights reserved - Do Not Redistribute
# Authors:
# Christopher Huhn <c.huhn@gsi.de>
# Dennis Klein <d.klein@gsi.de>
# Ilona Neis <i.neis@gsi.de>
# Bastian Neuburger <b.neuburger@gsi.de>
# Matthias Pausch <m.pausch@gsi.de>
# Victor Penso <v.penso@gsi.de>
#
# 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.
#
server_url = node['sys']['chef']['server_url']
......@@ -64,6 +70,12 @@ end
package 'ruby-sysloglogger' if node['sys']['chef']['use_syslog']
directory '/etc/chef' do
owner 'root'
group node['sys']['chef']['group']
mode 0o0750
end
# compile attributes for the client.rb template:
v = node['sys']['chef'].to_hash
v[:server_url] = server_url
......@@ -114,11 +126,47 @@ if node['sys']['chef']['restart_via_cron'] # ~FC023
end
end
# Comments in systemctl-src say that update-rc.d does not provide
# information wheter a service is enabled or not and always returns
# false. Work around that.
actions = [:start]
actions << :enable if Dir.glob('/etc/rc2.d/*chef-client*').empty?
if node['sys']['chef']['init_style'] == 'systemd'
# mimic the chef-client cookbook systemd unit:
systemd_unit 'chef-client.service' do
content(
'Unit' => {
'Description' => 'Chef Infra Client',
'After' => 'network.target auditd.service',
},
'Service' => {
'Type' => 'oneshot',
'EnvironmentFile' => '/etc/default/chef-client',
'ExecStart' => '/usr/bin/chef-client -c $CONFIG $OPTIONS',
'ExecReload' => '/bin/kill -HUP $MAINPID',
'SuccessExitStatus' => 3,
},
'Install' => { 'WantedBy' => 'multi-user.target' },
)
action :create
end
# mimic the chef-client cookbook systemd unit:
systemd_unit 'chef-client.timer' do
content(
'Unit' => { 'Description' => 'chef-client periodic run' },
'Install' => { 'WantedBy' => 'timers.target' },
'Timer' => {
'OnBootSec' => '1min',
'OnUnitInactiveSec' => "#{node['sys']['chef']['interval']}sec",
'RandomizedDelaySec' => "#{node['sys']['chef']['splay']}sec",
}
)
action [:create, :enable, :start]
end
else
# Comments in systemctl-src say that update-rc.d does not provide
# information wheter a service is enabled or not and always returns
# false. Work around that.
actions = [:start]
actions << :enable if Dir.glob('/etc/rc2.d/*chef-client*').empty?
actions << :enable if Dir.glob('/etc/rc2.d/*chef-client*').empty?
end
service 'chef-client' do
supports :restart => true, :status => true
......
#
# Copyright 2014 - 2019, GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
# Copyright 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
#
# Authors:
# Dennis Klein
# Christopher Huhn
# Christopher Huhn <c.huhn@gsi.de>
# Dennis Klein <d.klein@gsi.de>
# Matthias Pausch <m.pausch@gsi.de>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
......@@ -17,32 +19,47 @@
# limitations under the License.
#
property :to, [Array, String],
# turn Strings into Arrays for simplicity:
coerce: proc { |t| Array(t) }
property :aliases_file, String, default: '/etc/aliases'
default_action :add
action :add do
new_line = "#{new_resource.name}: "
new_line += new_resource.to.map do |e|
e =~ /[:@#|]/ ? "\"#{e}\"" : e
end.join(', ')
replace_or_add "alias for #{new_resource.name}" do
path new_resource.aliases_file
pattern "^#{new_resource.name}:.*"
line new_line
backup true if respond_to?(:backup)
ignore_missing true if respond_to?(:ignore_missing)
if Gem::Requirement.new('>= 12.5')
.satisfied_by?(Gem::Version.new(Chef::VERSION))
property :to, [Array, String],
# turn Strings into Arrays for simplicity:
coerce: proc { |t| Array(t) }
property :aliases_file, String, default: '/etc/aliases'
default_action :add
action :add do
new_line = "#{new_resource.name}: "
new_line += new_resource.to.map do |e|
e =~ /[:@#|]/ ? "\"#{e}\"" : e
end.join(', ')
replace_or_add "alias for #{new_resource.name}" do
path new_resource.aliases_file
pattern "^#{new_resource.name}:.*"
line new_line
backup true if respond_to?(:backup)
ignore_missing true if respond_to?(:ignore_missing)
end
end
end
action :remove do
delete_lines "alias for #{new_resource.name}" do
path new_resource.aliases_file
pattern "^#{new_resource.name}:.*"
only_if { ::File.exist?(new_resource.aliases_file) }
action :remove do
delete_lines "alias for #{new_resource.name}" do
path new_resource.aliases_file
pattern "^#{new_resource.name}:.*"
only_if { ::File.exist?(new_resource.aliases_file) }
end
end
else
actions :add, :remove
default_action :add
attribute :name, :kind_of => String, :name_attribute => true,
:required => true
attribute :to, :kind_of => [Array, String], :default => nil
attribute :aliases_file, :kind_of => String, :default => '/etc/aliases'
attr_accessor :exists
end
......@@ -30,8 +30,8 @@ pid_file "/var/run/chef/client.pid"
<%- unless @odisable.empty? -%>
<%# Make sure to write symbols into the configuration file %>
<%- plugins = @odisable.map { |p| p.capitalize.to_sym } -%>
Ohai::Config[:disabled_plugins] = <%= plugins %>
ohai.disabled_plugins = <%= plugins %>
<%- end %>
Ohai::Config[:plugin_path] << "<%= @opath %>"
ohai.plugin_path << "<%= @opath %>"
<%= @custom_config %>
source 'http://rubygems.org'
group :jessie do
# net-ssh >= 5 requires ruby 2.2 and
# net-telnet >= 0.2 requires ruby 2.3
if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.2.0')
gem 'net-ssh', '< 5'
gem 'net-telnet', '< 0.2'
end
end
group :wheezy do
# net-ssh >= 5 requires ruby 2.2
if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
gem 'rake', '< 12.3'
end
end
#
# Cookbook Name:: sys
# Serverspec integration tests for sys::chef
#
# Copyright 2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
#
# Authors:
# Christopher Huhn <C.Huhn@gsi.de>
#
# 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 'spec_helper'
context 'chef-client config' do
before(:all) do
# start chef-zero
`/opt/chef/embedded/bin/chef-zero --daemon --port 4000`
end
describe command('chef-client') do
its(:exit_status) { should be_zero }
its(:stdout) { should contain('Chef Run complete') }
end
end
require 'serverspec'
set :backend, :exec
......@@ -5,9 +5,9 @@
# Copyright 2015-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
#
# Authors:
# Christopher Huhn <c.huhn@gsi.de>
# Dennis Klein <d.klein@gsi.de>
# Matthias Pausch <m.pausch@gsi.de>
# Christopher Huhn <c.huhn@gsi.de>
# Dennis Klein <d.klein@gsi.de>
# Matthias Pausch <m.pausch@gsi.de>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
......@@ -100,9 +100,11 @@ describe 'sys::mail' do
etc_postfix_virtual = '/etc/postfix/virtual'
it "manages #{etc_postfix_virtual}" do
expect(chef_run).to create_template(etc_postfix_virtual).with_mode('0600')
expect(chef_run.template(etc_postfix_virtual)).to notify("execute[update-virtual]").to(:run).immediately
expect(chef_run.execute('update-virtual')).to do_nothing
expect(chef_run.execute('update-virtual')).to notify("service[#{postfix}]").to(:reload).delayed
expect(chef_run.template(etc_postfix_virtual))
.to notify("execute[#{update_virtual}]").to(:run).immediately
expect(chef_run.execute(update_virtual)).to do_nothing
expect(chef_run.execute(update_virtual))
.to notify("service[#{postfix}]").to(:reload).delayed
end
etc_postfix_main_cf = '/etc/postfix/main.cf'
......