@opentag/cli 0.3.3 → 0.3.4
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/dist/index.js +61 -7
- package/dist/index.js.map +1 -1
- package/dist/service.d.ts +1 -0
- package/dist/service.d.ts.map +1 -1
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -2667,6 +2667,15 @@ var serviceHardeningEnvKeys = [
|
|
|
2667
2667
|
"OPENTAG_RATE_LIMIT_MAX_REQUESTS",
|
|
2668
2668
|
"OPENTAG_RATE_LIMIT_DISABLED"
|
|
2669
2669
|
];
|
|
2670
|
+
var launchAgentCliPath = [
|
|
2671
|
+
"/opt/homebrew/bin",
|
|
2672
|
+
"/opt/homebrew/sbin",
|
|
2673
|
+
"/usr/local/bin",
|
|
2674
|
+
"/usr/bin",
|
|
2675
|
+
"/bin",
|
|
2676
|
+
"/usr/sbin",
|
|
2677
|
+
"/sbin"
|
|
2678
|
+
].join(":");
|
|
2670
2679
|
function loggerFrom(dependencies) {
|
|
2671
2680
|
return dependencies.logger ?? console;
|
|
2672
2681
|
}
|
|
@@ -2769,11 +2778,38 @@ function assertMacOS(dependencies) {
|
|
|
2769
2778
|
function runLaunchctlOrThrow(dependencies, args, action) {
|
|
2770
2779
|
const result = launchctlRunner(dependencies)(args);
|
|
2771
2780
|
if (result.status !== 0) {
|
|
2772
|
-
const detail =
|
|
2781
|
+
const detail = launchctlDetail(result);
|
|
2773
2782
|
throw new Error(`${action} failed${detail ? `: ${detail}` : "."}`);
|
|
2774
2783
|
}
|
|
2775
2784
|
return result;
|
|
2776
2785
|
}
|
|
2786
|
+
function launchctlDetail(result) {
|
|
2787
|
+
return [result.stderr.trim(), result.stdout.trim()].filter(Boolean).join("\n");
|
|
2788
|
+
}
|
|
2789
|
+
function printLaunchdService(dependencies) {
|
|
2790
|
+
return launchctlRunner(dependencies)(["print", launchdServiceTarget(dependencies)]);
|
|
2791
|
+
}
|
|
2792
|
+
function sleepFrom(dependencies) {
|
|
2793
|
+
return dependencies.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
|
|
2794
|
+
}
|
|
2795
|
+
async function waitForLaunchdLoaded(dependencies, input = {}) {
|
|
2796
|
+
const intervalMs = input.intervalMs ?? 100;
|
|
2797
|
+
const deadline = Date.now() + (input.timeoutMs ?? 1500);
|
|
2798
|
+
while (true) {
|
|
2799
|
+
if (printLaunchdService(dependencies).status === 0) return true;
|
|
2800
|
+
if (Date.now() >= deadline) return false;
|
|
2801
|
+
await sleepFrom(dependencies)(intervalMs);
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
async function waitForLaunchdUnloaded(dependencies, input = {}) {
|
|
2805
|
+
const intervalMs = input.intervalMs ?? 100;
|
|
2806
|
+
const deadline = Date.now() + (input.timeoutMs ?? 1500);
|
|
2807
|
+
while (true) {
|
|
2808
|
+
if (printLaunchdService(dependencies).status !== 0) return true;
|
|
2809
|
+
if (Date.now() >= deadline) return false;
|
|
2810
|
+
await sleepFrom(dependencies)(intervalMs);
|
|
2811
|
+
}
|
|
2812
|
+
}
|
|
2777
2813
|
function serviceWorkingDirectory(configPath) {
|
|
2778
2814
|
const config = readCliConfig(configPath);
|
|
2779
2815
|
return config.daemon.repositories[0]?.checkoutPath ?? dirname2(configPath);
|
|
@@ -2850,6 +2886,7 @@ function formatConnectorReadiness(config) {
|
|
|
2850
2886
|
function launchAgentEnvironment(options, paths) {
|
|
2851
2887
|
return {
|
|
2852
2888
|
OPENTAG_CONFIG_PATH: paths.configPath,
|
|
2889
|
+
PATH: launchAgentCliPath,
|
|
2853
2890
|
...serviceHardeningEnvironment(options)
|
|
2854
2891
|
};
|
|
2855
2892
|
}
|
|
@@ -2889,13 +2926,17 @@ function startService(options = {}, dependencies = {}) {
|
|
|
2889
2926
|
const launchctl = launchctlRunner(dependencies);
|
|
2890
2927
|
const bootstrap = launchctl(["bootstrap", launchdDomain(dependencies), paths.plistPath]);
|
|
2891
2928
|
if (bootstrap.status !== 0) {
|
|
2892
|
-
const print =
|
|
2929
|
+
const print = printLaunchdService(dependencies);
|
|
2893
2930
|
if (print.status !== 0) {
|
|
2894
|
-
const detail =
|
|
2931
|
+
const detail = launchctlDetail(bootstrap);
|
|
2895
2932
|
throw new Error(`launchctl bootstrap failed${detail ? `: ${detail}` : "."}`);
|
|
2896
2933
|
}
|
|
2897
2934
|
}
|
|
2898
|
-
|
|
2935
|
+
const kickstart = launchctl(["kickstart", "-k", launchdServiceTarget(dependencies)]);
|
|
2936
|
+
if (kickstart.status !== 0 && printLaunchdService(dependencies).status !== 0) {
|
|
2937
|
+
const detail = launchctlDetail(kickstart);
|
|
2938
|
+
throw new Error(`launchctl kickstart failed${detail ? `: ${detail}` : "."}`);
|
|
2939
|
+
}
|
|
2899
2940
|
return paths;
|
|
2900
2941
|
}
|
|
2901
2942
|
function stopService(options = {}, dependencies = {}) {
|
|
@@ -2904,10 +2945,11 @@ function stopService(options = {}, dependencies = {}) {
|
|
|
2904
2945
|
if (!installed(paths)) return paths;
|
|
2905
2946
|
const launchctl = launchctlRunner(dependencies);
|
|
2906
2947
|
const first = launchctl(["bootout", launchdServiceTarget(dependencies)]);
|
|
2907
|
-
if (first.status !== 0
|
|
2948
|
+
if (first.status !== 0) {
|
|
2908
2949
|
const second = launchctl(["bootout", launchdDomain(dependencies), paths.plistPath]);
|
|
2909
2950
|
if (second.status !== 0 && !isNotLoaded(second)) {
|
|
2910
|
-
const
|
|
2951
|
+
const firstDetail = isNotLoaded(first) ? "" : launchctlDetail(first);
|
|
2952
|
+
const detail = [launchctlDetail(second), firstDetail].filter(Boolean).join("\n");
|
|
2911
2953
|
throw new Error(`launchctl bootout failed${detail ? `: ${detail}` : "."}`);
|
|
2912
2954
|
}
|
|
2913
2955
|
}
|
|
@@ -3166,6 +3208,9 @@ async function runServiceInstallCommand(options, dependencies = {}) {
|
|
|
3166
3208
|
}
|
|
3167
3209
|
async function runServiceStartCommand(options, dependencies = {}) {
|
|
3168
3210
|
const paths = startService(options, dependencies);
|
|
3211
|
+
if (!await waitForLaunchdLoaded(dependencies)) {
|
|
3212
|
+
throw new Error("OpenTag service start did not leave launchd loaded. Run `opentag service status` and `opentag service logs` for details.");
|
|
3213
|
+
}
|
|
3169
3214
|
loggerFrom(dependencies).log(`OpenTag service started: ${paths.label}`);
|
|
3170
3215
|
}
|
|
3171
3216
|
async function runServiceStopCommand(options, dependencies = {}) {
|
|
@@ -3174,7 +3219,16 @@ async function runServiceStopCommand(options, dependencies = {}) {
|
|
|
3174
3219
|
}
|
|
3175
3220
|
async function runServiceRestartCommand(options, dependencies = {}) {
|
|
3176
3221
|
stopService(options, dependencies);
|
|
3177
|
-
|
|
3222
|
+
await waitForLaunchdUnloaded(dependencies, { timeoutMs: 1e3 });
|
|
3223
|
+
let paths = startService(options, dependencies);
|
|
3224
|
+
let loaded = await waitForLaunchdLoaded(dependencies, { timeoutMs: 500 });
|
|
3225
|
+
if (!loaded) {
|
|
3226
|
+
paths = startService(options, dependencies);
|
|
3227
|
+
loaded = await waitForLaunchdLoaded(dependencies);
|
|
3228
|
+
}
|
|
3229
|
+
if (!loaded) {
|
|
3230
|
+
throw new Error("OpenTag service restart did not leave launchd loaded. Run `opentag service status` and `opentag service logs` for details.");
|
|
3231
|
+
}
|
|
3178
3232
|
loggerFrom(dependencies).log(`OpenTag service restarted: ${paths.label}`);
|
|
3179
3233
|
}
|
|
3180
3234
|
async function runServiceUninstallCommand(options, dependencies = {}) {
|