Skip to content

Commit 4cfa5ca

Browse files
committed
fixup! feat(cli): changes to run to work better with detached stdin (no shell)
1 parent 52306dd commit 4cfa5ca

2 files changed

Lines changed: 41 additions & 33 deletions

File tree

apps/cli/src/commands/run.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { DEFAULT_SDK_VERSION, PREFERRED_PORT } from "../config.js";
2020
import {
2121
AVAILABLE_SERVICES,
2222
deployApplication,
23+
host,
2324
removeApplication,
2425
type RollupsDeployment,
2526
startEnvironment,
@@ -298,11 +299,15 @@ export const createRunCommand = () => {
298299
// configure optional anvil fork
299300
const forkConfig = await configureFork(options);
300301

302+
// if TTY is not attached, run on foreground (not detached)
303+
const detach = process.stdin.isTTY;
304+
301305
// run compose environment (detached)
302-
const { address, config } = await startEnvironment({
306+
const { cmd, config } = await startEnvironment({
303307
blockTime,
304308
cpus,
305309
defaultBlock,
310+
detach,
306311
dryRun,
307312
forkConfig,
308313
memory,
@@ -313,6 +318,9 @@ export const createRunCommand = () => {
313318
verbose,
314319
});
315320

321+
// host address
322+
const address = `${host}:${port}`;
323+
316324
if (dryRun && config) {
317325
// just show the docker compose configuration and quit
318326
process.stdout.write(config);
@@ -365,7 +373,7 @@ export const createRunCommand = () => {
365373
process.exit(0);
366374
};
367375

368-
if (process.stdin.isTTY) {
376+
if (detach) {
369377
// inhibit SIGINT and SIGTERM, will be handled gracefully by the shell
370378
process.on("SIGINT", () => {});
371379
process.on("SIGTERM", () => {});
@@ -387,18 +395,19 @@ export const createRunCommand = () => {
387395
});
388396
await shutdown();
389397
} else {
390-
// non-interactive mode: wait for SIGINT or SIGTERM to shutdown
391-
await new Promise<void>((resolve) => {
392-
// keep the event loop alive
393-
const keepAlive = setInterval(() => {}, 1 << 30);
394-
const handler = () => {
395-
clearInterval(keepAlive);
396-
resolve();
397-
};
398-
process.on("SIGINT", handler);
399-
process.on("SIGTERM", handler);
400-
});
401-
await shutdown();
398+
process.on("SIGINT", shutdown);
399+
process.on("SIGTERM", shutdown);
400+
try {
401+
await cmd;
402+
} catch (error: unknown) {
403+
if (error instanceof ExecaError) {
404+
// just continue gracefully
405+
if (error.exitCode === 130) {
406+
return;
407+
}
408+
throw error;
409+
}
410+
}
402411
}
403412
});
404413
};

apps/cli/src/exec/rollups.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ type Service = {
135135
errorTitle?: string; // title of the service when it is not healthy
136136
};
137137

138-
const host = "http://127.0.0.1";
138+
export const host = "http://127.0.0.1";
139139

140140
// services configuration
141141
const baseServices: Service[] = [
@@ -242,6 +242,7 @@ export const startEnvironment = async (options: {
242242
blockTime: number;
243243
cpus?: number;
244244
defaultBlock: "latest" | "safe" | "pending" | "finalized";
245+
detach: boolean;
245246
dryRun: boolean;
246247
forkConfig?: ForkConfig;
247248
memory?: number;
@@ -255,6 +256,7 @@ export const startEnvironment = async (options: {
255256
blockTime,
256257
cpus,
257258
defaultBlock,
259+
detach,
258260
dryRun,
259261
forkConfig,
260262
memory,
@@ -265,25 +267,26 @@ export const startEnvironment = async (options: {
265267
verbose,
266268
} = options;
267269

268-
const address = `${host}:${port}`;
269-
270270
// setup the environment variable used in docker compose
271271
const env: NodeJS.ProcessEnv = {
272272
CARTESI_BLOCKCHAIN_DEFAULT_BLOCK: defaultBlock,
273273
CARTESI_LISTEN_PORT: port.toString(),
274274
CARTESI_LOG_LEVEL: verbose ? "debug" : "info",
275275
};
276276

277+
// local dev environment, we don't need security
278+
const databasePassword = "password";
279+
277280
const files = [
278281
anvil({
279282
blockTime,
280283
forkConfig,
281284
imageTag: runtimeVersion,
282285
}),
283-
database({ imageTag: runtimeVersion, password: "password" }),
286+
database({ imageTag: runtimeVersion, password: databasePassword }),
284287
node({
285288
cpus,
286-
databasePassword: "password",
289+
databasePassword,
287290
defaultBlock,
288291
forkChainId: forkConfig?.chainId,
289292
imageTag: runtimeVersion,
@@ -298,7 +301,7 @@ export const startEnvironment = async (options: {
298301
explorer({
299302
imageTag: "1.4.0",
300303
apiTag: "1.1.0",
301-
databasePassword: "password",
304+
databasePassword,
302305
port,
303306
}),
304307
);
@@ -316,7 +319,7 @@ export const startEnvironment = async (options: {
316319
const composeArgs = ["compose", "-f", "-", "--project-directory", "."];
317320

318321
// run in detached mode (background)
319-
const upArgs = ["--detach"];
322+
const upArgs = detach ? ["--detach"] : [];
320323

321324
// merge files, following Docker Compose merge rules
322325
const composeFile = concat([{ name: projectName }, ...files]);
@@ -330,25 +333,21 @@ export const startEnvironment = async (options: {
330333
{ env, input: stringify(composeFile, { lineWidth: 0, indent: 2 }) },
331334
);
332335

333-
return { address, config };
336+
return { config };
334337
}
335338

336-
// pull images first
337-
// const pullArgs = ["--policy", "missing"];
338-
// await execa("docker", [...composeArgs, "pull", ...pullArgs], {
339-
// env,
340-
////FIXME: stdio and input won't work together
341-
// stdio: "inherit",
342-
// input: composeFile.build()
343-
// });
344-
345339
// run compose
346-
await execa("docker", [...composeArgs, "up", ...upArgs], {
340+
const cmd = execa("docker", [...composeArgs, "up", ...upArgs], {
347341
env,
348342
input: stringify(composeFile, { lineWidth: 0, indent: 2 }),
349343
});
350344

351-
return { address };
345+
// if detached, wait to finish
346+
if (detach) {
347+
await cmd;
348+
}
349+
350+
return { cmd };
352351
};
353352

354353
/**

0 commit comments

Comments
 (0)