From 5612a195ef34d130800a955bf6380c41e5c10977 Mon Sep 17 00:00:00 2001 From: Mason Malone <651224+MasonM@users.noreply.github.com> Date: Sat, 7 Dec 2024 17:25:42 -0800 Subject: [PATCH 1/2] fix parsing of backslash at end of line If you have an option with a line ending with a backslash that's on the last line of the file (or preceeding the last line when it's a comment or empty space), then the option isn't added to the corresponding section. I discovered this because the [k3s installer](https://get.k3s.io/) generates a unit file that looks like this: ``` [Service] Type=notify ExecStart=/usr/local/bin/k3s \ server \ ``` but attempting to start it generates the error `ERROR:systemctl: k3s.service: Service lacks both ExecStart and ExecStop= setting. Refusing.` Signed-off-by: Mason Malone <651224+MasonM@users.noreply.github.com> --- files/docker/systemctl3.py | 2 ++ testsuite.py | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/files/docker/systemctl3.py b/files/docker/systemctl3.py index c29ba2d..86ae586 100755 --- a/files/docker/systemctl3.py +++ b/files/docker/systemctl3.py @@ -810,6 +810,8 @@ def read_sysd(self, filename): else: # hint: an empty line shall reset the value-list self.set(section, name, text and text or None) + if nextline: + self.set(section, name, text) return self def read_sysv(self, filename): """ an LSB header is scanned and converted to (almost) diff --git a/testsuite.py b/testsuite.py index 9c3e99f..e4adc05 100755 --- a/testsuite.py +++ b/testsuite.py @@ -1383,17 +1383,27 @@ def test_1062_can_have_multi_line_settings_with_linebreak_mark(self) -> None: which is quite special [Service] PIDFile=/var/run/zzfoo.pid + ExecStart=sleep \\ + 2 \\ + """) textA = reads(os_path(root, "/etc/systemd/system/zza.service")) self.assertTrue(greps(textA, "Testing A")) self.assertTrue(greps(textA, "quite special")) self.assertTrue(greps(textA, "PIDFile=")) + self.assertTrue(greps(textA, "ExecStart=")) cmd = "{systemctl} __get_description zza.service" out, end = output2(cmd.format(**locals())) logg.info("%s => \n%s", cmd, out) self.assertEqual(end, 0) self.assertTrue(greps(out, "Testing A")) self.assertTrue(greps(out, "quite special")) + cmd = "{systemctl} command zza.service" + out, end = output2(cmd.format(**locals())) + logg.info("%s => \n%s", cmd, out) + self.assertEqual(end, 0) + self.assertEqual(len(lines(out)), 3) + self.assertTrue(greps(out, "sleep \\\\")) cmd = "{systemctl} __get_pid_file zza.service" out, end = output2(cmd.format(**locals())) logg.info("%s => \n%s", cmd, out) From 18c3676e008cac8fa1f6e376a3f0af5d47c77b14 Mon Sep 17 00:00:00 2001 From: Mason Malone <651224+MasonM@users.noreply.github.com> Date: Sat, 7 Dec 2024 17:53:24 -0800 Subject: [PATCH 2/2] Fix systemctl.py too Signed-off-by: Mason Malone <651224+MasonM@users.noreply.github.com> --- files/docker/systemctl.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/files/docker/systemctl.py b/files/docker/systemctl.py index 28e934c..0edce83 100755 --- a/files/docker/systemctl.py +++ b/files/docker/systemctl.py @@ -810,6 +810,8 @@ def read_sysd(self, filename): else: # hint: an empty line shall reset the value-list self.set(section, name, text and text or None) + if nextline: + self.set(section, name, text) return self def read_sysv(self, filename): """ an LSB header is scanned and converted to (almost)