From 9cdba322b58c833db3829c45d1a03dd9557b977d Mon Sep 17 00:00:00 2001 From: Mahmoud Emad Date: Sun, 23 Jun 2024 12:52:42 +0300 Subject: [PATCH 1/2] feat: Calculate the root file system when creating the deployment machine: - Created a new function called 'calculateRootFs' to calculate the size of the root file system based on the machine specs. - Created unit tests for the created function to ensure that no weird behavior happens during the calculation. --- packages/grid_client/src/helpers/root_fs.ts | 24 +++++++++++++++++++ .../grid_client/src/high_level/machine.ts | 7 ++++++ .../tests/unittests/root_fs.test.ts | 15 ++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 packages/grid_client/src/helpers/root_fs.ts create mode 100644 packages/grid_client/tests/unittests/root_fs.test.ts 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..de116c0ef5 --- /dev/null +++ b/packages/grid_client/src/helpers/root_fs.ts @@ -0,0 +1,24 @@ +import { Decimal } from "decimal.js"; + +const GB = 1024; + +export 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; +} + +export default function calculateRootFs(options?: RootFSOptions): number { + let cu = 0; + + if (options && options.CPUCores && options.RAMInMegaBytes) { + console.log("Here", options); + cu = new Decimal(options.CPUCores) + .mul(options.RAMInMegaBytes) + .divToInt(8 * GB) + .toNumber(); + } + + return cu === 0 ? 500 / GB : 2; +} diff --git a/packages/grid_client/src/high_level/machine.ts b/packages/grid_client/src/high_level/machine.ts index d01821d906..a5745bb4c7 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 calculateRootFs 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 = calculateRootFs({ + 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..dbd0a63fb9 --- /dev/null +++ b/packages/grid_client/tests/unittests/root_fs.test.ts @@ -0,0 +1,15 @@ +import calculateRootFs 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 = calculateRootFs(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 = calculateRootFs(options); + expect(result).toEqual(0.48828125); + }); +}); From 077aa55cfb68bbb6aae0440256cd8d8778451e7f Mon Sep 17 00:00:00 2001 From: Mahmoud Emad Date: Sun, 23 Jun 2024 17:38:20 +0300 Subject: [PATCH 2/2] chore: Replaced the `rootFS` function with the GC: - Removed the `rootFS` function/file. - Updated the solutions with the newly implemented `calculateRootFileSystem`. - Removed the un-needed debug logs. - Docstring the newly implemented function. --- packages/grid_client/src/helpers/index.ts | 1 + packages/grid_client/src/helpers/root_fs.ts | 21 +++++++++++++++--- .../grid_client/src/high_level/machine.ts | 4 ++-- .../tests/unittests/root_fs.test.ts | 6 ++--- .../src/components/caprover_worker.vue | 7 ++++-- .../playground/src/components/k8s_worker.vue | 11 +++++++--- .../manage_caprover_worker_dialog.vue | 8 ++++--- .../src/components/root_fs_size.vue | 8 +++---- packages/playground/src/utils/root_fs.ts | 16 -------------- packages/playground/src/weblets/freeflow.vue | 7 +++--- .../playground/src/weblets/tf_caprover.vue | 22 ++++++++++++++----- .../playground/src/weblets/tf_casperlabs.vue | 7 +++--- .../playground/src/weblets/tf_discourse.vue | 7 +++--- .../playground/src/weblets/tf_funkwhale.vue | 7 +++--- .../playground/src/weblets/tf_mattermost.vue | 7 +++--- .../playground/src/weblets/tf_nextcloud.vue | 7 +++--- .../playground/src/weblets/tf_owncloud.vue | 7 +++--- .../playground/src/weblets/tf_peertube.vue | 7 +++--- .../playground/src/weblets/tf_presearch.vue | 5 ++--- .../src/weblets/tf_staticwebsite.vue | 7 +++--- .../playground/src/weblets/tf_subsquid.vue | 7 +++--- packages/playground/src/weblets/tf_taiga.vue | 7 +++--- packages/playground/src/weblets/tf_umbrel.vue | 7 +++--- .../playground/src/weblets/tf_wordpress.vue | 7 +++--- 24 files changed, 117 insertions(+), 83 deletions(-) delete mode 100644 packages/playground/src/utils/root_fs.ts 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 index de116c0ef5..6988b959be 100644 --- a/packages/grid_client/src/helpers/root_fs.ts +++ b/packages/grid_client/src/helpers/root_fs.ts @@ -2,18 +2,31 @@ import { Decimal } from "decimal.js"; const GB = 1024; -export interface RootFSOptions { +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; } -export default function calculateRootFs(options?: RootFSOptions): 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) { - console.log("Here", options); cu = new Decimal(options.CPUCores) .mul(options.RAMInMegaBytes) .divToInt(8 * GB) @@ -22,3 +35,5 @@ export default function calculateRootFs(options?: RootFSOptions): number { 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 a5745bb4c7..0de7b154c1 100644 --- a/packages/grid_client/src/high_level/machine.ts +++ b/packages/grid_client/src/high_level/machine.ts @@ -2,7 +2,7 @@ import { GridClientErrors, ValidationError } from "@threefold/types"; import { Addr } from "netaddr"; import { events } from "../helpers/events"; -import calculateRootFs from "../helpers/root_fs"; +import { calculateRootFileSystem } from "../helpers/root_fs"; import { randomChoice, zeroPadding } from "../helpers/utils"; import { validateHexSeed } from "../helpers/validator"; import { DiskModel, MyceliumNetworkModel, QSFSDiskModel } from "../modules/models"; @@ -55,7 +55,7 @@ class VMHL extends HighLevelBase { gpus: string[] = [], ): Promise<[TwinDeployment[], string]> { if (!rootfs_size) { - rootfs_size = calculateRootFs({ + rootfs_size = calculateRootFileSystem({ CPUCores: cpu, RAMInMegaBytes: memory, }); diff --git a/packages/grid_client/tests/unittests/root_fs.test.ts b/packages/grid_client/tests/unittests/root_fs.test.ts index dbd0a63fb9..f4e07a1e79 100644 --- a/packages/grid_client/tests/unittests/root_fs.test.ts +++ b/packages/grid_client/tests/unittests/root_fs.test.ts @@ -1,15 +1,15 @@ -import calculateRootFs from "../../src/helpers/root_fs"; +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 = calculateRootFs(options); + 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 = calculateRootFs(options); + 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) {