diff --git a/packages/grid_client/src/helpers/index.ts b/packages/grid_client/src/helpers/index.ts
index ef382c8e77..df0e217c10 100644
--- a/packages/grid_client/src/helpers/index.ts
+++ b/packages/grid_client/src/helpers/index.ts
@@ -4,3 +4,4 @@ export * from "./events";
export * from "./validator";
export * from "./expose";
export * from "./migration";
+export * from "./root_fs";
diff --git a/packages/grid_client/src/helpers/root_fs.ts b/packages/grid_client/src/helpers/root_fs.ts
new file mode 100644
index 0000000000..6988b959be
--- /dev/null
+++ b/packages/grid_client/src/helpers/root_fs.ts
@@ -0,0 +1,39 @@
+import { Decimal } from "decimal.js";
+
+const GB = 1024;
+
+interface RootFSOptions {
+ /** The machine CPU, should be in cores e.g. 5 cores*/
+ CPUCores: number;
+ /** The machine memory, should be in megabytes e.g. 1024 or 2048 MG*/
+ RAMInMegaBytes: number;
+}
+
+/**
+ * Calculate the root filesystem size (CU - Compute Units) based on provided options.
+ *
+ * This function calculates the compute units (CU) required based on the CPU cores and RAM in megabytes.
+ * If both CPU cores and RAM are provided in the `options` parameter, it calculates CU by multiplying
+ * the CPU cores with RAM and dividing by 8 * GB, then converting the result to an integer. If the
+ * calculated CU is zero, it returns 500 / GB; otherwise, it returns 2.
+ *
+ * @param {RootFSOptions} [options] - Optional configuration object.
+ * @param {number} [options.CPUCores] - The number of CPU cores.
+ * @param {number} [options.RAMInMegaBytes] - The RAM size in megabytes.
+ *
+ * @returns {number} - The calculated compute units (CU) based on the provided options.
+ */
+function calculateRootFileSystem(options?: RootFSOptions): number {
+ let cu = 0;
+
+ if (options && options.CPUCores && options.RAMInMegaBytes) {
+ cu = new Decimal(options.CPUCores)
+ .mul(options.RAMInMegaBytes)
+ .divToInt(8 * GB)
+ .toNumber();
+ }
+
+ return cu === 0 ? 500 / GB : 2;
+}
+
+export { calculateRootFileSystem, RootFSOptions };
diff --git a/packages/grid_client/src/high_level/machine.ts b/packages/grid_client/src/high_level/machine.ts
index d01821d906..0de7b154c1 100644
--- a/packages/grid_client/src/high_level/machine.ts
+++ b/packages/grid_client/src/high_level/machine.ts
@@ -2,6 +2,7 @@ import { GridClientErrors, ValidationError } from "@threefold/types";
import { Addr } from "netaddr";
import { events } from "../helpers/events";
+import { calculateRootFileSystem } from "../helpers/root_fs";
import { randomChoice, zeroPadding } from "../helpers/utils";
import { validateHexSeed } from "../helpers/validator";
import { DiskModel, MyceliumNetworkModel, QSFSDiskModel } from "../modules/models";
@@ -53,6 +54,12 @@ class VMHL extends HighLevelBase {
zlogsOutput?: string,
gpus: string[] = [],
): Promise<[TwinDeployment[], string]> {
+ if (!rootfs_size) {
+ rootfs_size = calculateRootFileSystem({
+ CPUCores: cpu,
+ RAMInMegaBytes: memory,
+ });
+ }
const deployments: TwinDeployment[] = [];
const workloads: Workload[] = [];
let totalDisksSize = rootfs_size;
diff --git a/packages/grid_client/tests/unittests/root_fs.test.ts b/packages/grid_client/tests/unittests/root_fs.test.ts
new file mode 100644
index 0000000000..f4e07a1e79
--- /dev/null
+++ b/packages/grid_client/tests/unittests/root_fs.test.ts
@@ -0,0 +1,15 @@
+import { calculateRootFileSystem } from "../../src/helpers/root_fs";
+
+describe("Calculate the rootFS size based on the machine specs", () => {
+ it("should return 2GB when the options are provided", () => {
+ const options = { CPUCores: 5, RAMInMegaBytes: 2048 };
+ const result = calculateRootFileSystem(options);
+ expect(result).toEqual(2);
+ });
+
+ it("should return 0.48828125 when CPU cores and RAM are zero", () => {
+ const options = { CPUCores: 0, RAMInMegaBytes: 0 };
+ const result = calculateRootFileSystem(options);
+ expect(result).toEqual(0.48828125);
+ });
+});
diff --git a/packages/playground/src/components/caprover_worker.vue b/packages/playground/src/components/caprover_worker.vue
index 542bc4f715..cbc2a8073c 100644
--- a/packages/playground/src/components/caprover_worker.vue
+++ b/packages/playground/src/components/caprover_worker.vue
@@ -47,13 +47,13 @@
diff --git a/packages/playground/src/components/manage_caprover_worker_dialog.vue b/packages/playground/src/components/manage_caprover_worker_dialog.vue
index 80e0581631..3904d7faae 100644
--- a/packages/playground/src/components/manage_caprover_worker_dialog.vue
+++ b/packages/playground/src/components/manage_caprover_worker_dialog.vue
@@ -82,7 +82,6 @@ import { ref } from "vue";
import { useGrid } from "../stores";
import { addMachine, deleteMachine, loadVM } from "../utils/deploy_vm";
-import rootFs from "../utils/root_fs";
const props = defineProps<{ master: any; data: any[]; projectName: string }>();
const emits = defineEmits<{ (event: "close"): void; (event: "update:caprover", data: any): void }>();
@@ -139,7 +138,10 @@ async function deploy(layout: any) {
{ key: "SWM_NODE_MODE", value: "worker" },
{ key: "PUBLIC_KEY", value: props.master.env.PUBLIC_KEY },
],
- rootFilesystemSize: rootFs(worker.value.solution!.cpu, worker.value.solution!.memory),
+ rootFilesystemSize: calculateRootFileSystem({
+ CPUCores: worker.value.solution!.cpu,
+ RAMInMegaBytes: worker.value.solution!.memory,
+ }),
});
const [leader, ...workers] = vm;
@@ -181,7 +183,7 @@ async function onDelete(cb: (workers: any[]) => void) {