vmsan 0.1.0 → 0.1.1
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/_chunks/doctor.mjs +64 -1
- package/dist/_chunks/errors.mjs +22 -6
- package/package.json +1 -1
package/dist/_chunks/doctor.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { l as handleCommandError } from "./errors.mjs";
|
|
|
3
3
|
import { r as getOutputMode, t as createCommandLogger } from "./logger.mjs";
|
|
4
4
|
import { basename, join } from "node:path";
|
|
5
5
|
import { execSync } from "node:child_process";
|
|
6
|
-
import { accessSync, constants, existsSync, readdirSync, statfsSync } from "node:fs";
|
|
6
|
+
import { accessSync, constants, existsSync, readFileSync, readdirSync, statfsSync } from "node:fs";
|
|
7
7
|
import { consola } from "consola";
|
|
8
8
|
import { defineCommand } from "citty";
|
|
9
9
|
function checkKvm() {
|
|
@@ -82,6 +82,67 @@ function checkDefaultInterface() {
|
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
function checkTunDevice() {
|
|
86
|
+
try {
|
|
87
|
+
accessSync("/dev/net/tun", constants.R_OK | constants.W_OK);
|
|
88
|
+
return {
|
|
89
|
+
category: "System",
|
|
90
|
+
name: "TUN device",
|
|
91
|
+
status: "pass",
|
|
92
|
+
detail: "/dev/net/tun"
|
|
93
|
+
};
|
|
94
|
+
} catch {
|
|
95
|
+
return {
|
|
96
|
+
category: "System",
|
|
97
|
+
name: "TUN device",
|
|
98
|
+
status: "fail",
|
|
99
|
+
detail: "/dev/net/tun not accessible",
|
|
100
|
+
fix: "Load the tun kernel module: sudo modprobe tun"
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function checkJailerFilesystem(jailerBaseDir) {
|
|
105
|
+
try {
|
|
106
|
+
const mounts = readFileSync("/proc/mounts", "utf-8");
|
|
107
|
+
let bestMatch = "";
|
|
108
|
+
let bestOptions = "";
|
|
109
|
+
for (const line of mounts.split("\n")) {
|
|
110
|
+
const parts = line.split(" ");
|
|
111
|
+
if (parts.length < 4) continue;
|
|
112
|
+
const mountpoint = parts[1];
|
|
113
|
+
if ((jailerBaseDir === mountpoint || jailerBaseDir.startsWith(mountpoint.endsWith("/") ? mountpoint : `${mountpoint}/`)) && mountpoint.length > bestMatch.length) {
|
|
114
|
+
bestMatch = mountpoint;
|
|
115
|
+
bestOptions = parts[3];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!bestMatch) return {
|
|
119
|
+
category: "System",
|
|
120
|
+
name: "Jailer filesystem",
|
|
121
|
+
status: "pass",
|
|
122
|
+
detail: "Check skipped"
|
|
123
|
+
};
|
|
124
|
+
if (bestOptions.split(",").includes("nodev")) return {
|
|
125
|
+
category: "System",
|
|
126
|
+
name: "Jailer filesystem",
|
|
127
|
+
status: "fail",
|
|
128
|
+
detail: `${bestMatch} mounted with nodev`,
|
|
129
|
+
fix: `The jailer needs device nodes to work. Remount without nodev: sudo mount -o remount,dev ${bestMatch}`
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
category: "System",
|
|
133
|
+
name: "Jailer filesystem",
|
|
134
|
+
status: "pass",
|
|
135
|
+
detail: bestMatch
|
|
136
|
+
};
|
|
137
|
+
} catch {
|
|
138
|
+
return {
|
|
139
|
+
category: "System",
|
|
140
|
+
name: "Jailer filesystem",
|
|
141
|
+
status: "pass",
|
|
142
|
+
detail: "Check skipped"
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
85
146
|
function checkFirecracker(binDir) {
|
|
86
147
|
const fcPath = join(binDir, "firecracker");
|
|
87
148
|
if (!existsSync(fcPath)) return {
|
|
@@ -193,8 +254,10 @@ function runDoctorChecks(paths) {
|
|
|
193
254
|
const p = paths ?? vmsanPaths();
|
|
194
255
|
return [
|
|
195
256
|
checkKvm(),
|
|
257
|
+
checkTunDevice(),
|
|
196
258
|
checkDiskSpace(p.baseDir),
|
|
197
259
|
checkDefaultInterface(),
|
|
260
|
+
checkJailerFilesystem(p.jailerBaseDir),
|
|
198
261
|
checkFirecracker(p.binDir),
|
|
199
262
|
checkJailer(p.binDir),
|
|
200
263
|
checkAgent(p.agentBin),
|
package/dist/_chunks/errors.mjs
CHANGED
|
@@ -154,12 +154,28 @@ var FirecrackerApiError = class extends VmsanError {
|
|
|
154
154
|
};
|
|
155
155
|
}
|
|
156
156
|
};
|
|
157
|
-
const firecrackerApiError = (method, path, httpStatus, body) =>
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
})
|
|
157
|
+
const firecrackerApiError = (method, path, httpStatus, body) => {
|
|
158
|
+
const opts = {
|
|
159
|
+
method,
|
|
160
|
+
path,
|
|
161
|
+
httpStatus,
|
|
162
|
+
message: `${method} ${path} failed (${httpStatus}): ${body}`
|
|
163
|
+
};
|
|
164
|
+
if (body.includes("/dev/net/tun") && body.includes("Permission denied")) {
|
|
165
|
+
opts.why = "Firecracker cannot open /dev/net/tun inside the jailer chroot. This usually means the filesystem where the vmsan data directory resides is mounted with the 'nodev' option.";
|
|
166
|
+
opts.fix = [
|
|
167
|
+
"Run 'vmsan doctor' to check for nodev and other issues.",
|
|
168
|
+
"",
|
|
169
|
+
"If the filesystem is mounted with 'nodev', remount without it:",
|
|
170
|
+
" sudo mount -o remount,dev <mountpoint>",
|
|
171
|
+
"",
|
|
172
|
+
"Or move vmsan to a different filesystem:",
|
|
173
|
+
" export VMSAN_DIR=/var/lib/vmsan",
|
|
174
|
+
" curl -fsSL https://vmsan.dev/install | bash"
|
|
175
|
+
].join("\n");
|
|
176
|
+
}
|
|
177
|
+
return new FirecrackerApiError("ERR_FIRECRACKER_API", opts);
|
|
178
|
+
};
|
|
163
179
|
var NetworkError = class extends VmsanError {
|
|
164
180
|
constructor(code, options) {
|
|
165
181
|
super(code, options);
|