diff --git a/README.md b/README.md index a2423d6..49e9c0f 100644 --- a/README.md +++ b/README.md @@ -1,174 +1,193 @@ # Systemd [![Puppet Forge](http://img.shields.io/puppetforge/v/camptocamp/systemd.svg)](https://forge.puppetlabs.com/camptocamp/systemd) [![Build Status](https://travis-ci.org/camptocamp/puppet-systemd.png?branch=master)](https://travis-ci.org/camptocamp/puppet-systemd) ## Overview This module declares exec resources to create global sync points for reloading systemd. **Version 2 and newer of the module don't work with Hiera 3! You need to migrate your existing Hiera setup to Hiera 5** ## Usage and examples There are two ways to use this module. ### unit files Let this module handle file creation and systemd reloading. ```puppet systemd::unit_file { 'foo.service': source => "puppet:///modules/${module_name}/foo.service", } ~> service {'foo': ensure => 'running', } ``` Or handle file creation yourself and trigger systemd. ```puppet include systemd::systemctl::daemon_reload file { '/usr/lib/systemd/system/foo.service': ensure => file, owner => 'root', group => 'root', mode => '0644', source => "puppet:///modules/${module_name}/foo.service", } ~> Class['systemd::systemctl::daemon_reload'] service {'foo': ensure => 'running', subscribe => File['/usr/lib/systemd/system/foo.service'], } ``` ### drop-in files Drop-in files are used to add or alter settings of a unit without modifying the unit itself. As for the unit files, the module can handle the file and directory creation and systemd reloading: ```puppet systemd::dropin_file { 'foo.conf': unit => 'foo.service', source => "puppet:///modules/${module_name}/foo.conf", } ~> service {'foo': ensure => 'running', } ``` Or handle file and directory creation yourself and trigger systemd: ```puppet include systemd::systemctl::daemon_reload file { '/etc/systemd/system/foo.service.d': ensure => directory, owner => 'root', group => 'root', } file { '/etc/systemd/system/foo.service.d/foo.conf': ensure => file, owner => 'root', group => 'root', mode => '0644', source => "puppet:///modules/${module_name}/foo.conf", } ~> Class['systemd::systemctl::daemon_reload'] service {'foo': ensure => 'running', subscribe => File['/etc/systemd/system/foo.service.d/foo.conf'], } ``` ### tmpfiles Let this module handle file creation and systemd reloading ```puppet systemd::tmpfile { 'foo.conf': source => "puppet:///modules/${module_name}/foo.conf", } ``` Or handle file creation yourself and trigger systemd. ```puppet include systemd::tmpfiles file { '/etc/tmpfiles.d/foo.conf': ensure => file, owner => 'root', group => 'root', mode => '0644', source => "puppet:///modules/${module_name}/foo.conf", } ~> Class['systemd::tmpfiles'] ``` ### service limits Manage soft and hard limits on various resources for executed processes. ```puppet systemd::service_limits { 'foo.service': limits => { 'LimitNOFILE' => 8192, 'LimitNPROC' => 16384, } } ``` Or provide the configuration file yourself. Systemd reloading and restarting of the service are handled by the module. ```puppet systemd::service_limits { 'foo.service': source => "puppet:///modules/${module_name}/foo.conf", } ``` ### network systemd-networkd is able to manage your network configuration. We provide a defined resource which can write the interface configurations. systemd-networkd needs to be restarted to apply the configs. The defined resource can do this for you: ```puppet systemd::network{'eth0.network': source => "puppet:///modules/${module_name}/eth0.network", restart_service => true, } ``` ### Services Systemd provides multiple services. Currently you can manage `systemd-resolved`, `systemd-timesyncd` and `systemd-networkd` via the main class: ```puppet class{'systemd': manage_resolved => true, manage_networkd => true, manage_timesyncd => true, } ``` $manage_networkd is required if you want to reload it for new `systemd::network` resources. Setting $manage_resolved will also manage your `/etc/resolv.conf`. It is possible to configure the default ntp servers in /etc/systemd/timesyncd.conf: ```puppet class{'systemd': manage_timesyncd => true, ntp_server => ['0.pool.ntp.org', '1.pool.ntp.org'], fallback_ntp_server => ['2.pool.ntp.org', '3.pool.ntp.org'], } ``` This requires puppetlabs-inifile, which is only a soft dependency in this module (you need to explicitly install it). Both parameters accept a string or an array. + +### Resource Accounting + +Systemd has support for different accounting option. It can track +CPU/Memory/Network stats per process. This is explained in depth at [systemd-system.conf](https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html). +This defaults to off (default on most operating systems). You can enable this +with the `$manage_accounting` parameter. The module provides a default set of +working accounting options per operating system, but you can still modify them +with `$accounting`: + +```puppet +class{'systemd': + manage_accounting => true, + accounting => { + 'DefaultCPUAccounting' => 'yes', + 'DefaultMemoryAccounting' => 'no', + } +} +``` diff --git a/data/Archlinux.yaml b/data/Archlinux.yaml new file mode 100644 index 0000000..176f0ed --- /dev/null +++ b/data/Archlinux.yaml @@ -0,0 +1,8 @@ +--- +systemd::accounting: + DefaultCPUAccounting: 'yes' + DefaultIOAccounting: 'yes' + DefaultIPAccounting: 'yes' + DefaultBlockIOAccounting: 'yes' + DefaultMemoryAccounting: 'yes' + DefaultTasksAccounting: 'yes' diff --git a/data/CentOS-7.yaml b/data/CentOS-7.yaml new file mode 100644 index 0000000..888cb17 --- /dev/null +++ b/data/CentOS-7.yaml @@ -0,0 +1,6 @@ +--- +systemd::accounting: + DefaultCPUAccounting: 'yes' + DefaultBlockIOAccounting: 'yes' + DefaultMemoryAccounting: 'yes' + DefaultTasksAccounting: 'yes' diff --git a/data/Debian-10.yaml b/data/Debian-10.yaml new file mode 100644 index 0000000..176f0ed --- /dev/null +++ b/data/Debian-10.yaml @@ -0,0 +1,8 @@ +--- +systemd::accounting: + DefaultCPUAccounting: 'yes' + DefaultIOAccounting: 'yes' + DefaultIPAccounting: 'yes' + DefaultBlockIOAccounting: 'yes' + DefaultMemoryAccounting: 'yes' + DefaultTasksAccounting: 'yes' diff --git a/data/Debian-8.yaml b/data/Debian-8.yaml new file mode 100644 index 0000000..a3be163 --- /dev/null +++ b/data/Debian-8.yaml @@ -0,0 +1,5 @@ +--- +systemd::accounting: + DefaultCPUAccounting: 'yes' + DefaultBlockIOAccounting: 'yes' + DefaultMemoryAccounting: 'yes' diff --git a/data/Debian-9.yaml b/data/Debian-9.yaml new file mode 100644 index 0000000..a3be163 --- /dev/null +++ b/data/Debian-9.yaml @@ -0,0 +1,5 @@ +--- +systemd::accounting: + DefaultCPUAccounting: 'yes' + DefaultBlockIOAccounting: 'yes' + DefaultMemoryAccounting: 'yes' diff --git a/data/RedHat-7.yaml b/data/RedHat-7.yaml new file mode 100644 index 0000000..888cb17 --- /dev/null +++ b/data/RedHat-7.yaml @@ -0,0 +1,6 @@ +--- +systemd::accounting: + DefaultCPUAccounting: 'yes' + DefaultBlockIOAccounting: 'yes' + DefaultMemoryAccounting: 'yes' + DefaultTasksAccounting: 'yes' diff --git a/data/Ubuntu-16.04.yaml b/data/Ubuntu-16.04.yaml new file mode 100644 index 0000000..888cb17 --- /dev/null +++ b/data/Ubuntu-16.04.yaml @@ -0,0 +1,6 @@ +--- +systemd::accounting: + DefaultCPUAccounting: 'yes' + DefaultBlockIOAccounting: 'yes' + DefaultMemoryAccounting: 'yes' + DefaultTasksAccounting: 'yes' diff --git a/data/common.yaml b/data/common.yaml index 6432a91..a220c0c 100644 --- a/data/common.yaml +++ b/data/common.yaml @@ -1,10 +1,12 @@ --- systemd::service_limits: {} systemd::manage_resolved: false systemd::resolved_ensure: 'running' systemd::manage_networkd: false systemd::networkd_ensure: 'running' systemd::manage_timesyncd: false systemd::timesyncd_ensure: 'running' systemd::ntp_server: ~ systemd::fallback_ntp_server: ~ +systemd::manage_accounting: false +systemd::accounting: {} diff --git a/manifests/init.pp b/manifests/init.pp index 2231a1e..396a0c2 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,62 +1,68 @@ # This module allows triggering systemd commands once for all modules # # @api public # # @param service_limits # May be passed a resource hash suitable for passing directly into the # ``create_resources()`` function as called on ``systemd::service_limits`` # # @param manage_resolved # Manage the systemd resolver # # @param resolved_ensure # The state that the ``resolved`` service should be in # # @param manage_networkd # Manage the systemd network daemon # # @param networkd_ensure # The state that the ``networkd`` service should be in # # @param manage_timesyncd # Manage the systemd tiemsyncd daemon # # @param timesyncd_ensure # The state that the ``timesyncd`` service should be in # # @param ntp_server # comma separated list of ntp servers, will be combined with interface specific # addresses from systemd-networkd. requires puppetlabs-inifile # # @param fallback_ntp_server # A space-separated list of NTP server host names or IP addresses to be used # as the fallback NTP servers. Any per-interface NTP servers obtained from # systemd-networkd take precedence over this setting. requires puppetlabs-inifile class systemd ( Hash[String, Hash[String, Any]] $service_limits, Boolean $manage_resolved, Enum['stopped','running'] $resolved_ensure, Boolean $manage_networkd, Enum['stopped','running'] $networkd_ensure, Boolean $manage_timesyncd, Enum['stopped','running'] $timesyncd_ensure, Optional[Variant[Array,String]] $ntp_server, Optional[Variant[Array,String]] $fallback_ntp_server, + Boolean $manage_accounting, + Hash[String,String] $accounting, ){ contain systemd::systemctl::daemon_reload create_resources('systemd::service_limits', $service_limits) if $manage_resolved and $facts['systemd_internal_services'] and $facts['systemd_internal_services']['systemd-resolved.service'] { contain systemd::resolved } if $manage_networkd and $facts['systemd_internal_services'] and $facts['systemd_internal_services']['systemd-networkd.service'] { contain systemd::networkd } if $manage_timesyncd and $facts['systemd_internal_services'] and $facts['systemd_internal_services']['systemd-timesyncd.service'] { contain systemd::timesyncd } + + if $manage_accounting { + contain systemd::system + } } diff --git a/manifests/system.pp b/manifests/system.pp new file mode 100644 index 0000000..82b4a9e --- /dev/null +++ b/manifests/system.pp @@ -0,0 +1,19 @@ +# **NOTE: THIS IS A [PRIVATE](https://github.com/puppetlabs/puppetlabs-stdlib#assert_private) CLASS** +# +# This class provides a solution to enable accounting +# +class systemd::system { + + assert_private() + + $systemd::accounting.each |$option, $value| { + ini_setting{$option: + ensure => 'present', + path => '/etc/systemd/system.conf', + section => 'Manager', + setting => $option, + value => $value, + notify => Class['systemd::systemctl::daemon_reload'], + } + } +} diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index 379026c..d0a6ad4 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -1,73 +1,96 @@ require 'spec_helper' describe 'systemd' do context 'supported operating systems' do on_supported_os.each do |os, facts| context "on #{os}" do let(:facts) { facts } it { is_expected.to compile.with_all_deps } it { is_expected.to create_class('systemd') } it { is_expected.to create_class('systemd::systemctl::daemon_reload') } it { is_expected.to_not create_service('systemd-resolved') } it { is_expected.to_not create_service('systemd-networkd') } it { is_expected.to_not create_service('systemd-timesyncd') } context 'when enabling resolved and networkd' do let(:params) {{ :manage_resolved => true, :manage_networkd => true }} it { is_expected.to create_service('systemd-resolved').with_ensure('running') } it { is_expected.to create_service('systemd-resolved').with_enable(true) } it { is_expected.to create_service('systemd-networkd').with_ensure('running') } it { is_expected.to create_service('systemd-networkd').with_enable(true) } end context 'when enabling timesyncd' do let(:params) {{ :manage_timesyncd => true }} it { is_expected.to create_service('systemd-timesyncd').with_ensure('running') } it { is_expected.to create_service('systemd-timesyncd').with_enable(true) } it { is_expected.not_to create_service('systemd-resolved').with_ensure('running') } it { is_expected.not_to create_service('systemd-resolved').with_enable(true) } it { is_expected.not_to create_service('systemd-networkd').with_ensure('running') } it { is_expected.not_to create_service('systemd-networkd').with_enable(true) } end context 'when enabling timesyncd with NTP values (string)' do let(:params) {{ :manage_timesyncd => true, :ntp_server => '0.pool.ntp.org 1.pool.ntp.org', :fallback_ntp_server => '2.pool.ntp.org 3.pool.ntp.org' }} it { is_expected.to compile.with_all_deps } it { is_expected.to contain_ini_setting('ntp_server')} it { is_expected.to contain_ini_setting('fallback_ntp_server')} end context 'when enabling timesyncd with NTP values (array)' do let(:params) {{ :manage_timesyncd => true, :ntp_server => %w(0.pool.ntp.org 1.pool.ntp.org), :fallback_ntp_server => %w(2.pool.ntp.org 3.pool.ntp.org) }} it { is_expected.to compile.with_all_deps } it { is_expected.to contain_ini_setting('ntp_server')} it { is_expected.to contain_ini_setting('fallback_ntp_server')} end context 'when passing service limits' do let(:params) {{ :service_limits => {'openstack-nova-compute.service' => {'limits' => {'LimitNOFILE' => 32768}}} }} it { is_expected.to compile.with_all_deps } it { is_expected.to contain_systemd__service_limits('openstack-nova-compute.service').with_limits({'LimitNOFILE' => 32768}) } end + + context 'when managing Accounting options' do + let :params do + { + manage_accounting: true, + } + end + + it { is_expected.to contain_class('systemd::system')} + + case facts[:os]['family'] + when 'Archlinux' + accounting = ['DefaultCPUAccounting', 'DefaultIOAccounting', 'DefaultIPAccounting', 'DefaultBlockIOAccounting', 'DefaultMemoryAccounting', 'DefaultTasksAccounting'] + when 'Debian' + accounting = ['DefaultCPUAccounting', 'DefaultBlockIOAccounting', 'DefaultMemoryAccounting'] + when 'RedHat' + accounting = ['DefaultCPUAccounting', 'DefaultBlockIOAccounting', 'DefaultMemoryAccounting', 'DefaultTasksAccounting'] + end + accounting.each do |account| + it { is_expected.to contain_ini_setting(account)} + end + it { is_expected.to compile.with_all_deps } + end end end end end