@push.rocks/smartdaemon 2.6.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartdaemon',
6
- version: '2.6.0',
6
+ version: '2.7.1',
7
7
  description: 'Start scripts as long running daemons and manage them.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx5QkFBeUI7SUFDL0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHdEQUF3RDtDQUN0RSxDQUFBIn0=
@@ -1,13 +1,11 @@
1
1
  import { type ISystemdServiceStartup, type ISystemdServiceDependencies, type ISystemdServiceInstallTargets } from './systemd.definition.js';
2
2
  export type { ISystemdServiceStartup, ISystemdServiceDependencies, ISystemdServiceInstallTargets } from './systemd.definition.js';
3
- export interface ISystemdServiceDefinitionOptions {
3
+ interface ISystemdServiceDefinitionBaseOptions {
4
4
  unitName: string;
5
5
  description: string;
6
6
  executable: string;
7
7
  args: readonly string[];
8
8
  workingDirectory: string;
9
- user: string;
10
- group: string;
11
9
  restart: 'no' | 'on-failure' | 'always';
12
10
  killMode: 'mixed' | 'control-group';
13
11
  timeoutStopSeconds: number;
@@ -15,12 +13,22 @@ export interface ISystemdServiceDefinitionOptions {
15
13
  dependencies?: ISystemdServiceDependencies;
16
14
  install?: ISystemdServiceInstallTargets;
17
15
  }
16
+ export type ISystemdServiceDefinitionOptions = ISystemdServiceDefinitionBaseOptions & ({
17
+ scope?: 'system';
18
+ user: string;
19
+ group: string;
20
+ } | {
21
+ scope: 'user';
22
+ user?: never;
23
+ group?: never;
24
+ });
18
25
  export declare class SystemdServiceDefinitionError extends Error {
19
26
  constructor();
20
27
  }
21
28
  /** Literal direct-execution definition; never introduces a shell or environment expansion. */
22
29
  export declare class SystemdServiceDefinition {
23
30
  readonly unitName: string;
31
+ readonly scope: 'system' | 'user';
24
32
  readonly content: string;
25
33
  readonly sha256: string;
26
34
  constructor(options: ISystemdServiceDefinitionOptions);
@@ -13,6 +13,16 @@ export class SystemdServiceDefinition {
13
13
  if (!value)
14
14
  throw new SystemdServiceDefinitionError();
15
15
  };
16
+ requireValue(options && !plugins.util.types.isProxy(options) &&
17
+ Object.getPrototypeOf(options) === Object.prototype);
18
+ const scopeDescriptor = Object.getOwnPropertyDescriptor(options, 'scope');
19
+ requireValue(scopeDescriptor === undefined ||
20
+ scopeDescriptor.enumerable && 'value' in scopeDescriptor);
21
+ const scopeValue = scopeDescriptor?.value ?? 'system';
22
+ if (scopeValue !== 'system' && scopeValue !== 'user') {
23
+ throw new SystemdServiceDefinitionError();
24
+ }
25
+ const scope = scopeValue;
16
26
  const text = (value, maximum = 4096) => typeof value === 'string' && value.length <= maximum && !/[\x00-\x1f\x7f]/.test(value) &&
17
27
  !/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u.test(value);
18
28
  const absolute = (value) => text(value) && plugins.path.isAbsolute(value) &&
@@ -23,15 +33,13 @@ export class SystemdServiceDefinition {
23
33
  'executable',
24
34
  'args',
25
35
  'workingDirectory',
26
- 'user',
27
- 'group',
28
36
  'restart',
29
37
  'killMode',
30
38
  'timeoutStopSeconds',
39
+ ...(scope === 'system' ? ['user', 'group'] : []),
31
40
  ];
32
- requireValue(options && !plugins.util.types.isProxy(options) && Object.getPrototypeOf(options) === Object.prototype &&
33
- Reflect.ownKeys(options).every(key => typeof key === 'string' && [...keys, 'startup', 'dependencies', 'install'].includes(key)
34
- && Object.getOwnPropertyDescriptor(options, key)?.enumerable && 'value' in Object.getOwnPropertyDescriptor(options, key)) && keys.every((key) => {
41
+ requireValue(Reflect.ownKeys(options).every(key => typeof key === 'string' && [...keys, 'scope', 'startup', 'dependencies', 'install'].includes(key)
42
+ && Object.getOwnPropertyDescriptor(options, key)?.enumerable && 'value' in Object.getOwnPropertyDescriptor(options, key)) && keys.every((key) => {
35
43
  const descriptor = Object.getOwnPropertyDescriptor(options, key);
36
44
  return descriptor && 'value' in descriptor;
37
45
  }));
@@ -49,7 +57,9 @@ export class SystemdServiceDefinition {
49
57
  Reflect.ownKeys(options.args).length === options.args.length + 1 &&
50
58
  Array.from({ length: options.args.length }, (_, index) => Object.getOwnPropertyDescriptor(options.args, String(index)))
51
59
  .every((descriptor) => descriptor && 'value' in descriptor && text(descriptor.value)));
52
- requireValue([options.user, options.group].every((value) => typeof value === 'string' && /^[a-zA-Z_][a-zA-Z0-9_-]{0,63}$/.test(value)));
60
+ if (scope === 'system') {
61
+ requireValue([options.user, options.group].every((value) => typeof value === 'string' && /^[a-zA-Z_][a-zA-Z0-9_-]{0,63}$/.test(value)));
62
+ }
53
63
  requireValue(['no', 'on-failure', 'always'].includes(options.restart) &&
54
64
  ['mixed', 'control-group'].includes(options.killMode) &&
55
65
  Number.isSafeInteger(options.timeoutStopSeconds) &&
@@ -59,8 +69,9 @@ export class SystemdServiceDefinition {
59
69
  .replaceAll('\\', '\\\\').replaceAll('"', '\\"').replaceAll('%', '%%')
60
70
  .replaceAll('$', () => command ? '$$' : '$') +
61
71
  '"';
62
- const relations = renderServiceRelations(options, options.unitName, options.restart, () => { throw new SystemdServiceDefinitionError(); });
72
+ const relations = renderServiceRelations(options, options.unitName, options.restart, scope, () => { throw new SystemdServiceDefinitionError(); });
63
73
  this.unitName = options.unitName;
74
+ this.scope = scope;
64
75
  this.content = [
65
76
  '[Unit]',
66
77
  `Description=${options.description.replaceAll('%', '%%')}`,
@@ -68,8 +79,7 @@ export class SystemdServiceDefinition {
68
79
  '',
69
80
  '[Service]',
70
81
  ...relations.service,
71
- `User=${options.user}`,
72
- `Group=${options.group}`,
82
+ ...(scope === 'system' ? [`User=${options.user}`, `Group=${options.group}`] : []),
73
83
  `ExecStart=${[quote(options.executable), ...options.args.map((value) => quote(value, true))].join(' ')}`,
74
84
  // WorkingDirectory is a raw path value, not an ExecStart word list.
75
85
  `WorkingDirectory=${options.workingDirectory.replaceAll('%', '%%')}`,
@@ -93,4 +103,4 @@ export class SystemdServiceDefinition {
93
103
  Object.freeze(this);
94
104
  }
95
105
  }
96
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kc2VydmljZWRlZmluaXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnN5c3RlbWRzZXJ2aWNlZGVmaW5pdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxzQkFBc0IsRUFDTyxNQUFNLHlCQUF5QixDQUFDO0FBbUJ0RSxNQUFNLE9BQU8sNkJBQThCLFNBQVEsS0FBSztJQUN0RDtRQUNFLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxJQUFJLEdBQUcsK0JBQStCLENBQUM7SUFDOUMsQ0FBQztDQUNGO0FBRUQsOEZBQThGO0FBQzlGLE1BQU0sT0FBTyx3QkFBd0I7SUFLbkMsWUFBWSxPQUF5QztRQUNuRCxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQWMsRUFBUSxFQUFFO1lBQzVDLElBQUksQ0FBQyxLQUFLO2dCQUFFLE1BQU0sSUFBSSw2QkFBNkIsRUFBRSxDQUFDO1FBQ3hELENBQUMsQ0FBQztRQUNGLE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBYyxFQUFFLE9BQU8sR0FBRyxJQUFJLEVBQW1CLEVBQUUsQ0FDL0QsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUN0RixDQUFDLHlFQUF5RSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6RixNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQWMsRUFBRSxFQUFFLENBQ2xDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7WUFDN0MsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxD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
106
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kc2VydmljZWRlZmluaXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnN5c3RlbWRzZXJ2aWNlZGVmaW5pdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxzQkFBc0IsRUFDTyxNQUFNLHlCQUF5QixDQUFDO0FBc0J0RSxNQUFNLE9BQU8sNkJBQThCLFNBQVEsS0FBSztJQUN0RDtRQUNFLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxJQUFJLEdBQUcsK0JBQStCLENBQUM7SUFDOUMsQ0FBQztDQUNGO0FBRUQsOEZBQThGO0FBQzlGLE1BQU0sT0FBTyx3QkFBd0I7SUFNbkMsWUFBWSxPQUF5QztRQUNuRCxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQWMsRUFBUSxFQUFFO1lBQzVDLElBQUksQ0FBQyxLQUFLO2dCQUFFLE1BQU0sSUFBSSw2QkFBNkIsRUFBRSxDQUFDO1FBQ3hELENBQUMsQ0FBQztRQUNGLFlBQVksQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1lBQzFELE1BQU0sQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEtBQUssTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDMUUsWUFBWSxDQUFDLGVBQWUsS0FBSyxTQUFTO1lBQ3hDLGVBQWUsQ0FBQyxVQUFVLElBQUksT0FBTyxJQUFJLGVBQWUsQ0FBQyxDQUFDO1FBQzVELE1BQU0sVUFBVSxHQUFZLGVBQWUsRUFBRSxLQUFLLElBQUksUUFBUSxDQUFDO1FBQy9ELElBQUksVUFBVSxLQUFLLFFBQVEsSUFB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
@@ -1,5 +1,12 @@
1
1
  export interface ISystemdUnitOptions {
2
2
  unitName: string;
3
+ /** Defaults to the system manager. User scope addresses the calling user's manager only. */
4
+ scope?: 'system' | 'user';
5
+ /**
6
+ * User-manager socket directory. Defaults to a non-empty XDG_RUNTIME_DIR. May be absent at
7
+ * construction; every call that contacts the user manager then refuses with `invalid_options`.
8
+ */
9
+ runtimeDirectory?: string;
3
10
  /** Absolute executable path supplied by trusted owning code. */
4
11
  systemctlPath?: string;
5
12
  /** Bounds the systemctl client, not the server-side job. Defaults to 120 seconds. */
@@ -44,6 +51,11 @@ export declare class SystemdUnit {
44
51
  private readonly unitName;
45
52
  private readonly executable;
46
53
  private readonly timeout;
54
+ private readonly scope;
55
+ private readonly runtimeDirectory?;
56
+ private readonly homeDirectory?;
57
+ private readonly configDirectory?;
58
+ private readonly dataDirectory?;
47
59
  constructor(optionsArg: ISystemdUnitOptions);
48
60
  /** Snapshot only. Callers own application-specific admission and restart policy. */
49
61
  inspect(): Promise<ISystemdUnitState>;
@@ -60,5 +72,6 @@ export declare class SystemdUnit {
60
72
  inspectConfiguration(): Promise<ISystemdUnitConfigurationState>;
61
73
  /** Reloads unit definitions globally; does not enable, unmask, start or stop a unit. */
62
74
  reloadConfiguration(): Promise<ISystemdUnitConfigurationState>;
75
+ private validateUserRuntime;
63
76
  private command;
64
77
  }
@@ -24,11 +24,32 @@ export class SystemdUnit {
24
24
  this.unitName = optionsArg?.unitName;
25
25
  this.executable = optionsArg?.systemctlPath ?? '/usr/bin/systemctl';
26
26
  this.timeout = optionsArg?.commandTimeoutMs ?? 120000;
27
+ this.scope = optionsArg?.scope ?? 'system';
28
+ // An empty XDG_RUNTIME_DIR counts as unset, like the sibling XDG variables below. An explicit
29
+ // option is never reinterpreted, so an empty or relative option stays malformed.
30
+ this.runtimeDirectory = this.scope === 'user'
31
+ ? optionsArg?.runtimeDirectory ?? (process.env.XDG_RUNTIME_DIR || undefined) : undefined;
32
+ this.homeDirectory = this.scope === 'user' ? plugins.os.userInfo().homedir : undefined;
33
+ this.configDirectory = this.scope === 'user' ? process.env.XDG_CONFIG_HOME || undefined : undefined;
34
+ this.dataDirectory = this.scope === 'user' ? process.env.XDG_DATA_HOME || undefined : undefined;
35
+ const safeDirectory = (value) => typeof value === 'string' && value !== '/' && plugins.path.isAbsolute(value) &&
36
+ plugins.path.normalize(value) === value && !value.endsWith('/') &&
37
+ value.length <= 4000 && !/[\x00-\x1f\x7f]/.test(value);
38
+ // Only a supplied runtime directory is validated here. Its absence matters solely to calls that
39
+ // reach the user manager, and those refuse it in validateUserRuntime(). Admitting absence lets
40
+ // owners read protected unit files from contexts without a login session (cron, plain ssh).
27
41
  if (typeof this.unitName !== 'string' ||
28
42
  !/^[a-zA-Z0-9][a-zA-Z0-9_.:@-]{0,230}\.service$/.test(this.unitName) ||
29
43
  typeof this.executable !== 'string' || !plugins.path.isAbsolute(this.executable) ||
30
44
  this.executable.includes('\0') || !Number.isSafeInteger(this.timeout) ||
31
- this.timeout < 1 || this.timeout > 600000)
45
+ this.timeout < 1 || this.timeout > 600000 ||
46
+ !['system', 'user'].includes(this.scope) ||
47
+ (this.scope === 'system' && optionsArg?.runtimeDirectory !== undefined) ||
48
+ (this.scope === 'user' &&
49
+ (this.runtimeDirectory !== undefined && !safeDirectory(this.runtimeDirectory) ||
50
+ !safeDirectory(this.homeDirectory) ||
51
+ this.configDirectory !== undefined && !safeDirectory(this.configDirectory) ||
52
+ this.dataDirectory !== undefined && !safeDirectory(this.dataDirectory))))
32
53
  throw new SystemdUnitError('invalid_options');
33
54
  }
34
55
  /** Snapshot only. Callers own application-specific admission and restart policy. */
@@ -137,15 +158,43 @@ export class SystemdUnit {
137
158
  await this.command(['daemon-reload']);
138
159
  return this.inspectConfiguration();
139
160
  }
140
- command(argsArg) {
161
+ async validateUserRuntime() {
162
+ if (this.scope !== 'user')
163
+ return;
164
+ // Runs before every systemctl invocation, so a missing directory refuses without side effects.
165
+ const runtimeDirectory = this.runtimeDirectory;
166
+ if (runtimeDirectory === undefined)
167
+ throw new SystemdUnitError('invalid_options');
168
+ try {
169
+ const uid = process.getuid?.();
170
+ if (process.platform !== 'linux' || uid === undefined || process.geteuid?.() !== uid ||
171
+ await plugins.fs.realpath(runtimeDirectory) !== runtimeDirectory) {
172
+ throw new SystemdUnitError('invalid_options');
173
+ }
174
+ const info = await plugins.fs.lstat(runtimeDirectory);
175
+ if (!info.isDirectory() || info.isSymbolicLink() || info.uid !== uid ||
176
+ (info.mode & 0o077) !== 0)
177
+ throw new SystemdUnitError('invalid_options');
178
+ }
179
+ catch {
180
+ throw new SystemdUnitError('invalid_options');
181
+ }
182
+ }
183
+ async command(argsArg) {
184
+ await this.validateUserRuntime();
141
185
  return new Promise((resolve, reject) => {
142
- plugins.childProcess.execFile(this.executable, ['--system', '--no-ask-password', '--no-pager', ...argsArg], {
186
+ plugins.childProcess.execFile(this.executable, [this.scope === 'user' ? '--user' : '--system', '--no-ask-password', '--no-pager', ...argsArg], {
143
187
  encoding: 'utf8',
144
188
  timeout: this.timeout,
145
189
  killSignal: 'SIGKILL',
146
190
  maxBuffer: 16384,
147
191
  windowsHide: true,
148
- env: { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C' },
192
+ env: this.scope === 'user'
193
+ ? { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C',
194
+ HOME: this.homeDirectory, XDG_RUNTIME_DIR: this.runtimeDirectory,
195
+ ...(this.configDirectory ? { XDG_CONFIG_HOME: this.configDirectory } : {}),
196
+ ...(this.dataDirectory ? { XDG_DATA_HOME: this.dataDirectory } : {}) }
197
+ : { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C' },
149
198
  }, (error, stdout) => {
150
199
  // execFile settles after the client closes. A timed-out client's remote job may continue.
151
200
  if (error)
@@ -156,4 +205,4 @@ export class SystemdUnit {
156
205
  });
157
206
  }
158
207
  }
159
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kdW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuc3lzdGVtZHVuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSwwQkFBMEIsQ0FBQztBQTJDcEQsTUFBTSxPQUFPLGdCQUFpQixTQUFRLEtBQUs7SUFDekMsWUFBNEIsSUFBNEQ7UUFDdEYsS0FBSyxDQUFDLGtDQUFrQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBRHZCLFNBQUksR0FBSixJQUFJLENBQXdEO1FBRXRGLElBQUksQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7SUFDakMsQ0FBQztDQUNGO0FBRUQsTUFBTSxVQUFVLEdBQUc7SUFDakIsSUFBSTtJQUNKLFdBQVc7SUFDWCxhQUFhO0lBQ2IsVUFBVTtJQUNWLGVBQWU7SUFDZixTQUFTO0lBQ1QsWUFBWTtJQUNaLGNBQWM7SUFDZCxVQUFVO0lBQ1YsS0FBSztDQUNHLENBQUM7QUFFWCxrR0FBa0c7QUFDbEcsTUFBTSxPQUFPLFdBQVc7SUFLdEIsWUFBWSxVQUErQjtRQUN6QyxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsRUFBRSxRQUFRLENBQUM7UUFDckMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLEVBQUUsYUFBYSxJQUFJLG9CQUFvQixDQUFDO1FBQ3BFLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxFQUFFLGdCQUFnQixJQUFJLE1BQU0sQ0FBQztRQUN0RCxJQUNFLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO1lBQ2pDLENBQUMsK0NBQStDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDcEUsT0FBTyxJQUFJLENBQUMsVUFBVSxLQUFLLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDaEYsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDckUsSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNO1lBQ3pDLE1BQU0sSUFBSSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRCxvRkFBb0Y7SUFDN0UsS0FBSyxDQUFDLE9BQU87UUFDbEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQ2hDLE1BQU07WUFDTixJQUFJLENBQUMsUUFBUTtZQUNiLGNBQWMsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUNwQyxPQUFPO1NBQ1IsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFDekMsS0FBSyxNQUFNLElBQUksSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDaEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUNyQyxJQUFJLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBRSxVQUFnQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3pGLE1BQU0sSUFBSSxnQkFBZ0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM5QyxDQUFDO1lBQ0QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsSUFDRSxNQUFNLENBQUMsSUFBSSxLQUFLLFVBQVUsQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsUUFBUTtZQUN2RSxDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEUsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDckMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQzNGO1lBQ0QsTUFBTSxJQUFJLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzlDLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUNuQixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsU0FBUyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFFO1lBQ25DLFdBQVcsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBRTtZQUN2QyxRQUFRLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUU7WUFDakMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFFO1lBQzNDLE9BQU8sRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN0QyxVQUFVLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDNUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFFO1lBQ3pDLFFBQVEsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBRTtZQUNqQyxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUU7U0FDeEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELG9GQUFvRjtJQUM3RSxLQUFLLENBQUMsS0FBSztRQUNoQixNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDN0MsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVEO3VHQUNtRztJQUM1RixLQUFLLENBQUMsTUFBTTtRQUNqQixNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDOUMsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVELDBHQUEwRztJQUNuRyxLQUFLLENBQUMsb0JBQW9CO1FBQy9CLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ25HLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDcEcsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFDekMsS0FBSyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3RGLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3BFLElBQUksU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7Z0JBQUUsTUFBTSxJQUFJLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3pHLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLFFBQVE7WUFBRSxNQUFNLElBQUksZ0JBQWdCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDbkgsTUFBTSxLQUFLLEdBQUcsQ0FBQyxHQUFXLEVBQXFCLEVBQUU7WUFDL0MsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUUsQ0FBQztZQUM5QixNQUFNLE1BQU0sR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbEQsOEVBQThFO1lBQzlFLHlFQUF5RTtZQUN6RSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUc7Z0JBQ3pDLENBQUMseUhBQXlILENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUN2SSxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLE1BQU07Z0JBQUUsTUFBTSxJQUFJLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3RGLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUM7UUFDRixPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDO1lBQzVGLFFBQVEsRUFBRSxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLFdBQVcsQ0FBQztZQUNqRixVQUFVLEVBQUUsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFFRCxzR0FBc0c7SUFDL0YsS0FBSyxDQUFDLElBQUk7UUFDZixNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDNUMsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVELDBGQUEwRjtJQUNuRixLQUFLLENBQUMsb0JBQW9CO1FBQy9CLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUN2RSxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxjQUFjLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3BHLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBQ3pDLEtBQUssTUFBTSxJQUFJLElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2hELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3BFLElBQUksU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUM1RCxNQUFNLElBQUksZ0JBQWdCLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDOUMsQ0FBQztZQUNELE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLFFBQVE7WUFDbkUsQ0FBQyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBRSxDQUFDLEVBQUUsQ0FBQztZQUMzRCxNQUFNLElBQUksZ0JBQWdCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUNuQixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsWUFBWSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFFO1lBQ3pDLFdBQVcsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBRTtZQUN2QyxXQUFXLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEtBQUs7U0FDdEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHdGQUF3RjtJQUNqRixLQUFLLENBQUMsbUJBQW1CO1FBQzlCLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7UUFDdEMsT0FBTyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRU8sT0FBTyxDQUFDLE9BQWlCO1FBQy9CLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckMsT0FBTyxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQzNCLElBQUksQ0FBQyxVQUFVLEVBQ2YsQ0FBQyxVQUFVLEVBQUUsbUJBQW1CLEVBQUUsWUFBWSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQzNEO2dCQUNFLFFBQVEsRUFBRSxNQUFNO2dCQUNoQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87Z0JBQ3JCLFVBQVUsRUFBRSxTQUFTO2dCQUNyQixTQUFTLEVBQUUsS0FBSztnQkFDaEIsV0FBVyxFQUFFLElBQUk7Z0JBQ2pCLEdBQUcsRUFBRSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFO2FBQ3ZELEVBQ0QsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQ2hCLDBGQUEwRjtnQkFDMUYsSUFBSSxLQUFLO29CQUFFLE1BQU0sQ0FBQyxJQUFJLGdCQUFnQixDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQzs7b0JBQ3JELE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN2QixDQUFDLENBQ0YsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGIn0=
208
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kdW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuc3lzdGVtZHVuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSwwQkFBMEIsQ0FBQztBQWtEcEQsTUFBTSxPQUFPLGdCQUFpQixTQUFRLEtBQUs7SUFDekMsWUFBNEIsSUFBNEQ7UUFDdEYsS0FBSyxDQUFDLGtDQUFrQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBRHZCLFNBQUksR0FBSixJQUFJLENBQXdEO1FBRXRGLElBQUksQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7SUFDakMsQ0FBQztDQUNGO0FBRUQsTUFBTSxVQUFVLEdBQUc7SUFDakIsSUFBSTtJQUNKLFdBQVc7SUFDWCxhQUFhO0lBQ2IsVUFBVTtJQUNWLGVBQWU7SUFDZixTQUFTO0lBQ1QsWUFBWTtJQUNaLGNBQWM7SUFDZCxVQUFVO0lBQ1YsS0FBSztDQUNHLENBQUM7QUFFWCxrR0FBa0c7QUFDbEcsTUFBTSxPQUFPLFdBQVc7SUFVdEIsWUFBWSxVQUErQjtRQUN6QyxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsRUFBRSxRQUFRLENBQUM7UUFDckMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLEVBQUUsYUFBYSxJQUFJLG9CQUFvQixDQUFDO1FBQ3BFLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxFQUFFLGdCQUFnQixJQUFJLE1BQU0sQ0FBQztRQUN0RCxJQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsRUFBRSxLQUFLLElBQUksUUFBUSxDQUFDO1FBQzNDLDhGQUE4RjtRQUM5RixpRkFBaUY7UUFDakYsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxLQUFLLEtBQUssTUFBTTtZQUMzQyxDQUFDLENBQUMsVUFBVSxFQUFFLGdCQUFnQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLElBQUksU0FBUyxDQUFD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
@@ -3,7 +3,7 @@ import { type ISystemdUnitOptions } from './classes.systemdunit.js';
3
3
  export interface ISystemdUnitFileOptions extends ISystemdUnitOptions {
4
4
  /** Local vendor definitions can be installed without removing an administrator's mask. */
5
5
  unitDirectory?: string;
6
- /** Trusted owning-code qualification only. Defaults to root. */
6
+ /** Trusted owning-code qualification only. Defaults to root for system, current uid for user. */
7
7
  expectedUid?: number;
8
8
  }
9
9
  export interface ISystemdUnitFileRecord {
@@ -22,11 +22,17 @@ export declare class SystemdUnitFile {
22
22
  readonly path: string;
23
23
  private readonly directory;
24
24
  private readonly uid;
25
+ private readonly scope;
26
+ private readonly configDirectory?;
27
+ private readonly runtimeDirectory?;
25
28
  private readonly unit;
26
29
  private readonly name;
27
30
  private busy;
28
31
  constructor(options: ISystemdUnitFileOptions);
29
- /** Reads only the exact protected definition; no systemd or filesystem mutation. */
32
+ /**
33
+ * Reads only the exact protected definition; no systemd or filesystem mutation.
34
+ * Needs no user-manager runtime directory.
35
+ */
30
36
  inspect(): Promise<ISystemdUnitFileRecord | null>;
31
37
  /**
32
38
  * Expected previous digest is mandatory; null admits an absent file. Exact desired bytes are idempotent.
@@ -29,16 +29,34 @@ export class SystemdUnitFile {
29
29
  this.busy = false;
30
30
  this.unit = new SystemdUnit(options);
31
31
  this.name = options.unitName;
32
- this.directory = options.unitDirectory ?? '/usr/local/lib/systemd/system';
33
- this.uid = options.expectedUid ?? 0;
34
- requireValue(typeof this.directory === 'string' && this.directory !== '/' &&
35
- plugins.path.isAbsolute(this.directory) &&
36
- plugins.path.normalize(this.directory) === this.directory &&
37
- !this.directory.endsWith('/') && !/[\x00-\x1f\x7f]/.test(this.directory) &&
38
- this.directory.length <= 4000 && Number.isSafeInteger(this.uid) && this.uid >= 0, 'invalid_options');
32
+ this.scope = options.scope ?? 'system';
33
+ const home = this.scope === 'user' ? plugins.os.userInfo().homedir : undefined;
34
+ const dataDirectory = this.scope === 'user'
35
+ ? process.env.XDG_DATA_HOME || plugins.path.join(home, '.local/share') : undefined;
36
+ this.configDirectory = this.scope === 'user'
37
+ ? process.env.XDG_CONFIG_HOME || plugins.path.join(home, '.config') : undefined;
38
+ // Resolved exactly as SystemdUnit resolves it, so both agree on presence.
39
+ this.runtimeDirectory = this.scope === 'user'
40
+ ? options.runtimeDirectory ?? (process.env.XDG_RUNTIME_DIR || undefined) : undefined;
41
+ this.directory = options.unitDirectory ?? (this.scope === 'user'
42
+ ? plugins.path.join(dataDirectory, 'systemd/user') : '/usr/local/lib/systemd/system');
43
+ this.uid = options.expectedUid ?? (this.scope === 'user' ? process.getuid?.() ?? -1 : 0);
44
+ const validDirectory = (directory) => typeof directory === 'string' && directory !== '/' &&
45
+ plugins.path.isAbsolute(directory) && plugins.path.normalize(directory) === directory &&
46
+ !directory.endsWith('/') && !/[\x00-\x1f\x7f]/.test(directory) &&
47
+ directory.length <= 4000;
48
+ requireValue(validDirectory(this.directory) && Number.isSafeInteger(this.uid) && this.uid >= 0 &&
49
+ (this.scope === 'system' ||
50
+ this.uid === process.getuid?.() && validDirectory(this.configDirectory) &&
51
+ // inspect() reads only the unit directory, so an absent runtime directory is refused
52
+ // later, by install(); a supplied one must still be well formed.
53
+ (this.runtimeDirectory === undefined || validDirectory(this.runtimeDirectory))), 'invalid_options');
39
54
  this.path = plugins.path.join(this.directory, this.name);
40
55
  }
41
- /** Reads only the exact protected definition; no systemd or filesystem mutation. */
56
+ /**
57
+ * Reads only the exact protected definition; no systemd or filesystem mutation.
58
+ * Needs no user-manager runtime directory.
59
+ */
42
60
  async inspect() {
43
61
  if (!await this.directories(false))
44
62
  return null;
@@ -51,8 +69,13 @@ export class SystemdUnitFile {
51
69
  */
52
70
  async install(definition, expectedSha256) {
53
71
  requireValue(definition instanceof SystemdServiceDefinition && definition.unitName === this.name &&
72
+ definition.scope === this.scope &&
54
73
  (expectedSha256 === null ||
55
- typeof expectedSha256 === 'string' && /^[a-f0-9]{64}$/.test(expectedSha256)), 'invalid_options');
74
+ typeof expectedSha256 === 'string' && /^[a-f0-9]{64}$/.test(expectedSha256)) &&
75
+ // Installation admits, reloads and verifies through the user manager and recognizes its
76
+ // runtime mask path. Refusing here, before the busy latch and any directory or systemctl
77
+ // effect, keeps the local error code instead of a wrapped write_failed.
78
+ (this.scope === 'system' || this.runtimeDirectory !== undefined), 'invalid_options');
56
79
  requireValue(!this.busy, 'busy');
57
80
  this.busy = true;
58
81
  let temporary;
@@ -138,11 +161,15 @@ export class SystemdUnitFile {
138
161
  ['enabled', 'enabled-runtime', 'disabled'].includes(state.unitFileState) ||
139
162
  state.loadState === 'not-found' && state.unitFileState === ''), 'unsafe_unit');
140
163
  const configuration = await this.unit.inspectConfiguration();
141
- const maskPath = plugins.path.join(state.unitFileState === 'masked-runtime' ? '/run/systemd/system' : '/etc/systemd/system', this.name);
164
+ const maskPaths = this.scope === 'system'
165
+ ? [plugins.path.join(state.unitFileState === 'masked-runtime' ? '/run/systemd/system' : '/etc/systemd/system', this.name)]
166
+ : (state.unitFileState === 'masked-runtime'
167
+ ? [this.runtimeDirectory, '/run'].map(root => plugins.path.join(root, 'systemd/user', this.name))
168
+ : [this.configDirectory, '/etc'].map(root => plugins.path.join(root, 'systemd/user', this.name)));
142
169
  requireValue(!configuration.needsReload && configuration.dropInPaths === '' &&
143
170
  (masked(state)
144
171
  ? configuration.fragmentPath !== this.path &&
145
- ['/dev/null', maskPath].includes(configuration.fragmentPath)
172
+ ['/dev/null', ...maskPaths].includes(configuration.fragmentPath)
146
173
  : configuration.fragmentPath === (state.loadState === 'not-found' ? '' : this.path)), 'unsafe_unit');
147
174
  return configuration;
148
175
  }
@@ -246,4 +273,4 @@ export class SystemdUnitFile {
246
273
  }
247
274
  }
248
275
  }
249
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kdW5pdGZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnN5c3RlbWR1bml0ZmlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBQ3BELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ2pGLE9BQU8sRUFJTCxXQUFXLEdBQ1osTUFBTSwwQkFBMEIsQ0FBQztBQVlsQyxNQUFNLE9BQU8sb0JBQXFCLFNBQVEsS0FBSztJQUM3QyxZQUNrQixJQU9HO1FBRW5CLEtBQUssQ0FBQyxnREFBZ0QsSUFBSSxHQUFHLENBQUMsQ0FBQztRQVQvQyxTQUFJLEdBQUosSUFBSSxDQU9EO1FBR25CLElBQUksQ0FBQyxJQUFJLEdBQUcsc0JBQXNCLENBQUM7SUFDckMsQ0FBQztDQUNGO0FBQ0QsTUFBTSxZQUFZLEdBQUcsQ0FBQyxLQUFjLEVBQUUsSUFBa0MsRUFBUSxFQUFFO0lBQ2hGLElBQUksQ0FBQyxLQUFLO1FBQUUsTUFBTSxJQUFJLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25ELENBQUMsQ0FBQztBQUNGLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBaUIsRUFBRSxFQUFFLENBQ25DLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbEUsTUFBTSxLQUFLLEdBQUcsQ0FBQyxLQUF3QixFQUFFLEVBQUUsQ0FDekMsS0FBSyxDQUFDLE9BQU8sS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxDQUFDO0lBQzdDLEtBQUssQ0FBQyxZQUFZLEtBQUssRUFBRSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssRUFBRTtJQUM3QyxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUss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
276
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kdW5pdGZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnN5c3RlbWR1bml0ZmlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBQ3BELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ2pGLE9BQU8sRUFJTCxXQUFXLEdBQ1osTUFBTSwwQkFBMEIsQ0FBQztBQVlsQyxNQUFNLE9BQU8sb0JBQXFCLFNBQVEsS0FBSztJQUM3QyxZQUNrQixJQU9HO1FBRW5CLEtBQUssQ0FBQyxnREFBZ0QsSUFBSSxHQUFHLENBQUMsQ0FBQztRQVQvQyxTQUFJLEdBQUosSUFBSSxDQU9EO1FBR25CLElBQUksQ0FBQyxJQUFJLEdBQUcsc0JBQXNCLENBQUM7SUFDckMsQ0FBQztDQUNGO0FBQ0QsTUFBTSxZQUFZLEdBQUcsQ0FBQyxLQUFjLEVBQUUsSUFBa0MsRUFBUSxFQUFFO0lBQ2hGLElBQUksQ0FBQyxLQUFLO1FBQUUsTUFBTSxJQUFJLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25ELENBQUMsQ0FBQztBQUNGLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBaUIsRUFBRSxFQUFFLENBQ25DLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbEUsTUFBTSxLQUFLLEdBQUcsQ0FBQyxLQUF3QixFQUFFLEVBQUUsQ0FDekMsS0FBSyxDQUFDLE9BQU8sS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxDQUFDO0lBQzdDLEtBQUssQ0FBQyxZQUFZLEtBQUssRUFBRSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssRUFBRTtJQUM3QyxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUss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
@@ -4,8 +4,9 @@ import * as fs from 'node:fs/promises';
4
4
  import { constants as fsConstants } from 'node:fs';
5
5
  import * as crypto from 'node:crypto';
6
6
  import * as util from 'node:util';
7
+ import * as os from 'node:os';
7
8
  export type { Stats } from 'node:fs';
8
- export { path, childProcess, fs, fsConstants, crypto, util };
9
+ export { path, childProcess, fs, fsConstants, crypto, util, os };
9
10
  import * as lik from '@push.rocks/lik';
10
11
  import * as smartfm from '@push.rocks/smartfm';
11
12
  import * as smartfs from '@push.rocks/smartfs';
@@ -5,7 +5,8 @@ import * as fs from 'node:fs/promises';
5
5
  import { constants as fsConstants } from 'node:fs';
6
6
  import * as crypto from 'node:crypto';
7
7
  import * as util from 'node:util';
8
- export { path, childProcess, fs, fsConstants, crypto, util };
8
+ import * as os from 'node:os';
9
+ export { path, childProcess, fs, fsConstants, crypto, util, os };
9
10
  // @pushrocks scope
10
11
  import * as lik from '@push.rocks/lik';
11
12
  import * as smartfm from '@push.rocks/smartfm';
@@ -17,4 +18,4 @@ import * as smartshell from '@push.rocks/smartshell';
17
18
  import * as smartsystem from '@push.rocks/smartsystem';
18
19
  export { lik, smartfm, smartfs, smartlog, smartlogDestinationLocal, smartpath, smartshell, smartsystem, };
19
20
  // third party
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYWVtb24ucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0ZGFlbW9uLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxZQUFZLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxLQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsU0FBUyxJQUFJLFdBQVcsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNuRCxPQUFPLEtBQUssTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUdsQyxPQUFPLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUU3RCxtQkFBbUI7QUFDbkIsT0FBTyxLQUFLLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQztBQUN2QyxPQUFPLEtBQUssT0FBTyxNQUFNLHFCQUFxQixDQUFDO0FBQy9DLE9BQU8sS0FBSyxPQUFPLE1BQU0scUJBQXFCLENBQUM7QUFDL0MsT0FBTyxLQUFLLFFBQVEsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRCxPQUFPLEtBQUssd0JBQXdCLE1BQU0sd0NBQXdDLENBQUM7QUFDbkYsT0FBTyxLQUFLLFNBQVMsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRCxPQUFPLEtBQUssVUFBVSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFFdkQsT0FBTyxFQUNMLEdBQUcsRUFDSCxPQUFPLEVBQ1AsT0FBTyxFQUNQLFFBQVEsRUFDUix3QkFBd0IsRUFDeEIsU0FBUyxFQUNULFVBQVUsRUFDVixXQUFXLEdBQ1osQ0FBQztBQUVGLGNBQWMifQ==
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYWVtb24ucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0ZGFlbW9uLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxZQUFZLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxLQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsU0FBUyxJQUFJLFdBQVcsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNuRCxPQUFPLEtBQUssTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUNsQyxPQUFPLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUc5QixPQUFPLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUM7QUFFakUsbUJBQW1CO0FBQ25CLE9BQU8sS0FBSyxHQUFHLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxLQUFLLE9BQU8sTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLEtBQUssT0FBTyxNQUFNLHFCQUFxQixDQUFDO0FBQy9DLE9BQU8sS0FBSyxRQUFRLE1BQU0sc0JBQXNCLENBQUM7QUFDakQsT0FBTyxLQUFLLHdCQUF3QixNQUFNLHdDQUF3QyxDQUFDO0FBQ25GLE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBRXZELE9BQU8sRUFDTCxHQUFHLEVBQ0gsT0FBTyxFQUNQLE9BQU8sRUFDUCxRQUFRLEVBQ1Isd0JBQXdCLEVBQ3hCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsV0FBVyxHQUNaLENBQUM7QUFFRixjQUFjIn0=
@@ -3,7 +3,7 @@ export interface ISystemdServiceStartup {
3
3
  remainAfterExit: boolean;
4
4
  timeoutStartSeconds: number;
5
5
  }
6
- /** Complete literal relations. After=local-fs.target is always retained. */
6
+ /** Complete literal relations. System services always retain After=local-fs.target. */
7
7
  export interface ISystemdServiceDependencies {
8
8
  defaultDependencies: boolean;
9
9
  after: readonly string[];
@@ -22,7 +22,7 @@ export declare const renderServiceRelations: (options: {
22
22
  startup?: ISystemdServiceStartup;
23
23
  dependencies?: ISystemdServiceDependencies;
24
24
  install?: ISystemdServiceInstallTargets;
25
- }, unitName: string, restart: string, fail: () => never) => {
25
+ }, unitName: string, restart: string, scope: "system" | "user", fail: () => never) => {
26
26
  unit: string[];
27
27
  service: string[];
28
28
  install: string[];
@@ -1,6 +1,6 @@
1
1
  import * as plugins from './smartdaemon.plugins.js';
2
2
  /** Internal validated renderer; no systemd/process/filesystem effects. */
3
- export const renderServiceRelations = (options, unitName, restart, fail) => {
3
+ export const renderServiceRelations = (options, unitName, restart, scope, fail) => {
4
4
  const requireValue = (value) => { if (!value)
5
5
  fail(); };
6
6
  const record = (value, keys) => {
@@ -27,7 +27,11 @@ export const renderServiceRelations = (options, unitName, restart, fail) => {
27
27
  return result.sort();
28
28
  };
29
29
  const line = (key, value) => value.length ? [`${key}=${value.join(' ')}`] : [];
30
- const result = { unit: ['After=local-fs.target'], service: ['Type=exec'], install: ['WantedBy=multi-user.target'] };
30
+ const result = {
31
+ unit: scope === 'system' ? ['After=local-fs.target'] : [],
32
+ service: ['Type=exec'],
33
+ install: [scope === 'system' ? 'WantedBy=multi-user.target' : 'WantedBy=default.target'],
34
+ };
31
35
  if (options.startup !== undefined) {
32
36
  const value = options.startup;
33
37
  record(value, ['type', 'remainAfterExit', 'timeoutStartSeconds']);
@@ -39,7 +43,7 @@ export const renderServiceRelations = (options, unitName, restart, fail) => {
39
43
  const value = options.dependencies;
40
44
  record(value, ['defaultDependencies', 'after', 'before', 'requires', 'wants', 'conflicts']);
41
45
  requireValue(typeof value.defaultDependencies === 'boolean');
42
- const after = [...new Set(['local-fs.target', ...units(value.after)])].sort();
46
+ const after = [...new Set([...(scope === 'system' ? ['local-fs.target'] : []), ...units(value.after)])].sort();
43
47
  const before = units(value.before), requires = units(value.requires), wants = units(value.wants), conflicts = units(value.conflicts);
44
48
  requireValue(before.every(item => !after.includes(item)) && conflicts.every(item => !requires.includes(item) && !wants.includes(item)));
45
49
  result.unit = [`DefaultDependencies=${value.defaultDependencies ? 'yes' : 'no'}`, ...line('After', after),
@@ -54,4 +58,4 @@ export const renderServiceRelations = (options, unitName, restart, fail) => {
54
58
  }
55
59
  return result;
56
60
  };
57
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVtZC5kZWZpbml0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc3lzdGVtZC5kZWZpbml0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sMEJBQTBCLENBQUM7QUF3QnBELDBFQUEwRTtBQUMxRSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLE9BSXRDLEVBQUUsUUFBZ0IsRUFBRSxPQUFlLEVBQUUsSUFBaUIsRUFFckQsRUFBRTtJQUNGLE1BQU0sWUFBWSxHQUFHLENBQUMsS0FBYyxFQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSztRQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBYyxFQUFFLElBQXVCLEVBQVEsRUFBRTtRQUMvRCxZQUFZLENBQUMsS0FBSyxLQUFLLElBQUksSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO2VBQ3pGLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLEtBQUssTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3hELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBZSxDQUFDLENBQUM7UUFDaEQsWUFBWSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO2VBQzFHLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEVBQUUsVUFBVSxJQUFJLE9BQU8sSUFBSSxNQUFNLENBQUMsd0JBQXdCLENBQUMsS0FBSyxF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
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVtZC5kZWZpbml0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc3lzdGVtZC5kZWZpbml0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sMEJBQTBCLENBQUM7QUF3QnBELDBFQUEwRTtBQUMxRSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLE9BSXRDLEVBQUUsUUFBZ0IsRUFBRSxPQUFlLEVBQUUsS0FBd0IsRUFBRSxJQUFpQixFQUUvRSxFQUFFO0lBQ0YsTUFBTSxZQUFZLEdBQUcsQ0FBQyxLQUFjLEVBQVEsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLO1FBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkUsTUFBTSxNQUFNLEdBQUcsQ0FBQyxLQUFjLEVBQUUsSUFBdUIsRUFBUSxFQUFFO1FBQy9ELFlBQVksQ0FBQyxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7ZUFDekYsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsS0FBSyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFlLENBQUMsQ0FBQztRQUNoRCxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEdBQUcsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7ZUFDMUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsRUFBRSxVQUFVLElBQUksT0FBTyxJQUFJLE1BQU0sQ0FBQyx3QkFBd0Is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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartdaemon",
3
- "version": "2.6.0",
3
+ "version": "2.7.1",
4
4
  "private": false,
5
5
  "description": "Start scripts as long running daemons and manage them.",
6
6
  "main": "dist_ts/index.js",
@@ -26,10 +26,10 @@
26
26
  },
27
27
  "homepage": "https://code.foss.global/push.rocks/smartdaemon",
28
28
  "devDependencies": {
29
- "@git.zone/tsbuild": "^4.4.3",
30
- "@git.zone/tsrun": "^2.0.6",
31
- "@git.zone/tstest": "^6.0.0",
32
- "@types/node": "^26.4.1"
29
+ "@git.zone/tsbuild": "^5.0.0",
30
+ "@git.zone/tsrun": "^3.0.0",
31
+ "@git.zone/tstest": "^6.2.1",
32
+ "@types/node": "^26.6.1"
33
33
  },
34
34
  "dependencies": {
35
35
  "@push.rocks/lik": "^6.4.1",
package/readme.md CHANGED
@@ -164,6 +164,10 @@ const unit = new SystemdUnit({ unitName: 'smartdaemon_my-api-server.service' });
164
164
  const state = await unit.inspect();
165
165
  console.log(state.loadState, state.activeState, state.unitFileState);
166
166
 
167
+ // Address the calling user's manager when running as that user.
168
+ const userUnit = new SystemdUnit({ unitName: 'authswitch.service', scope: 'user' });
169
+ const userState = await userUnit.inspect();
170
+
167
171
  // Application code decides whether stopping or restarting is appropriate.
168
172
  // await unit.stop();
169
173
  // await unit.start();
@@ -185,6 +189,17 @@ Calls use an absolute `systemctlPath` (default `/usr/bin/systemctl`), a clean
185
189
  environment, no shell or password prompt, and bounded output. Trusted owning code
186
190
  can choose another absolute executable path and `commandTimeoutMs` (default
187
191
  120000, maximum 600000). This timeout bounds the client process only.
192
+ The default `scope: 'system'` retains system-manager behavior. `scope: 'user'`
193
+ uses `systemctl --user` as the calling user. Every `SystemdUnit` operation contacts
194
+ the user manager, so each requires a real, owned, private `XDG_RUNTIME_DIR` (or an
195
+ explicit `runtimeDirectory`) and passes that directory with the user's home and
196
+ valid XDG config/data roots to the command. The directory is checked again before
197
+ each call; a missing, replaced, linked or group-accessible runtime directory fails
198
+ with `invalid_options` before contacting systemd. Construction itself does not
199
+ require one, so a unit can be constructed without a login session (cron, a plain
200
+ ssh command); an empty `XDG_RUNTIME_DIR` counts as unset. A supplied directory, from
201
+ the option or a non-empty `XDG_RUNTIME_DIR`, that is not an absolute, normalized path
202
+ without a trailing slash is still rejected at construction.
188
203
 
189
204
  `inspectConfiguration()` reports the selected `fragmentPath`, opaque `dropInPaths`
190
205
  list and `needsReload` flag. `reloadConfiguration()` explicitly reloads the manager's
@@ -211,7 +226,9 @@ drop-ins and `needsReload === false` before permitting dependent activation.
211
226
  ### Installing a direct systemd service definition
212
227
 
213
228
  `SystemdServiceDefinition` encodes a literal executable and argument list, with
214
- explicit user, group, restart policy, kill mode and stop timeout. It defaults to `Type=exec`,
229
+ explicit restart policy, kill mode and stop timeout. System-scope definitions require
230
+ `user` and `group`; user-scope definitions reject both directives because the user
231
+ manager already runs under the calling identity. It defaults to `Type=exec`,
215
232
  journal output and null stdin. It introduces no shell; percent specifiers and
216
233
  argument environment expansion are escaped. Paths must be absolute and normalized;
217
234
  control characters are rejected. Descriptions and working directories cannot have
@@ -240,6 +257,45 @@ const installed = await file.install(definition, previous?.sha256 ?? null);
240
257
  console.log(installed.changed, installed.masked, installed.record.sha256);
241
258
  ```
242
259
 
260
+ For a user service, give the definition and installer the same scope:
261
+
262
+ ```typescript
263
+ const userDefinition = new SystemdServiceDefinition({
264
+ scope: 'user',
265
+ unitName: 'authswitch.service',
266
+ description: 'Account authority',
267
+ executable: '/opt/authswitch/bin/authswitch',
268
+ args: ['daemon'],
269
+ workingDirectory: '/opt/authswitch',
270
+ restart: 'on-failure',
271
+ killMode: 'mixed',
272
+ timeoutStopSeconds: 60,
273
+ });
274
+ const userFile = new SystemdUnitFile({ scope: 'user', unitName: userDefinition.unitName });
275
+ const previousUserFile = await userFile.inspect();
276
+ await userFile.install(userDefinition, previousUserFile?.sha256 ?? null);
277
+ ```
278
+
279
+ User definitions default to `WantedBy=default.target` and have no system-only
280
+ `After=local-fs.target` edge. User unit files default to
281
+ `$XDG_DATA_HOME/systemd/user` (or `~/.local/share/systemd/user`), below the user's
282
+ config directory in the unit load path. Installation and enablement use the
283
+ current user manager and do not escalate privileges. The installer rejects unsafe
284
+ ownership or group-writable path components; prepare those directories explicitly
285
+ before installation. It never changes the permissions of existing directories.
286
+
287
+ A user-scope `SystemdUnitFile` needs the user manager's runtime directory only for
288
+ `install()`, which admits, reloads and verifies through the manager. Without one,
289
+ `install()` rejects with `invalid_options` before touching any directory or running
290
+ `systemctl`. Construction and `inspect()` read only the unit directory and work
291
+ without it, so an owner can ask whether its definition is installed from a context
292
+ without a login session:
293
+
294
+ ```typescript
295
+ // Resolves to null when the file is absent, or { path, sha256 } for a protected definition.
296
+ const installed = await new SystemdUnitFile({ scope: 'user', unitName: 'authswitch.service' }).inspect();
297
+ ```
298
+
243
299
  For a boot prerequisite that must finish before dependent services start, supply
244
300
  `startup: { type: 'oneshot', remainAfterExit: true, timeoutStartSeconds: 120 }`.
245
301
  Systemd waits for successful process exit; `RemainAfterExit` keeps the completed
@@ -260,7 +316,7 @@ dependencies: {
260
316
  install: { wantedBy: [], requiredBy: ['network-pre.target', 'systemd-networkd.service'] },
261
317
  ```
262
318
 
263
- `After=local-fs.target` is always retained. Disable default dependencies only for
319
+ System definitions always retain `After=local-fs.target`. Disable default dependencies only for
264
320
  an intentionally early boot or late shutdown service. Every list is bounded to
265
321
  32 distinct literal unit names, sorted deterministically; templates, specifiers,
266
322
  self references and contradictory direct relationships are rejected. These local
@@ -305,17 +361,21 @@ read-only ISO. The API fixture checks enablement without implicit start, oneshot
305
361
  readiness, unchanged definition/configuration, detection of a missing provider
306
362
  link despite enabled state, exact enable retry and preservation of a mask.
307
363
 
308
- Installation requires Linux, root and a quiescent exact unit with no process,
364
+ Installation requires Linux, the relevant manager's user identity and a quiescent
365
+ exact unit with no process,
309
366
  cgroup or job. It rejects effective drop-ins and shadowing fragments. Definitions
310
- default to `/usr/local/lib/systemd/system`, below administrator configuration in
311
- the load path, so existing persistent/runtime masks remain intact. Existing
367
+ default to `/usr/local/lib/systemd/system` for system scope and the user's data
368
+ unit directory for user scope, below administrator or user configuration in the
369
+ load path, so existing persistent/runtime masks remain intact. Existing
312
370
  enablement is preserved; an absent unit becomes disabled. It never enables,
313
371
  unmasks, starts or stops a service, or invokes sudo.
314
372
 
315
- Masked units may report `/dev/null` or their exact administrator mask path:
373
+ Masked system units may report `/dev/null` or their exact administrator mask path:
316
374
  `/etc/systemd/system/<unit>` for a persistent mask, `/run/systemd/system/<unit>`
317
375
  for a runtime mask. Installation preserves that exact manager-selected fragment
318
376
  through the write and reload, and never replaces the masking fragment itself.
377
+ For user scope, the exact user config or runtime mask path and the global user-unit
378
+ mask paths are also recognized.
319
379
  Pending manager reloads are rejected before writing; inspect and explicitly
320
380
  reload an existing changed configuration before retrying installation.
321
381
 
@@ -329,7 +389,10 @@ the manager and checks its selected fragment and final bytes. A reload failure
329
389
  leaves the new file and retained previous definition in place; recovery requires
330
390
  inspection, never an automatic rollback. Filesystem and definition errors use
331
391
  `SystemdUnitFileError` with a local code. Trusted qualification code can set
332
- `unitDirectory`, `expectedUid` and the inherited `SystemdUnit` command options.
392
+ `unitDirectory`, `expectedUid` and the inherited `SystemdUnit` command options;
393
+ user scope requires `expectedUid` to match the caller's actual uid. The manager's
394
+ selected fragment must match the installed file after reload, so an unrecognized
395
+ custom user unit path fails closed.
333
396
 
334
397
  With `killMode: 'mixed'`, the main process owns graceful child shutdown and must
335
398
  remain alive until its children have joined. Systemd sends SIGTERM to the main
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartdaemon',
6
- version: '2.6.0',
6
+ version: '2.7.1',
7
7
  description: 'Start scripts as long running daemons and manage them.'
8
8
  }
@@ -3,14 +3,12 @@ import { renderServiceRelations, type ISystemdServiceStartup, type ISystemdServi
3
3
  type ISystemdServiceInstallTargets } from './systemd.definition.js';
4
4
  export type { ISystemdServiceStartup, ISystemdServiceDependencies, ISystemdServiceInstallTargets } from './systemd.definition.js';
5
5
 
6
- export interface ISystemdServiceDefinitionOptions {
6
+ interface ISystemdServiceDefinitionBaseOptions {
7
7
  unitName: string;
8
8
  description: string;
9
9
  executable: string;
10
10
  args: readonly string[];
11
11
  workingDirectory: string;
12
- user: string;
13
- group: string;
14
12
  restart: 'no' | 'on-failure' | 'always';
15
13
  killMode: 'mixed' | 'control-group';
16
14
  timeoutStopSeconds: number;
@@ -19,6 +17,11 @@ export interface ISystemdServiceDefinitionOptions {
19
17
  install?: ISystemdServiceInstallTargets;
20
18
  }
21
19
 
20
+ export type ISystemdServiceDefinitionOptions = ISystemdServiceDefinitionBaseOptions & (
21
+ { scope?: 'system'; user: string; group: string } |
22
+ { scope: 'user'; user?: never; group?: never }
23
+ );
24
+
22
25
  export class SystemdServiceDefinitionError extends Error {
23
26
  constructor() {
24
27
  super('Invalid direct systemd service definition.');
@@ -29,6 +32,7 @@ export class SystemdServiceDefinitionError extends Error {
29
32
  /** Literal direct-execution definition; never introduces a shell or environment expansion. */
30
33
  export class SystemdServiceDefinition {
31
34
  public readonly unitName: string;
35
+ public readonly scope: 'system' | 'user';
32
36
  public readonly content: string;
33
37
  public readonly sha256: string;
34
38
 
@@ -36,6 +40,16 @@ export class SystemdServiceDefinition {
36
40
  const requireValue = (value: unknown): void => {
37
41
  if (!value) throw new SystemdServiceDefinitionError();
38
42
  };
43
+ requireValue(options && !plugins.util.types.isProxy(options) &&
44
+ Object.getPrototypeOf(options) === Object.prototype);
45
+ const scopeDescriptor = Object.getOwnPropertyDescriptor(options, 'scope');
46
+ requireValue(scopeDescriptor === undefined ||
47
+ scopeDescriptor.enumerable && 'value' in scopeDescriptor);
48
+ const scopeValue: unknown = scopeDescriptor?.value ?? 'system';
49
+ if (scopeValue !== 'system' && scopeValue !== 'user') {
50
+ throw new SystemdServiceDefinitionError();
51
+ }
52
+ const scope = scopeValue;
39
53
  const text = (value: unknown, maximum = 4096): value is string =>
40
54
  typeof value === 'string' && value.length <= maximum && !/[\x00-\x1f\x7f]/.test(value) &&
41
55
  !/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u.test(value);
@@ -48,15 +62,13 @@ export class SystemdServiceDefinition {
48
62
  'executable',
49
63
  'args',
50
64
  'workingDirectory',
51
- 'user',
52
- 'group',
53
65
  'restart',
54
66
  'killMode',
55
67
  'timeoutStopSeconds',
68
+ ...(scope === 'system' ? ['user', 'group'] : []),
56
69
  ];
57
70
  requireValue(
58
- options && !plugins.util.types.isProxy(options) && Object.getPrototypeOf(options) === Object.prototype &&
59
- Reflect.ownKeys(options).every(key => typeof key === 'string' && [...keys, 'startup', 'dependencies', 'install'].includes(key)
71
+ Reflect.ownKeys(options).every(key => typeof key === 'string' && [...keys, 'scope', 'startup', 'dependencies', 'install'].includes(key)
60
72
  && Object.getOwnPropertyDescriptor(options, key)?.enumerable && 'value' in Object.getOwnPropertyDescriptor(options, key)!) && keys.every((key) => {
61
73
  const descriptor = Object.getOwnPropertyDescriptor(options, key);
62
74
  return descriptor && 'value' in descriptor;
@@ -87,11 +99,13 @@ export class SystemdServiceDefinition {
87
99
  )
88
100
  .every((descriptor) => descriptor && 'value' in descriptor && text(descriptor.value)),
89
101
  );
90
- requireValue(
91
- [options.user, options.group].every((value) =>
92
- typeof value === 'string' && /^[a-zA-Z_][a-zA-Z0-9_-]{0,63}$/.test(value)
93
- ),
94
- );
102
+ if (scope === 'system') {
103
+ requireValue(
104
+ [options.user, options.group].every((value) =>
105
+ typeof value === 'string' && /^[a-zA-Z_][a-zA-Z0-9_-]{0,63}$/.test(value)
106
+ ),
107
+ );
108
+ }
95
109
  requireValue(
96
110
  ['no', 'on-failure', 'always'].includes(options.restart) &&
97
111
  ['mixed', 'control-group'].includes(options.killMode) &&
@@ -104,8 +118,9 @@ export class SystemdServiceDefinition {
104
118
  .replaceAll('\\', '\\\\').replaceAll('"', '\\"').replaceAll('%', '%%')
105
119
  .replaceAll('$', () => command ? '$$' : '$') +
106
120
  '"';
107
- const relations = renderServiceRelations(options, options.unitName, options.restart, () => { throw new SystemdServiceDefinitionError(); });
121
+ const relations = renderServiceRelations(options, options.unitName, options.restart, scope, () => { throw new SystemdServiceDefinitionError(); });
108
122
  this.unitName = options.unitName;
123
+ this.scope = scope;
109
124
  this.content = [
110
125
  '[Unit]',
111
126
  `Description=${options.description.replaceAll('%', '%%')}`,
@@ -113,8 +128,7 @@ export class SystemdServiceDefinition {
113
128
  '',
114
129
  '[Service]',
115
130
  ...relations.service,
116
- `User=${options.user}`,
117
- `Group=${options.group}`,
131
+ ...(scope === 'system' ? [`User=${options.user}`, `Group=${options.group}`] : []),
118
132
  `ExecStart=${
119
133
  [quote(options.executable), ...options.args.map((value) => quote(value, true))].join(' ')
120
134
  }`,
@@ -2,6 +2,13 @@ import * as plugins from './smartdaemon.plugins.js';
2
2
 
3
3
  export interface ISystemdUnitOptions {
4
4
  unitName: string;
5
+ /** Defaults to the system manager. User scope addresses the calling user's manager only. */
6
+ scope?: 'system' | 'user';
7
+ /**
8
+ * User-manager socket directory. Defaults to a non-empty XDG_RUNTIME_DIR. May be absent at
9
+ * construction; every call that contacts the user manager then refuses with `invalid_options`.
10
+ */
11
+ runtimeDirectory?: string;
5
12
  /** Absolute executable path supplied by trusted owning code. */
6
13
  systemctlPath?: string;
7
14
  /** Bounds the systemctl client, not the server-side job. Defaults to 120 seconds. */
@@ -66,17 +73,44 @@ export class SystemdUnit {
66
73
  private readonly unitName: string;
67
74
  private readonly executable: string;
68
75
  private readonly timeout: number;
76
+ private readonly scope: 'system' | 'user';
77
+ private readonly runtimeDirectory?: string;
78
+ private readonly homeDirectory?: string;
79
+ private readonly configDirectory?: string;
80
+ private readonly dataDirectory?: string;
69
81
 
70
82
  constructor(optionsArg: ISystemdUnitOptions) {
71
83
  this.unitName = optionsArg?.unitName;
72
84
  this.executable = optionsArg?.systemctlPath ?? '/usr/bin/systemctl';
73
85
  this.timeout = optionsArg?.commandTimeoutMs ?? 120000;
86
+ this.scope = optionsArg?.scope ?? 'system';
87
+ // An empty XDG_RUNTIME_DIR counts as unset, like the sibling XDG variables below. An explicit
88
+ // option is never reinterpreted, so an empty or relative option stays malformed.
89
+ this.runtimeDirectory = this.scope === 'user'
90
+ ? optionsArg?.runtimeDirectory ?? (process.env.XDG_RUNTIME_DIR || undefined) : undefined;
91
+ this.homeDirectory = this.scope === 'user' ? plugins.os.userInfo().homedir : undefined;
92
+ this.configDirectory = this.scope === 'user' ? process.env.XDG_CONFIG_HOME || undefined : undefined;
93
+ this.dataDirectory = this.scope === 'user' ? process.env.XDG_DATA_HOME || undefined : undefined;
94
+ const safeDirectory = (value: unknown): value is string =>
95
+ typeof value === 'string' && value !== '/' && plugins.path.isAbsolute(value) &&
96
+ plugins.path.normalize(value) === value && !value.endsWith('/') &&
97
+ value.length <= 4000 && !/[\x00-\x1f\x7f]/.test(value);
98
+ // Only a supplied runtime directory is validated here. Its absence matters solely to calls that
99
+ // reach the user manager, and those refuse it in validateUserRuntime(). Admitting absence lets
100
+ // owners read protected unit files from contexts without a login session (cron, plain ssh).
74
101
  if (
75
102
  typeof this.unitName !== 'string' ||
76
103
  !/^[a-zA-Z0-9][a-zA-Z0-9_.:@-]{0,230}\.service$/.test(this.unitName) ||
77
104
  typeof this.executable !== 'string' || !plugins.path.isAbsolute(this.executable) ||
78
105
  this.executable.includes('\0') || !Number.isSafeInteger(this.timeout) ||
79
- this.timeout < 1 || this.timeout > 600000
106
+ this.timeout < 1 || this.timeout > 600000 ||
107
+ !['system', 'user'].includes(this.scope) ||
108
+ (this.scope === 'system' && optionsArg?.runtimeDirectory !== undefined) ||
109
+ (this.scope === 'user' &&
110
+ (this.runtimeDirectory !== undefined && !safeDirectory(this.runtimeDirectory) ||
111
+ !safeDirectory(this.homeDirectory) ||
112
+ this.configDirectory !== undefined && !safeDirectory(this.configDirectory) ||
113
+ this.dataDirectory !== undefined && !safeDirectory(this.dataDirectory)))
80
114
  ) throw new SystemdUnitError('invalid_options');
81
115
  }
82
116
 
@@ -193,18 +227,43 @@ export class SystemdUnit {
193
227
  return this.inspectConfiguration();
194
228
  }
195
229
 
196
- private command(argsArg: string[]): Promise<string> {
230
+ private async validateUserRuntime(): Promise<void> {
231
+ if (this.scope !== 'user') return;
232
+ // Runs before every systemctl invocation, so a missing directory refuses without side effects.
233
+ const runtimeDirectory = this.runtimeDirectory;
234
+ if (runtimeDirectory === undefined) throw new SystemdUnitError('invalid_options');
235
+ try {
236
+ const uid = process.getuid?.();
237
+ if (process.platform !== 'linux' || uid === undefined || process.geteuid?.() !== uid ||
238
+ await plugins.fs.realpath(runtimeDirectory) !== runtimeDirectory) {
239
+ throw new SystemdUnitError('invalid_options');
240
+ }
241
+ const info = await plugins.fs.lstat(runtimeDirectory);
242
+ if (!info.isDirectory() || info.isSymbolicLink() || info.uid !== uid ||
243
+ (info.mode & 0o077) !== 0) throw new SystemdUnitError('invalid_options');
244
+ } catch {
245
+ throw new SystemdUnitError('invalid_options');
246
+ }
247
+ }
248
+
249
+ private async command(argsArg: string[]): Promise<string> {
250
+ await this.validateUserRuntime();
197
251
  return new Promise((resolve, reject) => {
198
252
  plugins.childProcess.execFile(
199
253
  this.executable,
200
- ['--system', '--no-ask-password', '--no-pager', ...argsArg],
254
+ [this.scope === 'user' ? '--user' : '--system', '--no-ask-password', '--no-pager', ...argsArg],
201
255
  {
202
256
  encoding: 'utf8',
203
257
  timeout: this.timeout,
204
258
  killSignal: 'SIGKILL',
205
259
  maxBuffer: 16384,
206
260
  windowsHide: true,
207
- env: { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C' },
261
+ env: this.scope === 'user'
262
+ ? { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C',
263
+ HOME: this.homeDirectory!, XDG_RUNTIME_DIR: this.runtimeDirectory!,
264
+ ...(this.configDirectory ? { XDG_CONFIG_HOME: this.configDirectory } : {}),
265
+ ...(this.dataDirectory ? { XDG_DATA_HOME: this.dataDirectory } : {}) }
266
+ : { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C' },
208
267
  },
209
268
  (error, stdout) => {
210
269
  // execFile settles after the client closes. A timed-out client's remote job may continue.
@@ -10,7 +10,7 @@ import {
10
10
  export interface ISystemdUnitFileOptions extends ISystemdUnitOptions {
11
11
  /** Local vendor definitions can be installed without removing an administrator's mask. */
12
12
  unitDirectory?: string;
13
- /** Trusted owning-code qualification only. Defaults to root. */
13
+ /** Trusted owning-code qualification only. Defaults to root for system, current uid for user. */
14
14
  expectedUid?: number;
15
15
  }
16
16
  export interface ISystemdUnitFileRecord {
@@ -56,6 +56,9 @@ export class SystemdUnitFile {
56
56
  public readonly path: string;
57
57
  private readonly directory: string;
58
58
  private readonly uid: number;
59
+ private readonly scope: 'system' | 'user';
60
+ private readonly configDirectory?: string;
61
+ private readonly runtimeDirectory?: string;
59
62
  private readonly unit: SystemdUnit;
60
63
  private readonly name: string;
61
64
  private busy = false;
@@ -63,20 +66,39 @@ export class SystemdUnitFile {
63
66
  constructor(options: ISystemdUnitFileOptions) {
64
67
  this.unit = new SystemdUnit(options);
65
68
  this.name = options.unitName;
66
- this.directory = options.unitDirectory ?? '/usr/local/lib/systemd/system';
67
- this.uid = options.expectedUid ?? 0;
69
+ this.scope = options.scope ?? 'system';
70
+ const home = this.scope === 'user' ? plugins.os.userInfo().homedir : undefined;
71
+ const dataDirectory = this.scope === 'user'
72
+ ? process.env.XDG_DATA_HOME || plugins.path.join(home!, '.local/share') : undefined;
73
+ this.configDirectory = this.scope === 'user'
74
+ ? process.env.XDG_CONFIG_HOME || plugins.path.join(home!, '.config') : undefined;
75
+ // Resolved exactly as SystemdUnit resolves it, so both agree on presence.
76
+ this.runtimeDirectory = this.scope === 'user'
77
+ ? options.runtimeDirectory ?? (process.env.XDG_RUNTIME_DIR || undefined) : undefined;
78
+ this.directory = options.unitDirectory ?? (this.scope === 'user'
79
+ ? plugins.path.join(dataDirectory!, 'systemd/user') : '/usr/local/lib/systemd/system');
80
+ this.uid = options.expectedUid ?? (this.scope === 'user' ? process.getuid?.() ?? -1 : 0);
81
+ const validDirectory = (directory: unknown): directory is string =>
82
+ typeof directory === 'string' && directory !== '/' &&
83
+ plugins.path.isAbsolute(directory) && plugins.path.normalize(directory) === directory &&
84
+ !directory.endsWith('/') && !/[\x00-\x1f\x7f]/.test(directory) &&
85
+ directory.length <= 4000;
68
86
  requireValue(
69
- typeof this.directory === 'string' && this.directory !== '/' &&
70
- plugins.path.isAbsolute(this.directory) &&
71
- plugins.path.normalize(this.directory) === this.directory &&
72
- !this.directory.endsWith('/') && !/[\x00-\x1f\x7f]/.test(this.directory) &&
73
- this.directory.length <= 4000 && Number.isSafeInteger(this.uid) && this.uid >= 0,
87
+ validDirectory(this.directory) && Number.isSafeInteger(this.uid) && this.uid >= 0 &&
88
+ (this.scope === 'system' ||
89
+ this.uid === process.getuid?.() && validDirectory(this.configDirectory) &&
90
+ // inspect() reads only the unit directory, so an absent runtime directory is refused
91
+ // later, by install(); a supplied one must still be well formed.
92
+ (this.runtimeDirectory === undefined || validDirectory(this.runtimeDirectory))),
74
93
  'invalid_options',
75
94
  );
76
95
  this.path = plugins.path.join(this.directory, this.name);
77
96
  }
78
97
 
79
- /** Reads only the exact protected definition; no systemd or filesystem mutation. */
98
+ /**
99
+ * Reads only the exact protected definition; no systemd or filesystem mutation.
100
+ * Needs no user-manager runtime directory.
101
+ */
80
102
  public async inspect(): Promise<ISystemdUnitFileRecord | null> {
81
103
  if (!await this.directories(false)) return null;
82
104
  const file = await this.read(this.path);
@@ -93,8 +115,13 @@ export class SystemdUnitFile {
93
115
  ): Promise<Readonly<{ changed: boolean; record: ISystemdUnitFileRecord; masked: boolean }>> {
94
116
  requireValue(
95
117
  definition instanceof SystemdServiceDefinition && definition.unitName === this.name &&
118
+ definition.scope === this.scope &&
96
119
  (expectedSha256 === null ||
97
- typeof expectedSha256 === 'string' && /^[a-f0-9]{64}$/.test(expectedSha256)),
120
+ typeof expectedSha256 === 'string' && /^[a-f0-9]{64}$/.test(expectedSha256)) &&
121
+ // Installation admits, reloads and verifies through the user manager and recognizes its
122
+ // runtime mask path. Refusing here, before the busy latch and any directory or systemctl
123
+ // effect, keeps the local error code instead of a wrapped write_failed.
124
+ (this.scope === 'system' || this.runtimeDirectory !== undefined),
98
125
  'invalid_options',
99
126
  );
100
127
  requireValue(!this.busy, 'busy');
@@ -196,15 +223,19 @@ export class SystemdUnitFile {
196
223
  'unsafe_unit',
197
224
  );
198
225
  const configuration = await this.unit.inspectConfiguration();
199
- const maskPath = plugins.path.join(
200
- state.unitFileState === 'masked-runtime' ? '/run/systemd/system' : '/etc/systemd/system',
201
- this.name,
202
- );
226
+ const maskPaths = this.scope === 'system'
227
+ ? [plugins.path.join(
228
+ state.unitFileState === 'masked-runtime' ? '/run/systemd/system' : '/etc/systemd/system',
229
+ this.name,
230
+ )]
231
+ : (state.unitFileState === 'masked-runtime'
232
+ ? [this.runtimeDirectory!, '/run'].map(root => plugins.path.join(root, 'systemd/user', this.name))
233
+ : [this.configDirectory!, '/etc'].map(root => plugins.path.join(root, 'systemd/user', this.name)));
203
234
  requireValue(
204
235
  !configuration.needsReload && configuration.dropInPaths === '' &&
205
236
  (masked(state)
206
237
  ? configuration.fragmentPath !== this.path &&
207
- ['/dev/null', maskPath].includes(configuration.fragmentPath)
238
+ ['/dev/null', ...maskPaths].includes(configuration.fragmentPath)
208
239
  : configuration.fragmentPath === (state.loadState === 'not-found' ? '' : this.path)),
209
240
  'unsafe_unit',
210
241
  );
@@ -5,9 +5,10 @@ import * as fs from 'node:fs/promises';
5
5
  import { constants as fsConstants } from 'node:fs';
6
6
  import * as crypto from 'node:crypto';
7
7
  import * as util from 'node:util';
8
+ import * as os from 'node:os';
8
9
  export type { Stats } from 'node:fs';
9
10
 
10
- export { path, childProcess, fs, fsConstants, crypto, util };
11
+ export { path, childProcess, fs, fsConstants, crypto, util, os };
11
12
 
12
13
  // @pushrocks scope
13
14
  import * as lik from '@push.rocks/lik';
@@ -6,7 +6,7 @@ export interface ISystemdServiceStartup {
6
6
  timeoutStartSeconds: number;
7
7
  }
8
8
 
9
- /** Complete literal relations. After=local-fs.target is always retained. */
9
+ /** Complete literal relations. System services always retain After=local-fs.target. */
10
10
  export interface ISystemdServiceDependencies {
11
11
  defaultDependencies: boolean;
12
12
  after: readonly string[];
@@ -27,7 +27,7 @@ export const renderServiceRelations = (options: {
27
27
  startup?: ISystemdServiceStartup;
28
28
  dependencies?: ISystemdServiceDependencies;
29
29
  install?: ISystemdServiceInstallTargets;
30
- }, unitName: string, restart: string, fail: () => never): {
30
+ }, unitName: string, restart: string, scope: 'system' | 'user', fail: () => never): {
31
31
  unit: string[]; service: string[]; install: string[];
32
32
  } => {
33
33
  const requireValue = (value: unknown): void => { if (!value) fail(); };
@@ -55,7 +55,11 @@ export const renderServiceRelations = (options: {
55
55
  return result.sort();
56
56
  };
57
57
  const line = (key: string, value: readonly string[]): string[] => value.length ? [`${key}=${value.join(' ')}`] : [];
58
- const result = { unit: ['After=local-fs.target'], service: ['Type=exec'], install: ['WantedBy=multi-user.target'] };
58
+ const result = {
59
+ unit: scope === 'system' ? ['After=local-fs.target'] : [] as string[],
60
+ service: ['Type=exec'],
61
+ install: [scope === 'system' ? 'WantedBy=multi-user.target' : 'WantedBy=default.target'],
62
+ };
59
63
  if (options.startup !== undefined) {
60
64
  const value = options.startup;
61
65
  record(value, ['type', 'remainAfterExit', 'timeoutStartSeconds']);
@@ -67,7 +71,7 @@ export const renderServiceRelations = (options: {
67
71
  const value = options.dependencies;
68
72
  record(value, ['defaultDependencies', 'after', 'before', 'requires', 'wants', 'conflicts']);
69
73
  requireValue(typeof value.defaultDependencies === 'boolean');
70
- const after = [...new Set(['local-fs.target', ...units(value.after)])].sort();
74
+ const after = [...new Set([...(scope === 'system' ? ['local-fs.target'] : []), ...units(value.after)])].sort();
71
75
  const before = units(value.before), requires = units(value.requires), wants = units(value.wants), conflicts = units(value.conflicts);
72
76
  requireValue(before.every(item => !after.includes(item)) && conflicts.every(item => !requires.includes(item) && !wants.includes(item)));
73
77
  result.unit = [`DefaultDependencies=${value.defaultDependencies ? 'yes' : 'no'}`, ...line('After', after),