@getmonoceros/workbench 1.6.2 → 1.6.3
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 +69 -11
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -797,13 +797,14 @@ function isValidHomeSubpath(p) {
|
|
|
797
797
|
return p.length > 0 && !p.startsWith("/") && !p.includes("..") && HOME_SUBPATH_RE.test(p);
|
|
798
798
|
}
|
|
799
799
|
var HOME_SUBPATH_RE = /^[A-Za-z0-9._-]+(\/[A-Za-z0-9._-]+)*$/;
|
|
800
|
-
function buildDevcontainerJson(opts) {
|
|
800
|
+
function buildDevcontainerJson(opts, dockerMode = "rootful") {
|
|
801
801
|
const resolvedFeatures = resolveFeatures(opts);
|
|
802
802
|
const features = {};
|
|
803
803
|
for (const f of resolvedFeatures) {
|
|
804
804
|
features[f.devcontainerKey] = f.options;
|
|
805
805
|
}
|
|
806
806
|
const featuresField = Object.keys(features).length > 0 ? { features } : void 0;
|
|
807
|
+
const idmapSuffix = dockerMode === "rootless" ? ",idmap" : "";
|
|
807
808
|
const homeMounts = [];
|
|
808
809
|
for (const f of resolvedFeatures) {
|
|
809
810
|
const allSubs = [
|
|
@@ -812,7 +813,7 @@ function buildDevcontainerJson(opts) {
|
|
|
812
813
|
];
|
|
813
814
|
for (const sub of allSubs) {
|
|
814
815
|
homeMounts.push(
|
|
815
|
-
`source=\${localWorkspaceFolder}/home/${sub},target=/home/node/${sub},type=bind`
|
|
816
|
+
`source=\${localWorkspaceFolder}/home/${sub},target=/home/node/${sub},type=bind${idmapSuffix}`
|
|
816
817
|
);
|
|
817
818
|
}
|
|
818
819
|
}
|
|
@@ -831,10 +832,14 @@ function buildDevcontainerJson(opts) {
|
|
|
831
832
|
}
|
|
832
833
|
const mounts = [...homeMounts];
|
|
833
834
|
const mountsField = mounts.length > 0 ? { mounts } : {};
|
|
835
|
+
const workspaceMountField = dockerMode === "rootless" ? {
|
|
836
|
+
workspaceMount: `source=\${localWorkspaceFolder},target=/workspaces/${opts.name},type=bind${idmapSuffix}`
|
|
837
|
+
} : {};
|
|
834
838
|
return {
|
|
835
839
|
name: opts.name,
|
|
836
840
|
image: BASE_IMAGE,
|
|
837
841
|
remoteUser: "node",
|
|
842
|
+
...workspaceMountField,
|
|
838
843
|
...mountsField,
|
|
839
844
|
runArgs: ["--cap-add=NET_ADMIN"],
|
|
840
845
|
forwardPorts: [3e3, 4e3],
|
|
@@ -842,15 +847,25 @@ function buildDevcontainerJson(opts) {
|
|
|
842
847
|
...featuresField ?? {}
|
|
843
848
|
};
|
|
844
849
|
}
|
|
845
|
-
function buildComposeYaml(opts) {
|
|
850
|
+
function buildComposeYaml(opts, dockerMode = "rootful") {
|
|
846
851
|
const lines = ["services:"];
|
|
852
|
+
const isRootless = dockerMode === "rootless";
|
|
847
853
|
lines.push(" workspace:");
|
|
848
854
|
lines.push(` image: ${BASE_IMAGE}`);
|
|
849
855
|
lines.push(" command: 'sleep infinity'");
|
|
850
856
|
lines.push(" cap_add:");
|
|
851
857
|
lines.push(" - NET_ADMIN");
|
|
852
858
|
lines.push(" volumes:");
|
|
853
|
-
|
|
859
|
+
if (isRootless) {
|
|
860
|
+
lines.push(" - type: bind");
|
|
861
|
+
lines.push(" source: ..");
|
|
862
|
+
lines.push(` target: /workspaces/${opts.name}`);
|
|
863
|
+
lines.push(" bind:");
|
|
864
|
+
lines.push(" create_host_path: true");
|
|
865
|
+
lines.push(" idmap: true");
|
|
866
|
+
} else {
|
|
867
|
+
lines.push(` - ..:/workspaces/${opts.name}:cached`);
|
|
868
|
+
}
|
|
854
869
|
const resolvedFeatures = resolveFeatures(opts);
|
|
855
870
|
for (const f of resolvedFeatures) {
|
|
856
871
|
const allSubs = [
|
|
@@ -858,7 +873,16 @@ function buildComposeYaml(opts) {
|
|
|
858
873
|
...f.persistentHomeFiles.map((entry2) => entry2.path)
|
|
859
874
|
];
|
|
860
875
|
for (const sub of allSubs) {
|
|
861
|
-
|
|
876
|
+
if (isRootless) {
|
|
877
|
+
lines.push(" - type: bind");
|
|
878
|
+
lines.push(` source: ../home/${sub}`);
|
|
879
|
+
lines.push(` target: /home/node/${sub}`);
|
|
880
|
+
lines.push(" bind:");
|
|
881
|
+
lines.push(" create_host_path: true");
|
|
882
|
+
lines.push(" idmap: true");
|
|
883
|
+
} else {
|
|
884
|
+
lines.push(` - ../home/${sub}:/home/node/${sub}`);
|
|
885
|
+
}
|
|
862
886
|
}
|
|
863
887
|
}
|
|
864
888
|
for (const svcId of opts.services) {
|
|
@@ -990,7 +1014,8 @@ async function writePostCreateScript(devcontainerDir, opts) {
|
|
|
990
1014
|
await fs2.writeFile(dest, buildPostCreateScript(opts));
|
|
991
1015
|
await fs2.chmod(dest, 493);
|
|
992
1016
|
}
|
|
993
|
-
async function writeScaffold(opts, targetDir) {
|
|
1017
|
+
async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
|
|
1018
|
+
const dockerMode = scaffoldOpts.dockerMode ?? "rootful";
|
|
994
1019
|
const devcontainerDir = path2.join(targetDir, ".devcontainer");
|
|
995
1020
|
const monocerosDir = path2.join(targetDir, ".monoceros");
|
|
996
1021
|
const projectsDir = path2.join(targetDir, "projects");
|
|
@@ -1019,7 +1044,7 @@ async function writeScaffold(opts, targetDir) {
|
|
|
1019
1044
|
path2.join(monocerosDir, ".gitignore"),
|
|
1020
1045
|
"git-credentials*\ngitconfig\n"
|
|
1021
1046
|
);
|
|
1022
|
-
const devcontainerJson = buildDevcontainerJson(opts);
|
|
1047
|
+
const devcontainerJson = buildDevcontainerJson(opts, dockerMode);
|
|
1023
1048
|
await fs2.writeFile(
|
|
1024
1049
|
path2.join(devcontainerDir, "devcontainer.json"),
|
|
1025
1050
|
JSON.stringify(devcontainerJson, null, 2) + "\n"
|
|
@@ -1050,7 +1075,7 @@ async function writeScaffold(opts, targetDir) {
|
|
|
1050
1075
|
await writePostCreateScript(devcontainerDir, opts);
|
|
1051
1076
|
const composePath = path2.join(devcontainerDir, "compose.yaml");
|
|
1052
1077
|
if (needsCompose(opts)) {
|
|
1053
|
-
await fs2.writeFile(composePath, buildComposeYaml(opts));
|
|
1078
|
+
await fs2.writeFile(composePath, buildComposeYaml(opts, dockerMode));
|
|
1054
1079
|
} else if (existsSync2(composePath)) {
|
|
1055
1080
|
await fs2.rm(composePath);
|
|
1056
1081
|
}
|
|
@@ -2613,14 +2638,44 @@ function adviceForKind(kind) {
|
|
|
2613
2638
|
}
|
|
2614
2639
|
}
|
|
2615
2640
|
|
|
2616
|
-
// src/devcontainer/
|
|
2641
|
+
// src/devcontainer/docker-mode.ts
|
|
2617
2642
|
import { spawn as spawn5 } from "child_process";
|
|
2643
|
+
var realDockerInfo = () => {
|
|
2644
|
+
return new Promise((resolve, reject) => {
|
|
2645
|
+
const child = spawn5(
|
|
2646
|
+
"docker",
|
|
2647
|
+
["info", "--format", "{{json .SecurityOptions}}"],
|
|
2648
|
+
{
|
|
2649
|
+
stdio: ["ignore", "pipe", "inherit"]
|
|
2650
|
+
}
|
|
2651
|
+
);
|
|
2652
|
+
let stdout = "";
|
|
2653
|
+
child.stdout.on("data", (chunk) => {
|
|
2654
|
+
stdout += chunk.toString();
|
|
2655
|
+
});
|
|
2656
|
+
child.on("error", reject);
|
|
2657
|
+
child.on("exit", (code) => resolve({ stdout, exitCode: code ?? 0 }));
|
|
2658
|
+
});
|
|
2659
|
+
};
|
|
2660
|
+
async function detectDockerMode(options = {}) {
|
|
2661
|
+
const spawnFn = options.spawn ?? realDockerInfo;
|
|
2662
|
+
try {
|
|
2663
|
+
const result = await spawnFn();
|
|
2664
|
+
if (result.exitCode !== 0) return "rootful";
|
|
2665
|
+
return /\brootless\b/i.test(result.stdout) ? "rootless" : "rootful";
|
|
2666
|
+
} catch {
|
|
2667
|
+
return "rootful";
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
// src/devcontainer/identity.ts
|
|
2672
|
+
import { spawn as spawn6 } from "child_process";
|
|
2618
2673
|
import { promises as fs7 } from "fs";
|
|
2619
2674
|
import path7 from "path";
|
|
2620
2675
|
import { consola as consola9 } from "consola";
|
|
2621
2676
|
var realGitConfigGet = (key) => {
|
|
2622
2677
|
return new Promise((resolve, reject) => {
|
|
2623
|
-
const child =
|
|
2678
|
+
const child = spawn6("git", ["config", "--global", "--get", key], {
|
|
2624
2679
|
stdio: ["ignore", "pipe", "inherit"]
|
|
2625
2680
|
});
|
|
2626
2681
|
let stdout = "";
|
|
@@ -2804,8 +2859,11 @@ ${sectionLine(label)}
|
|
|
2804
2859
|
}
|
|
2805
2860
|
}
|
|
2806
2861
|
section("Scaffold");
|
|
2862
|
+
const dockerMode = await detectDockerMode({
|
|
2863
|
+
...opts.dockerInfoSpawn ? { spawn: opts.dockerInfoSpawn } : {}
|
|
2864
|
+
});
|
|
2807
2865
|
await fs8.mkdir(targetDir, { recursive: true });
|
|
2808
|
-
await writeScaffold(createOpts, targetDir);
|
|
2866
|
+
await writeScaffold(createOpts, targetDir, { dockerMode });
|
|
2809
2867
|
await writeStateFile(
|
|
2810
2868
|
targetDir,
|
|
2811
2869
|
buildStateFile({
|