amaprice 1.0.13 → 1.0.15
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/background/service.js +73 -22
package/package.json
CHANGED
|
@@ -114,15 +114,17 @@ function isLaunchdSupported(platform = process.platform) {
|
|
|
114
114
|
return platform === 'darwin';
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
function
|
|
117
|
+
function getLaunchdDomains() {
|
|
118
118
|
if (typeof process.getuid !== 'function') {
|
|
119
119
|
throw new Error('launchd requires a POSIX uid');
|
|
120
120
|
}
|
|
121
|
-
|
|
121
|
+
const uid = process.getuid();
|
|
122
|
+
return [`gui/${uid}`, `user/${uid}`];
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
function buildServiceTarget(label) {
|
|
125
|
-
|
|
125
|
+
function buildServiceTarget(label, domain = null) {
|
|
126
|
+
const safeDomain = domain || getLaunchdDomains()[0];
|
|
127
|
+
return `${safeDomain}/${label}`;
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
async function runLaunchctl(args, { allowFailure = false } = {}) {
|
|
@@ -233,24 +235,38 @@ async function getLaunchdServiceStatus({ label }) {
|
|
|
233
235
|
backend: 'launchd',
|
|
234
236
|
label,
|
|
235
237
|
plistPath,
|
|
238
|
+
domain: null,
|
|
236
239
|
installed: false,
|
|
237
240
|
loaded: false,
|
|
238
241
|
running: false,
|
|
239
242
|
};
|
|
240
243
|
}
|
|
241
244
|
|
|
242
|
-
const
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
245
|
+
const domains = getLaunchdDomains();
|
|
246
|
+
for (const domain of domains) {
|
|
247
|
+
const print = await runLaunchctl(['print', buildServiceTarget(label, domain)], { allowFailure: true });
|
|
248
|
+
if (!print.ok) continue;
|
|
249
|
+
const output = `${print.stdout}\n${print.stderr}`;
|
|
250
|
+
const running = /state = running/i.test(output) || /pid = \d+/i.test(output);
|
|
251
|
+
return {
|
|
252
|
+
backend: 'launchd',
|
|
253
|
+
label,
|
|
254
|
+
plistPath,
|
|
255
|
+
domain,
|
|
256
|
+
installed: true,
|
|
257
|
+
loaded: true,
|
|
258
|
+
running,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
246
261
|
|
|
247
262
|
return {
|
|
248
263
|
backend: 'launchd',
|
|
249
264
|
label,
|
|
250
265
|
plistPath,
|
|
266
|
+
domain: domains[0] || null,
|
|
251
267
|
installed: true,
|
|
252
|
-
loaded,
|
|
253
|
-
running,
|
|
268
|
+
loaded: false,
|
|
269
|
+
running: false,
|
|
254
270
|
};
|
|
255
271
|
}
|
|
256
272
|
|
|
@@ -283,24 +299,53 @@ async function enableLaunchdService({
|
|
|
283
299
|
});
|
|
284
300
|
await fs.writeFile(plistPath, plist, 'utf8');
|
|
285
301
|
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
throw new Error(`Could not bootstrap launchd service: ${bootstrap.stderr || bootstrap.stdout || 'unknown error'}`);
|
|
289
|
-
}
|
|
302
|
+
const domains = getLaunchdDomains();
|
|
303
|
+
const errors = [];
|
|
290
304
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
305
|
+
for (const domain of domains) {
|
|
306
|
+
const domainTarget = buildServiceTarget(label, domain);
|
|
307
|
+
|
|
308
|
+
// Clean stale state first, then bootstrap fresh.
|
|
309
|
+
await runLaunchctl(['bootout', domainTarget], { allowFailure: true });
|
|
310
|
+
await runLaunchctl(['disable', domainTarget], { allowFailure: true });
|
|
311
|
+
await runLaunchctl(['enable', domainTarget], { allowFailure: true });
|
|
312
|
+
|
|
313
|
+
let bootstrap = await runLaunchctl(['bootstrap', domain, plistPath], { allowFailure: true });
|
|
314
|
+
if (!bootstrap.ok && !isAlreadyLoadedError(bootstrap)) {
|
|
315
|
+
await runLaunchctl(['bootout', domainTarget], { allowFailure: true });
|
|
316
|
+
await runLaunchctl(['enable', domainTarget], { allowFailure: true });
|
|
317
|
+
bootstrap = await runLaunchctl(['bootstrap', domain, plistPath], { allowFailure: true });
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (!bootstrap.ok && !isAlreadyLoadedError(bootstrap)) {
|
|
321
|
+
errors.push(`${domain}: ${bootstrap.stderr || bootstrap.stdout || 'unknown error'}`);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
await runLaunchctl(['enable', domainTarget], { allowFailure: true });
|
|
326
|
+
const kick = await runLaunchctl(['kickstart', '-k', domainTarget], { allowFailure: true });
|
|
327
|
+
if (!kick.ok) {
|
|
328
|
+
await runLaunchctl(['start', label], { allowFailure: true });
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const status = await getLaunchdServiceStatus({ label });
|
|
332
|
+
if (status.loaded) {
|
|
333
|
+
return status;
|
|
334
|
+
}
|
|
335
|
+
errors.push(`${domain}: bootstrapped but service not loaded`);
|
|
295
336
|
}
|
|
296
337
|
|
|
297
|
-
|
|
338
|
+
const msg = errors.length > 0 ? errors.join(' | ') : 'unknown error';
|
|
339
|
+
throw new Error(`Could not bootstrap launchd service: ${msg}`);
|
|
298
340
|
}
|
|
299
341
|
|
|
300
342
|
async function disableLaunchdService({ label }) {
|
|
301
343
|
const plistPath = getLaunchdPlistPath(label);
|
|
302
|
-
|
|
303
|
-
|
|
344
|
+
for (const domain of getLaunchdDomains()) {
|
|
345
|
+
const target = buildServiceTarget(label, domain);
|
|
346
|
+
await runLaunchctl(['bootout', target], { allowFailure: true });
|
|
347
|
+
await runLaunchctl(['disable', target], { allowFailure: true });
|
|
348
|
+
}
|
|
304
349
|
try {
|
|
305
350
|
await fs.unlink(plistPath);
|
|
306
351
|
} catch (err) {
|
|
@@ -332,7 +377,7 @@ async function ensureBackgroundOn({
|
|
|
332
377
|
const { collector, statePath } = await ensureCollectorEnabled({
|
|
333
378
|
userId,
|
|
334
379
|
collectorName,
|
|
335
|
-
status: '
|
|
380
|
+
status: 'paused',
|
|
336
381
|
});
|
|
337
382
|
|
|
338
383
|
const service = await enableLaunchdService({
|
|
@@ -342,6 +387,10 @@ async function ensureBackgroundOn({
|
|
|
342
387
|
userId,
|
|
343
388
|
});
|
|
344
389
|
|
|
390
|
+
if (!service.loaded) {
|
|
391
|
+
throw new Error('launchd service did not load');
|
|
392
|
+
}
|
|
393
|
+
|
|
345
394
|
await heartbeatCollector({
|
|
346
395
|
collectorId: collector.id,
|
|
347
396
|
status: 'active',
|
|
@@ -500,6 +549,8 @@ module.exports.__test = {
|
|
|
500
549
|
resolvePollSeconds,
|
|
501
550
|
getLaunchdLabel,
|
|
502
551
|
getLaunchdPlistPath,
|
|
552
|
+
getLaunchdDomains,
|
|
553
|
+
buildServiceTarget,
|
|
503
554
|
renderLaunchdPlist,
|
|
504
555
|
isLaunchdSupported,
|
|
505
556
|
};
|