From ef6f964592cc553e8304a382ab44022f5a08db1f Mon Sep 17 00:00:00 2001
From: Thomas Bellman <bellman@lysator.liu.se>
Date: Mon, 4 Oct 2021 21:56:23 +0200
Subject: [PATCH] Forbid minus-prefixed option names in systemd::unit.

In systemd::unit_options, you can prefix an option name with a minus
sign (Unicode 002D "hyphen-minus") to "reset" a list option to the
empty list, so the new values don't just append to the existing list
of values.  That makes sense when overriding/supplementing options in
earlier unit files, but systemd::unit installs the "main" unit file,
the one that is read first, so list options *always* have the empty
list as their value when the file is read.

We here modify the unitfile.erb template file to see if it is called
from systemd::unit or systemd::unit_options, and if the former, it
raises an error if it encounters an option name starting with a minus
sign.  And of course also remove the paragraph describing that beha-
viour in the 'options' parameter documentation.
---
 manifests/unit.pp      |  5 -----
 templates/unitfile.erb | 10 +++++++++-
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/manifests/unit.pp b/manifests/unit.pp
index a4560d4..674df7a 100644
--- a/manifests/unit.pp
+++ b/manifests/unit.pp
@@ -35,11 +35,6 @@ define systemd::unit(
 	# support multi-value options, e.g. "ExecStart" in a service config,
 	# or "ListenStream" in a socket config.
 	#
-	# If the option name starts with a minus sign ("-"), an extra line
-	# setting that option to the empty string is prepended, in order to
-	# reset that option to the empty list, as systemd would otherwise
-	# just append the new value(s) to the existing list.
-	#
 	$options=undef,
 
 	# String to put in the unit file.  This is equivalent to the
diff --git a/templates/unitfile.erb b/templates/unitfile.erb
index c3b3221..5f704fb 100644
--- a/templates/unitfile.erb
+++ b/templates/unitfile.erb
@@ -13,9 +13,17 @@
 [<%= section_name %>]
 <%    section_options.sort.each do |optname,value| -%>
 <%       if optname =~ /^-(.*)/
-            optname = $1
+            if @systemd_resource_type == 'Unit_options'
+               optname = $1
 -%>
 <%= optname %>=
+<%          elsif @systemd_resource_type == 'Unit'
+               raise(Puppet::ParseError, "Bad option name, ``#{optname}''")
+            else
+               raise(Puppet::ParseError,
+                     'Internal error: $systemd_resource_type bad value')
+-%>
+<%          end -%>
 <%       end -%>
 <%       [value].flatten.each do |v| -%>
 <%= optname %>=<%= v %>
-- 
GitLab