@getmonoceros/workbench 1.38.12 → 1.38.14
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.
|
@@ -52,5 +52,13 @@ usageNotes:
|
|
|
52
52
|
briefing:
|
|
53
53
|
- text: 'Identity & access management, reached in-container as host `keycloak`. Admin console + API at `$KEYCLOAK_URL` (admin `$KEYCLOAK_USER` / `$KEYCLOAK_PASSWORD`).'
|
|
54
54
|
- text: 'Keycloak auto-imports realms at startup (`--import-realm`) from `/opt/keycloak/data/import`, and its database is ephemeral - it re-seeds from those files on every apply. So keep the realm as a file in the repo at `projects/<app>/keycloak/realm.json`; do NOT configure it by hand in the admin UI, that is lost on the next apply.'
|
|
55
|
-
- text:
|
|
55
|
+
- text: |-
|
|
56
|
+
You can create/edit that realm.json, but the bind-mount that feeds it to Keycloak lives in the container yml on the host, which you cannot edit from inside. Give the user this exact block to add under the `keycloak` service in the container yml, with `<app>` replaced by the real project name in BOTH places (the source path and the import target filename):
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
volumes:
|
|
60
|
+
- projects/<app>/keycloak/realm.json:/opt/keycloak/data/import/<app>.json:ro
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Mount the single realm.json to a distinctly-named `*.json` target under the import dir. Do NOT mount the whole `keycloak/` directory onto `/opt/keycloak/data/import`, and do NOT prefix the source with `./`. Then have the user run `monoceros apply <name>` on the host.
|
|
56
64
|
- text: "In the realm, define a public client (e.g. `<app>-web`) with your app's redirect URIs, and have the frontend reach Keycloak same-origin under `/realms/<realm>` so the issuer follows the request host (works on `.localhost` and over `monoceros share`)."
|
package/dist/bin.js
CHANGED
|
@@ -1537,10 +1537,14 @@ var init_locate_running = __esm({
|
|
|
1537
1537
|
};
|
|
1538
1538
|
realContainerExec = (containerId, argv) => {
|
|
1539
1539
|
return new Promise((resolve, reject) => {
|
|
1540
|
-
const child = spawn(
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1540
|
+
const child = spawn(
|
|
1541
|
+
"docker",
|
|
1542
|
+
["exec", "-u", "node", containerId, ...argv],
|
|
1543
|
+
{
|
|
1544
|
+
// Inherit stdio so live git output reaches the user.
|
|
1545
|
+
stdio: ["ignore", "inherit", "inherit"]
|
|
1546
|
+
}
|
|
1547
|
+
);
|
|
1544
1548
|
child.on("error", reject);
|
|
1545
1549
|
child.on("exit", (code) => resolve({ exitCode: code ?? 0 }));
|
|
1546
1550
|
});
|
|
@@ -4076,7 +4080,11 @@ function buildPostCreateScript(opts) {
|
|
|
4076
4080
|
lines.push(
|
|
4077
4081
|
`if [ ! -d "projects/${repo.path}" ]; then`,
|
|
4078
4082
|
` echo "\u2192 Cloning ${repo.path} from ${url}\u2026"`,
|
|
4079
|
-
` git clone "${url}" "projects/${repo.path}"`,
|
|
4083
|
+
` if ! git clone "${url}" "projects/${repo.path}"; then`,
|
|
4084
|
+
` echo "\u26A0 Could not clone ${repo.path} from ${url} \u2014 skipping." >&2`,
|
|
4085
|
+
` echo " If it is private, set a token and re-apply (see the repo-access notice)." >&2`,
|
|
4086
|
+
` rm -rf "projects/${repo.path}"`,
|
|
4087
|
+
` fi`,
|
|
4080
4088
|
`else`,
|
|
4081
4089
|
` echo "\u2192 projects/${repo.path} already exists, skipping clone"`,
|
|
4082
4090
|
`fi`
|
|
@@ -4085,8 +4093,10 @@ function buildPostCreateScript(opts) {
|
|
|
4085
4093
|
const safeName = repo.gitUser.name.replace(/"/g, '\\"');
|
|
4086
4094
|
const safeEmail = repo.gitUser.email.replace(/"/g, '\\"');
|
|
4087
4095
|
lines.push(
|
|
4088
|
-
`
|
|
4089
|
-
`git -C "projects/${repo.path}" config user.
|
|
4096
|
+
`if [ -d "projects/${repo.path}/.git" ]; then`,
|
|
4097
|
+
` git -C "projects/${repo.path}" config user.name "${safeName}"`,
|
|
4098
|
+
` git -C "projects/${repo.path}" config user.email "${safeEmail}"`,
|
|
4099
|
+
`fi`
|
|
4090
4100
|
);
|
|
4091
4101
|
}
|
|
4092
4102
|
}
|
|
@@ -8069,6 +8079,30 @@ var init_docker_mode = __esm({
|
|
|
8069
8079
|
}
|
|
8070
8080
|
});
|
|
8071
8081
|
|
|
8082
|
+
// src/devcontainer/daemon-ready.ts
|
|
8083
|
+
async function waitForDockerDaemon(options = {}) {
|
|
8084
|
+
const exec = options.exec ?? defaultDockerExec;
|
|
8085
|
+
const attempts = options.attempts ?? 12;
|
|
8086
|
+
const delayMs = options.delayMs ?? 500;
|
|
8087
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
8088
|
+
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
8089
|
+
try {
|
|
8090
|
+
const result = await exec(["ps", "-q"]);
|
|
8091
|
+
if (result.exitCode === 0) return true;
|
|
8092
|
+
} catch {
|
|
8093
|
+
}
|
|
8094
|
+
if (attempt === 0) options.onWait?.();
|
|
8095
|
+
if (attempt < attempts - 1) await sleep(delayMs);
|
|
8096
|
+
}
|
|
8097
|
+
return false;
|
|
8098
|
+
}
|
|
8099
|
+
var init_daemon_ready = __esm({
|
|
8100
|
+
"src/devcontainer/daemon-ready.ts"() {
|
|
8101
|
+
"use strict";
|
|
8102
|
+
init_proxy();
|
|
8103
|
+
}
|
|
8104
|
+
});
|
|
8105
|
+
|
|
8072
8106
|
// src/devcontainer/identity.ts
|
|
8073
8107
|
import { spawn as spawn9 } from "child_process";
|
|
8074
8108
|
import { promises as fs14 } from "fs";
|
|
@@ -8434,6 +8468,17 @@ Fix the value in the env file (or the yml).`
|
|
|
8434
8468
|
}
|
|
8435
8469
|
}
|
|
8436
8470
|
section("Scaffold");
|
|
8471
|
+
const daemonReady = await waitForDockerDaemon({
|
|
8472
|
+
exec: opts.dockerExec ?? defaultDockerExec,
|
|
8473
|
+
onWait: () => (logger.warn ?? logger.info)(
|
|
8474
|
+
"Waiting for the Docker daemon to become ready\u2026"
|
|
8475
|
+
)
|
|
8476
|
+
});
|
|
8477
|
+
if (!daemonReady) {
|
|
8478
|
+
(logger.warn ?? logger.info)(
|
|
8479
|
+
"Docker daemon still not responding \u2014 continuing; the next docker step will report the error."
|
|
8480
|
+
);
|
|
8481
|
+
}
|
|
8437
8482
|
const dockerMode = await detectDockerMode({
|
|
8438
8483
|
...opts.dockerInfoSpawn ? { spawn: opts.dockerInfoSpawn } : {}
|
|
8439
8484
|
});
|
|
@@ -8807,6 +8852,7 @@ var init_apply = __esm({
|
|
|
8807
8852
|
init_credentials();
|
|
8808
8853
|
init_docker_mode();
|
|
8809
8854
|
init_cli();
|
|
8855
|
+
init_daemon_ready();
|
|
8810
8856
|
init_proxy();
|
|
8811
8857
|
init_dynamic();
|
|
8812
8858
|
init_port_check();
|
|
@@ -9006,7 +9052,7 @@ var CLI_VERSION;
|
|
|
9006
9052
|
var init_version = __esm({
|
|
9007
9053
|
"src/version.ts"() {
|
|
9008
9054
|
"use strict";
|
|
9009
|
-
CLI_VERSION = true ? "1.38.
|
|
9055
|
+
CLI_VERSION = true ? "1.38.14" : "dev";
|
|
9010
9056
|
}
|
|
9011
9057
|
});
|
|
9012
9058
|
|