@calltelemetry/cli 1.3.0 → 1.5.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/commands/k8s.d.ts.map +1 -1
- package/dist/commands/k8s.js +29 -0
- package/dist/commands/k8s.js.map +1 -1
- package/dist/lib/env-to-values.d.ts +34 -0
- package/dist/lib/env-to-values.d.ts.map +1 -0
- package/dist/lib/env-to-values.js +163 -0
- package/dist/lib/env-to-values.js.map +1 -0
- package/dist/lib/k8s/appliance-info.d.ts +78 -0
- package/dist/lib/k8s/appliance-info.d.ts.map +1 -0
- package/dist/lib/k8s/appliance-info.js +226 -0
- package/dist/lib/k8s/appliance-info.js.map +1 -0
- package/dist/lib/k8s/appliance-job-logger.d.ts +63 -0
- package/dist/lib/k8s/appliance-job-logger.d.ts.map +1 -0
- package/dist/lib/k8s/appliance-job-logger.js +228 -0
- package/dist/lib/k8s/appliance-job-logger.js.map +1 -0
- package/dist/lib/k8s/appliance-orchestrator.d.ts +101 -0
- package/dist/lib/k8s/appliance-orchestrator.d.ts.map +1 -0
- package/dist/lib/k8s/appliance-orchestrator.js +496 -0
- package/dist/lib/k8s/appliance-orchestrator.js.map +1 -0
- package/dist/lib/k8s/index.d.ts +8 -0
- package/dist/lib/k8s/index.d.ts.map +1 -0
- package/dist/lib/k8s/index.js +8 -0
- package/dist/lib/k8s/index.js.map +1 -0
- package/dist/lib/prefs.d.ts +25 -0
- package/dist/lib/prefs.d.ts.map +1 -1
- package/dist/lib/prefs.js +0 -0
- package/dist/lib/prefs.js.map +1 -1
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appliance-info.js","sourceRoot":"","sources":["../../../src/lib/k8s/appliance-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export declare const JOB_LOG_SCHEMA_VERSION = 1;
|
|
2
|
+
export declare const DEFAULT_JOB_LOG_MAX_BYTES: number;
|
|
3
|
+
export type ApplianceJobLogLevel = 'info' | 'warn' | 'error';
|
|
4
|
+
export declare const APPLIANCE_JOB_LOG_LEVELS: readonly ApplianceJobLogLevel[];
|
|
5
|
+
export type ApplianceJobLogDetail = string | number | boolean;
|
|
6
|
+
export interface ApplianceJobLogEvent {
|
|
7
|
+
schemaVersion: typeof JOB_LOG_SCHEMA_VERSION;
|
|
8
|
+
jobId: string;
|
|
9
|
+
seq: number;
|
|
10
|
+
at: string;
|
|
11
|
+
level: ApplianceJobLogLevel;
|
|
12
|
+
phase: string;
|
|
13
|
+
message: string;
|
|
14
|
+
details?: Record<string, ApplianceJobLogDetail>;
|
|
15
|
+
}
|
|
16
|
+
export interface JobLogValidation {
|
|
17
|
+
valid: boolean;
|
|
18
|
+
errors: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface JobLogReadResult {
|
|
21
|
+
events: ApplianceJobLogEvent[];
|
|
22
|
+
invalid: Array<{
|
|
23
|
+
line: number;
|
|
24
|
+
error: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
export declare class JobLogValidationError extends Error {
|
|
28
|
+
readonly errors: string[];
|
|
29
|
+
constructor(errors: string[]);
|
|
30
|
+
}
|
|
31
|
+
/** Redact a single string value without changing non-secret text. */
|
|
32
|
+
export declare function redactJobLogValue(value: string): string;
|
|
33
|
+
/** Redact secret-looking keys and URL userinfo from a detail map. */
|
|
34
|
+
export declare function redactJobLogDetails(details: Record<string, unknown> | undefined): Record<string, ApplianceJobLogDetail> | undefined;
|
|
35
|
+
export declare function validateJobLogEvent(event: unknown): JobLogValidation;
|
|
36
|
+
export declare function assertValidJobLogEvent(event: unknown): asserts event is ApplianceJobLogEvent;
|
|
37
|
+
/** Build a fully populated, redacted event. */
|
|
38
|
+
export declare function createJobLogEvent(input: {
|
|
39
|
+
jobId: string;
|
|
40
|
+
seq: number;
|
|
41
|
+
phase: string;
|
|
42
|
+
message: string;
|
|
43
|
+
level?: ApplianceJobLogLevel;
|
|
44
|
+
details?: Record<string, unknown>;
|
|
45
|
+
now?: Date;
|
|
46
|
+
}): ApplianceJobLogEvent;
|
|
47
|
+
export declare function resolveJobLogPath(installDir: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Append one event as a single JSONL record. The file is created/kept mode
|
|
50
|
+
* 0600. A permission failure falls back to passwordless `sudo tee -a`, the
|
|
51
|
+
* same contract as `writeFileSafe`.
|
|
52
|
+
*/
|
|
53
|
+
export declare function appendJobLogEvent(logPath: string, event: ApplianceJobLogEvent): Promise<void>;
|
|
54
|
+
/** Parse the log, reporting (but not throwing on) corrupt lines. */
|
|
55
|
+
export declare function readJobLog(logPath: string): JobLogReadResult;
|
|
56
|
+
/** Return the most recent valid events, preserving file order. */
|
|
57
|
+
export declare function tailJobLog(logPath: string, limit?: number): ApplianceJobLogEvent[];
|
|
58
|
+
/**
|
|
59
|
+
* Rotate an oversized log to `<path>.1`, keeping one previous generation.
|
|
60
|
+
* Returns true when a rotation happened.
|
|
61
|
+
*/
|
|
62
|
+
export declare function rotateJobLogIfNeeded(logPath: string, maxBytes?: number): boolean;
|
|
63
|
+
//# sourceMappingURL=appliance-job-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appliance-job-logger.d.ts","sourceRoot":"","sources":["../../../src/lib/k8s/appliance-job-logger.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,sBAAsB,IAAI,CAAC;AACxC,eAAO,MAAM,yBAAyB,QAAkB,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC7D,eAAO,MAAM,wBAAwB,EAAE,SAAS,oBAAoB,EAA8B,CAAC;AAEnG,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,OAAO,sBAAsB,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,oBAAoB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBAEd,MAAM,EAAE,MAAM,EAAE;CAK7B;AA2BD,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC3C,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAAG,SAAS,CAenD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CA0DpE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,oBAAoB,CAG5F;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GAAG,oBAAoB,CAcvB;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAsB5D;AAED,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,oBAAoB,EAAE,CAM9E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,SAA4B,GACnC,OAAO,CAKT"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable job log for appliance Kubernetes orchestration.
|
|
3
|
+
*
|
|
4
|
+
* Each job appends one JSON object per line. The log is intentionally
|
|
5
|
+
* append-only and self-describing so a failed `ct k8s sync` can be audited
|
|
6
|
+
* after the process exits, and corrupt/truncated tails are skipped rather
|
|
7
|
+
* than making the whole log unreadable.
|
|
8
|
+
*
|
|
9
|
+
* Log records never contain credentials: secret-looking detail keys and
|
|
10
|
+
* URL userinfo are redacted before the record is validated and written.
|
|
11
|
+
*/
|
|
12
|
+
import { appendFileSync, chmodSync, existsSync, readFileSync, renameSync, statSync, } from 'node:fs';
|
|
13
|
+
import { dirname, join } from 'node:path';
|
|
14
|
+
import { execa } from 'execa';
|
|
15
|
+
import { mkdirSafe } from '../fs.js';
|
|
16
|
+
export const JOB_LOG_SCHEMA_VERSION = 1;
|
|
17
|
+
export const DEFAULT_JOB_LOG_MAX_BYTES = 5 * 1024 * 1024;
|
|
18
|
+
export const APPLIANCE_JOB_LOG_LEVELS = ['info', 'warn', 'error'];
|
|
19
|
+
export class JobLogValidationError extends Error {
|
|
20
|
+
errors;
|
|
21
|
+
constructor(errors) {
|
|
22
|
+
super(`Invalid job log event: ${errors.join('; ')}`);
|
|
23
|
+
this.name = 'JobLogValidationError';
|
|
24
|
+
this.errors = errors;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const JOB_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
|
|
28
|
+
const PHASE = /^[a-z][a-z0-9._-]{0,63}$/;
|
|
29
|
+
const DETAIL_KEY = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
30
|
+
const SECRET_KEY = /(password|passwd|secret|token|credential|api[-_]?key|private[-_]?key|authorization)/i;
|
|
31
|
+
const URL_USERINFO = /(:\/\/)([^/@\s:]+):([^/@\s]+)@/g;
|
|
32
|
+
const MAX_MESSAGE_LENGTH = 4096;
|
|
33
|
+
const MAX_DETAIL_STRING_LENGTH = 1024;
|
|
34
|
+
const MAX_DETAIL_KEYS = 50;
|
|
35
|
+
const REDACTED = '[redacted]';
|
|
36
|
+
function isIsoTimestamp(value) {
|
|
37
|
+
return typeof value === 'string' && Number.isFinite(Date.parse(value));
|
|
38
|
+
}
|
|
39
|
+
function hasControlCharacter(value) {
|
|
40
|
+
// eslint-disable-next-line no-control-regex
|
|
41
|
+
return /[\u0000-\u001f\u007f]/.test(value);
|
|
42
|
+
}
|
|
43
|
+
function isScalarDetail(value) {
|
|
44
|
+
if (typeof value === 'number')
|
|
45
|
+
return Number.isFinite(value);
|
|
46
|
+
if (typeof value === 'boolean')
|
|
47
|
+
return true;
|
|
48
|
+
return typeof value === 'string';
|
|
49
|
+
}
|
|
50
|
+
/** Redact a single string value without changing non-secret text. */
|
|
51
|
+
export function redactJobLogValue(value) {
|
|
52
|
+
return value.replace(URL_USERINFO, `$1$2:${REDACTED}@`);
|
|
53
|
+
}
|
|
54
|
+
/** Redact secret-looking keys and URL userinfo from a detail map. */
|
|
55
|
+
export function redactJobLogDetails(details) {
|
|
56
|
+
if (!details)
|
|
57
|
+
return undefined;
|
|
58
|
+
const redacted = {};
|
|
59
|
+
for (const [key, raw] of Object.entries(details)) {
|
|
60
|
+
if (SECRET_KEY.test(key)) {
|
|
61
|
+
redacted[key] = REDACTED;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (typeof raw === 'string') {
|
|
65
|
+
redacted[key] = redactJobLogValue(raw);
|
|
66
|
+
}
|
|
67
|
+
else if (typeof raw === 'number' || typeof raw === 'boolean') {
|
|
68
|
+
redacted[key] = raw;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return redacted;
|
|
72
|
+
}
|
|
73
|
+
export function validateJobLogEvent(event) {
|
|
74
|
+
const errors = [];
|
|
75
|
+
if (typeof event !== 'object' || event === null || Array.isArray(event)) {
|
|
76
|
+
return { valid: false, errors: ['event must be an object'] };
|
|
77
|
+
}
|
|
78
|
+
const value = event;
|
|
79
|
+
if (value.schemaVersion !== JOB_LOG_SCHEMA_VERSION) {
|
|
80
|
+
errors.push(`schemaVersion must be ${JOB_LOG_SCHEMA_VERSION}`);
|
|
81
|
+
}
|
|
82
|
+
if (typeof value.jobId !== 'string' || !JOB_ID.test(value.jobId)) {
|
|
83
|
+
errors.push('jobId must be a 1-128 character identifier');
|
|
84
|
+
}
|
|
85
|
+
if (!Number.isInteger(value.seq) || (value.seq ?? -1) < 0) {
|
|
86
|
+
errors.push('seq must be a non-negative integer');
|
|
87
|
+
}
|
|
88
|
+
if (!isIsoTimestamp(value.at)) {
|
|
89
|
+
errors.push('at must be an ISO timestamp');
|
|
90
|
+
}
|
|
91
|
+
if (typeof value.level !== 'string' || !APPLIANCE_JOB_LOG_LEVELS.includes(value.level)) {
|
|
92
|
+
errors.push(`level must be one of ${APPLIANCE_JOB_LOG_LEVELS.join(', ')}`);
|
|
93
|
+
}
|
|
94
|
+
if (typeof value.phase !== 'string' || !PHASE.test(value.phase)) {
|
|
95
|
+
errors.push('phase must be a lowercase phase identifier');
|
|
96
|
+
}
|
|
97
|
+
if (typeof value.message !== 'string' ||
|
|
98
|
+
value.message.length === 0 ||
|
|
99
|
+
value.message.length > MAX_MESSAGE_LENGTH ||
|
|
100
|
+
hasControlCharacter(value.message)) {
|
|
101
|
+
errors.push(`message must be a single line of 1-${MAX_MESSAGE_LENGTH} characters`);
|
|
102
|
+
}
|
|
103
|
+
if (value.details !== undefined) {
|
|
104
|
+
if (typeof value.details !== 'object' || value.details === null || Array.isArray(value.details)) {
|
|
105
|
+
errors.push('details must be an object');
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
const entries = Object.entries(value.details);
|
|
109
|
+
if (entries.length > MAX_DETAIL_KEYS)
|
|
110
|
+
errors.push(`details must have at most ${MAX_DETAIL_KEYS} keys`);
|
|
111
|
+
for (const [key, detail] of entries) {
|
|
112
|
+
if (!DETAIL_KEY.test(key) || ['__proto__', 'constructor', 'prototype'].includes(key)) {
|
|
113
|
+
errors.push(`details.${key} is not a valid key`);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (!isScalarDetail(detail)) {
|
|
117
|
+
errors.push(`details.${key} must be a string, number, or boolean`);
|
|
118
|
+
}
|
|
119
|
+
else if (typeof detail === 'string' &&
|
|
120
|
+
(detail.length > MAX_DETAIL_STRING_LENGTH || hasControlCharacter(detail))) {
|
|
121
|
+
errors.push(`details.${key} must be a single line of at most ${MAX_DETAIL_STRING_LENGTH} characters`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return { valid: errors.length === 0, errors };
|
|
127
|
+
}
|
|
128
|
+
export function assertValidJobLogEvent(event) {
|
|
129
|
+
const result = validateJobLogEvent(event);
|
|
130
|
+
if (!result.valid)
|
|
131
|
+
throw new JobLogValidationError(result.errors);
|
|
132
|
+
}
|
|
133
|
+
/** Build a fully populated, redacted event. */
|
|
134
|
+
export function createJobLogEvent(input) {
|
|
135
|
+
const event = {
|
|
136
|
+
schemaVersion: JOB_LOG_SCHEMA_VERSION,
|
|
137
|
+
jobId: input.jobId,
|
|
138
|
+
seq: input.seq,
|
|
139
|
+
at: (input.now ?? new Date()).toISOString(),
|
|
140
|
+
level: input.level ?? 'info',
|
|
141
|
+
phase: input.phase,
|
|
142
|
+
message: redactJobLogValue(input.message),
|
|
143
|
+
};
|
|
144
|
+
const details = redactJobLogDetails(input.details);
|
|
145
|
+
if (details)
|
|
146
|
+
event.details = details;
|
|
147
|
+
assertValidJobLogEvent(event);
|
|
148
|
+
return event;
|
|
149
|
+
}
|
|
150
|
+
export function resolveJobLogPath(installDir) {
|
|
151
|
+
return join(installDir, 'k8s', 'jobs.jsonl');
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Append one event as a single JSONL record. The file is created/kept mode
|
|
155
|
+
* 0600. A permission failure falls back to passwordless `sudo tee -a`, the
|
|
156
|
+
* same contract as `writeFileSafe`.
|
|
157
|
+
*/
|
|
158
|
+
export async function appendJobLogEvent(logPath, event) {
|
|
159
|
+
assertValidJobLogEvent(event);
|
|
160
|
+
const line = JSON.stringify(event) + '\n';
|
|
161
|
+
await mkdirSafe(dirname(logPath));
|
|
162
|
+
try {
|
|
163
|
+
appendFileSync(logPath, line, { encoding: 'utf-8', mode: 0o600 });
|
|
164
|
+
try {
|
|
165
|
+
chmodSync(logPath, 0o600);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
/* chmod is best-effort on filesystems that do not support modes */
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
if (err?.code !== 'EACCES' && err?.code !== 'EPERM')
|
|
173
|
+
throw err;
|
|
174
|
+
await execa('sudo', ['-n', 'tee', '-a', logPath], {
|
|
175
|
+
input: line,
|
|
176
|
+
stdout: 'ignore',
|
|
177
|
+
stderr: 'pipe',
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Parse the log, reporting (but not throwing on) corrupt lines. */
|
|
182
|
+
export function readJobLog(logPath) {
|
|
183
|
+
if (!existsSync(logPath))
|
|
184
|
+
return { events: [], invalid: [] };
|
|
185
|
+
const events = [];
|
|
186
|
+
const invalid = [];
|
|
187
|
+
const lines = readFileSync(logPath, 'utf-8').split('\n');
|
|
188
|
+
lines.forEach((line, index) => {
|
|
189
|
+
if (!line.trim())
|
|
190
|
+
return;
|
|
191
|
+
let parsed;
|
|
192
|
+
try {
|
|
193
|
+
parsed = JSON.parse(line);
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
invalid.push({ line: index + 1, error: `invalid JSON: ${err.message}` });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const result = validateJobLogEvent(parsed);
|
|
200
|
+
if (!result.valid) {
|
|
201
|
+
invalid.push({ line: index + 1, error: result.errors.join('; ') });
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
events.push(parsed);
|
|
205
|
+
});
|
|
206
|
+
return { events, invalid };
|
|
207
|
+
}
|
|
208
|
+
/** Return the most recent valid events, preserving file order. */
|
|
209
|
+
export function tailJobLog(logPath, limit = 50) {
|
|
210
|
+
if (!Number.isInteger(limit) || limit < 0) {
|
|
211
|
+
throw new Error('limit must be a non-negative integer');
|
|
212
|
+
}
|
|
213
|
+
const { events } = readJobLog(logPath);
|
|
214
|
+
return limit === 0 ? [] : events.slice(-limit);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Rotate an oversized log to `<path>.1`, keeping one previous generation.
|
|
218
|
+
* Returns true when a rotation happened.
|
|
219
|
+
*/
|
|
220
|
+
export function rotateJobLogIfNeeded(logPath, maxBytes = DEFAULT_JOB_LOG_MAX_BYTES) {
|
|
221
|
+
if (!existsSync(logPath))
|
|
222
|
+
return false;
|
|
223
|
+
if (statSync(logPath).size <= maxBytes)
|
|
224
|
+
return false;
|
|
225
|
+
renameSync(logPath, `${logPath}.1`);
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=appliance-job-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appliance-job-logger.js","sourceRoot":"","sources":["../../../src/lib/k8s/appliance-job-logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export declare const APPLIANCE_JOB_SCHEMA_VERSION = 1;
|
|
2
|
+
export declare const DEFAULT_JOB_STALE_AFTER_MS: number;
|
|
3
|
+
export type ApplianceJobKind = 'install' | 'update' | 'validate' | 'render' | 'sync' | 'diff' | 'apply' | 'backup' | 'restore' | 'scale' | 'verify';
|
|
4
|
+
export declare const APPLIANCE_JOB_KINDS: readonly ApplianceJobKind[];
|
|
5
|
+
export type ApplianceJobStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'interrupted';
|
|
6
|
+
export declare const APPLIANCE_JOB_STATUSES: readonly ApplianceJobStatus[];
|
|
7
|
+
export type ApplianceJobStepStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'skipped';
|
|
8
|
+
export declare const APPLIANCE_JOB_STEP_STATUSES: readonly ApplianceJobStepStatus[];
|
|
9
|
+
export interface ApplianceJobStep {
|
|
10
|
+
name: string;
|
|
11
|
+
status: ApplianceJobStepStatus;
|
|
12
|
+
startedAt?: string;
|
|
13
|
+
finishedAt?: string;
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ApplianceJob {
|
|
17
|
+
schemaVersion: typeof APPLIANCE_JOB_SCHEMA_VERSION;
|
|
18
|
+
id: string;
|
|
19
|
+
kind: ApplianceJobKind;
|
|
20
|
+
status: ApplianceJobStatus;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
startedAt?: string;
|
|
24
|
+
finishedAt?: string;
|
|
25
|
+
steps: ApplianceJobStep[];
|
|
26
|
+
error?: string;
|
|
27
|
+
metadata?: Record<string, string | number | boolean>;
|
|
28
|
+
}
|
|
29
|
+
export interface ApplianceJobValidation {
|
|
30
|
+
valid: boolean;
|
|
31
|
+
errors: string[];
|
|
32
|
+
}
|
|
33
|
+
export declare class ApplianceJobValidationError extends Error {
|
|
34
|
+
readonly errors: string[];
|
|
35
|
+
constructor(errors: string[]);
|
|
36
|
+
}
|
|
37
|
+
export declare function validateApplianceJob(job: unknown): ApplianceJobValidation;
|
|
38
|
+
export declare function assertValidApplianceJob(job: unknown): asserts job is ApplianceJob;
|
|
39
|
+
/** Resolve the per-install job state directory. */
|
|
40
|
+
export declare function resolveJobStateDir(installDir: string): string;
|
|
41
|
+
export declare function resolveJobRecordPath(jobDir: string, id: string): string;
|
|
42
|
+
export interface CreateApplianceJobInput {
|
|
43
|
+
kind: ApplianceJobKind;
|
|
44
|
+
steps: string[];
|
|
45
|
+
id?: string;
|
|
46
|
+
metadata?: Record<string, unknown>;
|
|
47
|
+
now?: Date;
|
|
48
|
+
}
|
|
49
|
+
/** Create a validated `queued` job record without writing it. */
|
|
50
|
+
export declare function createApplianceJob(input: CreateApplianceJobInput): ApplianceJob;
|
|
51
|
+
/** Persist a validated job record as mode-0600 JSON. */
|
|
52
|
+
export declare function saveApplianceJob(job: ApplianceJob, jobDir: string): Promise<void>;
|
|
53
|
+
/** Load one job record. Missing files return null; invalid files throw. */
|
|
54
|
+
export declare function loadApplianceJob(jobDir: string, id: string): ApplianceJob | null;
|
|
55
|
+
/** List every valid job record, oldest first. */
|
|
56
|
+
export declare function listApplianceJobs(jobDir: string): ApplianceJob[];
|
|
57
|
+
/** Return the currently running job, if any. */
|
|
58
|
+
export declare function findRunningApplianceJob(jobDir: string): ApplianceJob | null;
|
|
59
|
+
/**
|
|
60
|
+
* Mark jobs left `running` by a killed process as `interrupted`. A running
|
|
61
|
+
* step is rewound to `pending` so `resumeApplianceJob` can retry it.
|
|
62
|
+
*/
|
|
63
|
+
export declare function recoverInterruptedApplianceJobs(jobDir: string, options?: {
|
|
64
|
+
now?: Date;
|
|
65
|
+
staleAfterMs?: number;
|
|
66
|
+
}): Promise<ApplianceJob[]>;
|
|
67
|
+
export interface ApplianceJobExecutionContext {
|
|
68
|
+
job: ApplianceJob;
|
|
69
|
+
step: ApplianceJobStep;
|
|
70
|
+
index: number;
|
|
71
|
+
}
|
|
72
|
+
export type ApplianceJobExecutor = (context: ApplianceJobExecutionContext) => Promise<void>;
|
|
73
|
+
interface JobRunHooks {
|
|
74
|
+
jobDir: string;
|
|
75
|
+
logPath?: string;
|
|
76
|
+
now?: () => Date;
|
|
77
|
+
metadata?: Record<string, unknown>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Create, persist, and execute a job step-by-step. The record is written
|
|
81
|
+
* before each step and after every transition. A thrown executor error
|
|
82
|
+
* leaves a persisted `failed` record and is rethrown to the caller.
|
|
83
|
+
*/
|
|
84
|
+
export declare function runApplianceJob(options: JobRunHooks & {
|
|
85
|
+
kind: ApplianceJobKind;
|
|
86
|
+
steps: string[];
|
|
87
|
+
executor: ApplianceJobExecutor;
|
|
88
|
+
id?: string;
|
|
89
|
+
}): Promise<ApplianceJob>;
|
|
90
|
+
export interface ResumeApplianceJobOptions extends JobRunHooks {
|
|
91
|
+
id: string;
|
|
92
|
+
executor: ApplianceJobExecutor;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Resume a queued, interrupted, or failed job. Completed/skipped steps are
|
|
96
|
+
* preserved; a step left `running` is retried; a failed step is reset to
|
|
97
|
+
* `pending`.
|
|
98
|
+
*/
|
|
99
|
+
export declare function resumeApplianceJob(options: ResumeApplianceJobOptions): Promise<ApplianceJob>;
|
|
100
|
+
export {};
|
|
101
|
+
//# sourceMappingURL=appliance-orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appliance-orchestrator.d.ts","sourceRoot":"","sources":["../../../src/lib/k8s/appliance-orchestrator.ts"],"names":[],"mappings":"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"}
|