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

New systemd::timer define type #138

Merged
merged 1 commit into from
Feb 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,82 @@ file { '/etc/tmpfiles.d/foo.conf':
~> Class['systemd::tmpfiles']
```

### timer units
Create a systemd timer unit and a systemd service unit to execute from
that timer

The following will create a timer unit and a service unit file.
The execution of `systemctl daemon-reload` will occur.
When `active` and `enable` are set to `true` the puppet service `runoften.timer` will be
declared, started and enabled.

```puppet
systemd::timer{'runoften.timer':
timer_source => "puppet:///modules/${module_name}/runoften.timer",
service_source => "puppet:///modules/${module_name}/runoften.service",
active => true,
enable => true,
}
```

A trivial daily run.
In this case enable and active are both unset and so the service `daily.timer`
is not declared by the `systemd::timer` type.

```puppet
$_timer = @(EOT)
[Timer]
OnCalendar=daily
RandomizedDelaySec=1d
EOT

$_service = @(EOT)
[Service]
Type=oneshot
ExecStart=/usr/bin/touch /tmp/file
EOT

systemd::timer{'daily.timer':
timer_content => $_timer,
service_content => $_service,
}

service{'daily.timer':
ensure => running,
subscribe => Systemd::Timer['daily.timer'],
}

```

If neither `service_content` or `service_source` are specified then no
service unit will be created.

The service unit name can also be specified.

```puppet
$_timer = @(EOT)
[Timer]
OnCalendar=daily
RandomizedDelaySec=1d
Unit=touch-me-today.service
EOT

$_service = @(EOT)
[Service]
Type=oneshot
ExecStart=/usr/bin/touch /tmp/file
EOT


systemd::timer{'daily.timer':
timer_content => $_timer,
service_unit => 'touch-me-today.service',
service_content => $_service,
active => true,
enable => true,
}
```

### service limits

Manage soft and hard limits on various resources for executed processes.
Expand Down
106 changes: 106 additions & 0 deletions manifests/timer.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# @summary Create a timer and optionally a service unit to execute with the timer unit
#
# @api public
#
# @see https://www.freedesktop.org/software/systemd/man/systemd.timer.html systemd.timer(5)
#
# @param name [Pattern['^.+\.timer$]]
# The target of the timer unit to create
#
# @param path
# The main systemd configuration path
#
# @param timer_content
# The full content of the timer unit file
#
# * Mutually exclusive with ``$timer_source``
#
# @param timer_source
# The ``File`` resource compatible ``source``
#
# * Mutually exclusive with ``$timer_content``
#
# @param service_content
# The full content of the service unit file
#
# * Mutually exclusive with ``$service_source``
#
# @param service_source
# The ``File`` resource compatible ``source``
#
# * Mutually exclusive with ``$service_content``
#
# @param owner
# The owner to set on the dropin file
#
# @param group
# The group to set on the dropin file
#
# @param mode
# The mode to set on the dropin file
#
# @param show_diff
# Whether to show the diff when updating dropin file
#
# @param service_unit
# If set then the service_unit will have this name.
# If not set the service unit has the same name
# as the timer unit with s/.timer/.service/
#
# @param active
# If set to true or false the timer service will be maintained.
# If true the timer service will be running and enabled, if false it will
# explictly stopped and disabled.
#
# @param enable
# If set, will manage the state of the unit.
#
define systemd::timer (
Enum['present', 'absent', 'file'] $ensure = 'present',
Stdlib::Absolutepath $path = '/etc/systemd/system',
Optional[String[1]] $timer_content = undef,
Optional[String[1]] $timer_source = undef,
Optional[String[1]] $service_content = undef,
Optional[String[1]] $service_source = undef,
String[1] $owner = 'root',
String[1] $group = 'root',
Stdlib::Filemode $mode = '0444',
Optional[Systemd::Unit] $service_unit = undef,
Boolean $show_diff = true,
Optional[Variant[Boolean, Enum['mask']]] $enable = undef,
Optional[Boolean] $active = undef,
) {
assert_type(Pattern['^.+\.timer$'],$name)

if $service_unit {
$_service_unit = $service_unit
} else {
$_service_unit = "${basename($name,'.timer')}.service"
}

if $service_content or $service_source {
systemd::unit_file{$_service_unit:
ensure => $ensure,
content => $service_content,
source => $service_source,
path => $path,
owner => $owner,
group => $group,
mode => $mode,
show_diff => $show_diff,
}
}

systemd::unit_file{$name:
ensure => $ensure,
content => $timer_content,
source => $timer_source,
path => $path,
owner => $owner,
group => $group,
mode => $mode,
show_diff => $show_diff,
enable => $enable,
active => $active,
}
}
85 changes: 85 additions & 0 deletions spec/defines/timer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
require 'spec_helper'

describe 'systemd::timer' do
context 'supported operating systems' do
on_supported_os.each do |os, facts|
context "on #{os}" do
let(:facts) { facts }

let(:title) { 'foobar.timer' }

context('with timer_content and service_content') do
let(:params) do
{
timer_content: "[Timer]\nOnCalendar=weekly",
service_content: "[Service]\nExecStart=/bin/touch /tmp/foobar",
}
end

it { is_expected.to compile.with_all_deps }

it {
is_expected.to contain_systemd__unit_file('foobar.timer').with(
content: "[Timer]\nOnCalendar=weekly",
)
}

it {
is_expected.to contain_systemd__unit_file('foobar.service').with(
content: "[Service]\nExecStart=/bin/touch /tmp/foobar",
)
}
end

context('with timer_source and service_source') do
let(:params) do
{
timer_source: 'puppet:///timer',
service_source: 'puppet:///source',
}
end

it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_systemd__unit_file('foobar.timer').with_source('puppet:///timer') }
it { is_expected.to contain_systemd__unit_file('foobar.service').with_source('puppet:///source') }
end

context('with timer_source only set') do
let(:params) do
{
timer_source: 'puppet:///timer',
}
end

it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_systemd__unit_file('foobar.timer').with_source('puppet:///timer') }
it { is_expected.not_to contain_systemd__unit_file('foobar.service') }
end

context 'with service_unit specified' do
let(:params) do
{
timer_content: "[Timer]\nOnCalendar=weekly",
service_content: "[Service]\nExecStart=/bin/touch /tmp/foobar",
service_unit: 'gamma.service',
}
end

it { is_expected.to contain_systemd__unit_file('foobar.timer').with_content("[Timer]\nOnCalendar=weekly") }

it { is_expected.to contain_systemd__unit_file('gamma.service').with_content("[Service]\nExecStart=/bin/touch /tmp/foobar") }
end

context 'with a bad timer name' do
let(:title) { 'foobar' }

it {
expect {
is_expected.to compile.with_all_deps
}.to raise_error(%r{expects a match for})
}
end
end
end
end
end