diff --git a/REFERENCE.md b/REFERENCE.md
index 43cf9f0f..89841e9b 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -87,6 +87,7 @@
* [`Systemd::Unit::Service::Exec`](#Systemd--Unit--Service--Exec): Possible strings for ExecStart, ExecStartPrep, ...
* [`Systemd::Unit::Slice`](#Systemd--Unit--Slice): Possible keys for the [Slice] section of a unit file
* [`Systemd::Unit::Socket`](#Systemd--Unit--Socket): Possible keys for the [Socket] section of a unit file
+* [`Systemd::Unit::Swap`](#Systemd--Unit--Swap): Possible keys for the [Swap] section of a unit file
* [`Systemd::Unit::Timer`](#Systemd--Unit--Timer): Possible keys for the [Timer] section of a unit file
* [`Systemd::Unit::Timespan`](#Systemd--Unit--Timespan): Timer specification for systemd time spans, e.g. timers.
* [`Systemd::Unit::Unit`](#Systemd--Unit--Unit): Possible keys for the [Unit] section of a unit file
@@ -1125,6 +1126,7 @@ The following parameters are available in the `systemd::manage_dropin` defined t
* [`path_entry`](#-systemd--manage_dropin--path_entry)
* [`socket_entry`](#-systemd--manage_dropin--socket_entry)
* [`mount_entry`](#-systemd--manage_dropin--mount_entry)
+* [`swap_entry`](#-systemd--manage_dropin--swap_entry)
##### `unit`
@@ -1276,6 +1278,14 @@ key value pairs for the [Mount] section of the unit file
Default value: `undef`
+##### `swap_entry`
+
+Data type: `Optional[Systemd::Unit::Swap]`
+
+key value pairs for the [Swap] section of the unit file
+
+Default value: `undef`
+
### `systemd::manage_unit`
Generate unit file from template
@@ -1377,6 +1387,43 @@ systemd::manage_dropin { 'tmpfs-db.conf':
}
```
+##### Create and Mound a Swap File
+
+```puppet
+
+systemd::manage_unit{'swapfile.swap':
+ ensure => present,
+ enable => true,
+ active => true,
+ unit_entry => {
+ 'Description' => 'Mount /swapfile as a swap file',
+ 'After' => 'mkswap.service',
+ 'Requires' => 'mkswap.service',
+ },
+ swap_entry => {
+ 'What' => '/swapfile',
+ },
+ install_entry => {
+ 'WantedBy' => 'multi-user.target',
+ },
+ require => Systemd::Manage_unit['mkswap.service'],
+}
+systemd::manage_unit{'mkswap.service':
+ ensure => present,
+ unit_entry => {
+ 'Description' => 'Format a swapfile at /swapfile',
+ 'ConditionPathExists' => '!/swapfile',
+ },
+ service_entry => {
+ 'type' => 'oneshot',
+ 'ExecStart' => [
+ '/usr/bin/dd if=/dev/zero of=/swapfile bs=1024 count=1000',
+ '/usr/sbin/mkswap /swapfile',
+ ],
+ },
+}
+```
+
##### Remove a unit file
```puppet
@@ -1411,6 +1458,7 @@ The following parameters are available in the `systemd::manage_unit` defined typ
* [`path_entry`](#-systemd--manage_unit--path_entry)
* [`socket_entry`](#-systemd--manage_unit--socket_entry)
* [`mount_entry`](#-systemd--manage_unit--mount_entry)
+* [`swap_entry`](#-systemd--manage_unit--swap_entry)
##### `name`
@@ -1586,6 +1634,14 @@ kev value pairs for [Mount] section of the unit file.
Default value: `undef`
+##### `swap_entry`
+
+Data type: `Optional[Systemd::Unit::Swap]`
+
+kev value pairs for [Swap] section of the unit file.
+
+Default value: `undef`
+
### `systemd::modules_load`
Creates a modules-load.d drop file
@@ -3435,6 +3491,24 @@ Struct[{
}]
```
+### `Systemd::Unit::Swap`
+
+Possible keys for the [Swap] section of a unit file
+
+* **See also**
+ * https://www.freedesktop.org/software/systemd/man/latest/systemd.swap.html
+
+Alias of
+
+```puppet
+Struct[{
+ Optional['What'] => String[1],
+ Optional['Options'] => String[1],
+ Optional['Priority'] => Integer,
+ Optional['TimeoutSec'] => Variant[Integer[0],String[0]]
+ }]
+```
+
### `Systemd::Unit::Timer`
Possible keys for the [Timer] section of a unit file
diff --git a/manifests/manage_dropin.pp b/manifests/manage_dropin.pp
index 8df9da9c..a5f7d0bb 100644
--- a/manifests/manage_dropin.pp
+++ b/manifests/manage_dropin.pp
@@ -89,6 +89,7 @@
# @param path_entry key value pairs for [Path] section of the unit file
# @param socket_entry key value pairs for the [Socket] section of the unit file
# @param mount_entry key value pairs for the [Mount] section of the unit file
+# @param swap_entry key value pairs for the [Swap] section of the unit file
#
define systemd::manage_dropin (
Systemd::Unit $unit,
@@ -110,6 +111,7 @@
Optional[Systemd::Unit::Path] $path_entry = undef,
Optional[Systemd::Unit::Socket] $socket_entry = undef,
Optional[Systemd::Unit::Mount] $mount_entry = undef,
+ Optional[Systemd::Unit::Swap] $swap_entry = undef,
) {
if $timer_entry and $unit !~ Pattern['^[^/]+\.timer'] {
fail("Systemd::Manage_dropin[${name}]: for unit ${unit} timer_entry is only valid for timer units")
@@ -131,6 +133,10 @@
fail("Systemd::Manage_dropin[${name}]: for unit ${unit} mount_entry is only valid for mount units")
}
+ if $swap_entry and $unit !~ Pattern['^[^/]+\.swap'] {
+ fail("Systemd::Manage_dropin[${name}]: for unit ${unit} mount_entry is only valid for swap units")
+ }
+
systemd::dropin_file { $name:
ensure => $ensure,
filename => $filename,
@@ -152,6 +158,7 @@
'path_entry' => $path_entry,
'socket_entry' => $socket_entry,
'mount_entry' => $mount_entry,
+ 'swap_entry' => $swap_entry,
}),
}
}
diff --git a/manifests/manage_unit.pp b/manifests/manage_unit.pp
index c406a5ca..b9177f37 100644
--- a/manifests/manage_unit.pp
+++ b/manifests/manage_unit.pp
@@ -84,6 +84,40 @@
# },
# }
#
+# @example Create and Mound a Swap File
+#
+# systemd::manage_unit{'swapfile.swap':
+# ensure => present,
+# enable => true,
+# active => true,
+# unit_entry => {
+# 'Description' => 'Mount /swapfile as a swap file',
+# 'After' => 'mkswap.service',
+# 'Requires' => 'mkswap.service',
+# },
+# swap_entry => {
+# 'What' => '/swapfile',
+# },
+# install_entry => {
+# 'WantedBy' => 'multi-user.target',
+# },
+# require => Systemd::Manage_unit['mkswap.service'],
+# }
+# systemd::manage_unit{'mkswap.service':
+# ensure => present,
+# unit_entry => {
+# 'Description' => 'Format a swapfile at /swapfile',
+# 'ConditionPathExists' => '!/swapfile',
+# },
+# service_entry => {
+# 'type' => 'oneshot',
+# 'ExecStart' => [
+# '/usr/bin/dd if=/dev/zero of=/swapfile bs=1024 count=1000',
+# '/usr/sbin/mkswap /swapfile',
+# ],
+# },
+# }
+#
# @example Remove a unit file
# systemd::manage_unit { 'my.service':
# ensure => 'absent',
@@ -118,6 +152,7 @@
# @param path_entry key value pairs for [Path] section of the unit file.
# @param socket_entry kev value paors for [Socket] section of the unit file.
# @param mount_entry kev value pairs for [Mount] section of the unit file.
+# @param swap_entry kev value pairs for [Swap] section of the unit file.
#
define systemd::manage_unit (
Enum['present', 'absent'] $ensure = 'present',
@@ -141,6 +176,7 @@
Optional[Systemd::Unit::Path] $path_entry = undef,
Optional[Systemd::Unit::Socket] $socket_entry = undef,
Optional[Systemd::Unit::Mount] $mount_entry = undef,
+ Optional[Systemd::Unit::Swap] $swap_entry = undef,
) {
assert_type(Systemd::Unit, $name)
@@ -164,6 +200,10 @@
fail("Systemd::Manage_unit[${name}]: mount_entry is only valid for mount units")
}
+ if $swap_entry and $name !~ Pattern['^[^/]+\.swap'] {
+ fail("Systemd::Manage_unit[${name}]: swap_entry is only valid for swap units")
+ }
+
if $ensure != 'absent' and $name =~ Pattern['^[^/]+\.service'] and !$service_entry {
fail("Systemd::Manage_unit[${name}]: service_entry is required for service units")
}
@@ -190,6 +230,7 @@
'path_entry' => $path_entry,
'socket_entry' => $socket_entry,
'mount_entry' => $mount_entry,
+ 'swap_entry' => $swap_entry,
}),
}
}
diff --git a/spec/defines/manage_dropin_spec.rb b/spec/defines/manage_dropin_spec.rb
index 08ff4791..a6d5c5bc 100644
--- a/spec/defines/manage_dropin_spec.rb
+++ b/spec/defines/manage_dropin_spec.rb
@@ -134,6 +134,26 @@
end
end
+ context 'on a swap unit' do
+ let(:params) do
+ {
+ unit: 'file.swap',
+ swap_entry: {
+ 'Priority' => 10,
+ }
+ }
+ end
+
+ it { is_expected.to compile.with_all_deps }
+
+ it {
+ is_expected.to contain_systemd__dropin_file('foobar.conf').
+ with_unit('file.swap').
+ with_content(%r{^\[Swap\]$}).
+ with_content(%r{^Priority=10$})
+ }
+ end
+
context 'on a timer' do
let(:params) do
{
diff --git a/spec/defines/manage_unit_spec.rb b/spec/defines/manage_unit_spec.rb
index 0e283030..003e0acc 100644
--- a/spec/defines/manage_unit_spec.rb
+++ b/spec/defines/manage_unit_spec.rb
@@ -127,6 +127,35 @@
}
end
+ context 'on a swap' do
+ let(:title) { 'file.swap' }
+
+ let(:params) do
+ {
+ unit_entry: {
+ Description: 'Add swap from a file',
+ },
+ swap_entry: {
+ 'What' => '/file',
+ 'TimeoutSec' => 100,
+ 'Options' => 'trim',
+ 'Priority' => 10,
+ },
+ }
+ end
+
+ it { is_expected.to compile.with_all_deps }
+
+ it {
+ is_expected.to contain_systemd__unit_file('file.swap').
+ with_content(%r{^\[Swap\]$}).
+ with_content(%r{^What=/file$}).
+ with_content(%r{^TimeoutSec=100$}).
+ with_content(%r{^Options=trim$}).
+ with_content(%r{^Priority=10$})
+ }
+ end
+
context 'on a timer' do
let(:title) { 'winter.timer' }
diff --git a/spec/type_aliases/systemd_unit_swap_spec.rb b/spec/type_aliases/systemd_unit_swap_spec.rb
new file mode 100644
index 00000000..626d1a52
--- /dev/null
+++ b/spec/type_aliases/systemd_unit_swap_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Systemd::Unit::Swap' do
+ context 'with a key of What can have thing to mount' do
+ it { is_expected.to allow_value({ 'What' => '/tmpfs' }) }
+ it { is_expected.to allow_value({ 'What' => '/dev/vda1' }) }
+ end
+
+ context 'with a key of Options' do
+ it { is_expected.to allow_value({ 'Options' => 'trim' }) }
+ end
+
+ context 'with a key of Priority' do
+ it { is_expected.to allow_value({ 'Priority' => 10 }) }
+ end
+
+ context 'with a key of TimeoutSec can have a mode of' do
+ it { is_expected.to allow_value({ 'TimeoutSec' => '100' }) }
+ it { is_expected.to allow_value({ 'TimeoutSec' => '5min 20s' }) }
+ it { is_expected.to allow_value({ 'TimeoutSec' => '' }) }
+ end
+
+ context 'with a key of Where' do
+ it { is_expected.not_to allow_value({ 'Where' => '/mnt/foo' }) }
+ end
+end
diff --git a/templates/unit_file.epp b/templates/unit_file.epp
index 59cfa7ec..2d3a7803 100644
--- a/templates/unit_file.epp
+++ b/templates/unit_file.epp
@@ -7,6 +7,7 @@
Optional[Hash] $path_entry,
Optional[Hash] $socket_entry,
Optional[Hash] $mount_entry,
+ Optional[Hash] $swap_entry,
| -%>
<%-
@@ -22,6 +23,7 @@
'Socket',
'Install',
'Mount',
+ 'Swap',
]
# Directives which are pair of items to be expressed as a space seperated pair.
diff --git a/types/unit/swap.pp b/types/unit/swap.pp
new file mode 100644
index 00000000..03106911
--- /dev/null
+++ b/types/unit/swap.pp
@@ -0,0 +1,11 @@
+# @summary Possible keys for the [Swap] section of a unit file
+# @see https://www.freedesktop.org/software/systemd/man/latest/systemd.swap.html
+#
+type Systemd::Unit::Swap = Struct[
+ {
+ Optional['What'] => String[1],
+ Optional['Options'] => String[1],
+ Optional['Priority'] => Integer,
+ Optional['TimeoutSec'] => Variant[Integer[0],String[0]]
+ }
+]