basic functions for room Creation using docker

This commit is contained in:
MathieuSevignyLavallee 2024-11-11 11:32:46 -05:00
parent cca9a2c99a
commit b744284472
2 changed files with 105 additions and 45 deletions

View file

@ -1,6 +1,5 @@
class Room { class Room {
constructor(id,name,host,nbStudents){ constructor(id, name, host, nbStudents = 0) { // Default nbStudents to 0
this.id = id; this.id = id;
this.name = name; this.name = name;
this.host = host; this.host = host;
@ -17,7 +16,7 @@ class RoomRepository{
async init() { async init() {
if (!this.connection) { if (!this.connection) {
await this.db.connect() await this.db.connect();
this.connection = this.db.getConnection(); this.connection = this.db.getConnection();
} }
if (!this.collection) this.collection = this.connection.collection('rooms'); if (!this.collection) this.collection = this.connection.collection('rooms');
@ -36,33 +35,41 @@ class RoomRepository{
async get(id) { async get(id) {
await this.init(); await this.init();
const existingRoom = await this.collection.findOne({ id: id }); const existingRoom = await this.collection.findOne({ id: id });
return existingRoom if (!existingRoom) {
console.warn(`Room with id ${id} not found.`);
return null;
}
return existingRoom;
} }
async getAll() { async getAll() {
await this.init(); await this.init();
const result = await this.collection.find().toArray(); return await this.collection.find().toArray();
return result;
} }
async update(room) { async update(room) {
await this.init(); await this.init();
const result = await this.collection.updateOne( const result = await this.collection.updateOne(
{ id: room.id }, { id: room.id },
{ { $set: room }
$set: room
}
); );
return result.modifiedCount === 1; if (result.modifiedCount === 0) {
console.warn(`Room with id ${room.id} was not updated because it was not found.`);
return false;
}
return true;
} }
async delete(id) { async delete(id) {
await this.init(); await this.init();
const result = await this.collection.deleteMany({ id: id }); const result = await this.collection.deleteOne({ id: id });
return result.deletedCount > 0; if (result.deletedCount === 0) {
console.warn(`Room with id ${id} not found for deletion.`);
return false;
}
return true;
} }
} }
module.exports = { Room, RoomRepository }; module.exports = { Room, RoomRepository };

View file

@ -12,7 +12,7 @@ class DockerRoomProvider extends BaseRoomProvider {
const container_name = `room_${roomId}`; const container_name = `room_${roomId}`;
const containerConfig = { const containerConfig = {
Image: 'evaluetonsavoir-quizroom', // Your local Docker image name Image: 'evaluetonsavoir-quizroom',
name: container_name, name: container_name,
ExposedPorts: { ExposedPorts: {
"4500/tcp": {} "4500/tcp": {}
@ -29,7 +29,6 @@ class DockerRoomProvider extends BaseRoomProvider {
Env: options.env || [] Env: options.env || []
}; };
// Use `this.docker` instead of `docker`
const container = await this.docker.createContainer(containerConfig); const container = await this.docker.createContainer(containerConfig);
await container.start(); await container.start();
@ -41,28 +40,36 @@ class DockerRoomProvider extends BaseRoomProvider {
} }
async deleteRoom(roomId) { async deleteRoom(roomId) {
return await this.roomRepository.delete(roomId); // Short-circuit -- not implemented yet const container_name = `room_${roomId}`;
try { try {
const container = this.docker.getContainer(roomId); const container = this.docker.getContainer(container_name);
const containerInfo = await container.inspect();
if (containerInfo) {
await container.stop(); await container.stop();
await container.remove(); await container.remove();
console.log(`Container for room ${roomId} stopped and removed.`);
await this.roomRepository.delete(roomId); }
console.log(`Conteneur pour la salle ${roomId} supprimé.`);
} catch (error) { } catch (error) {
console.error(`Erreur lors de la suppression du conteneur pour la salle ${roomId}:`, error); if (error.statusCode === 404) {
console.warn(`Container for room ${roomId} not found, proceeding to delete room record.`);
} else {
console.error(`Error handling container for room ${roomId}:`, error);
throw new Error("Failed to delete room"); throw new Error("Failed to delete room");
} }
} }
await this.roomRepository.delete(roomId);
console.log(`Room ${roomId} deleted from repository.`);
}
async getRoomStatus(roomId) { async getRoomStatus(roomId) {
const room = await this.roomRepository.get(roomId); const room = await this.roomRepository.get(roomId);
if (!room) return null; if (!room) return null;
return room; // Short-circuit -- not implemented yet
try { try {
const container = this.docker.getContainer(room.containerId); const container = this.docker.getContainer(room.containerId || `room_${roomId}`);
const info = await container.inspect(); const info = await container.inspect();
const updatedRoomInfo = { const updatedRoomInfo = {
@ -79,10 +86,27 @@ class DockerRoomProvider extends BaseRoomProvider {
await this.roomRepository.update(updatedRoomInfo); await this.roomRepository.update(updatedRoomInfo);
return updatedRoomInfo; return updatedRoomInfo;
} catch (error) { } catch (error) {
console.error(`Erreur lors de la récupération du statut du conteneur pour la salle ${roomId}:`, error); if (error.statusCode === 404) {
console.warn(`Container for room ${roomId} not found, room status set to "terminated".`);
const terminatedRoomInfo = {
...room,
status: "terminated",
containerStatus: {
Running: false,
StartedAt: room.containerStatus?.StartedAt || null,
FinishedAt: Date.now(),
},
lastUpdate: Date.now(),
};
await this.roomRepository.update(terminatedRoomInfo);
return terminatedRoomInfo;
} else {
console.error(`Error retrieving container status for room ${roomId}:`, error);
return null; return null;
} }
} }
}
async listRooms() { async listRooms() {
const rooms = await this.roomRepository.getAll(); const rooms = await this.roomRepository.getAll();
@ -90,16 +114,45 @@ class DockerRoomProvider extends BaseRoomProvider {
} }
async cleanup() { async cleanup() {
/* const rooms = await this.roomRepository.getAll();
const rooms = await this.listRooms(); const roomIds = new Set(rooms.map(room => room.id));
for (const room of rooms) {
if(room.nbStudents == 0){ const containers = await this.docker.listContainers({ all: true });
await this.deleteRoom(room.roomId); const containerIds = new Set();
for (const containerInfo of containers) {
const containerName = containerInfo.Names[0].replace("/", "");
if (containerName.startsWith("room_")) {
const roomId = containerName.split("_")[1];
containerIds.add(roomId);
if (!roomIds.has(roomId)) {
try {
const container = this.docker.getContainer(containerInfo.Id);
await container.stop();
await container.remove();
console.log(`Loose container ${containerName} deleted.`);
} catch (error) {
console.error(`Failed to delete loose container ${containerName}:`, error);
} }
} }
console.log("Nettoyage des salles terminé.");
*/
} }
} }
for (const room of rooms) {
if (!containerIds.has(room.id)) {
try {
await this.roomRepository.delete(room.id);
console.log(`Orphan room ${room.id} deleted from repository.`);
} catch (error) {
console.error(`Failed to delete orphan room ${room.id} from repository:`, error);
}
}
}
console.log("Cleanup of loose containers and orphan rooms completed.");
}
}
module.exports = DockerRoomProvider; module.exports = DockerRoomProvider;