Keep installation checks readable and require a loaded unit

Visual review found the bounded systemctl example clipped its option lines on a phone. Give each property its own line and distinguish a missing unit from a loaded root service before interpreting its settings.

Contract-Neutral: Documentation and focused verification only; no installer, runtime, API, persistence or security contract delta.
Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-10-04 04:37:48 +01:00
parent a6959e571b
commit 01adf338a4
4 changed files with 35 additions and 11 deletions
+12 -4
View File
@@ -211,13 +211,21 @@ values or credentials:
```bash
systemctl show pulse.service \
--property=User --property=Group --property=NoNewPrivileges \
--property=PrivateTmp --property=ProtectSystem --property=ProtectHome
--property=LoadState \
--property=User \
--property=Group \
--property=NoNewPrivileges \
--property=PrivateTmp \
--property=ProtectSystem \
--property=ProtectHome
```
Use your actual server unit name if it differs; older installations may use
`pulse-backend.service`. An empty `User=` means systemd runs the service as
root. Missing hardening is not repaired just by downloading a new binary:
`pulse-backend.service`. Interpret these settings only when
`LoadState=loaded`; `LoadState=not-found` means the selected unit is missing,
not that a root service is running. For a loaded service, an empty `User=`
means systemd runs it as root. Missing hardening is not repaired just by
downloading a new binary:
**the installer preserves existing service units during updates**, including
custom units.
@@ -53,7 +53,8 @@ const { chromium, webkit } = require('playwright');
assert.notEqual(await details.getAttribute('open'), null);
const content = await details.innerText();
for (const text of ['use the signed installer above', 'User=pulse', 'Group=pulse',
'NoNewPrivileges=true', 'ProtectSystem=strict', 'An empty User= means',
'NoNewPrivileges=true', 'ProtectSystem=strict', 'LoadState=loaded',
'not that a root service is running', 'an empty User=',
'the installer preserves existing service units during updates',
'Do not overwrite a working unit, change only its service user',
'preserve the data directory and its encryption key',
@@ -61,6 +62,8 @@ const { chromium, webkit } = require('playwright');
assert.ok(content.includes(text), text);
const command = await details.locator('pre').innerText();
assert.ok(command.startsWith('systemctl show pulse.service'));
assert.ok(command.includes('--property=LoadState'));
assert.ok(Math.max(...command.split('\n').map((line) => line.length)) < 34);
assert.ok(!/--property=(Environment|ExecStart)|sudo|tee|install -m/.test(command));
assert.ok(!await page.locator('article').innerText().then((text) =>
text.includes('sudo tee /etc/systemd/system/pulse.service')));
@@ -78,7 +81,8 @@ const { chromium, webkit } = require('playwright');
assert.deepEqual(errors, []);
results.push({ engine, version: browser.version(), width,
keyboardDisclosure: true, nonRootServer: true, agentBoundary: true,
readOnlyCredentialSafeCommand: true, preservationWarning: true,
readOnlyCredentialSafeCommand: true, loadedUnitRequired: true, phoneCommandFits: true,
preservationWarning: true,
noDocumentOverflow: true, keyboardRecoveryLink: true, errors });
await browser.close();
browser = undefined;
+12 -4
View File
@@ -211,13 +211,21 @@ values or credentials:
```bash
systemctl show pulse.service \
--property=User --property=Group --property=NoNewPrivileges \
--property=PrivateTmp --property=ProtectSystem --property=ProtectHome
--property=LoadState \
--property=User \
--property=Group \
--property=NoNewPrivileges \
--property=PrivateTmp \
--property=ProtectSystem \
--property=ProtectHome
```
Use your actual server unit name if it differs; older installations may use
`pulse-backend.service`. An empty `User=` means systemd runs the service as
root. Missing hardening is not repaired just by downloading a new binary:
`pulse-backend.service`. Interpret these settings only when
`LoadState=loaded`; `LoadState=not-found` means the selected unit is missing,
not that a root service is running. For a loaded service, an empty `User=`
means systemd runs it as root. Missing hardening is not repaired just by
downloading a new binary:
**the installer preserves existing service units during updates**, including
custom units.
@@ -69,7 +69,9 @@ describe('docsLinks', () => {
expect(custom).toContain('use the signed installer above');
expect(custom).toContain('`User=pulse`, `Group=pulse`');
expect(custom).toContain('`ProtectSystem=strict` and `ProtectHome=true`');
expect(custom).toContain('An empty `User=` means');
expect(custom).toContain('`LoadState=loaded`');
expect(custom).toContain('not that a root service is running');
expect(custom).toContain('an empty `User=`');
expect(custom).toContain('the installer preserves existing service units during updates');
expect(custom).toContain('Do not overwrite a working unit, change only its service user');
expect(custom).toContain('preserve the data directory and its encryption');
@@ -77,6 +79,8 @@ describe('docsLinks', () => {
const commands = [...custom.matchAll(/```bash\n([\s\S]*?)```/g)].map((match) => match[1]);
expect(commands).toHaveLength(1);
expect(commands[0]).toContain('systemctl show pulse.service');
expect(commands[0]).toContain('--property=LoadState');
expect(Math.max(...commands[0].split('\n').map((line) => line.length))).toBeLessThan(34);
expect(commands[0]).not.toMatch(/--property=(Environment|ExecStart)|sudo|tee|install -m/);
expect(installation).not.toContain('sudo tee /etc/systemd/system/pulse.service');
expect(installation).not.toContain('ExecStart=/usr/local/bin/pulse');