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 #2751

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion docker-compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ services:
- "80:80"
- "443:443"
volumes:
- $PWD/Caddyfile:/etc/caddy/Caddyfile
- ./Caddyfile:/etc/caddy/Caddyfile
VanshikaSabharwal marked this conversation as resolved.
Show resolved Hide resolved
- $PWD/site:/srv
- caddy_data:/data
- caddy_config:/config
Expand Down
34 changes: 34 additions & 0 deletions sample_data/venue.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[
{
"_id": "6437904485008f171cf29925",
"name": "Unity Foundation",
"description": "A large hall for community events in the Bronx.",
"capacity": 500,
"imageUrl": "https://example.com/bronx-hall.jpg",
"organization": "6437904485008f171cf29924"
},
{
"_id": "6537904485008f171cf29925",
"name": "Unity Conference Room - Queens",
"description": "A small conference room for meetings in Queens.",
"capacity": 50,
"imageUrl": "https://example.com/queens-conference-room.jpg",
"organization": "6537904485008f171cf29924"
},
{
"_id": "6637904485008f171cf29925",
"name": "Unity Arena - Staten Island",
"description": "A large outdoor arena for public events in Staten Island.",
"capacity": 2000,
"imageUrl": "https://example.com/staten-island-arena.jpg",
"organization": "6637904485008f171cf29924"
},
{
"_id": "6737904485008f171cf29925",
"name": "Unity Hall - Brooklyn",
"description": "A community hall in Brooklyn for social events.",
"capacity": 300,
"imageUrl": "https://example.com/brooklyn-hall.jpg",
"organization": "6737904485008f171cf29924"
}
]
119 changes: 117 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" },
);

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,
});
VanshikaSabharwal marked this conversation as resolved.
Show resolved Hide resolved

if (isDockerInstallation) {
Expand Down Expand Up @@ -1181,6 +1238,64 @@ 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++;
}
}
VanshikaSabharwal marked this conversation as resolved.
Show resolved Hide resolved

if (shouldImportSampleData) {
await importData();
}
} catch (err) {
console.log("Some error occurred: " + err);
}
}
}
}

main();
11 changes: 10 additions & 1 deletion src/models/SampleData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface InterfaceSampleData extends Document {
| "Organization"
| "Post"
| "Event"
| "Venue"
| "User"
| "Plugin"
| "AppUserProfile";
Expand All @@ -28,7 +29,15 @@ const sampleDataSchema = new Schema<InterfaceSampleData>({
collectionName: {
type: String,
required: true,
enum: ["Organization", "Post", "Event", "User", "AppUserProfile", "Plugin"],
enum: [
"Organization",
"Post",
"Event",
"Venue",
"User",
"AppUserProfile",
"Plugin",
],
},
});

Expand Down
6 changes: 6 additions & 0 deletions src/utilities/loadSampleData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Organization,
Post,
User,
Venue,
} from "../models";
import { RecurrenceRule } from "../models/RecurrenceRule";

Expand Down Expand Up @@ -128,6 +129,9 @@ async function insertCollections(collections: string[]): Promise<void> {
case "events":
await Event.insertMany(docs);
break;
case "venue":
await Venue.insertMany(docs);
break;
case "recurrenceRules":
await RecurrenceRule.insertMany(docs);
break;
Expand Down Expand Up @@ -172,6 +176,7 @@ async function checkCountAfterImport(): Promise<void> {
{ name: "events", model: Event },
{ name: "recurrenceRules", model: RecurrenceRule },
{ name: "posts", model: Post },
{ name: "venue", model: Venue },
{ name: "appUserProfiles", model: AppUserProfile },
];

Expand Down Expand Up @@ -201,6 +206,7 @@ const collections = [
"organizations",
"posts",
"events",
"venue",
VanshikaSabharwal marked this conversation as resolved.
Show resolved Hide resolved
"recurrenceRules",
"appUserProfiles",
"actionItemCategories",
Expand Down
2 changes: 2 additions & 0 deletions src/utilities/removeSampleOrganizationUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Organization,
Plugin,
Post,
Venue,
SampleData,
User,
} from "../models";
Expand All @@ -27,6 +28,7 @@ export async function removeSampleOrganization(): Promise<void> {
Post,
Event,
User,
Venue,
Plugin,
AppUserProfile,
};
Expand Down
2 changes: 1 addition & 1 deletion tests/resolvers/Query/getVolunteerRanks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe("resolvers -> Query -> getVolunteerRanks", () => {
},
{},
)) as unknown as VolunteerRank[];
expect(volunteerRanks[0].hoursVolunteered).toEqual(0);
expect(volunteerRanks[0].hoursVolunteered).toEqual(2);
expect(volunteerRanks[0].user._id).toEqual(testUser1?._id);
expect(volunteerRanks[0].rank).toEqual(1);
});
Expand Down
Loading