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

Correct typing for IOReadIOPSMax, IOWriteIOPSMax,... in systemd::manage_dropin #430

Merged
merged 1 commit into from
Mar 11, 2024
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
34 changes: 24 additions & 10 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,20 @@ systemd::manage_dropin { 'userlimits.conf':
}
```

##### set IO limits on two devices

```puppet
systemd::manage_dropin { 'devicelimits.conf':
unit => 'special.service',
service_entry => {
'IOReadIOPSMax' => [
['/dev/afs',100],
['/dev/gluster','1000K'],
],
},
}
```

#### Parameters

The following parameters are available in the `systemd::manage_dropin` defined type:
Expand Down Expand Up @@ -2649,11 +2663,11 @@ Struct[{
Optional['IOAccounting'] => Boolean,
Optional['IOWeight'] => Integer[1,10000],
Optional['StartupIOWeight'] => Integer[1,10000],
Optional['IODeviceWeight'] => Array[Hash[Stdlib::Absolutepath, Integer[1,10000], 1, 1]],
Optional['IOReadBandwidthMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount, 1, 1]],
Optional['IOWriteBandwidthMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount, 1, 1]],
Optional['IOReadIOPSMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount, 1, 1]],
Optional['IOWriteIOPSMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount, 1, 1]],
Optional['IODeviceWeight'] => Variant[Tuple[Stdlib::Absolutepath, Integer[1,10000]],Array[Tuple[Stdlib::Absolutepath, Integer[1,10000]]]],
Optional['IOReadBandwidthMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOWriteBandwidthMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOReadIOPSMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOWriteIOPSMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['DeviceAllow'] => String[1],
Optional['DevicePolicy'] => Enum['auto','closed','strict'],
Optional['Slice'] => String[1],
Expand Down Expand Up @@ -2748,12 +2762,12 @@ Struct[{
Optional['DeviceAllow'] => Pattern['^(/dev/)|(char-)|(block-).*$'],
Optional['DevicePolicy'] => Enum['auto','closed','strict'],
Optional['IOAccounting'] => Boolean,
Optional['IODeviceWeight'] => Array[Hash[Stdlib::Absolutepath, Integer[1,10000], 1, 1]],
Optional['IOReadBandwidthMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount], 1, 1],
Optional['IOReadIOPSMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount], 1, 1],
Optional['IODeviceWeight'] => Variant[Tuple[Stdlib::Absolutepath, Integer[1,10000]],Array[Tuple[Stdlib::Absolutepath, Integer[1,10000]]]],
Optional['IOReadBandwidthMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOReadIOPSMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOWeight'] => Integer[1,10000],
Optional['IOWriteBandwidthMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount], 1, 1],
Optional['IOWriteIOPSMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount], 1, 1],
Optional['IOWriteBandwidthMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOWriteIOPSMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IPAccounting'] => Boolean,
Optional['MemoryAccounting'] => Boolean,
Optional['MemoryHigh'] => Systemd::Unit::AmountOrPercent,
Expand Down
11 changes: 11 additions & 0 deletions manifests/manage_dropin.pp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@
# }
# }
#
# @example set IO limits on two devices
# systemd::manage_dropin { 'devicelimits.conf':
# unit => 'special.service',
# service_entry => {
# 'IOReadIOPSMax' => [
# ['/dev/afs',100],
# ['/dev/gluster','1000K'],
# ],
# },
# }
#
# @param unit The unit to create a dropfile for
# @param filename The target unit file to create. The filename of the drop in. The full path is determined using the path, unit and this filename.
# @param ensure The state of this dropin file
Expand Down
36 changes: 35 additions & 1 deletion spec/defines/manage_dropin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@
it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_systemd__dropin_file('foobar.conf').with_content(%r{^# Deployed with puppet$}) }

context 'with empty sections' do
let(:params) do
super().merge(
unit_entry: {},
service_entry: {}
)
end

it { is_expected.to compile.with_all_deps }

it {
is_expected.to contain_systemd__dropin_file('foobar.conf').
with_content(%r{^\[Unit\]$}).
with_content(%r{^\[Service\]$}).
without_content(%r{^\[Slice\]$})
}
end

context 'setting some parameters simply' do
let(:params) do
super().merge(
Expand All @@ -29,6 +47,12 @@
service_entry: {
SyslogIdentifier: 'simple',
LimitCORE: 'infinity',
IODeviceWeight:
[
['/dev/weight', 10],
['/dev/weight2', 20],
],
IOReadBandwidthMax: ['/dev/weight3', '50K'],
}
)
end
Expand All @@ -38,6 +62,9 @@
with_content(%r{^LimitCORE=infinity$}).
with_content(%r{^DefaultDependencies=true$}).
with_content(%r{^SyslogIdentifier=simple$}).
with_content(%r{^IODeviceWeight=/dev/weight 10$}).
with_content(%r{^IODeviceWeight=/dev/weight2 20$}).
with_content(%r{^IOReadBandwidthMax=/dev/weight3 50K$}).
without_content(%r{^\[Slice\]$})
}
end
Expand Down Expand Up @@ -133,6 +160,10 @@
slice_entry: {
'MemoryMax' => '10G',
'MemoryAccounting' => true,
'IOWriteBandwidthMax' => [
['/dev/afs', '50P'],
['/dev/gluster', 50],
]
}
}
end
Expand All @@ -142,8 +173,11 @@
it {
is_expected.to contain_systemd__dropin_file('foobar.conf').
with_unit('user-.slice').
with_content(%r{^IOWriteBandwidthMax=/dev/afs 50P$}).
with_content(%r{^IOWriteBandwidthMax=/dev/gluster 50$}).
with_content(%r{^MemoryMax=10G$}).
with_content(%r{^MemoryAccounting=true$})
with_content(%r{^MemoryAccounting=true$}).
without_content(%r{^\[Service\]$})
}
end

Expand Down
15 changes: 12 additions & 3 deletions spec/defines/manage_unit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
Type: 'oneshot',
ExecStart: '/usr/bin/doit.sh',
SyslogIdentifier: 'doit-backwards.sh',
Environment: ['bla=foo', 'foo=bla']
Environment: ['bla=foo', 'foo=bla'],
IOReadIOPSMax: ['/dev/afs', '1K'],
},
install_entry: {
WantedBy: 'multi-user.target',
Expand All @@ -43,6 +44,7 @@
with_content(%r{^Description=My great service$}).
with_content(%r{^Description=has two lines of description$}).
with_content(%r{^Type=oneshot$}).
with_content(%r{^IOReadIOPSMax=/dev/afs 1K$}).
without_content(%r{^\[Slice\]$})
}

Expand Down Expand Up @@ -180,7 +182,11 @@
slice_entry: {
'MemoryMax' => '10G',
'IOAccounting' => true,
}
'IOWriteIOPSMax' => [
['/dev/gluster', 20],
['/dev/afs', '50K'],
],
},
}
end

Expand All @@ -190,7 +196,10 @@
is_expected.to contain_systemd__unit_file('myslice.slice').
with_content(%r{^\[Slice\]$}).
with_content(%r{^MemoryMax=10G$}).
with_content(%r{^IOAccounting=true$})
with_content(%r{^IOAccounting=true$}).
with_content(%r{^IOWriteIOPSMax=/dev/gluster 20$}).
with_content(%r{^IOWriteIOPSMax=/dev/afs 50K$}).
without_content(%r{^\[Service\]$})
}
end

Expand Down
17 changes: 17 additions & 0 deletions spec/type_aliases/systemd_unit_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,21 @@
it { is_expected.not_to allow_value({ 'CPUQuota' => 50 }) }
it { is_expected.not_to allow_value({ 'CPUQuota' => '0%' }) }
it { is_expected.not_to allow_value({ 'MemoryHigh' => '1Y' }) }

it { is_expected.to allow_value({ 'IODeviceWeight' => ['/dev/afs', 1000] }) }
it { is_expected.to allow_value({ 'IODeviceWeight' => [['/dev/afs', 1000], ['/dev/gluster', 10]] }) }
it { is_expected.not_to allow_value({ 'IODeviceWeight' => ['/dev/afs', 10_001] }) }
it { is_expected.not_to allow_value({ 'IODeviceWeight' => ['absolute/path', 10_001] }) }
it { is_expected.not_to allow_value({ 'IODeviceWeight' => '/dev/afs 1000' }) }

%w[IOReadBandwidthMax IOWriteBandwidthMax IOWriteIOPSMax IOWriteIOPSMax].each do |device_size|
context "with a key of #{device_size} can have a typle and size" do
it {
is_expected.to allow_value({ device_size => ['/dev/afs', 1000] })
is_expected.to allow_value({ device_size => [['/dev/afs', 1000], ['/dev/gluster', '12G']] })
is_expected.not_to allow_value({ device_size => '/dev/afs 1000' })
is_expected.not_to allow_value({ device_size => [['absolute/path', 1000], ['/dev/gluster', '12G']] })
}
end
end
end
36 changes: 31 additions & 5 deletions templates/unit_file.epp
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,47 @@
'Install',
]

# Directives which are pair of items to be expressed as a space seperated pair.
$_tupled_values = [
'IODeviceWeight',
'IOReadBandwidthMax',
'IOWriteBandwidthMax',
'IOReadIOPSMax',
'IOWriteIOPSMax',
]

-%>
# Deployed with puppet
#
<%-
$_unit_sections.each | $_section | {
$_values = getvar("${downcase($_section)}_entry")
if $_values {
-%>
-%>

[<%= $_section %>]
<%-
$_values.each | $_key, $_value | {
Array($_value, true).each | $_subvalue | { -%>
<%-

# De-tuple the tupled values to space seperation
$_myvalues = $_values.map | $_key, $_value | {
if $_key in $_tupled_values {
if $_value =~ Array[Tuple[String[1],Variant[Integer,String[1]]]] {
{ $_key => $_value.map | $_inner_value | { "${_inner_value[0]} ${_inner_value[1]}" } }
} else {
{$_key => "${_value[0]} ${_value[1]}"}
}
} else {
{$_key => $_value}
}
}.reduce | $_memo, $_value | { $_memo + $_value }

if $_myvalues {
$_myvalues.each | $_key, $_value | {
Array($_value, true).each | $_subvalue | {
-%>
<%= $_key %>=<%= $_subvalue %>
<%-
<%-
}
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions types/unit/service.pp
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@
Optional['IOAccounting'] => Boolean,
Optional['IOWeight'] => Integer[1,10000],
Optional['StartupIOWeight'] => Integer[1,10000],
Optional['IODeviceWeight'] => Array[Hash[Stdlib::Absolutepath, Integer[1,10000], 1, 1]],
Optional['IOReadBandwidthMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount, 1, 1]],
Optional['IOWriteBandwidthMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount, 1, 1]],
Optional['IOReadIOPSMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount, 1, 1]],
Optional['IOWriteIOPSMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount, 1, 1]],
Optional['IODeviceWeight'] => Variant[Tuple[Stdlib::Absolutepath, Integer[1,10000]],Array[Tuple[Stdlib::Absolutepath, Integer[1,10000]]]],
Optional['IOReadBandwidthMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOWriteBandwidthMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOReadIOPSMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOWriteIOPSMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['DeviceAllow'] => String[1],
Optional['DevicePolicy'] => Enum['auto','closed','strict'],
Optional['Slice'] => String[1],
Expand Down
10 changes: 5 additions & 5 deletions types/unit/slice.pp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
Optional['DeviceAllow'] => Pattern['^(/dev/)|(char-)|(block-).*$'],
Optional['DevicePolicy'] => Enum['auto','closed','strict'],
Optional['IOAccounting'] => Boolean,
Optional['IODeviceWeight'] => Array[Hash[Stdlib::Absolutepath, Integer[1,10000], 1, 1]],
Optional['IOReadBandwidthMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount], 1, 1],
Optional['IOReadIOPSMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount], 1, 1],
Optional['IODeviceWeight'] => Variant[Tuple[Stdlib::Absolutepath, Integer[1,10000]],Array[Tuple[Stdlib::Absolutepath, Integer[1,10000]]]],
Optional['IOReadBandwidthMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOReadIOPSMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOWeight'] => Integer[1,10000],
Optional['IOWriteBandwidthMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount], 1, 1],
Optional['IOWriteIOPSMax'] => Array[Hash[Stdlib::Absolutepath, Systemd::Unit::Amount], 1, 1],
Optional['IOWriteBandwidthMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IOWriteIOPSMax'] => Variant[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount],Array[Tuple[Stdlib::Absolutepath, Systemd::Unit::Amount]]],
Optional['IPAccounting'] => Boolean,
Optional['MemoryAccounting'] => Boolean,
Optional['MemoryHigh'] => Systemd::Unit::AmountOrPercent,
Expand Down