@getmonoceros/workbench 1.36.4 → 1.36.6
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/bin.js +55 -40
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -2154,67 +2154,59 @@ async function containersPublishing(docker, hostPort) {
|
|
|
2154
2154
|
if (ps.exitCode !== 0) return [];
|
|
2155
2155
|
return ps.stdout.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
2156
2156
|
}
|
|
2157
|
+
function hostPortFallbackLines(hostPort) {
|
|
2158
|
+
return [
|
|
2159
|
+
dim("Or set a different proxy port in ") + cyan2("~/.monoceros/monoceros-config.yml") + dim(":"),
|
|
2160
|
+
" " + cyan2("schemaVersion: 1"),
|
|
2161
|
+
" " + cyan2("routing:"),
|
|
2162
|
+
" " + cyan2(" hostPort: 8080"),
|
|
2163
|
+
"",
|
|
2164
|
+
dim(
|
|
2165
|
+
`Aborting. Re-run once port ${hostPort} is free or a different port is set.`
|
|
2166
|
+
)
|
|
2167
|
+
];
|
|
2168
|
+
}
|
|
2157
2169
|
function formatLiveContainerError(hostPort, containers) {
|
|
2158
2170
|
const firstName = containers[0].split(" ")[0];
|
|
2159
2171
|
return [
|
|
2160
2172
|
`Host port ${hostPort} is in use: it is published by a running container.`,
|
|
2161
2173
|
"",
|
|
2162
|
-
|
|
2163
|
-
...containers.map((c) =>
|
|
2174
|
+
dim("Held by:"),
|
|
2175
|
+
...containers.map((c) => " " + cyan2(c)),
|
|
2164
2176
|
"",
|
|
2165
|
-
|
|
2177
|
+
dim("Stop or re-map it, then re-run:"),
|
|
2178
|
+
" " + cyan2(`docker stop ${firstName}`),
|
|
2166
2179
|
"",
|
|
2167
|
-
|
|
2168
|
-
"",
|
|
2169
|
-
`Or move Monoceros off the port: set \`routing.hostPort\` in`,
|
|
2170
|
-
`~/.monoceros/monoceros-config.yml.`,
|
|
2171
|
-
"",
|
|
2172
|
-
`Aborting. Re-run after the conflict is resolved.`
|
|
2180
|
+
...hostPortFallbackLines(hostPort)
|
|
2173
2181
|
].join("\n");
|
|
2174
2182
|
}
|
|
2175
2183
|
function formatLeftoverHolderError(hostPort) {
|
|
2176
2184
|
return [
|
|
2177
|
-
`Host port ${hostPort} is in use, but no
|
|
2178
|
-
`engine publishes it.`,
|
|
2179
|
-
"",
|
|
2180
|
-
`This is almost always a leftover Docker port-forwarder (docker-proxy)`,
|
|
2181
|
-
`whose container is already gone. It is left behind when a native Docker`,
|
|
2182
|
-
`daemon is restarted while a container held the port, which is common with`,
|
|
2183
|
-
`dockerd-via-systemd inside WSL (WSL restarts it on every shutdown). The`,
|
|
2184
|
-
`forwarder keeps the port bound with nothing behind it. Two ways out:`,
|
|
2185
|
-
"",
|
|
2186
|
-
` 1) Recommended: reap the leftover by restarting the Docker daemon`,
|
|
2187
|
-
` (harmless, it just clears stale forwarders):`,
|
|
2188
|
-
` WSL / native dockerd: sudo systemctl restart docker`,
|
|
2189
|
-
` Docker Desktop: restart it from its menu`,
|
|
2190
|
-
` Then re-run.`,
|
|
2185
|
+
`Host port ${hostPort} is in use, but no running container publishes it.`,
|
|
2191
2186
|
"",
|
|
2192
|
-
|
|
2193
|
-
|
|
2187
|
+
dim("Most likely a leftover docker-proxy whose container is already gone"),
|
|
2188
|
+
dim("(a native dockerd in WSL strands these on restart), or a holder in"),
|
|
2189
|
+
dim("another Docker engine. Fix it one of two ways, then re-run:"),
|
|
2194
2190
|
"",
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
` hostPort: 8080 # any free port`,
|
|
2191
|
+
dim("Reap the leftover by restarting the Docker daemon (harmless):"),
|
|
2192
|
+
" " + cyan2("sudo systemctl restart docker"),
|
|
2198
2193
|
"",
|
|
2199
|
-
|
|
2200
|
-
"",
|
|
2201
|
-
`Aborting. Re-run after the conflict is resolved.`
|
|
2194
|
+
...hostPortFallbackLines(hostPort)
|
|
2202
2195
|
].join("\n");
|
|
2203
2196
|
}
|
|
2204
2197
|
function formatHostPortHeldError(hostPort, _code, systemMessage) {
|
|
2205
2198
|
return [
|
|
2206
2199
|
`Cannot reach host port ${hostPort}: ${systemMessage}`,
|
|
2207
2200
|
"",
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2201
|
+
dim('This is not the typical "port already in use" case. The pre-flight'),
|
|
2202
|
+
dim("uses a TCP-connect probe (not a bind), so EACCES / privileged-port"),
|
|
2203
|
+
dim("errors normally do not appear here. Most likely something on your"),
|
|
2204
|
+
dim("host network stack (firewall, network namespace) is interfering with"),
|
|
2205
|
+
dim("loopback connects."),
|
|
2213
2206
|
"",
|
|
2214
|
-
"Workaround: move Monoceros off this port by setting",
|
|
2215
|
-
"`routing.hostPort` in ~/.monoceros/monoceros-config.yml.",
|
|
2207
|
+
dim("Workaround: move Monoceros off this port by setting ") + cyan2("routing.hostPort") + dim(" in ") + cyan2("~/.monoceros/monoceros-config.yml") + dim("."),
|
|
2216
2208
|
"",
|
|
2217
|
-
|
|
2209
|
+
dim("Aborting. Re-run after the issue is resolved.")
|
|
2218
2210
|
].join("\n");
|
|
2219
2211
|
}
|
|
2220
2212
|
var CONNECT_TIMEOUT_MS, realPortProbe;
|
|
@@ -2222,6 +2214,7 @@ var init_port_check = __esm({
|
|
|
2222
2214
|
"src/proxy/port-check.ts"() {
|
|
2223
2215
|
"use strict";
|
|
2224
2216
|
init_proxy();
|
|
2217
|
+
init_format();
|
|
2225
2218
|
CONNECT_TIMEOUT_MS = 750;
|
|
2226
2219
|
realPortProbe = (port) => {
|
|
2227
2220
|
return new Promise((resolve) => {
|
|
@@ -3762,6 +3755,25 @@ function composeVolumeSource(spec, serviceName) {
|
|
|
3762
3755
|
const relative = src.startsWith("./") ? src.slice(2) : src;
|
|
3763
3756
|
return `../${relative}:${rest}`;
|
|
3764
3757
|
}
|
|
3758
|
+
function serviceVolumeHostDirs(services, repos = []) {
|
|
3759
|
+
const cloneTargets = repos.map((r) => `projects/${r.path}`);
|
|
3760
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
3761
|
+
for (const svc of services) {
|
|
3762
|
+
for (const vol of svc.volumes) {
|
|
3763
|
+
const src = vol.split(":")[0];
|
|
3764
|
+
if (src === "data") continue;
|
|
3765
|
+
const rel = src.startsWith("./") ? src.slice(2) : src;
|
|
3766
|
+
if (cloneTargets.some((t) => rel === t || rel.startsWith(`${t}/`))) {
|
|
3767
|
+
continue;
|
|
3768
|
+
}
|
|
3769
|
+
const slash = rel.lastIndexOf("/");
|
|
3770
|
+
const lastSeg = slash === -1 ? rel : rel.slice(slash + 1);
|
|
3771
|
+
const dir = lastSeg.includes(".") ? slash === -1 ? "" : rel.slice(0, slash) : rel;
|
|
3772
|
+
if (dir) dirs.add(dir);
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
return [...dirs];
|
|
3776
|
+
}
|
|
3765
3777
|
function buildComposeYaml(opts, dockerMode = "rootful") {
|
|
3766
3778
|
void dockerMode;
|
|
3767
3779
|
const hasPorts = (opts.ports?.length ?? 0) > 0;
|
|
@@ -4115,6 +4127,9 @@ async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
|
|
|
4115
4127
|
await fs8.mkdir(path11.join(dataDir, svc.name), { recursive: true });
|
|
4116
4128
|
}
|
|
4117
4129
|
}
|
|
4130
|
+
for (const dir of serviceVolumeHostDirs(opts.services, opts.repos)) {
|
|
4131
|
+
await fs8.mkdir(path11.join(targetDir, dir), { recursive: true });
|
|
4132
|
+
}
|
|
4118
4133
|
}
|
|
4119
4134
|
const containerGitignore = path11.join(targetDir, ".gitignore");
|
|
4120
4135
|
await fs8.writeFile(
|
|
@@ -8857,7 +8872,7 @@ var CLI_VERSION;
|
|
|
8857
8872
|
var init_version = __esm({
|
|
8858
8873
|
"src/version.ts"() {
|
|
8859
8874
|
"use strict";
|
|
8860
|
-
CLI_VERSION = true ? "1.36.
|
|
8875
|
+
CLI_VERSION = true ? "1.36.6" : "dev";
|
|
8861
8876
|
}
|
|
8862
8877
|
});
|
|
8863
8878
|
|