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

Updating the setup script to handle sample data import for Docker #2691

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
30adcd8
Updating the setup script to handle sample data import for Docker
Suyash878 Nov 18, 2024
eab9d94
Coderabbitai suggestion for improved syntax and error handling
Suyash878 Nov 18, 2024
41c9aac
Apply suggestions from code review
Suyash878 Nov 18, 2024
6144664
Moving the os module import to the top.
Suyash878 Nov 18, 2024
124127b
Merge branch 'develop' into issue#2270
Suyash878 Nov 19, 2024
0146c7f
Adding suggestions from coderabbit
Suyash878 Nov 19, 2024
49b4d2f
Merge branch 'develop' into issue#2270
Suyash878 Nov 22, 2024
6210573
Merge branch 'develop' into issue#2270
Suyash878 Nov 24, 2024
270e7fa
Improving the setup script prompts for the sample-data import for doc…
Nov 26, 2024
b7fbd06
Apply suggestions from code review
Suyash878 Nov 26, 2024
bd04520
Merge branch 'develop' into issue#2270
Suyash878 Nov 26, 2024
5443eb3
Fixing formatting issues
Nov 26, 2024
b31922f
Merge branch 'issue#2270' of https://github.com/Suyash878/talawa-api …
Nov 26, 2024
27df373
Adding suggestions from coderabbit
Suyash878 Dec 1, 2024
18fd631
fixing lint error
Suyash878 Dec 1, 2024
ee6b384
fixing formatting error
Suyash878 Dec 1, 2024
9b96d01
Improving error handling
Suyash878 Dec 4, 2024
3c10f42
Fixing linting and formatting errors
Suyash878 Dec 4, 2024
1962ba2
Apply suggestions from code review
Suyash878 Dec 4, 2024
cef2e14
Adding suggestions from coderabbit
Suyash878 Dec 5, 2024
4b71e18
Applying suggestions from coderabbit
Suyash878 Dec 5, 2024
1c56ca1
resolving the flaky test
Suyash878 Dec 8, 2024
6ff5257
Merge branch 'develop' into issue#2270
Suyash878 Dec 8, 2024
94bbaa5
Apply suggestions from code review
Suyash878 Dec 9, 2024
d706bbd
Update setup.ts
Suyash878 Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ ACCESS_TOKEN_SECRET=

REFRESH_TOKEN_SECRET=

# This environment variable is for storing user's response to whether they are using
# docker to setup or not. When using Docker, ensure:
# 1. Never expose Docker daemon socket
# 2. Use non-root user in containers
# 3. Keep base images updated
# Possible values: true/false
DOCKER=


# This environment variable is used to provide connection string of the mongoDB
# database for talawa-api to connect to.
Expand Down
117 changes: 115 additions & 2 deletions setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import fs from "fs";
import inquirer from "inquirer";
import path from "path";
import type { ExecException } from "child_process";
import { exec } from "child_process";
import { exec, spawn } from "child_process";
import { MongoClient } from "mongodb";
import { MAXIMUM_IMAGE_SIZE_LIMIT_KB } from "./src/constants";
import {
Expand Down Expand Up @@ -462,6 +462,63 @@ export async function mongoDB(): Promise<void> {
}
}

/*
For Docker setup
*/

async function runDockerComposeWithLogs(): Promise<void> {
// Check if Docker daemon is running
try {
await new Promise((resolve, reject) => {
const dockerCheck = spawn(
process.platform === "win32" ? "docker.exe" : "docker",
["info"],
{ stdio: "ignore" },
);
dockerCheck.on("error", reject);
dockerCheck.on("close", (code) =>
code === 0
? resolve(null)
: reject(new Error("Docker daemon not running")),
);
});
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(
`Docker daemon is not running. Please start Docker and try again. Details: ${errorMessage}`,
);
}

return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
dockerCompose.kill();
reject(new Error('Docker compose operation timed out after 5 minutes'));
}, 300000);

const dockerCompose = spawn(
process.platform === "win32" ? "docker-compose.exe" : "docker-compose",
["-f", "docker-compose.dev.yaml", "up", "--build", "-d"],
{ stdio: "inherit" },
);
Comment on lines +498 to +502
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using path.join for Docker compose file path.

For better cross-platform compatibility and to prevent path traversal attacks, use path.join for the Docker compose file path.

-      ["-f", "docker-compose.dev.yaml", "up", "--build", "-d"],
+      ["-f", path.join(process.cwd(), "docker-compose.dev.yaml"), "up", "--build", "-d"],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const dockerCompose = spawn(
process.platform === "win32" ? "docker-compose.exe" : "docker-compose",
["-f", "docker-compose.dev.yaml", "up", "--build", "-d"],
{ stdio: "inherit" },
);
const dockerCompose = spawn(
process.platform === "win32" ? "docker-compose.exe" : "docker-compose",
["-f", path.join(process.cwd(), "docker-compose.dev.yaml"), "up", "--build", "-d"],
{ stdio: "inherit" },
);


dockerCompose.on("error", (error) => {
clearTimeout(timeout);
console.error("Error running docker-compose:", error);
reject(error);
});

dockerCompose.on("close", (code) => {
clearTimeout(timeout);
if (code === 0) {
console.log("Docker Compose completed successfully.");
resolve();
} else {
reject(new Error(`Docker Compose exited with code ${code}`));
}
});
});
}

//Get recaptcha details
/**
* The function `recaptcha` prompts the user to enter a reCAPTCHA secret key, validates the input, and
Expand Down Expand Up @@ -917,7 +974,7 @@ async function main(): Promise<void> {
type: "confirm",
name: "isDockerInstallation",
message: "Are you setting up this project using Docker?",
default: false,
default: process.env.MONGO ? false : true,
});

if (isDockerInstallation) {
Expand Down Expand Up @@ -1181,6 +1238,62 @@ async function main(): Promise<void> {
console.log(
"\nCongratulations! Talawa API has been successfully setup! 🥂🎉",
);

const { shouldStartDockerContainers } = await inquirer.prompt({
type: "confirm",
name: "shouldStartDockerContainers",
message: "Do you want to start the Docker containers now?",
default: true,
});

const { shouldImportSampleData } = await inquirer.prompt({
type: "confirm",
name: "shouldImportSampleData",
message:
"Do you want to import Talawa sample data for testing and evaluation purposes?",
default: true,
});

if (isDockerInstallation) {
if (shouldStartDockerContainers) {
console.log("Starting docker container...");
try {
await runDockerComposeWithLogs();
console.log("Docker containers have been built successfully!");
// Wait for mongoDB to be ready
console.log("Waiting for mongoDB to be ready...");
let isConnected = false;
const maxRetries = 30; // 30 seconds timeout
let retryCount = 0;
while (!isConnected) {
if (retryCount >= maxRetries) {
throw new Error('Timed out waiting for MongoDB to be ready after 30 seconds');
}
try {
const client = new MongoClient(process.env.MONGO_DB_URL as string);
await client.connect();
await client.db().command({ ping: 1 });
client.close();
isConnected = true;
console.log("MongoDB is ready!");
} catch (err) {
const error = err instanceof Error ? err.message : String(err);
console.log(
`Waiting for MongoDB to be ready... Retry ${retryCount + 1}/${maxRetries}. Details: ${error}`,
);
await new Promise((resolve) => setTimeout(resolve, 1000));
retryCount++;
}
}

if (shouldImportSampleData) {
await importData();
}
} catch (err) {
console.log("Some error occurred: " + err);
}
Comment on lines +1292 to +1294
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling in catch block.

The error handling could be more informative and type-safe.

-        console.log("Some error occurred: " + err);
+        const errorMessage = err instanceof Error ? err.message : String(err);
+        console.error(`Failed to start Docker containers: ${errorMessage}`);
+        throw err;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (err) {
console.log("Some error occurred: " + err);
}
} catch (err) {
const errorMessage = err instanceof Error ? err.message : String(err);
console.error(`Failed to start Docker containers: ${errorMessage}`);
throw err;
}

}
}
}

main();
Loading