Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect if port for local Fauna is already occupied. Allow users to control hostIp. #512

Merged
merged 11 commits into from
Dec 13, 2024
82 changes: 59 additions & 23 deletions src/commands/local.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ensureContainerRunning } from "../lib/docker-containers.mjs";
import { CommandError } from "../lib/errors.mjs";

/**
* Starts the local Fauna container
Expand All @@ -10,9 +11,12 @@ async function startLocal(argv) {
await ensureContainerRunning({
imageName: argv.image,
containerName: argv.name,
hostIp: argv.hostIp,
hostPort: argv.hostPort,
containerPort: argv.containerPort,
pull: argv.pull,
interval: argv.interval,
maxAttempts: argv.maxAttempts,
});
}

Expand All @@ -22,29 +26,61 @@ async function startLocal(argv) {
* @returns {import('yargs').Argv} The yargs instance
*/
function buildLocalCommand(yargs) {
return yargs.options({
containerPort: {
describe: "The port inside the container Fauna listens on.",
type: "number",
default: "8443",
},
hostPort: {
describe:
"The port on the host machine mapped to the container's port. This is the port you'll connect to Fauna on.",
type: "number",
default: "8443",
},
name: {
describe: "The name to give the container",
type: "string",
default: "faunadb",
},
pull: {
describe: "Pull the latest image before starting the container.",
type: "boolean",
default: true,
},
});
return yargs
.options({
containerPort: {
describe: "The port inside the container Fauna listens on.",
type: "number",
default: 8443,
},
hostPort: {
describe:
"The port on the host machine mapped to the container's port. This is the port you'll connect to Fauna on.",
type: "number",
default: 8443,
},
hostIp: {
describe: `The IP address to bind the container's exposed port on the host.`,
type: "string",
default: "0.0.0.0",
},
interval: {
describe:
"The interval (in milliseconds) between health check attempts. Determines how often the CLI checks if the Fauna container is ready.",
type: "number",
default: 10000,
},
maxAttempts: {
describe:
"The maximum number of health check attempts before declaring the start Fauna continer process as failed.",
type: "number",
default: 100,
},
name: {
describe: "The name to give the container",
type: "string",
default: "faunadb",
},
pull: {
describe: "Pull the latest image before starting the container.",
type: "boolean",
default: true,
},
})
.check((argv) => {
if (argv.maxAttempts < 1) {
throw new CommandError("--maxAttempts must be greater than 0.", {
hideHelp: false,
});
}
if (argv.interval < 0) {
throw new CommandError(
"--interval must be greater than or equal to 0.",
{ hideHelp: false },
);
}
return true;
});
}

export default {
Expand Down
2 changes: 2 additions & 0 deletions src/config/setup-container.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fs from "node:fs";
import * as fsp from "node:fs/promises";
import net from "node:net";
import os from "node:os";
import path from "node:path";
import { exit } from "node:process";
Expand Down Expand Up @@ -60,6 +61,7 @@ export const injectables = {
fetch: awilix.asValue(fetchWrapper),
fs: awilix.asValue(fs),
fsp: awilix.asValue(fsp),
net: awilix.asValue(net),
dirname: awilix.asValue(path.dirname),
normalize: awilix.asValue(path.normalize),
homedir: awilix.asValue(os.homedir),
Expand Down
3 changes: 3 additions & 0 deletions src/config/setup-test-container.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import fs from "node:fs";
import net from "node:net";
import path from "node:path";
import { PassThrough } from "node:stream";

Expand Down Expand Up @@ -43,6 +44,7 @@ export function setupTestContainer() {

const thingsToManuallyMock = automock(container);
const customfs = stub({ ...fs });
const customNet = stub({ ...net });
// this is a mock used by the default profile behavior
customfs.readdirSync.withArgs(process.cwd()).returns([]);

Expand All @@ -58,6 +60,7 @@ export function setupTestContainer() {
// real implementation
parseYargs: awilix.asValue(spy(parseYargs)),
fs: awilix.asValue(customfs),
net: awilix.asValue(customNet),
homedir: awilix.asValue(
stub().returns(path.join(__dirname, "../../test/test-homedir")),
),
Expand Down
Loading
Loading