From 8fc9d358b621c86b76231b62911448f29c3b2ca8 Mon Sep 17 00:00:00 2001 From: Greg Cox Date: Mon, 27 Nov 2023 21:24:02 +0000 Subject: [PATCH] Add some missing Unit options The puppet type for Systemd::Unit::Unit is missing a number of options allowed in the Unit section. This adds in ones that I was able to figure out tests for. There is more needed to fully match the man page, but this much I was able to do. --- REFERENCE.md | 21 ++++++- spec/type_aliases/systemd_unit_unit_spec.rb | 65 +++++++++++++++++++-- types/unit/unit.pp | 21 ++++++- 3 files changed, 100 insertions(+), 7 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index 3397e3a6..7ed830c5 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -2599,10 +2599,10 @@ Alias of Struct[{ Optional['Description'] => Variant[String,Array[String,1]], Optional['Documentation'] => Variant[String,Array[String,1]], - Optional['DefaultDependencies'] => Boolean, Optional['Wants'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['Requires'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['Requisite'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['BindsTo'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['PartOf'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['Upholds'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['Conflicts'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], @@ -2610,7 +2610,26 @@ Struct[{ Optional['After'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['OnFailure'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['OnSuccess'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['PropagatesReloadTo'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['ReloadPropagatedFrom'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['PropagatesStopTo'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['StopPropagatedFrom'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['JoinsNamespaceOf'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['RequiresMountsFor'] => Variant[Enum[''],Stdlib::Unixpath,Array[Variant[Enum[''],Stdlib::Unixpath],1]], + Optional['OnSuccessJobMode'] => Enum['fail', 'replace', 'replace-irreversibly', 'isolate', 'flush', 'ignore-dependencies', 'ignore-requirements'], + Optional['OnFailureJobMode'] => Enum['fail', 'replace', 'replace-irreversibly', 'isolate', 'flush', 'ignore-dependencies', 'ignore-requirements'], + Optional['IgnoreOnIsolate'] => Boolean, + Optional['StopWhenUnneeded'] => Boolean, + Optional['RefuseManualStart'] => Boolean, + Optional['RefuseManualStop'] => Boolean, + Optional['AllowIsolate'] => Boolean, + Optional['DefaultDependencies'] => Boolean, + Optional['SurviveFinalKillSignal'] => Boolean, + Optional['CollectMode'] => Enum['inactive', 'inactive-or-failed'], + Optional['FailureAction'] => Enum['none', 'reboot', 'reboot-force', 'reboot-immediate', 'poweroff', 'poweroff-force', 'poweroff-immediate', 'exit', 'exit-force', 'soft-reboot', 'soft-reboot-force', 'kexec', 'kexec-force', 'halt', 'halt-force', 'halt-immediate'], + Optional['SuccessAction'] => Enum['none', 'reboot', 'reboot-force', 'reboot-immediate', 'poweroff', 'poweroff-force', 'poweroff-immediate', 'exit', 'exit-force', 'soft-reboot', 'soft-reboot-force', 'kexec', 'kexec-force', 'halt', 'halt-force', 'halt-immediate'], + Optional['FailureActionExitStatus'] => Variant[Enum[''],Integer[0, 255]], + Optional['SuccessActionExitStatus'] => Variant[Enum[''],Integer[0, 255]], # Conditions and Asserts Optional['ConditionPathExists'] => Variant[Enum[''],Stdlib::Unixpath,Pattern[/^!.*$/],Array[Variant[Enum[''],Stdlib::Unixpath,Pattern[/^!.*$/]],1]], Optional['ConditionPathIsDirectory'] => Variant[Enum[''],Stdlib::Unixpath,Pattern[/^!.*$/],Array[Variant[Enum[''],Stdlib::Unixpath,Pattern[/^!.*$/]],1]], diff --git a/spec/type_aliases/systemd_unit_unit_spec.rb b/spec/type_aliases/systemd_unit_unit_spec.rb index 093be636..19e23b9a 100644 --- a/spec/type_aliases/systemd_unit_unit_spec.rb +++ b/spec/type_aliases/systemd_unit_unit_spec.rb @@ -15,7 +15,7 @@ it { is_expected.to allow_value({ 'Documentation' => %w[my special] }) } it { is_expected.to allow_value({ 'Documentation' => ['', 'special'] }) } - %w[Wants Requires Requisite Wants PartOf Upholds Conflicts Before After OnFailure OnSuccess].each do |depend| + %w[Wants Requires Requisite BindsTo Wants PartOf Upholds Conflicts Before After OnFailure OnSuccess PropagatesReloadTo ReloadPropagatedFrom PropagatesStopTo StopPropagatedFrom JoinsNamespaceOf].each do |depend| context "with a key of #{depend} can have values of units" do it { is_expected.to allow_value({ depend.to_s => 'foobar.service' }) } it { is_expected.to allow_value({ depend.to_s => ['foobar.service'] }) } @@ -26,6 +26,58 @@ end end + # JobModes + %w[OnSuccessJobMode OnFailureJobMode].each do |assert| + context "with a key of #{assert} can have appropriate values" do + it { is_expected.to allow_value({ assert.to_s => 'fail' }) } + it { is_expected.to allow_value({ assert.to_s => 'replace' }) } + it { is_expected.to allow_value({ assert.to_s => 'replace-irreversibly' }) } + it { is_expected.to allow_value({ assert.to_s => 'isolate' }) } + it { is_expected.to allow_value({ assert.to_s => 'flush' }) } + it { is_expected.to allow_value({ assert.to_s => 'ignore-dependencies' }) } + it { is_expected.to allow_value({ assert.to_s => 'ignore-requirements' }) } + it { is_expected.not_to allow_value({ assert.to_s => '' }) } + it { is_expected.not_to allow_value({ assert.to_s => 'some-other-mode' }) } + end + end + + # Actions + %w[FailureAction SuccessAction].each do |assert| + context "with a key of #{assert} can have appropriate values" do + it { is_expected.to allow_value({ assert.to_s => 'none' }) } + it { is_expected.to allow_value({ assert.to_s => 'reboot' }) } + it { is_expected.to allow_value({ assert.to_s => 'reboot-force' }) } + it { is_expected.to allow_value({ assert.to_s => 'reboot-immediate' }) } + it { is_expected.to allow_value({ assert.to_s => 'poweroff' }) } + it { is_expected.to allow_value({ assert.to_s => 'poweroff-force' }) } + it { is_expected.to allow_value({ assert.to_s => 'poweroff-immediate' }) } + it { is_expected.to allow_value({ assert.to_s => 'exit' }) } + it { is_expected.to allow_value({ assert.to_s => 'exit-force' }) } + it { is_expected.to allow_value({ assert.to_s => 'soft-reboot' }) } + it { is_expected.to allow_value({ assert.to_s => 'soft-reboot-force' }) } + it { is_expected.to allow_value({ assert.to_s => 'kexec' }) } + it { is_expected.to allow_value({ assert.to_s => 'kexec-force' }) } + it { is_expected.to allow_value({ assert.to_s => 'halt' }) } + it { is_expected.to allow_value({ assert.to_s => 'halt-force' }) } + it { is_expected.to allow_value({ assert.to_s => 'halt-immediate' }) } + it { is_expected.not_to allow_value({ assert.to_s => '' }) } + it { is_expected.not_to allow_value({ assert.to_s => 'another-action' }) } + end + end + + # ExitStatus + %w[FailureActionExitStatus SuccessActionExitStatus].each do |assert| + context "with a key of #{assert} can have appropriate values" do + it { is_expected.to allow_value({ assert.to_s => '' }) } + it { is_expected.to allow_value({ assert.to_s => 0 }) } + it { is_expected.to allow_value({ assert.to_s => 128 }) } + it { is_expected.to allow_value({ assert.to_s => 255 }) } + it { is_expected.not_to allow_value({ assert.to_s => -1 }) } + it { is_expected.not_to allow_value({ assert.to_s => 256 }) } + it { is_expected.not_to allow_value({ assert.to_s => '1' }) } + end + end + %w[ConditionPathExists ConditionPathIsDirectory AssertPathExists AssertPathIsDirectory].each do |assert| context "with a key of #{assert} can have files or negated files" do it { is_expected.to allow_value({ assert.to_s => '/my/existing/file' }) } @@ -36,15 +88,14 @@ end # Booleans - %w[DefaultDependencies].each do |assert| + %w[DefaultDependencies IgnoreOnIsolate StopWhenUnneeded RefuseManualStart RefuseManualStop AllowIsolate SurviveFinalKillSignal].each do |assert| context "with a key of #{assert} can have values set to true" do - it { is_expected.to allow_value(assert.to_s => true) } + it { is_expected.to allow_value({ assert.to_s => true }) } it { is_expected.to allow_value({ assert.to_s => false }) } + it { is_expected.not_to allow_value({ assert.to_s => 'yes' }) } end end - it { is_expected.not_to allow_value({ 'DefaultDependencies' => 'yes' }) } - it { is_expected.not_to allow_value({ 'Description' => 10 }) } it { is_expected.not_to allow_value({ 'Wants' => '/unitwith.service' }) } @@ -53,6 +104,10 @@ it { is_expected.not_to allow_value({ 'ConditionPathExists' => 'not/an/absolute/path' }) } it { is_expected.not_to allow_value({ 'ConditionPathExists' => ['not/an/absolute/path'] }) } + it { is_expected.to allow_value({ 'CollectMode' => 'inactive' }) } + it { is_expected.to allow_value({ 'CollectMode' => 'inactive-or-failed' }) } + it { is_expected.not_to allow_value({ 'CollectMode' => 'active' }) } + it { is_expected.to allow_value({ 'RequiresMountsFor' => '/an/absolute/path' }) } it { is_expected.to allow_value({ 'RequiresMountsFor' => '' }) } it { is_expected.to allow_value({ 'RequiresMountsFor' => ['', '/an/absolute/path'] }) } diff --git a/types/unit/unit.pp b/types/unit/unit.pp index dd9c6b04..35f77886 100644 --- a/types/unit/unit.pp +++ b/types/unit/unit.pp @@ -5,10 +5,10 @@ { Optional['Description'] => Variant[String,Array[String,1]], Optional['Documentation'] => Variant[String,Array[String,1]], - Optional['DefaultDependencies'] => Boolean, Optional['Wants'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['Requires'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['Requisite'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['BindsTo'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['PartOf'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['Upholds'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['Conflicts'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], @@ -16,7 +16,26 @@ Optional['After'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['OnFailure'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['OnSuccess'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['PropagatesReloadTo'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['ReloadPropagatedFrom'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['PropagatesStopTo'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['StopPropagatedFrom'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], + Optional['JoinsNamespaceOf'] => Variant[Enum[''],Systemd::Unit,Array[Variant[Enum[''],Systemd::Unit],1]], Optional['RequiresMountsFor'] => Variant[Enum[''],Stdlib::Unixpath,Array[Variant[Enum[''],Stdlib::Unixpath],1]], + Optional['OnSuccessJobMode'] => Enum['fail', 'replace', 'replace-irreversibly', 'isolate', 'flush', 'ignore-dependencies', 'ignore-requirements'], + Optional['OnFailureJobMode'] => Enum['fail', 'replace', 'replace-irreversibly', 'isolate', 'flush', 'ignore-dependencies', 'ignore-requirements'], + Optional['IgnoreOnIsolate'] => Boolean, + Optional['StopWhenUnneeded'] => Boolean, + Optional['RefuseManualStart'] => Boolean, + Optional['RefuseManualStop'] => Boolean, + Optional['AllowIsolate'] => Boolean, + Optional['DefaultDependencies'] => Boolean, + Optional['SurviveFinalKillSignal'] => Boolean, + Optional['CollectMode'] => Enum['inactive', 'inactive-or-failed'], + Optional['FailureAction'] => Enum['none', 'reboot', 'reboot-force', 'reboot-immediate', 'poweroff', 'poweroff-force', 'poweroff-immediate', 'exit', 'exit-force', 'soft-reboot', 'soft-reboot-force', 'kexec', 'kexec-force', 'halt', 'halt-force', 'halt-immediate'], + Optional['SuccessAction'] => Enum['none', 'reboot', 'reboot-force', 'reboot-immediate', 'poweroff', 'poweroff-force', 'poweroff-immediate', 'exit', 'exit-force', 'soft-reboot', 'soft-reboot-force', 'kexec', 'kexec-force', 'halt', 'halt-force', 'halt-immediate'], + Optional['FailureActionExitStatus'] => Variant[Enum[''],Integer[0, 255]], + Optional['SuccessActionExitStatus'] => Variant[Enum[''],Integer[0, 255]], # Conditions and Asserts Optional['ConditionPathExists'] => Variant[Enum[''],Stdlib::Unixpath,Pattern[/^!.*$/],Array[Variant[Enum[''],Stdlib::Unixpath,Pattern[/^!.*$/]],1]], Optional['ConditionPathIsDirectory'] => Variant[Enum[''],Stdlib::Unixpath,Pattern[/^!.*$/],Array[Variant[Enum[''],Stdlib::Unixpath,Pattern[/^!.*$/]],1]],