Skip to content

Commit

Permalink
feat: add a cron like wrapper for timers
Browse files Browse the repository at this point in the history
This helper will allow to define a timer in a cron like way, and will
setup a corresponding timer and service.
In basic usage it only requires a command, user, timerspec and an ensure
parameter.
For additional features the parameter `service_overrides`, `timer_overrides`,
`service_unit_overrides` and `timer_unit_overrides` can be used to define
additional aspects of the create units.
The correct order of the units is also ensured.

fixes voxpupuli#374
related to voxpupuli#287
  • Loading branch information
TheMeier committed Mar 3, 2024
1 parent bcec820 commit 01719f2
Show file tree
Hide file tree
Showing 5 changed files with 424 additions and 12 deletions.
151 changes: 145 additions & 6 deletions REFERENCE.md
Expand Up @@ -36,6 +36,7 @@
* [`systemd::network`](#systemd--network): Creates network config for systemd-networkd
* [`systemd::service_limits`](#systemd--service_limits): Adds a set of custom limits to the service
* [`systemd::timer`](#systemd--timer): Create a timer and optionally a service unit to execute with the timer unit
* [`systemd::timer_wrapper`](#systemd--timer_wrapper): Helper to define timer and accompanying services for a given task (cron like interface).
* [`systemd::tmpfile`](#systemd--tmpfile): Creates a systemd tmpfile
* [`systemd::udev::rule`](#systemd--udev--rule): Adds a custom udev rule
* [`systemd::unit_file`](#systemd--unit_file): Creates a systemd unit file
Expand Down Expand Up @@ -67,6 +68,7 @@
* [`Systemd::Unit::Service::Exec`](#Systemd--Unit--Service--Exec): Possible strings for ExecStart, ExecStartPrep, ...
* [`Systemd::Unit::Socket`](#Systemd--Unit--Socket): Possible keys for the [Socket] section of a unit file
* [`Systemd::Unit::Timer`](#Systemd--Unit--Timer): Possible keys for the [Timer] section of a unit file
* [`Systemd::Unit::Timer::TimerSpec`](#Systemd--Unit--Timer--TimerSpec): Timer specification for systemd timers
* [`Systemd::Unit::Unit`](#Systemd--Unit--Unit): Possible keys for the [Unit] section of a unit file

## Classes
Expand Down Expand Up @@ -1677,6 +1679,134 @@ Call `systemd::daemon_reload`

Default value: `true`

### <a name="systemd--timer_wrapper"></a>`systemd::timer_wrapper`

Helper to define timer and accompanying services for a given task (cron like interface).

#### Parameters

The following parameters are available in the `systemd::timer_wrapper` defined type:

* [`ensure`](#-systemd--timer_wrapper--ensure)
* [`command`](#-systemd--timer_wrapper--command)
* [`user`](#-systemd--timer_wrapper--user)
* [`on_active_sec`](#-systemd--timer_wrapper--on_active_sec)
* [`on_boot_sec`](#-systemd--timer_wrapper--on_boot_sec)
* [`on_start_up_sec`](#-systemd--timer_wrapper--on_start_up_sec)
* [`on_unit_active_sec`](#-systemd--timer_wrapper--on_unit_active_sec)
* [`on_unit_inactive_sec`](#-systemd--timer_wrapper--on_unit_inactive_sec)
* [`on_calendar`](#-systemd--timer_wrapper--on_calendar)
* [`service_overrides`](#-systemd--timer_wrapper--service_overrides)
* [`timer_overrides`](#-systemd--timer_wrapper--timer_overrides)
* [`service_unit_overrides`](#-systemd--timer_wrapper--service_unit_overrides)
* [`timer_unit_overrides`](#-systemd--timer_wrapper--timer_unit_overrides)

##### <a name="-systemd--timer_wrapper--ensure"></a>`ensure`

Data type: `Enum['present', 'absent']`

whether the timer and service should be present or absent

##### <a name="-systemd--timer_wrapper--command"></a>`command`

Data type: `Optional[String[1]]`

the command for the systemd servie to execute

Default value: `undef`

##### <a name="-systemd--timer_wrapper--user"></a>`user`

Data type: `Optional[String[1]]`

the user to run the command as

Default value: `undef`

##### <a name="-systemd--timer_wrapper--on_active_sec"></a>`on_active_sec`

Data type: `Optional[Systemd::Unit::Timer::TimerSpec]`

run service relative to the time when the timer was activated

Default value: `undef`

##### <a name="-systemd--timer_wrapper--on_boot_sec"></a>`on_boot_sec`

Data type: `Optional[Systemd::Unit::Timer::TimerSpec]`

run service relative to when the machine was booted

Default value: `undef`

##### <a name="-systemd--timer_wrapper--on_start_up_sec"></a>`on_start_up_sec`

Data type: `Optional[Systemd::Unit::Timer::TimerSpec]`

run service relative to when the service manager was started

Default value: `undef`

##### <a name="-systemd--timer_wrapper--on_unit_active_sec"></a>`on_unit_active_sec`

Data type: `Optional[Systemd::Unit::Timer::TimerSpec]`

run service relative to when the unit was last activated

Default value: `undef`

##### <a name="-systemd--timer_wrapper--on_unit_inactive_sec"></a>`on_unit_inactive_sec`

Data type: `Optional[Systemd::Unit::Timer::TimerSpec]`

run service relative to when the unit was last deactivated

Default value: `undef`

##### <a name="-systemd--timer_wrapper--on_calendar"></a>`on_calendar`

Data type: `Optional[Systemd::Unit::Timer::TimerSpec]`

the calendar event expressions time to run the service

Default value: `undef`

##### <a name="-systemd--timer_wrapper--service_overrides"></a>`service_overrides`

Data type: `Systemd::Unit::Service`

override for the`[Service]` section of the service
example: `'service_overrides' => { 'Wants' => 'network-online.target' }`

Default value: `{}`

##### <a name="-systemd--timer_wrapper--timer_overrides"></a>`timer_overrides`

Data type: `Systemd::Unit::Timer`

override for the`[Timer]` section of the timer
example: `'timer_overrides' => { 'OnBootSec' => '10' }`

Default value: `{}`

##### <a name="-systemd--timer_wrapper--service_unit_overrides"></a>`service_unit_overrides`

Data type: `Systemd::Unit::Unit`

override for the`[Unit]` section of the service
example: `'service_unit_overrides' => { 'Wants' => 'network-online.target' }`

Default value: `{}`

##### <a name="-systemd--timer_wrapper--timer_unit_overrides"></a>`timer_unit_overrides`

Data type: `Systemd::Unit::Unit`

override for the `[Unit]` section of the timer
can not be used in combination with `additional_timer_params`

Default value: `{}`

### <a name="systemd--tmpfile"></a>`systemd::tmpfile`

Creates a systemd tmpfile
Expand Down Expand Up @@ -2578,12 +2708,12 @@ Alias of

```puppet
Struct[{
Optional['OnActiveSec'] => Variant[Integer[0],String,Array[Variant[Integer[0],String]]],
Optional['OnBootSec'] => Variant[Integer[0],String,Array[Variant[Integer[0],String]]],
Optional['OnStartUpSec'] => Variant[Integer[0],String,Array[Variant[Integer[0],String]]],
Optional['OnUnitActiveSec'] => Variant[Integer[0],String,Array[Variant[Integer[0],String]]],
Optional['OnUnitInactiveSec'] => Variant[Integer[0],String,Array[Variant[Integer[0],String]]],
Optional['OnCalendar'] => Variant[Integer[0],String,Array[Variant[Integer[0],String]]],
Optional['OnActiveSec'] => Systemd::Unit::Timer::TimerSpec,
Optional['OnBootSec'] => Systemd::Unit::Timer::TimerSpec,
Optional['OnStartUpSec'] => Systemd::Unit::Timer::TimerSpec,
Optional['OnUnitActiveSec'] => Systemd::Unit::Timer::TimerSpec,
Optional['OnUnitInactiveSec'] => Systemd::Unit::Timer::TimerSpec,
Optional['OnCalendar'] => Systemd::Unit::Timer::TimerSpec,
Optional['AccuracySec'] => Variant[Integer[0],String],
Optional['RandomizedDelaySec'] => Variant[Integer[0],String],
Optional['FixedRandomDelay'] => Boolean,
Expand All @@ -2596,6 +2726,15 @@ Struct[{
}]
```

### <a name="Systemd--Unit--Timer--TimerSpec"></a>`Systemd::Unit::Timer::TimerSpec`

Timer specification for systemd timers

* **See also**
* https://www.freedesktop.org/software/systemd/man/systemd.timer.html

Alias of `Variant[Integer[0], String, Array[Variant[Integer[0],String]]]`

### <a name="Systemd--Unit--Unit"></a>`Systemd::Unit::Unit`

Possible keys for the [Unit] section of a unit file
Expand Down
92 changes: 92 additions & 0 deletions manifests/timer_wrapper.pp
@@ -0,0 +1,92 @@
# @summary
# Helper to define timer and accompanying services for a given task (cron like interface).
# @param ensure whether the timer and service should be present or absent
# @param command the command for the systemd servie to execute
# @param user the user to run the command as
# @param on_active_sec run service relative to the time when the timer was activated
# @param on_boot_sec run service relative to when the machine was booted
# @param on_start_up_sec run service relative to when the service manager was started
# @param on_unit_active_sec run service relative to when the unit was last activated
# @param on_unit_inactive_sec run service relative to when the unit was last deactivated
# @param on_calendar the calendar event expressions time to run the service
# @param service_overrides override for the`[Service]` section of the service
# example: `'service_overrides' => { 'Wants' => 'network-online.target' }`
# @param timer_overrides override for the`[Timer]` section of the timer
# example: `'timer_overrides' => { 'OnBootSec' => '10' }`
# @param service_unit_overrides override for the`[Unit]` section of the service
# example: `'service_unit_overrides' => { 'Wants' => 'network-online.target' }`
# @param timer_unit_overrides override for the `[Unit]` section of the timer
# can not be used in combination with `additional_timer_params`
define systemd::timer_wrapper (
Enum['present', 'absent'] $ensure,
Optional[Systemd::Unit::Service::Exec] $command = undef,
Optional[String[1]] $user = undef,
Optional[Systemd::Unit::Timer::TimerSpec] $on_active_sec = undef,
Optional[Systemd::Unit::Timer::TimerSpec] $on_boot_sec = undef,
Optional[Systemd::Unit::Timer::TimerSpec] $on_start_up_sec = undef,
Optional[Systemd::Unit::Timer::TimerSpec] $on_unit_active_sec = undef,
Optional[Systemd::Unit::Timer::TimerSpec] $on_unit_inactive_sec = undef,
Optional[Systemd::Unit::Timer::TimerSpec] $on_calendar = undef,
Systemd::Unit::Service $service_overrides = {},
Systemd::Unit::Timer $timer_overrides = {},
Systemd::Unit::Unit $timer_unit_overrides = {},
Systemd::Unit::Unit $service_unit_overrides = {},
) {
$_timer_spec = {
'OnActiveSec' => $on_active_sec,
'OnBootSec' => $on_boot_sec,
'OnStartUpSec' => $on_start_up_sec,
'OnUnitActiveSec' => $on_unit_active_sec,
'OnUnitInactiveSec' => $on_unit_inactive_sec,
'OnCalendar' => $on_calendar,
}.filter |$k, $v| { $v =~ NotUndef }

if $ensure == 'present' {
if $_timer_spec == {} {
fail('At least one of on_active_sec,
on_boot_sec,
on_start_up_sec,
on_unit_active_sec,
on_unit_inactive_sec,
or on_calendar must be set'
)
}
if ! $command {
fail('command must be set')
}
}

$service_ensure = $ensure ? { 'absent' => false, default => true, }
$unit_name = systemd::escape($title)

systemd::manage_unit { "${unit_name}.service":
ensure => $ensure,
unit_entry => $service_unit_overrides,
service_entry => {
'ExecStart' => $command, # if ensure present command is defined is checked above
'User' => $user, # defaults apply
'Type' => 'oneshot',
}.filter |$key, $val| { $val =~ NotUndef } + $service_overrides,
}
systemd::manage_unit { "${unit_name}.timer":
ensure => $ensure,
unit_entry => $timer_unit_overrides,
timer_entry => $_timer_spec + $timer_overrides,
}

service { "${unit_name}.timer":
ensure => $service_ensure,
enable => $service_ensure,
}

if $ensure == 'present' {
Systemd::Manage_unit["${unit_name}.service"]
-> Systemd::Manage_unit["${unit_name}.timer"]
-> Service["${unit_name}.timer"]
} else {
# Ensure the timer is stopped and disabled before the service
Service["${unit_name}.timer"]
-> Systemd::Manage_unit["${unit_name}.timer"]
-> Systemd::Manage_unit["${unit_name}.service"]
}
}

0 comments on commit 01719f2

Please sign in to comment.