fix: sync files to container instead of local file system

This commit is contained in:
James Murdza 2024-06-14 15:43:22 -04:00
parent 869ae6c148
commit 006c5cea66

View File

@ -1,4 +1,3 @@
import fs from "fs";
import os from "os"; import os from "os";
import path from "path"; import path from "path";
import cors from "cors"; import cors from "cors";
@ -19,7 +18,7 @@ import {
saveFile, saveFile,
} from "./fileoperations"; } from "./fileoperations";
import { LockManager } from "./utils"; import { LockManager } from "./utils";
import { Sandbox, Terminal } from "e2b"; import { Sandbox, Terminal, FilesystemManager } from "e2b";
import { import {
MAX_BODY_SIZE, MAX_BODY_SIZE,
createFileRL, createFileRL,
@ -48,7 +47,13 @@ const containers: Record<string, Sandbox> = {};
const connections: Record<string, number> = {}; const connections: Record<string, number> = {};
const terminals: Record<string, Terminal> = {}; const terminals: Record<string, Terminal> = {};
const dirName = path.join(__dirname, ".."); const dirName = "/home/user";
const moveFile = async (filesystem: FilesystemManager, filePath: string, newFilePath: string) => {
const fileContents = await filesystem.readBytes(filePath)
await filesystem.writeBytes(newFilePath, fileContents);
await filesystem.remove(filePath);
}
io.use(async (socket, next) => { io.use(async (socket, next) => {
const handshakeSchema = z.object({ const handshakeSchema = z.object({
@ -134,12 +139,10 @@ io.on("connection", async (socket) => {
}); });
const sandboxFiles = await getSandboxFiles(data.sandboxId); const sandboxFiles = await getSandboxFiles(data.sandboxId);
sandboxFiles.fileData.forEach((file) => { sandboxFiles.fileData.forEach(async (file) => {
const filePath = path.join(dirName, file.id); const filePath = path.join(dirName, file.id);
fs.mkdirSync(path.dirname(filePath), { recursive: true }); await containers[data.sandboxId].filesystem.makeDir(path.dirname(filePath));
fs.writeFile(filePath, file.data, function (err) { await containers[data.sandboxId].filesystem.write(filePath, file.data);
if (err) throw err;
});
}); });
socket.emit("loaded", sandboxFiles.files); socket.emit("loaded", sandboxFiles.files);
@ -173,9 +176,7 @@ io.on("connection", async (socket) => {
if (!file) return; if (!file) return;
file.data = body; file.data = body;
fs.writeFile(path.join(dirName, file.id), body, function (err) { await containers[data.sandboxId].filesystem.write(path.join(dirName, file.id), body);
if (err) throw err;
});
await saveFile(fileId, body); await saveFile(fileId, body);
} catch (e) { } catch (e) {
io.emit("rateLimit", "Rate limited: file saving. Please slow down."); io.emit("rateLimit", "Rate limited: file saving. Please slow down.");
@ -189,13 +190,11 @@ io.on("connection", async (socket) => {
const parts = fileId.split("/"); const parts = fileId.split("/");
const newFileId = folderId + "/" + parts.pop(); const newFileId = folderId + "/" + parts.pop();
fs.rename( await moveFile(
containers[data.sandboxId].filesystem,
path.join(dirName, fileId), path.join(dirName, fileId),
path.join(dirName, newFileId), path.join(dirName, newFileId)
function (err) { )
if (err) throw err;
}
);
file.id = newFileId; file.id = newFileId;
@ -221,9 +220,7 @@ io.on("connection", async (socket) => {
const id = `projects/${data.sandboxId}/${name}`; const id = `projects/${data.sandboxId}/${name}`;
fs.writeFile(path.join(dirName, id), "", function (err) { await containers[data.sandboxId].filesystem.write(path.join(dirName, id), "");
if (err) throw err;
});
sandboxFiles.files.push({ sandboxFiles.files.push({
id, id,
@ -250,9 +247,7 @@ io.on("connection", async (socket) => {
const id = `projects/${data.sandboxId}/${name}`; const id = `projects/${data.sandboxId}/${name}`;
fs.mkdir(path.join(dirName, id), { recursive: true }, function (err) { await containers[data.sandboxId].filesystem.makeDir(path.join(dirName, id));
if (err) throw err;
});
callback(); callback();
} catch (e) { } catch (e) {
@ -272,13 +267,12 @@ io.on("connection", async (socket) => {
const newFileId = const newFileId =
parts.slice(0, parts.length - 1).join("/") + "/" + newName; parts.slice(0, parts.length - 1).join("/") + "/" + newName;
fs.rename(
await moveFile(
containers[data.sandboxId].filesystem,
path.join(dirName, fileId), path.join(dirName, fileId),
path.join(dirName, newFileId), path.join(dirName, newFileId)
function (err) { )
if (err) throw err;
}
);
await renameFile(fileId, newFileId, file.data); await renameFile(fileId, newFileId, file.data);
} catch (e) { } catch (e) {
io.emit("rateLimit", "Rate limited: file renaming. Please slow down."); io.emit("rateLimit", "Rate limited: file renaming. Please slow down.");
@ -292,9 +286,7 @@ io.on("connection", async (socket) => {
const file = sandboxFiles.fileData.find((f) => f.id === fileId); const file = sandboxFiles.fileData.find((f) => f.id === fileId);
if (!file) return; if (!file) return;
fs.unlink(path.join(dirName, fileId), function (err) { await containers[data.sandboxId].filesystem.remove(path.join(dirName, fileId));
if (err) throw err;
});
sandboxFiles.fileData = sandboxFiles.fileData.filter( sandboxFiles.fileData = sandboxFiles.fileData.filter(
(f) => f.id !== fileId (f) => f.id !== fileId
); );
@ -317,9 +309,7 @@ io.on("connection", async (socket) => {
await Promise.all( await Promise.all(
files.map(async (file) => { files.map(async (file) => {
fs.unlink(path.join(dirName, file), function (err) { await containers[data.sandboxId].filesystem.remove(path.join(dirName, file));
if (err) throw err;
});
sandboxFiles.fileData = sandboxFiles.fileData.filter( sandboxFiles.fileData = sandboxFiles.fileData.filter(
(f) => f.id !== file (f) => f.id !== file
@ -348,6 +338,7 @@ io.on("connection", async (socket) => {
size: { cols: 80, rows: 20 }, size: { cols: 80, rows: 20 },
onExit: () => console.log("Terminal exited", id), onExit: () => console.log("Terminal exited", id),
}); });
await terminals[id].sendData(`cd "${path.join(dirName, "projects", data.sandboxId)}"\r`)
await terminals[id].sendData("export PS1='user> '\rclear\r"); await terminals[id].sendData("export PS1='user> '\rclear\r");
console.log("Created terminal", id); console.log("Created terminal", id);
} catch (error) { } catch (error) {