Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to support Puppet 4 #18

Merged
merged 11 commits into from Jul 19, 2017
2 changes: 1 addition & 1 deletion .fixtures.yml
@@ -1,6 +1,6 @@
---
fixtures:
repositories:
stdlib: https://github.com/puppetlabs/puppetlabs-stdlib.git
stdlib: https://github.com/puppetlabs/puppetlabs-stdlib
symlinks:
systemd: "#{source_dir}"
3 changes: 3 additions & 0 deletions .rspec
@@ -0,0 +1,3 @@
--format documentation
--color
--fail-fast
16 changes: 9 additions & 7 deletions README.md
Expand Up @@ -24,15 +24,16 @@ Let this module handle file creation and systemd reloading.
Or handle file creation yourself and trigger systemd.

```puppet
include ::systemd
include ::systemd::systemctl::daemon_reload
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd rather keep the interface in the systemd class and contain the subclasses (systemd::systemctl::daemon_reload and systemd::tmpfiles) for dependencies instead. Is there something that prevents from doing that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can contain daemon_reload but we can't contain tmpfiles since tmpfiles is triggered from the use of the tmpfile defined type.

A notify to Class[systemd] makes sense for reloading the whole thing though so I'll switch that one to a contain and hope that we don't get more creative in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you contained the class in init.pp, so I'm guessing the README is not up-to-date?


file { '/usr/lib/systemd/system/foo.service':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
source => "puppet:///modules/${module_name}/foo.service",
} ~>
Exec['systemctl-daemon-reload']
}
~> Class['systemd::systemctl::daemon_reload']
```

### tmpfiles
Expand All @@ -48,15 +49,16 @@ Let this module handle file creation and systemd reloading
Or handle file creation yourself and trigger systemd.

```puppet
include ::systemd
include ::systemd::tmpfiles

file { '/etc/tmpfiles.d/foo.conf':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
source => "puppet:///modules/${module_name}/foo.conf",
} ~>
Exec['systemd-tmpfiles-create']
}
~> Class['systemd::tmpfiles']
```

### service limits
Expand All @@ -67,7 +69,7 @@ Manage soft and hard limits on various resources for executed processes.
::systemd::service_limits { 'foo.service':
limits => {
LimitNOFILE => 8192,
LimitNPROC => 16384
LimitNPROC => 16384,
}
}
```
Expand Down
59 changes: 29 additions & 30 deletions manifests/init.pp
@@ -1,43 +1,42 @@
# -- Class systemd
# 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
#
class systemd (
$service_limits = {},
Boolean $manage_resolved = true,
Boolean $manage_networkd = true,
Optional[Systemd::ServiceLimits] $service_limits = undef,
Boolean $manage_resolved = false,
Enum['stopped','running'] $resolved_ensure = 'running',
Boolean $manage_networkd = false,
Enum['stopped','running'] $networkd_ensure = 'running',
){

Exec {
refreshonly => true,
path => $::path,
}

exec {
'systemctl-daemon-reload':
command => 'systemctl daemon-reload',
}
contain ::systemd::systemctl::daemon_reload

exec {
'systemd-tmpfiles-create':
command => 'systemd-tmpfiles --create',
if $service_limits {
create_resources('systemd::service_limits', $service_limits)
}

create_resources('systemd::service_limits', $service_limits, {})

if $manage_resolved {
service{'systemd-resolved':
ensure => 'running',
enable => true,
}
-> file{'/etc/resolv.conf':
ensure => 'symlink',
target => '/run/systemd/resolve/resolv.conf',
}
contain ::systemd::resolved
}

if $manage_networkd {
service{'systemd-networkd':
ensure => 'running',
enable => true,
}
contain ::systemd::networkd
}
}
24 changes: 24 additions & 0 deletions manifests/networkd.pp
@@ -0,0 +1,24 @@
# **NOTE: THIS IS A [PRIVATE](https://github.com/puppetlabs/puppetlabs-stdlib#assert_private) CLASS**
#
# This class provides an abstract way to trigger resolved
#
# @param ensure
# The state that the ``networkd`` service should be in
#
class systemd::networkd (
Enum['stopped','running'] $ensure = 'running',
){

assert_private()

$_enable_networkd = $ensure ? {
'stopped' => false,
'running' => true,
default => $ensure,
}

service{ 'systemd-networkd':
ensure => $ensure,
enable => $_enable_networkd,
}
}
30 changes: 30 additions & 0 deletions manifests/resolved.pp
@@ -0,0 +1,30 @@
# **NOTE: THIS IS A [PRIVATE](https://github.com/puppetlabs/puppetlabs-stdlib#assert_private) CLASS**
#
# This class provides an abstract way to trigger resolved
#
# @param ensure
# The state that the ``resolved`` service should be in
#
class systemd::resolved (
Enum['stopped','running'] $ensure = $::systemd::resolved_ensure,
){

assert_private()

$_enable_resolved = $ensure ? {
'stopped' => false,
'running' => true,
default => $ensure,
}

service { 'systemd-resolved':
ensure => $ensure,
enable => $_enable_resolved,
}

file { '/etc/resolv.conf':
ensure => 'symlink',
target => '/run/systemd/resolve/resolv.conf',
require => Service['systemd-resolved'],
}
}
82 changes: 60 additions & 22 deletions manifests/service_limits.pp
@@ -1,51 +1,89 @@
# -- Define: systemd::service_limits
# Creates a custom config file and reloads systemd
# Adds a set of custom limits to the service
#
# @api public
#
# @see systemd.exec(5)
#
# @attr name [Pattern['^.+\.(service|socket|mount|swap)$']]
# The name of the service that you will be modifying
#
# @param $ensure
# Whether to drop a file or remove it
#
# @param path
# The path to the main systemd settings directory
#
# @param limits
# A Hash of service limits matching the settings in ``systemd.exec(5)``
#
# * Mutually exclusive with ``$source``
#
# @param source
# A ``File`` resource compatible ``source``
#
# * Mutually exclusive with ``$limits``
#
# @param restart_service
# Restart the managed service after setting the limits
#
define systemd::service_limits(
$ensure = file,
$path = '/etc/systemd/system',
$limits = undef,
$source = undef,
$restart_service = true
Enum['present', 'absent', 'file'] $ensure = 'present',
Stdlib::Absolutepath $path = '/etc/systemd/system',
Optional[Systemd::ServiceLimits] $limits = undef,
Optional[String] $source = undef,
Boolean $restart_service = true
) {

include ::systemd

if $limits {
validate_hash($limits)
$content = template('systemd/limits.erb')
if $name !~ Pattern['^.+\.(service|socket|mount|swap)$'] {
fail('$name must match Pattern["^.+\.(service|socket|mount|swap)$"]')
}

if $limits and !empty($limits) {
$_content = template("${module_name}/limits.erb")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a $content variable. What is the need for $_content?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It denotes it as a private variable that should not be used outside of the class. It's been convention for a while but hasn't made it into the style guide yet.

When actual private variables become a thing, this will be easier.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, fine for me.

}
else {
$content = undef
$_content = undef
}

if $limits and $source {
if ($limits and !empty($limits)) and $source {
fail('You may not supply both limits and source parameters to systemd::service_limits')
} elsif $limits == undef and $source == undef {
}
elsif ($limits == undef or empty($limits)) and ($source == undef) {
fail('You must supply either the limits or source parameter to systemd::service_limits')
}

file { "${path}/${title}.d/":
file { "${path}/${name}.d/":
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644',
seltype => 'systemd_unit_file_t',
}

-> file { "${path}/${title}.d/limits.conf":
ensure => $ensure,
content => $content,
$_conf_file_ensure = $ensure ? {
'present' => 'file',
default => $ensure,
}

file { "${path}/${name}.d/90-limits.conf":
ensure => $_conf_file_ensure,
content => $_content,
source => $source,
owner => 'root',
group => 'root',
mode => '0444',
notify => Exec['systemctl-daemon-reload'],
mode => '0644',
notify => Class['systemd::systemctl::daemon_reload'],
}

if $restart_service {
exec { "systemctl restart ${title}":
exec { "restart ${name} because limits":
command => "systemctl restart ${name}",
path => $::path,
refreshonly => true,
subscribe => File["${path}/${title}.d/limits.conf"],
require => Exec['systemctl-daemon-reload'],
subscribe => File["${path}/${name}.d/90-limits.conf"],
require => Class['systemd::systemctl::daemon_reload'],
}
}
}
10 changes: 10 additions & 0 deletions manifests/systemctl/daemon_reload.pp
@@ -0,0 +1,10 @@
# Reload the systemctl daemon
#
# @api public
class systemd::systemctl::daemon_reload {
exec { 'systemctl-daemon-reload':
command => 'systemctl daemon-reload',
refreshonly => true,
path => $::path,
}
}
56 changes: 45 additions & 11 deletions manifests/tmpfile.pp
@@ -1,20 +1,54 @@
# -- Define: systemd::tmpfile
# Creates a tmpfile and reloads systemd
# Creates a systemd tmpfile
#
# @api public
#
# @see systemd-tmpfiles(8)
#
# @attr name [String]
# The name of the tmpfile to create
#
# * May not contain ``/``
#
# @param $ensure
# Whether to drop a file or remove it
#
# @param path
# The path to the main systemd tmpfiles directory
#
# @param content
# The literal content to write to the file
#
# * Mutually exclusive with ``$source``
#
# @param source
# A ``File`` resource compatible ``source``
#
# * Mutually exclusive with ``$limits``
#
define systemd::tmpfile(
$ensure = file,
$path = '/etc/tmpfiles.d',
$content = undef,
$source = undef,
Enum['present', 'absent', 'file'] $ensure = 'file',
Stdlib::Absolutepath $path = '/etc/tmpfiles.d',
Optional[String] $content = undef,
Optional[String] $source = undef,
) {
include ::systemd
include ::systemd::tmpfiles

file { "${path}/${title}":
ensure => $ensure,
if $name =~ Pattern['/'] {
fail('$name may not contain a forward slash "(/)"')
}

$_tmp_file_ensure = $ensure ? {
'present' => 'file',
default => $ensure,
}

file { "${path}/${name}":
ensure => $_tmp_file_ensure,
content => $content,
source => $source,
owner => 'root',
group => 'root',
mode => '0444',
notify => Exec['systemd-tmpfiles-create'],
notify => Class['systemd::tmpfiles'],
}
}
}