Defined Type: systemd::timer::job

Defined in:
modules/systemd/manifests/timer/job.pp

Summary

Generic wrapper around the basic timer definition that adds log handling and monitoring for defining recurring jobs, much like crons in non-systemd world

Overview

Parameters:

  • description (String)

    Description to place in the systemd unit.

  • command (Systemd::Command)

    Command to be executed periodically.

  • interval (Variant[ Systemd::Timer::Schedule, Array[Systemd::Timer::Schedule, 1]])

    Systemd interval to use. See Systemd::Timer::Schedule for the format. Several intervals can be provided as Array[See Systemd::Timer::Schedule]

  • splay (Optional[Integer]) (defaults to: undef)

    Passed to systemd::timer. See RandomizedDelaySec in systemd.timer(5)

  • timeout_start_sec (Optional[Integer]) (defaults to: undef)

    Configures the time to wait for start-up. If a daemon service does not signal start-up completion within the configured time, the service will be considered failed

  • user (String)

    User that runs the Systemd unit.

  • ensure (Wmflib::Ensure) (defaults to: 'present')

    The ensurable parameter

  • environment (Hash[String, String]) (defaults to: {})

    Hash containing 'Environment=' related values to insert in the

  • monitoring_enabled (Boolean) (defaults to: false)

    Periodically check the last execution of the unit and alarm if it ended up in a failed state.

  • monitoring_contact_groups (String) (defaults to: 'admins')

    The monitoring's contact group to send the alarm to.

  • monitoring_notes_url (Stdlib::HTTPSUrl) (defaults to: 'https://wikitech.wikimedia.org/wiki/Monitoring/systemd_unit_state')

    URL of the troubleshooting notes for this alert.

  • logging_enabled (Boolean) (defaults to: true)

    If true, log directories are created, rsyslog/logrotate rules are created.

  • send_mail (Boolean) (defaults to: false)

    If true, send a mail to root@ if there was output generated by the command. If MAILTO env variable or send_mail_to is specified, it will send it to that instead of root@

  • send_mail_to (String) (defaults to: "root@${facts['networking']['fqdn']}")

    If send_mail is true, send email to this address.

  • ignore_errors (Boolean) (defaults to: false)

    set this to true to ensure that a failed timer wont show up in systemctl status –failed

  • send_mail_only_on_error (Boolean) (defaults to: true)

    set this to true to send an email for any output to stdout, similar to cron

  • private_tmp (Boolean) (defaults to: false)

    use a private temporary directory

  • logfile_basedir (String) (defaults to: '/var/log')

    Base directory for log files, to which /$title will be appended. Logs will be saved at $logfile_basedir/$title/$logfile_name

  • logfile_name (String) (defaults to: 'syslog.log')

    The filename of the file storing the syslog output of the running unit.

  • logfile_owner (Optional[String]) (defaults to: undef)

    The user that owns the logfile. If undef, the value of $user will be used.

  • logfile_group (String) (defaults to: 'root')

    The group that owns the logfile.

  • logfile_perms (Enum['user', 'group', 'all']) (defaults to: 'all')

    The UNIX file permissions to set on the log file. Check systemd::syslog for more info about the available options.

  • syslog_force_stop (Boolean) (defaults to: true)

    Force logs to be written into the logfile but not in syslog/daemon.log. This is particularly useful for units that need to log a lot of information, since it prevents a duplication of space consumed on disk.

  • syslog_match_startswith (Boolean) (defaults to: true)

    If true, all syslog programnames that start with the service_name will be logged to the output log file. Else, only service_names that match exactly will be logged.

  • syslog_identifier (Optional[String]) (defaults to: undef)

    Adds the SyslogIdentifier parameter to the systemd unit to override the default behavior, namely using the program name. This is particularly useful when multiple timers are scheduled using the same program but with different parameters. Without an explicit SyslogIdentifier in fact they would end up sharing the same identifier and rsyslog rules wouldn't work anymore.

  • max_runtime_seconds (Optional[Integer]) (defaults to: undef)

    Add a RuntimeMaxSec=… stanza to the systemd unit triggered by the timer. This can be useful when setting a timer to run some code every N minutes and the process run by the unit has a potential for deadlocking rather than exiting under some internal error condition. See <www.freedesktop.org/software/systemd/man/systemd.service.html#RuntimeMaxSec=> for more details.

  • slice (Optional[Pattern[/\w+\.slice/]]) (defaults to: undef)

    Run the systemd timer's service unit under a specific slice. By default the service unit will run under the system.slice.

  • environment_file (Optional[Stdlib::Unixpath]) (defaults to: undef)

    String containing a file path to be used as 'EnvironmentFile=' in the Systemd unit.

  • stdin (Optional[Systemd::Input]) (defaults to: undef)

    change the where to read stdin

  • stdout (Optional[Systemd::Output]) (defaults to: undef)

    update where to send stdout

  • stderr (Optional[Systemd::Output]) (defaults to: undef)

    update where to send stderr

  • working_directory (Optional[Stdlib::Unixpath]) (defaults to: undef)

    Set the working directory

  • exec_start_pre (Optional[Systemd::Command]) (defaults to: undef)

    String with the command to be used as 'ExecStartPre' that will run at the beginning of each run.

  • after (Optional[String]) (defaults to: undef)

    String containing another service name used in 'After=' in the Systemd unit. Setting the value allows to run a timer job after another service.

  • group (Optional[String]) (defaults to: undef)

    The unix group to run the service unit as

  • path_exists (Optional[String]) (defaults to: undef)

    sets the ConditionPathExists value for the timer. If this path doesn't exist then the unit will fail. this parameter is intended to be used as a safety measure which prevents some disruptive action occurring if this folder doesn't exists

  • success_exit_statuses

    Sets an list of SuccessExitStatus, allowing non-zero exit codes to be treated as success. The statuses passed in this option will be used as well as a zero for success values.

  • team (Optional[Wmflib::Team]) (defaults to: undef)

    The team which owns this service

  • success_exit_status (Array[Integer[1, 255]]) (defaults to: [])


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'modules/systemd/manifests/timer/job.pp', line 108

define systemd::timer::job (
    Variant[
        Systemd::Timer::Schedule,
        Array[Systemd::Timer::Schedule, 1]] $interval,
    String                                  $description,
    Systemd::Command                        $command,
    String                                  $user,
    Wmflib::Ensure                          $ensure                    = 'present',
    Hash[String, String]                    $environment               = {},
    Boolean                                 $monitoring_enabled        = false,
    String                                  $monitoring_contact_groups = 'admins',
    Stdlib::HTTPSUrl                        $monitoring_notes_url      = 'https://wikitech.wikimedia.org/wiki/Monitoring/systemd_unit_state',
    Boolean                                 $logging_enabled           = true,
    String                                  $logfile_basedir           = '/var/log',
    String                                  $logfile_name              = 'syslog.log',
    String                                  $logfile_group             = 'root',
    Enum['user', 'group', 'all']            $logfile_perms             = 'all',
    Boolean                                 $syslog_force_stop         = true,
    Boolean                                 $syslog_match_startswith   = true,
    Boolean                                 $send_mail                 = false,
    String                                  $send_mail_to              = "root@${facts['networking']['fqdn']}",
    Boolean                                 $ignore_errors             = false,
    Boolean                                 $send_mail_only_on_error   = true,
    Boolean                                 $private_tmp               = false,
    Optional[Integer]                       $splay                     = undef,
    # TODO: set some sane default otherwise its infinite T324466
    Optional[Integer]                       $timeout_start_sec         = undef,
    Optional[String]                        $logfile_owner             = undef,
    Optional[String]                        $syslog_identifier         = undef,
    Optional[Integer]                       $max_runtime_seconds       = undef,
    Optional[Pattern[/\w+\.slice/]]         $slice                     = undef,
    Optional[Stdlib::Unixpath]              $environment_file          = undef,
    Optional[Systemd::Input]                $stdin                     = undef,
    Optional[Systemd::Output]               $stdout                    = undef,
    Optional[Systemd::Output]               $stderr                    = undef,
    Optional[Stdlib::Unixpath]              $working_directory         = undef,
    Optional[Systemd::Command]              $exec_start_pre            = undef,
    Optional[String]                        $after                     = undef,
    Optional[String]                        $group                     = undef,
    Optional[String]                        $path_exists               = undef,
    Array[Integer[1, 255]]                  $success_exit_status       = [],
    Optional[Wmflib::Team]                  $team                      = undef
) {

    unless $path_exists =~ Undef or $path_exists =~ Stdlib::UnixPath
            or ($path_exists[0] == '!' and $path_exists[1,-1] =~ Stdlib::UnixPath) {
        fail('$path_exists must either be Stdlib::UnixPath or Stdlib::UnixPath prefixed with `!`')
    }
    # Systemd doesn't play well with spaces in unit names, so check for that
    if $title =~ /\s/ {
        fail("Invalid title '${title}' for systemd timer - it should not include spaces.")
    }

    # Sanitize the title for use on the filesystem
    $safe_title = regsubst($title, '[^\w\-]', '_', 'G')

    $input_intervals = $interval ? {
        Systemd::Timer::Schedule => [$interval],
        default                  => $interval,
    }

    # If we were provided with only OnUnitActive/OnUnitInactive intervals, which are times relative
    # to when the service unit was last activated or deactivated, we need to add an additional
    # interval to get systemd to DTRT with this timer: an OnActiveSec that will start the service
    # for the first time after the timer and service are installed (or after a reboot).
    #
    # This activation gives meaning to the OnUnit intervals, as a null value for the timestamp of
    # last service activation/deactivation acts like NaN, making the comparison always false.
    $mangled_intervals = $input_intervals.all |$iv| { $iv['start'] =~ /OnUnit(In)?[Aa]ctive/ } ? {
        false => $input_intervals,
        true  => $input_intervals + [{
            'interval' => '1s',
            'start'    => 'OnActiveSec'
        }],
    }

    systemd::unit { "${title}.service":
        ensure  => $ensure,
        team    => $team,
        content => template('systemd/timer_service.erb'),
    }

    systemd::timer { $title:
        ensure          => $ensure,
        timer_intervals => $mangled_intervals,
        splay           => $splay,
        unit_name       => "${title}.service",
    }

    if $logging_enabled {
        # The owner of the log files
        $log_owner = $logfile_owner ? {
            undef   => $user,
            default => $logfile_owner
        }

        # If syslog_match_startswith is false, use equality when matching
        # the programname to output to the log file, else use startswith.
        $syslog_programname_comparison = $syslog_match_startswith ? {
            false => 'isequal',
            true  => 'startswith',
        }
        $syslog_title = $syslog_identifier ? {
            default => $syslog_identifier,
            undef   => $safe_title,
        }

        systemd::syslog { $syslog_title:
            ensure                 => $ensure,
            base_dir               => $logfile_basedir,
            log_filename           => $logfile_name,
            owner                  => $log_owner,
            group                  => $logfile_group,
            readable_by            => $logfile_perms,
            force_stop             => $syslog_force_stop,
            programname_comparison => $syslog_programname_comparison,
        }
    }

    if $monitoring_enabled {
        systemd::monitor { $title:
            ensure        => $ensure,
            notes_url     => $monitoring_notes_url,
            contact_group => $monitoring_contact_groups,
        }
    }
}