proxmox-mcps 0.1.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/.env.example +60 -0
- package/.mcp.json.example +19 -0
- package/LICENSE +21 -0
- package/README.md +72 -0
- package/dist/cli/check-config.d.ts +3 -0
- package/dist/cli/check-config.d.ts.map +1 -0
- package/dist/cli/check-config.js +29 -0
- package/dist/cli/check-config.js.map +1 -0
- package/dist/cli/print-tools.d.ts +4 -0
- package/dist/cli/print-tools.d.ts.map +1 -0
- package/dist/cli/print-tools.js +45 -0
- package/dist/cli/print-tools.js.map +1 -0
- package/dist/config/env.d.ts +183 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +149 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/index.d.ts +26 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +42 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +60 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +50 -0
- package/dist/config/types.js.map +1 -0
- package/dist/format/response.d.ts +40 -0
- package/dist/format/response.d.ts.map +1 -0
- package/dist/format/response.js +109 -0
- package/dist/format/response.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +200 -0
- package/dist/index.js.map +1 -0
- package/dist/jobs/sqlite-store.d.ts +34 -0
- package/dist/jobs/sqlite-store.d.ts.map +1 -0
- package/dist/jobs/sqlite-store.js +282 -0
- package/dist/jobs/sqlite-store.js.map +1 -0
- package/dist/jobs/store.d.ts +66 -0
- package/dist/jobs/store.d.ts.map +1 -0
- package/dist/jobs/store.js +101 -0
- package/dist/jobs/store.js.map +1 -0
- package/dist/log.d.ts +24 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +64 -0
- package/dist/log.js.map +1 -0
- package/dist/proxmox/auth.d.ts +30 -0
- package/dist/proxmox/auth.d.ts.map +1 -0
- package/dist/proxmox/auth.js +39 -0
- package/dist/proxmox/auth.js.map +1 -0
- package/dist/proxmox/client.d.ts +28 -0
- package/dist/proxmox/client.d.ts.map +1 -0
- package/dist/proxmox/client.js +192 -0
- package/dist/proxmox/client.js.map +1 -0
- package/dist/proxmox/errors.d.ts +51 -0
- package/dist/proxmox/errors.d.ts.map +1 -0
- package/dist/proxmox/errors.js +80 -0
- package/dist/proxmox/errors.js.map +1 -0
- package/dist/proxmox/paths.d.ts +126 -0
- package/dist/proxmox/paths.d.ts.map +1 -0
- package/dist/proxmox/paths.js +157 -0
- package/dist/proxmox/paths.js.map +1 -0
- package/dist/proxmox/types.d.ts +255 -0
- package/dist/proxmox/types.d.ts.map +1 -0
- package/dist/proxmox/types.js +9 -0
- package/dist/proxmox/types.js.map +1 -0
- package/dist/retry.d.ts +18 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +50 -0
- package/dist/retry.js.map +1 -0
- package/dist/safety/policy.d.ts +23 -0
- package/dist/safety/policy.d.ts.map +1 -0
- package/dist/safety/policy.js +81 -0
- package/dist/safety/policy.js.map +1 -0
- package/dist/safety/risk.d.ts +3 -0
- package/dist/safety/risk.d.ts.map +1 -0
- package/dist/safety/risk.js +234 -0
- package/dist/safety/risk.js.map +1 -0
- package/dist/security/url-guard.d.ts +22 -0
- package/dist/security/url-guard.d.ts.map +1 -0
- package/dist/security/url-guard.js +166 -0
- package/dist/security/url-guard.js.map +1 -0
- package/dist/server.d.ts +24 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +74 -0
- package/dist/server.js.map +1 -0
- package/dist/ssh/client.d.ts +32 -0
- package/dist/ssh/client.d.ts.map +1 -0
- package/dist/ssh/client.js +128 -0
- package/dist/ssh/client.js.map +1 -0
- package/dist/tools/backup-schedule.d.ts +10 -0
- package/dist/tools/backup-schedule.d.ts.map +1 -0
- package/dist/tools/backup-schedule.js +194 -0
- package/dist/tools/backup-schedule.js.map +1 -0
- package/dist/tools/backup.d.ts +7 -0
- package/dist/tools/backup.d.ts.map +1 -0
- package/dist/tools/backup.js +163 -0
- package/dist/tools/backup.js.map +1 -0
- package/dist/tools/cluster.d.ts +7 -0
- package/dist/tools/cluster.d.ts.map +1 -0
- package/dist/tools/cluster.js +20 -0
- package/dist/tools/cluster.js.map +1 -0
- package/dist/tools/container/config.d.ts +7 -0
- package/dist/tools/container/config.d.ts.map +1 -0
- package/dist/tools/container/config.js +97 -0
- package/dist/tools/container/config.js.map +1 -0
- package/dist/tools/container/console.d.ts +7 -0
- package/dist/tools/container/console.d.ts.map +1 -0
- package/dist/tools/container/console.js +65 -0
- package/dist/tools/container/console.js.map +1 -0
- package/dist/tools/container/crud.d.ts +7 -0
- package/dist/tools/container/crud.d.ts.map +1 -0
- package/dist/tools/container/crud.js +362 -0
- package/dist/tools/container/crud.js.map +1 -0
- package/dist/tools/container/diagnostics.d.ts +7 -0
- package/dist/tools/container/diagnostics.d.ts.map +1 -0
- package/dist/tools/container/diagnostics.js +115 -0
- package/dist/tools/container/diagnostics.js.map +1 -0
- package/dist/tools/container/migration.d.ts +7 -0
- package/dist/tools/container/migration.d.ts.map +1 -0
- package/dist/tools/container/migration.js +134 -0
- package/dist/tools/container/migration.js.map +1 -0
- package/dist/tools/context.d.ts +21 -0
- package/dist/tools/context.d.ts.map +1 -0
- package/dist/tools/context.js +2 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/ha.d.ts +7 -0
- package/dist/tools/ha.d.ts.map +1 -0
- package/dist/tools/ha.js +241 -0
- package/dist/tools/ha.js.map +1 -0
- package/dist/tools/helpers.d.ts +15 -0
- package/dist/tools/helpers.d.ts.map +1 -0
- package/dist/tools/helpers.js +7 -0
- package/dist/tools/helpers.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +66 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/iso.d.ts +7 -0
- package/dist/tools/iso.d.ts.map +1 -0
- package/dist/tools/iso.js +131 -0
- package/dist/tools/iso.js.map +1 -0
- package/dist/tools/jobs.d.ts +11 -0
- package/dist/tools/jobs.d.ts.map +1 -0
- package/dist/tools/jobs.js +173 -0
- package/dist/tools/jobs.js.map +1 -0
- package/dist/tools/node-admin.d.ts +10 -0
- package/dist/tools/node-admin.d.ts.map +1 -0
- package/dist/tools/node-admin.js +361 -0
- package/dist/tools/node-admin.js.map +1 -0
- package/dist/tools/node-certs.d.ts +7 -0
- package/dist/tools/node-certs.d.ts.map +1 -0
- package/dist/tools/node-certs.js +36 -0
- package/dist/tools/node-certs.js.map +1 -0
- package/dist/tools/node-disks.d.ts +7 -0
- package/dist/tools/node-disks.d.ts.map +1 -0
- package/dist/tools/node-disks.js +100 -0
- package/dist/tools/node-disks.js.map +1 -0
- package/dist/tools/node-network.d.ts +7 -0
- package/dist/tools/node-network.d.ts.map +1 -0
- package/dist/tools/node-network.js +102 -0
- package/dist/tools/node-network.js.map +1 -0
- package/dist/tools/node-services.d.ts +7 -0
- package/dist/tools/node-services.d.ts.map +1 -0
- package/dist/tools/node-services.js +39 -0
- package/dist/tools/node-services.js.map +1 -0
- package/dist/tools/node.d.ts +7 -0
- package/dist/tools/node.d.ts.map +1 -0
- package/dist/tools/node.js +85 -0
- package/dist/tools/node.js.map +1 -0
- package/dist/tools/pools.d.ts +10 -0
- package/dist/tools/pools.d.ts.map +1 -0
- package/dist/tools/pools.js +111 -0
- package/dist/tools/pools.js.map +1 -0
- package/dist/tools/replication.d.ts +7 -0
- package/dist/tools/replication.d.ts.map +1 -0
- package/dist/tools/replication.js +116 -0
- package/dist/tools/replication.js.map +1 -0
- package/dist/tools/sdn.d.ts +7 -0
- package/dist/tools/sdn.d.ts.map +1 -0
- package/dist/tools/sdn.js +358 -0
- package/dist/tools/sdn.js.map +1 -0
- package/dist/tools/snapshot.d.ts +10 -0
- package/dist/tools/snapshot.d.ts.map +1 -0
- package/dist/tools/snapshot.js +115 -0
- package/dist/tools/snapshot.js.map +1 -0
- package/dist/tools/storage-admin.d.ts +9 -0
- package/dist/tools/storage-admin.d.ts.map +1 -0
- package/dist/tools/storage-admin.js +126 -0
- package/dist/tools/storage-admin.js.map +1 -0
- package/dist/tools/storage.d.ts +7 -0
- package/dist/tools/storage.d.ts.map +1 -0
- package/dist/tools/storage.js +20 -0
- package/dist/tools/storage.js.map +1 -0
- package/dist/tools/tasks.d.ts +11 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +85 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/vm/config.d.ts +28 -0
- package/dist/tools/vm/config.d.ts.map +1 -0
- package/dist/tools/vm/config.js +221 -0
- package/dist/tools/vm/config.js.map +1 -0
- package/dist/tools/vm/console.d.ts +9 -0
- package/dist/tools/vm/console.d.ts.map +1 -0
- package/dist/tools/vm/console.js +141 -0
- package/dist/tools/vm/console.js.map +1 -0
- package/dist/tools/vm/crud.d.ts +10 -0
- package/dist/tools/vm/crud.d.ts.map +1 -0
- package/dist/tools/vm/crud.js +333 -0
- package/dist/tools/vm/crud.js.map +1 -0
- package/dist/tools/vm/diagnostics.d.ts +10 -0
- package/dist/tools/vm/diagnostics.d.ts.map +1 -0
- package/dist/tools/vm/diagnostics.js +256 -0
- package/dist/tools/vm/diagnostics.js.map +1 -0
- package/dist/tools/vm/migration.d.ts +7 -0
- package/dist/tools/vm/migration.d.ts.map +1 -0
- package/dist/tools/vm/migration.js +131 -0
- package/dist/tools/vm/migration.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed JobStore.
|
|
3
|
+
*
|
|
4
|
+
* Persists long-running Proxmox jobs across restarts. Schema is migrated
|
|
5
|
+
* forward by version — see `migrate()` for the canonical list of changes.
|
|
6
|
+
*
|
|
7
|
+
* Backed by `better-sqlite3` (synchronous, fast, single-process). For multi-
|
|
8
|
+
* process use, enable WAL mode (set by default) and serialize via a mutex.
|
|
9
|
+
*/
|
|
10
|
+
import BetterSqlite3 from "better-sqlite3";
|
|
11
|
+
import { randomUUID } from "node:crypto";
|
|
12
|
+
import { mkdirSync } from "node:fs";
|
|
13
|
+
import { dirname } from "node:path";
|
|
14
|
+
const SCHEMA_VERSION = 1;
|
|
15
|
+
const SCHEMA_DDL = {
|
|
16
|
+
1: `
|
|
17
|
+
CREATE TABLE IF NOT EXISTS jobs (
|
|
18
|
+
job_id TEXT PRIMARY KEY,
|
|
19
|
+
upid TEXT,
|
|
20
|
+
tool TEXT NOT NULL,
|
|
21
|
+
args_json TEXT NOT NULL,
|
|
22
|
+
node TEXT,
|
|
23
|
+
status TEXT NOT NULL,
|
|
24
|
+
started_at INTEGER NOT NULL,
|
|
25
|
+
ended_at INTEGER,
|
|
26
|
+
progress INTEGER,
|
|
27
|
+
exit_status TEXT,
|
|
28
|
+
result_json TEXT,
|
|
29
|
+
last_error TEXT,
|
|
30
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
31
|
+
previous_upids_json TEXT NOT NULL DEFAULT '[]',
|
|
32
|
+
retry_spec_json TEXT
|
|
33
|
+
);
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_jobs_started_at ON jobs(started_at DESC);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_jobs_status_started ON jobs(status, started_at DESC);
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_jobs_tool_started ON jobs(tool, started_at DESC);
|
|
37
|
+
`,
|
|
38
|
+
};
|
|
39
|
+
export class SqliteJobStore {
|
|
40
|
+
db;
|
|
41
|
+
ttlMs;
|
|
42
|
+
logger;
|
|
43
|
+
// Prepared statements (cached for perf)
|
|
44
|
+
stmtInsert;
|
|
45
|
+
stmtGet;
|
|
46
|
+
stmtList;
|
|
47
|
+
stmtUpdate;
|
|
48
|
+
stmtDelete;
|
|
49
|
+
stmtEvict;
|
|
50
|
+
stmtSetUpid;
|
|
51
|
+
constructor(opts) {
|
|
52
|
+
this.ttlMs = opts.ttlHours * 60 * 60 * 1000;
|
|
53
|
+
this.logger = opts.logger;
|
|
54
|
+
// Ensure parent directory exists
|
|
55
|
+
mkdirSync(dirname(opts.sqlitePath), { recursive: true });
|
|
56
|
+
this.db = new BetterSqlite3(opts.sqlitePath);
|
|
57
|
+
this.db.pragma("journal_mode = WAL");
|
|
58
|
+
this.db.pragma("synchronous = NORMAL");
|
|
59
|
+
this.db.pragma("busy_timeout = 5000");
|
|
60
|
+
this.db.pragma("foreign_keys = ON");
|
|
61
|
+
this.migrate();
|
|
62
|
+
this.stmtInsert = this.db.prepare(`
|
|
63
|
+
INSERT INTO jobs (
|
|
64
|
+
job_id, upid, tool, args_json, node, status, started_at, retry_count,
|
|
65
|
+
previous_upids_json, retry_spec_json
|
|
66
|
+
) VALUES (
|
|
67
|
+
@job_id, @upid, @tool, @args_json, @node, @status, @started_at, @retry_count,
|
|
68
|
+
@previous_upids_json, @retry_spec_json
|
|
69
|
+
)
|
|
70
|
+
`);
|
|
71
|
+
this.stmtGet = this.db.prepare(`SELECT * FROM jobs WHERE job_id = ?`);
|
|
72
|
+
this.stmtList = this.db.prepare(`
|
|
73
|
+
SELECT * FROM jobs
|
|
74
|
+
WHERE (@status IS NULL OR status = @status)
|
|
75
|
+
AND (@tool IS NULL OR tool = @tool)
|
|
76
|
+
ORDER BY started_at DESC
|
|
77
|
+
LIMIT @limit
|
|
78
|
+
`);
|
|
79
|
+
this.stmtUpdate = this.db.prepare(`
|
|
80
|
+
UPDATE jobs SET
|
|
81
|
+
started_at = COALESCE(@started_at, started_at),
|
|
82
|
+
upid = COALESCE(@upid, upid),
|
|
83
|
+
status = COALESCE(@status, status),
|
|
84
|
+
progress = COALESCE(@progress, progress),
|
|
85
|
+
exit_status = COALESCE(@exit_status, exit_status),
|
|
86
|
+
ended_at = COALESCE(@ended_at, ended_at),
|
|
87
|
+
result_json = COALESCE(@result_json, result_json),
|
|
88
|
+
last_error = COALESCE(@last_error, last_error),
|
|
89
|
+
retry_count = COALESCE(@retry_count, retry_count),
|
|
90
|
+
previous_upids_json = COALESCE(@previous_upids_json, previous_upids_json),
|
|
91
|
+
retry_spec_json = COALESCE(@retry_spec_json, retry_spec_json)
|
|
92
|
+
WHERE job_id = @job_id
|
|
93
|
+
`);
|
|
94
|
+
this.stmtDelete = this.db.prepare(`DELETE FROM jobs WHERE job_id = ?`);
|
|
95
|
+
this.stmtEvict = this.db.prepare(`DELETE FROM jobs WHERE COALESCE(ended_at, started_at) < ?`);
|
|
96
|
+
this.stmtSetUpid = this.db.prepare(`
|
|
97
|
+
UPDATE jobs SET
|
|
98
|
+
previous_upids_json = @previous_upids_json,
|
|
99
|
+
upid = @upid,
|
|
100
|
+
status = 'running'
|
|
101
|
+
WHERE job_id = @job_id
|
|
102
|
+
`);
|
|
103
|
+
}
|
|
104
|
+
// ---- JobStore interface --------------------------------------------------
|
|
105
|
+
create(opts) {
|
|
106
|
+
const job = {
|
|
107
|
+
job_id: randomUUID(),
|
|
108
|
+
upid: opts.upid ?? null,
|
|
109
|
+
tool: opts.tool,
|
|
110
|
+
args: scrubArgs(opts.args),
|
|
111
|
+
node: opts.node ?? null,
|
|
112
|
+
status: opts.upid ? "running" : "queued",
|
|
113
|
+
started_at: Date.now(),
|
|
114
|
+
ended_at: null,
|
|
115
|
+
progress: null,
|
|
116
|
+
exit_status: null,
|
|
117
|
+
result: null,
|
|
118
|
+
last_error: null,
|
|
119
|
+
retry_count: 0,
|
|
120
|
+
previous_upids: [],
|
|
121
|
+
retry_spec: { tool: opts.tool, args: scrubArgs(opts.args) },
|
|
122
|
+
};
|
|
123
|
+
this.stmtInsert.run({
|
|
124
|
+
job_id: job.job_id,
|
|
125
|
+
upid: job.upid,
|
|
126
|
+
tool: job.tool,
|
|
127
|
+
args_json: JSON.stringify(job.args),
|
|
128
|
+
node: job.node,
|
|
129
|
+
status: job.status,
|
|
130
|
+
started_at: job.started_at,
|
|
131
|
+
retry_count: job.retry_count,
|
|
132
|
+
previous_upids_json: JSON.stringify(job.previous_upids),
|
|
133
|
+
retry_spec_json: JSON.stringify(job.retry_spec),
|
|
134
|
+
});
|
|
135
|
+
this.logger?.debug({ job_id: job.job_id, tool: job.tool, upid: job.upid }, "jobs.created");
|
|
136
|
+
return job;
|
|
137
|
+
}
|
|
138
|
+
get(jobId) {
|
|
139
|
+
const row = this.stmtGet.get(jobId);
|
|
140
|
+
return row ? rowToJob(row) : null;
|
|
141
|
+
}
|
|
142
|
+
list(filter = {}) {
|
|
143
|
+
const rows = this.stmtList.all({
|
|
144
|
+
status: filter.status ?? null,
|
|
145
|
+
tool: filter.tool ?? null,
|
|
146
|
+
limit: filter.limit ?? 100,
|
|
147
|
+
});
|
|
148
|
+
return rows.map(rowToJob);
|
|
149
|
+
}
|
|
150
|
+
setUpid(jobId, upid) {
|
|
151
|
+
const existing = this.get(jobId);
|
|
152
|
+
if (!existing)
|
|
153
|
+
return;
|
|
154
|
+
const previous = [...existing.previous_upids];
|
|
155
|
+
if (existing.upid)
|
|
156
|
+
previous.push(existing.upid);
|
|
157
|
+
this.stmtSetUpid.run({
|
|
158
|
+
job_id: jobId,
|
|
159
|
+
upid,
|
|
160
|
+
previous_upids_json: JSON.stringify(previous),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
update(jobId, patch) {
|
|
164
|
+
// prepared statement has all named params; provide null for any field
|
|
165
|
+
// we're not updating so better-sqlite3 doesn't throw "Missing parameter".
|
|
166
|
+
const row = {
|
|
167
|
+
job_id: jobId,
|
|
168
|
+
started_at: patch.started_at !== undefined ? patch.started_at : null,
|
|
169
|
+
upid: patch.upid !== undefined ? patch.upid : null,
|
|
170
|
+
status: patch.status !== undefined ? patch.status : null,
|
|
171
|
+
progress: patch.progress !== undefined ? patch.progress : null,
|
|
172
|
+
exit_status: patch.exit_status !== undefined ? patch.exit_status : null,
|
|
173
|
+
ended_at: patch.ended_at !== undefined ? patch.ended_at : null,
|
|
174
|
+
result_json: patch.result !== undefined ? JSON.stringify(patch.result) : null,
|
|
175
|
+
last_error: patch.last_error !== undefined ? patch.last_error : null,
|
|
176
|
+
retry_count: patch.retry_count !== undefined ? patch.retry_count : null,
|
|
177
|
+
previous_upids_json: patch.previous_upids !== undefined ? JSON.stringify(patch.previous_upids) : null,
|
|
178
|
+
retry_spec_json: patch.retry_spec !== undefined ? JSON.stringify(patch.retry_spec) : null,
|
|
179
|
+
};
|
|
180
|
+
this.stmtUpdate.run(row);
|
|
181
|
+
}
|
|
182
|
+
delete(jobId) {
|
|
183
|
+
const result = this.stmtDelete.run(jobId);
|
|
184
|
+
return result.changes > 0;
|
|
185
|
+
}
|
|
186
|
+
evictExpired() {
|
|
187
|
+
const cutoff = Date.now() - this.ttlMs;
|
|
188
|
+
const result = this.stmtEvict.run(cutoff);
|
|
189
|
+
if (result.changes > 0) {
|
|
190
|
+
this.logger?.debug({ removed: result.changes }, "jobs.evicted");
|
|
191
|
+
}
|
|
192
|
+
return result.changes;
|
|
193
|
+
}
|
|
194
|
+
close() {
|
|
195
|
+
this.db.close();
|
|
196
|
+
}
|
|
197
|
+
// ---- Internals -----------------------------------------------------------
|
|
198
|
+
migrate() {
|
|
199
|
+
// Bootstrap schema_migrations table
|
|
200
|
+
this.db.exec(`
|
|
201
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
202
|
+
version INTEGER PRIMARY KEY,
|
|
203
|
+
applied_at INTEGER NOT NULL
|
|
204
|
+
);
|
|
205
|
+
`);
|
|
206
|
+
const applied = this.db.prepare(`SELECT MAX(version) AS v FROM schema_migrations`).get().v ?? 0;
|
|
207
|
+
for (let v = applied + 1; v <= SCHEMA_VERSION; v++) {
|
|
208
|
+
const ddl = SCHEMA_DDL[v];
|
|
209
|
+
if (!ddl)
|
|
210
|
+
continue;
|
|
211
|
+
this.db.transaction(() => {
|
|
212
|
+
this.db.exec(ddl);
|
|
213
|
+
this.db.prepare(`INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)`).run(v, Date.now());
|
|
214
|
+
})();
|
|
215
|
+
this.logger?.info({ version: v }, "jobs.migration_applied");
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function rowToJob(row) {
|
|
220
|
+
let result = null;
|
|
221
|
+
try {
|
|
222
|
+
if (row.result_json)
|
|
223
|
+
result = JSON.parse(row.result_json);
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
/* ignore malformed */
|
|
227
|
+
}
|
|
228
|
+
let retrySpec = null;
|
|
229
|
+
try {
|
|
230
|
+
if (row.retry_spec_json)
|
|
231
|
+
retrySpec = JSON.parse(row.retry_spec_json);
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
/* ignore */
|
|
235
|
+
}
|
|
236
|
+
let previousUpids = [];
|
|
237
|
+
try {
|
|
238
|
+
if (row.previous_upids_json)
|
|
239
|
+
previousUpids = JSON.parse(row.previous_upids_json);
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
/* ignore */
|
|
243
|
+
}
|
|
244
|
+
let args = {};
|
|
245
|
+
try {
|
|
246
|
+
if (row.args_json)
|
|
247
|
+
args = JSON.parse(row.args_json);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
/* ignore */
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
job_id: row.job_id,
|
|
254
|
+
upid: row.upid,
|
|
255
|
+
tool: row.tool,
|
|
256
|
+
args,
|
|
257
|
+
node: row.node,
|
|
258
|
+
status: row.status,
|
|
259
|
+
started_at: row.started_at,
|
|
260
|
+
ended_at: row.ended_at,
|
|
261
|
+
progress: row.progress,
|
|
262
|
+
exit_status: row.exit_status,
|
|
263
|
+
result,
|
|
264
|
+
last_error: row.last_error,
|
|
265
|
+
retry_count: row.retry_count,
|
|
266
|
+
previous_upids: previousUpids,
|
|
267
|
+
retry_spec: retrySpec,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function scrubArgs(args) {
|
|
271
|
+
const out = {};
|
|
272
|
+
for (const [k, v] of Object.entries(args)) {
|
|
273
|
+
if (k === "approval_token" || k === "password" || k === "new_password" || k === "cipassword") {
|
|
274
|
+
out[k] = "[REDACTED]";
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
out[k] = v;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return out;
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=sqlite-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-store.js","sourceRoot":"","sources":["../../src/jobs/sqlite-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,aAAkD,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,MAAM,UAAU,GAA2B;IACzC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;GAqBF;CACF,CAAC;AAEF,MAAM,OAAO,cAAc;IACR,EAAE,CAAiB;IACnB,KAAK,CAAS;IACd,MAAM,CAAqB;IAE5C,wCAAwC;IACvB,UAAU,CAA0B;IACpC,OAAO,CAA0B;IACjC,QAAQ,CAA0B;IAClC,UAAU,CAA0B;IACpC,UAAU,CAA0B;IACpC,SAAS,CAA0B;IACnC,WAAW,CAA0B;IAEtD,YAAY,IAA2B;QACrC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAE1B,iCAAiC;QACjC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEzD,IAAI,CAAC,EAAE,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACvC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;QAEf,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;;;;KAQjC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;QAEtE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;;KAM/B,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;;;;;KAcjC,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;QACvE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC;QAC9F,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;;KAMlC,CAAC,CAAC;IACL,CAAC;IAED,6EAA6E;IAE7E,MAAM,CAAC,IAAmB;QACxB,MAAM,GAAG,GAAc;YACrB,MAAM,EAAE,UAAU,EAAE;YACpB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;YACvB,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;YACxC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,IAAI;YAChB,WAAW,EAAE,CAAC;YACd,cAAc,EAAE,EAAE;YAClB,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAC5D,CAAC;QAEF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YACnC,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,mBAAmB,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC;YACvD,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC;SAChD,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,cAAc,CAAC,CAAC;QAC3F,OAAO,GAAG,CAAC;IACb,CAAC;IAED,GAAG,CAAC,KAAa;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAuB,CAAC;QAC1D,OAAO,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpC,CAAC;IAED,IAAI,CAAC,SAAgE,EAAE;QACrE,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,IAAI;YAC7B,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,GAAG;SAC3B,CAAa,CAAC;QACf,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,CAAC,KAAa,EAAE,IAAY;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC;QAC9C,IAAI,QAAQ,CAAC,IAAI;YAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;YACnB,MAAM,EAAE,KAAK;YACb,IAAI;YACJ,mBAAmB,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAa,EAAE,KAAyB;QAC7C,sEAAsE;QACtE,0EAA0E;QAC1E,MAAM,GAAG,GAA4B;YACnC,MAAM,EAAE,KAAK;YACb,UAAU,EAAE,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;YACpE,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;YAClD,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;YACxD,QAAQ,EAAE,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YAC9D,WAAW,EAAE,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;YACvE,QAAQ,EAAE,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YAC9D,WAAW,EAAE,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;YAC7E,UAAU,EAAE,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;YACpE,WAAW,EAAE,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;YACvE,mBAAmB,EACjB,KAAK,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI;YAClF,eAAe,EAAE,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI;SAC1F,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,KAAa;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,YAAY;QACV,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;IAED,6EAA6E;IAErE,OAAO;QACb,oCAAoC;QACpC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;KAKZ,CAAC,CAAC;QAEH,MAAM,OAAO,GAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,GAAG,EAA2B,CAAC,CAAC,IAAI,CAAC,CAAC;QAE1H,KAAK,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC,IAAI,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;gBACvB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAClB,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,mEAAmE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1G,CAAC,CAAC,EAAE,CAAC;YACL,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;CACF;AAsBD,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,MAAM,GAAY,IAAI,CAAC;IAC3B,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,WAAW;YAAE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;IAED,IAAI,SAAS,GAA4B,IAAI,CAAC;IAC9C,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,eAAe;YAAE,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IAED,IAAI,aAAa,GAAa,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,mBAAmB;YAAE,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IAED,IAAI,IAAI,GAA4B,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,SAAS;YAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IAED,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI;QACJ,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,MAAM;QACN,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,cAAc,EAAE,aAAa;QAC7B,UAAU,EAAE,SAAS;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,IAA6B;IAC9C,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC,KAAK,gBAAgB,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,cAAc,IAAI,CAAC,KAAK,YAAY,EAAE,CAAC;YAC7F,GAAG,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Logger } from "../log.js";
|
|
2
|
+
export type JobStatus = "queued" | "running" | "completed" | "failed" | "cancelled";
|
|
3
|
+
export interface JobRecord {
|
|
4
|
+
job_id: string;
|
|
5
|
+
upid: string | null;
|
|
6
|
+
tool: string;
|
|
7
|
+
args: Record<string, unknown>;
|
|
8
|
+
node: string | null;
|
|
9
|
+
status: JobStatus;
|
|
10
|
+
started_at: number;
|
|
11
|
+
ended_at: number | null;
|
|
12
|
+
progress: number | null;
|
|
13
|
+
exit_status: string | null;
|
|
14
|
+
result: unknown;
|
|
15
|
+
last_error: string | null;
|
|
16
|
+
retry_count: number;
|
|
17
|
+
previous_upids: string[];
|
|
18
|
+
/** Stored recipe to re-invoke the tool on retry. */
|
|
19
|
+
retry_spec: RetrySpec | null;
|
|
20
|
+
}
|
|
21
|
+
export interface RetrySpec {
|
|
22
|
+
tool: string;
|
|
23
|
+
args: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
export interface CreateJobOpts {
|
|
26
|
+
tool: string;
|
|
27
|
+
args: Record<string, unknown>;
|
|
28
|
+
node?: string | null;
|
|
29
|
+
upid?: string | null;
|
|
30
|
+
}
|
|
31
|
+
export interface JobStore {
|
|
32
|
+
create(opts: CreateJobOpts): JobRecord;
|
|
33
|
+
get(jobId: string): JobRecord | null;
|
|
34
|
+
list(filter?: {
|
|
35
|
+
status?: JobStatus;
|
|
36
|
+
tool?: string;
|
|
37
|
+
limit?: number;
|
|
38
|
+
}): JobRecord[];
|
|
39
|
+
setUpid(jobId: string, upid: string): void;
|
|
40
|
+
update(jobId: string, patch: Partial<JobRecord>): void;
|
|
41
|
+
delete(jobId: string): boolean;
|
|
42
|
+
/** Remove jobs older than `ttlHours`. */
|
|
43
|
+
evictExpired(): number;
|
|
44
|
+
}
|
|
45
|
+
export interface InMemoryJobStoreOptions {
|
|
46
|
+
ttlHours: number;
|
|
47
|
+
logger?: Logger;
|
|
48
|
+
}
|
|
49
|
+
export declare class InMemoryJobStore implements JobStore {
|
|
50
|
+
private readonly jobs;
|
|
51
|
+
private readonly ttlMs;
|
|
52
|
+
private readonly logger;
|
|
53
|
+
constructor(opts: InMemoryJobStoreOptions);
|
|
54
|
+
create(opts: CreateJobOpts): JobRecord;
|
|
55
|
+
get(jobId: string): JobRecord | null;
|
|
56
|
+
list(filter?: {
|
|
57
|
+
status?: JobStatus;
|
|
58
|
+
tool?: string;
|
|
59
|
+
limit?: number;
|
|
60
|
+
}): JobRecord[];
|
|
61
|
+
setUpid(jobId: string, upid: string): void;
|
|
62
|
+
update(jobId: string, patch: Partial<JobRecord>): void;
|
|
63
|
+
delete(jobId: string): boolean;
|
|
64
|
+
evictExpired(): number;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/jobs/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JobStore — track long-running Proxmox tasks behind stable job_ids.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1 ships an in-memory implementation behind a JobStore interface, so
|
|
5
|
+
* Phase 2 can swap in SQLite-backed persistence without changing tool code.
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID } from "node:crypto";
|
|
8
|
+
export class InMemoryJobStore {
|
|
9
|
+
jobs = new Map();
|
|
10
|
+
ttlMs;
|
|
11
|
+
logger;
|
|
12
|
+
constructor(opts) {
|
|
13
|
+
this.ttlMs = opts.ttlHours * 60 * 60 * 1000;
|
|
14
|
+
this.logger = opts.logger;
|
|
15
|
+
}
|
|
16
|
+
create(opts) {
|
|
17
|
+
const job = {
|
|
18
|
+
job_id: randomUUID(),
|
|
19
|
+
upid: opts.upid ?? null,
|
|
20
|
+
tool: opts.tool,
|
|
21
|
+
args: scrubArgs(opts.args),
|
|
22
|
+
node: opts.node ?? null,
|
|
23
|
+
status: opts.upid ? "running" : "queued",
|
|
24
|
+
started_at: Date.now(),
|
|
25
|
+
ended_at: null,
|
|
26
|
+
progress: null,
|
|
27
|
+
exit_status: null,
|
|
28
|
+
result: null,
|
|
29
|
+
last_error: null,
|
|
30
|
+
retry_count: 0,
|
|
31
|
+
previous_upids: [],
|
|
32
|
+
retry_spec: { tool: opts.tool, args: scrubArgs(opts.args) },
|
|
33
|
+
};
|
|
34
|
+
this.jobs.set(job.job_id, job);
|
|
35
|
+
this.logger?.debug({ job_id: job.job_id, tool: job.tool, upid: job.upid }, "jobs.created");
|
|
36
|
+
return job;
|
|
37
|
+
}
|
|
38
|
+
get(jobId) {
|
|
39
|
+
return this.jobs.get(jobId) ?? null;
|
|
40
|
+
}
|
|
41
|
+
list(filter = {}) {
|
|
42
|
+
const all = Array.from(this.jobs.values());
|
|
43
|
+
const filtered = all.filter((j) => {
|
|
44
|
+
if (filter.status && j.status !== filter.status)
|
|
45
|
+
return false;
|
|
46
|
+
if (filter.tool && j.tool !== filter.tool)
|
|
47
|
+
return false;
|
|
48
|
+
return true;
|
|
49
|
+
});
|
|
50
|
+
// Newest first
|
|
51
|
+
filtered.sort((a, b) => b.started_at - a.started_at);
|
|
52
|
+
return filter.limit ? filtered.slice(0, filter.limit) : filtered;
|
|
53
|
+
}
|
|
54
|
+
setUpid(jobId, upid) {
|
|
55
|
+
const job = this.jobs.get(jobId);
|
|
56
|
+
if (!job)
|
|
57
|
+
return;
|
|
58
|
+
if (job.upid) {
|
|
59
|
+
job.previous_upids.push(job.upid);
|
|
60
|
+
}
|
|
61
|
+
job.upid = upid;
|
|
62
|
+
job.status = "running";
|
|
63
|
+
}
|
|
64
|
+
update(jobId, patch) {
|
|
65
|
+
const job = this.jobs.get(jobId);
|
|
66
|
+
if (!job)
|
|
67
|
+
return;
|
|
68
|
+
Object.assign(job, patch);
|
|
69
|
+
}
|
|
70
|
+
delete(jobId) {
|
|
71
|
+
return this.jobs.delete(jobId);
|
|
72
|
+
}
|
|
73
|
+
evictExpired() {
|
|
74
|
+
const cutoff = Date.now() - this.ttlMs;
|
|
75
|
+
let removed = 0;
|
|
76
|
+
for (const [id, job] of this.jobs) {
|
|
77
|
+
const referenceTime = job.ended_at ?? job.started_at;
|
|
78
|
+
if (referenceTime < cutoff) {
|
|
79
|
+
this.jobs.delete(id);
|
|
80
|
+
removed++;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (removed > 0) {
|
|
84
|
+
this.logger?.debug({ removed }, "jobs.evicted");
|
|
85
|
+
}
|
|
86
|
+
return removed;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function scrubArgs(args) {
|
|
90
|
+
const out = {};
|
|
91
|
+
for (const [k, v] of Object.entries(args)) {
|
|
92
|
+
if (k === "approval_token" || k === "password" || k === "new_password" || k === "cipassword") {
|
|
93
|
+
out[k] = "[REDACTED]";
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
out[k] = v;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/jobs/store.ts"],"names":[],"mappings":"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"}
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger singleton — pino configured for stdio MCP transport.
|
|
3
|
+
*
|
|
4
|
+
* All log lines go to **stderr** (stdout is reserved for JSON-RPC).
|
|
5
|
+
* Sensitive fields (tokens, passwords, SSH keys) are redacted automatically.
|
|
6
|
+
*/
|
|
7
|
+
import { type Logger } from "pino";
|
|
8
|
+
export type { Logger };
|
|
9
|
+
export interface LoggerConfig {
|
|
10
|
+
level: "debug" | "info" | "warn" | "error";
|
|
11
|
+
pretty: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Build (or return cached) logger instance.
|
|
15
|
+
*
|
|
16
|
+
* @param cfg.level - pino log level
|
|
17
|
+
* @param cfg.pretty - pretty-print via pino-pretty (dev only)
|
|
18
|
+
*/
|
|
19
|
+
export declare function getLogger(cfg?: LoggerConfig): Logger;
|
|
20
|
+
/**
|
|
21
|
+
* Reset the cached logger. Useful for tests.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resetLogger(): void;
|
|
24
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAa,EAAE,KAAK,MAAM,EAAsB,MAAM,MAAM,CAAC;AAE7D,YAAY,EAAE,MAAM,EAAE,CAAC;AA0BvB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC3C,MAAM,EAAE,OAAO,CAAC;CACjB;AAID;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,GAAE,YAA+C,GAAG,MAAM,CAuBtF;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger singleton — pino configured for stdio MCP transport.
|
|
3
|
+
*
|
|
4
|
+
* All log lines go to **stderr** (stdout is reserved for JSON-RPC).
|
|
5
|
+
* Sensitive fields (tokens, passwords, SSH keys) are redacted automatically.
|
|
6
|
+
*/
|
|
7
|
+
import pino from "pino";
|
|
8
|
+
/** Fields that should never appear in log output. */
|
|
9
|
+
const REDACT_PATHS = [
|
|
10
|
+
"*.token_value",
|
|
11
|
+
"*.token",
|
|
12
|
+
"*.tokenValue",
|
|
13
|
+
"*.password",
|
|
14
|
+
"*.ssh_password",
|
|
15
|
+
"*.ssh_private_key",
|
|
16
|
+
"*.approval_token",
|
|
17
|
+
"*.approvalToken",
|
|
18
|
+
"*.new_password",
|
|
19
|
+
"*.cipassword",
|
|
20
|
+
"api.token",
|
|
21
|
+
"config.PROXMOX_TOKEN_VALUE",
|
|
22
|
+
"config.PROXMOX_SSH_PASSWORD",
|
|
23
|
+
"config.PROXMOX_MCP_APPROVAL_TOKEN",
|
|
24
|
+
"config.proxmox.tokenValue",
|
|
25
|
+
"config.safety.approvalToken",
|
|
26
|
+
"config.proxmox.tokenName",
|
|
27
|
+
"env.PROXMOX_TOKEN_VALUE",
|
|
28
|
+
"env.PROXMOX_SSH_PASSWORD",
|
|
29
|
+
"env.PROXMOX_MCP_APPROVAL_TOKEN",
|
|
30
|
+
];
|
|
31
|
+
let _logger = null;
|
|
32
|
+
/**
|
|
33
|
+
* Build (or return cached) logger instance.
|
|
34
|
+
*
|
|
35
|
+
* @param cfg.level - pino log level
|
|
36
|
+
* @param cfg.pretty - pretty-print via pino-pretty (dev only)
|
|
37
|
+
*/
|
|
38
|
+
export function getLogger(cfg = { level: "info", pretty: false }) {
|
|
39
|
+
if (_logger)
|
|
40
|
+
return _logger;
|
|
41
|
+
const options = {
|
|
42
|
+
level: cfg.level,
|
|
43
|
+
redact: { paths: REDACT_PATHS, censor: "[REDACTED]" },
|
|
44
|
+
base: { service: "proxmox-mcp" },
|
|
45
|
+
timestamp: pino.stdTimeFunctions.isoTime,
|
|
46
|
+
};
|
|
47
|
+
if (cfg.pretty) {
|
|
48
|
+
_logger = pino(options, pino.transport({
|
|
49
|
+
target: "pino-pretty",
|
|
50
|
+
options: { colorize: true, translateTime: "SYS:HH:MM:ss.l" },
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
_logger = pino(options);
|
|
55
|
+
}
|
|
56
|
+
return _logger;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Reset the cached logger. Useful for tests.
|
|
60
|
+
*/
|
|
61
|
+
export function resetLogger() {
|
|
62
|
+
_logger = null;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=log.js.map
|
package/dist/log.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,IAAyC,MAAM,MAAM,CAAC;AAI7D,qDAAqD;AACrD,MAAM,YAAY,GAAG;IACnB,eAAe;IACf,SAAS;IACT,cAAc;IACd,YAAY;IACZ,gBAAgB;IAChB,mBAAmB;IACnB,kBAAkB;IAClB,iBAAiB;IACjB,gBAAgB;IAChB,cAAc;IACd,WAAW;IACX,4BAA4B;IAC5B,6BAA6B;IAC7B,mCAAmC;IACnC,2BAA2B;IAC3B,6BAA6B;IAC7B,0BAA0B;IAC1B,yBAAyB;IACzB,0BAA0B;IAC1B,gCAAgC;CACjC,CAAC;AAOF,IAAI,OAAO,GAAkB,IAAI,CAAC;AAElC;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,MAAoB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;IAC5E,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,MAAM,OAAO,GAAkB;QAC7B,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE;QACrD,IAAI,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE;QAChC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,OAAO;KACzC,CAAC;IAEF,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,OAAO,GAAG,IAAI,CACZ,OAAO,EACP,IAAI,CAAC,SAAS,CAAC;YACb,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,gBAAgB,EAAE;SAC7D,CAAsC,CACxC,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxmox API authentication helpers.
|
|
3
|
+
*
|
|
4
|
+
* API token format: PVEAPIToken=<user>@<realm>!<tokenname>=<token-value>
|
|
5
|
+
* See: https://pve.proxmox.com/pve-docs/api-viewer/#/access/users/userid/token
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Construct the full token string used in the Authorization header.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* buildPveApiToken("root@pam", "mcp", "abc-def-...")
|
|
12
|
+
* // => "root@pam!mcp=abc-def-..."
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildPveApiToken(user: string, tokenName: string, tokenValue: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Construct the full Authorization header value.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* authHeader("root@pam", "mcp", "abc-def-...")
|
|
20
|
+
* // => "PVEAPIToken=root@pam!mcp=abc-def-..."
|
|
21
|
+
*/
|
|
22
|
+
export declare function authHeader(user: string, tokenName: string, tokenValue: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Extract the user portion from an API token string (sanity check / display).
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* parseTokenUser("root@pam!mcp=abc-def") => "root@pam"
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseTokenUser(tokenStr: string): string | null;
|
|
30
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/proxmox/auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5F;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEtF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI9D"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxmox API authentication helpers.
|
|
3
|
+
*
|
|
4
|
+
* API token format: PVEAPIToken=<user>@<realm>!<tokenname>=<token-value>
|
|
5
|
+
* See: https://pve.proxmox.com/pve-docs/api-viewer/#/access/users/userid/token
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Construct the full token string used in the Authorization header.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* buildPveApiToken("root@pam", "mcp", "abc-def-...")
|
|
12
|
+
* // => "root@pam!mcp=abc-def-..."
|
|
13
|
+
*/
|
|
14
|
+
export function buildPveApiToken(user, tokenName, tokenValue) {
|
|
15
|
+
return `${user}!${tokenName}=${tokenValue}`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Construct the full Authorization header value.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* authHeader("root@pam", "mcp", "abc-def-...")
|
|
22
|
+
* // => "PVEAPIToken=root@pam!mcp=abc-def-..."
|
|
23
|
+
*/
|
|
24
|
+
export function authHeader(user, tokenName, tokenValue) {
|
|
25
|
+
return `PVEAPIToken=${buildPveApiToken(user, tokenName, tokenValue)}`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Extract the user portion from an API token string (sanity check / display).
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* parseTokenUser("root@pam!mcp=abc-def") => "root@pam"
|
|
32
|
+
*/
|
|
33
|
+
export function parseTokenUser(tokenStr) {
|
|
34
|
+
const bang = tokenStr.indexOf("!");
|
|
35
|
+
if (bang < 0)
|
|
36
|
+
return null;
|
|
37
|
+
return tokenStr.slice(0, bang);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/proxmox/auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAAiB,EAAE,UAAkB;IAClF,OAAO,GAAG,IAAI,IAAI,SAAS,IAAI,UAAU,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,SAAiB,EAAE,UAAkB;IAC5E,OAAO,eAAe,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;AACxE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC"}
|