@rubytech/taskmaster 1.28.0 → 1.29.0
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/build-info.json +3 -3
- package/dist/cli/provision-cli.js +24 -0
- package/dist/logging/logger.js +16 -7
- package/package.json +1 -1
package/dist/build-info.json
CHANGED
|
@@ -66,6 +66,12 @@ async function runProvision(opts) {
|
|
|
66
66
|
console.log("[5/7] Hostname: skipped (macOS)");
|
|
67
67
|
console.log("[6/7] Avahi service: skipped (macOS)");
|
|
68
68
|
}
|
|
69
|
+
// Step 6b: Log directory (Linux only) — ensure /tmp/taskmaster is world-writable
|
|
70
|
+
// on every boot via systemd-tmpfiles.d so the gateway can always write logs there
|
|
71
|
+
// regardless of which user created the directory previously.
|
|
72
|
+
if (isLinux) {
|
|
73
|
+
await setupLogDir();
|
|
74
|
+
}
|
|
69
75
|
// Step 7: Install daemon
|
|
70
76
|
console.log("[7/7] Installing gateway daemon...");
|
|
71
77
|
await runDaemonInstall({ port, force: true });
|
|
@@ -218,6 +224,24 @@ async function restartAvahi() {
|
|
|
218
224
|
}
|
|
219
225
|
}
|
|
220
226
|
// ---------------------------------------------------------------------------
|
|
227
|
+
// Step 6b: Log directory (Linux only)
|
|
228
|
+
// ---------------------------------------------------------------------------
|
|
229
|
+
async function setupLogDir() {
|
|
230
|
+
const tmpfileConf = "/etc/tmpfiles.d/taskmaster.conf";
|
|
231
|
+
const confLine = "d /tmp/taskmaster 1777 root root -\n";
|
|
232
|
+
console.log("[6b/7] Log directory: writing systemd-tmpfiles.d entry...");
|
|
233
|
+
try {
|
|
234
|
+
await runCommandWithTimeout(["sudo", "sh", "-c", `echo '${confLine.trim()}' > ${tmpfileConf}`], { timeoutMs: 10_000 });
|
|
235
|
+
await runCommandWithTimeout(["sudo", "systemd-tmpfiles", "--create", tmpfileConf], {
|
|
236
|
+
timeoutMs: 10_000,
|
|
237
|
+
});
|
|
238
|
+
console.log(" /tmp/taskmaster: world-writable (1777), persists across reboots");
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
console.error(` log dir setup failed: ${String(err)}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
221
245
|
// Helpers
|
|
222
246
|
// ---------------------------------------------------------------------------
|
|
223
247
|
async function fileExists(p) {
|
package/dist/logging/logger.js
CHANGED
|
@@ -6,9 +6,14 @@ import { Logger as TsLogger } from "tslog";
|
|
|
6
6
|
import { levelToMinLevel, normalizeLogLevel } from "./levels.js";
|
|
7
7
|
import { readLoggingConfig } from "./config.js";
|
|
8
8
|
import { loggingState } from "./state.js";
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
|
|
9
|
+
// macOS: use /tmp so the Debug UI "Open log" button points to a stable path.
|
|
10
|
+
// os.tmpdir() on macOS can be a per-user randomized path which made that button a no-op.
|
|
11
|
+
// Linux (Pi): use ~/.taskmaster/logs — /tmp uses the sticky bit so directories created
|
|
12
|
+
// there by a root process (e.g. an earlier daemon run) cannot be chmod'd by the user,
|
|
13
|
+
// making /tmp/taskmaster permanently unwritable after any accidental root creation.
|
|
14
|
+
export const DEFAULT_LOG_DIR = process.platform === "darwin"
|
|
15
|
+
? "/tmp/taskmaster"
|
|
16
|
+
: path.join(os.homedir(), ".taskmaster", "logs");
|
|
12
17
|
export const DEFAULT_LOG_FILE = path.join(DEFAULT_LOG_DIR, "taskmaster.log"); // legacy single-file path
|
|
13
18
|
const LOG_PREFIX = "taskmaster";
|
|
14
19
|
const LOG_SUFFIX = ".log";
|
|
@@ -123,15 +128,16 @@ function buildLogger(settings) {
|
|
|
123
128
|
for (const transport of externalTransports) {
|
|
124
129
|
attachExternalTransport(logger, transport);
|
|
125
130
|
}
|
|
126
|
-
return logger;
|
|
131
|
+
return { logger, resolved: settings };
|
|
127
132
|
}
|
|
128
133
|
export function getLogger() {
|
|
129
134
|
const settings = resolveSettings();
|
|
130
135
|
const cachedLogger = loggingState.cachedLogger;
|
|
131
136
|
const cachedSettings = loggingState.cachedSettings;
|
|
132
137
|
if (!cachedLogger || settingsChanged(cachedSettings, settings)) {
|
|
133
|
-
|
|
134
|
-
loggingState.
|
|
138
|
+
const { logger, resolved } = buildLogger(settings);
|
|
139
|
+
loggingState.cachedLogger = logger;
|
|
140
|
+
loggingState.cachedSettings = resolved;
|
|
135
141
|
}
|
|
136
142
|
return loggingState.cachedLogger;
|
|
137
143
|
}
|
|
@@ -162,7 +168,10 @@ export function toPinoLikeLogger(logger, level) {
|
|
|
162
168
|
};
|
|
163
169
|
}
|
|
164
170
|
export function getResolvedLoggerSettings() {
|
|
165
|
-
|
|
171
|
+
// Return cached settings when available — they reflect the actual write location,
|
|
172
|
+
// which may differ from resolveSettings() if ensureWritableLogDir fell back to a
|
|
173
|
+
// different directory (e.g. when /tmp/taskmaster is owned by root).
|
|
174
|
+
return loggingState.cachedSettings ?? resolveSettings();
|
|
166
175
|
}
|
|
167
176
|
// Test helpers
|
|
168
177
|
export function setLoggerOverride(settings) {
|