unitup 0.1.1 → 0.1.2
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.
- package/package.json +1 -1
- package/src/schedule.js +4 -5
- package/src/unit.js +3 -10
- package/src/utils.js +26 -1
package/package.json
CHANGED
package/src/schedule.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
getUnitFilename,
|
|
7
7
|
getTimerFilename,
|
|
8
8
|
resolveAbsolutePath,
|
|
9
|
+
resolveWorkingDirectory,
|
|
9
10
|
validateDuration,
|
|
10
11
|
formatFutureTime,
|
|
11
12
|
formatRelativeTime,
|
|
@@ -125,11 +126,7 @@ export async function createSchedule(opts = {}) {
|
|
|
125
126
|
const execArgs = resolved.args;
|
|
126
127
|
const detectedRuntime = resolved.runtime;
|
|
127
128
|
|
|
128
|
-
const cwd = opts.cwd
|
|
129
|
-
? resolveAbsolutePath(opts.cwd)
|
|
130
|
-
: scriptPath
|
|
131
|
-
? path.dirname(scriptPath)
|
|
132
|
-
: process.cwd();
|
|
129
|
+
const cwd = resolveWorkingDirectory({ cwd: opts.cwd, script: scriptPath });
|
|
133
130
|
|
|
134
131
|
const envObj = {};
|
|
135
132
|
if (opts.env) {
|
|
@@ -173,6 +170,7 @@ export async function createSchedule(opts = {}) {
|
|
|
173
170
|
|
|
174
171
|
if (opts.start || opts.enable) {
|
|
175
172
|
await runCommand('systemctl', ['--user', 'daemon-reload']);
|
|
173
|
+
await runCommand('systemctl', ['--user', 'reset-failed', getUnitFilename(safeName), getTimerFilename(safeName)]);
|
|
176
174
|
await runCommand('systemctl', ['--user', 'enable', getTimerFilename(safeName)]);
|
|
177
175
|
await runCommand('systemctl', ['--user', 'start', getTimerFilename(safeName)]);
|
|
178
176
|
}
|
|
@@ -212,6 +210,7 @@ export async function enableSchedule(name) {
|
|
|
212
210
|
throw new Error(`Schedule timer unit up for "${name}" does not exist.`);
|
|
213
211
|
}
|
|
214
212
|
await runCommand('systemctl', ['--user', 'daemon-reload']);
|
|
213
|
+
await runCommand('systemctl', ['--user', 'reset-failed', getUnitFilename(safeName), getTimerFilename(safeName)]);
|
|
215
214
|
const res = await runCommand('systemctl', ['--user', 'enable', '--now', getTimerFilename(safeName)]);
|
|
216
215
|
return res.code === 0;
|
|
217
216
|
}
|
package/src/unit.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
formatSystemdEnv,
|
|
10
10
|
escapeExecArg,
|
|
11
11
|
resolveAbsolutePath,
|
|
12
|
+
resolveWorkingDirectory,
|
|
12
13
|
saveAppMetadata,
|
|
13
14
|
deleteAppMetadata,
|
|
14
15
|
saveScheduleMetadata,
|
|
@@ -83,11 +84,7 @@ export function generateUnitContent(opts) {
|
|
|
83
84
|
throw new Error('Either "command" or "script" must be provided to generate systemd unit file.');
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
const cwd = opts
|
|
87
|
-
? resolveAbsolutePath(opts.cwd)
|
|
88
|
-
: opts.script
|
|
89
|
-
? path.dirname(resolveAbsolutePath(opts.script))
|
|
90
|
-
: process.cwd();
|
|
87
|
+
const cwd = resolveWorkingDirectory(opts);
|
|
91
88
|
const restartPolicy = opts.restart || 'on-failure';
|
|
92
89
|
|
|
93
90
|
const execStartTokens = [commandExec, ...execArgs];
|
|
@@ -309,11 +306,7 @@ export function generateScheduleServiceContent(opts) {
|
|
|
309
306
|
throw new Error('Either "command" or "script" must be provided to generate scheduled unit file.');
|
|
310
307
|
}
|
|
311
308
|
|
|
312
|
-
const cwd = opts
|
|
313
|
-
? resolveAbsolutePath(opts.cwd)
|
|
314
|
-
: opts.script
|
|
315
|
-
? path.dirname(resolveAbsolutePath(opts.script))
|
|
316
|
-
: process.cwd();
|
|
309
|
+
const cwd = resolveWorkingDirectory(opts);
|
|
317
310
|
|
|
318
311
|
const execStartTokens = [commandExec, ...execArgs];
|
|
319
312
|
const execStartLine = execStartTokens.map(escapeExecArg).join(' ');
|
package/src/utils.js
CHANGED
|
@@ -141,7 +141,7 @@ export function saveAppMetadata(meta) {
|
|
|
141
141
|
const rawArgs = Array.isArray(meta.args) ? meta.args : (meta.script ? [meta.script] : []);
|
|
142
142
|
const args = rawArgs.map(a => (a.startsWith('/') || a.startsWith('./') || a.startsWith('../') || a.startsWith('~/')) ? resolveAbsolutePath(a) : a);
|
|
143
143
|
const scriptPath = meta.script ? resolveAbsolutePath(meta.script) : (args[0] ? resolveAbsolutePath(args[0]) : command);
|
|
144
|
-
const cwd =
|
|
144
|
+
const cwd = resolveWorkingDirectory(meta);
|
|
145
145
|
|
|
146
146
|
// Extract memory resources if present
|
|
147
147
|
const resources = meta.resources || {};
|
|
@@ -302,6 +302,31 @@ export function resolveAbsolutePath(filepath, baseDir = process.cwd()) {
|
|
|
302
302
|
return path.resolve(baseDir, p);
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
+
/**
|
|
306
|
+
* Safely resolves the working directory for a service or schedule unit.
|
|
307
|
+
*
|
|
308
|
+
* @param {Object} [opts]
|
|
309
|
+
* @returns {string}
|
|
310
|
+
*/
|
|
311
|
+
export function resolveWorkingDirectory(opts = {}) {
|
|
312
|
+
if (opts.cwd) {
|
|
313
|
+
return resolveAbsolutePath(opts.cwd);
|
|
314
|
+
}
|
|
315
|
+
if (opts.script) {
|
|
316
|
+
return path.dirname(resolveAbsolutePath(opts.script));
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
const cwd = process.cwd();
|
|
320
|
+
if (fs.existsSync(cwd)) {
|
|
321
|
+
fs.accessSync(cwd, fs.constants.R_OK | fs.constants.X_OK);
|
|
322
|
+
return cwd;
|
|
323
|
+
}
|
|
324
|
+
} catch {
|
|
325
|
+
// fallback if process.cwd() is inaccessible
|
|
326
|
+
}
|
|
327
|
+
return os.homedir();
|
|
328
|
+
}
|
|
329
|
+
|
|
305
330
|
/**
|
|
306
331
|
* Escapes values for systemd Environment= line entries.
|
|
307
332
|
* E.g. KEY="val with spaces"
|