Skip to content

Commit

Permalink
Merge pull request #223 from bogdant36/CTX-5921-swap
Browse files Browse the repository at this point in the history
CTX-5921: Swap limit check implemented.
  • Loading branch information
dule1322 committed Jul 2, 2024
2 parents 217a596 + 38c64ad commit f4f3def
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
24 changes: 23 additions & 1 deletion coretex/cli/modules/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,23 @@ def promptRam(config: Dict[str, Any], ramLimit: int) -> int:
return nodeRam


def promptSwap(nodeRam: int, swapLimit: int) -> int:
nodeSwap: int = clickPrompt(
f"Node SWAP memory limit in GB (Maximum: {swapLimit}GB) (press enter to use default)",
min(swapLimit, nodeRam * 2),
type = int
)

if nodeSwap > swapLimit:
errorEcho(
f"ERROR: SWAP memory limit in Docker Desktop ({swapLimit}GB) is lower than the configured value ({nodeSwap}GB). "
f"If you want to use higher value than {swapLimit}GB, you have to change docker limits."
)
return promptSwap(nodeRam, swapLimit)

return nodeSwap


def promptInvocationPrice() -> float:
invocationPrice: float = clickPrompt(
"Enter the price of a single endpoint invocation",
Expand Down Expand Up @@ -308,6 +325,7 @@ def checkResourceLimitations() -> None:
def isConfigurationValid(config: Dict[str, Any]) -> bool:
isValid = True
cpuLimit, ramLimit = docker.getResourceLimits()
swapLimit = docker.getDockerSwapLimit()

if not isinstance(config["nodeRam"], int):
errorEcho(f"Invalid config \"nodeRam\" field type \"{type(config['nodeRam'])}\". Expected: \"int\"")
Expand All @@ -329,6 +347,9 @@ def isConfigurationValid(config: Dict[str, Any]) -> bool:
errorEcho(f"Configuration not valid. RAM limit in Docker Desktop ({ramLimit}GB) is lower than the configured value ({config['nodeRam']}GB)")
isValid = False

if config["nodeSwap"] > swapLimit:
errorEcho(f"Configuration not valid. RAM limit in Docker Desktop ({swapLimit}GB) is lower than the configured value ({config['nodeSwap']}GB)")
isValid = False

if config["nodeRam"] < config_defaults.MINIMUM_RAM:
errorEcho(f"Configuration not valid. Minimum Node RAM requirement ({config_defaults.MINIMUM_RAM}GB) is higher than the configured value ({config['nodeRam']}GB)")
Expand All @@ -341,6 +362,7 @@ def configureNode(config: Dict[str, Any], verbose: bool) -> None:
highlightEcho("[Node Configuration]")

cpuLimit, ramLimit = docker.getResourceLimits()
swapLimit = docker.getDockerSwapLimit()

config["nodeName"] = clickPrompt("Node name", type = str)

Expand Down Expand Up @@ -380,8 +402,8 @@ def configureNode(config: Dict[str, Any], verbose: bool) -> None:

config["cpuCount"] = promptCpu(config, cpuLimit)
config["nodeRam"] = promptRam(config, ramLimit)
config["nodeSwap"] = promptSwap(config["nodeRam"], swapLimit)

config["nodeSwap"] = clickPrompt("Node swap memory limit in GB, make sure it is larger than mem limit (press enter to use default)", config_defaults.DEFAULT_SWAP_MEMORY, type = int)
config["nodeSharedMemory"] = clickPrompt("Node POSIX shared memory limit in GB (press enter to use default)", config_defaults.DEFAULT_SHARED_MEMORY, type = int)
config["allowDocker"] = clickPrompt("Allow Node to access system docker? This is a security risk! (Y/n)", config_defaults.DEFAULT_ALLOW_DOCKER, type = bool)
config["initScript"] = _configureInitScript()
Expand Down
10 changes: 10 additions & 0 deletions coretex/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ def getSwapUsage() -> float:
return psutil.swap_memory().percent


def getTotalSwapMemory() -> int:
"""
Returns
-------
int -> total swap memory in GB
"""

return int(psutil.swap_memory().total / (1024 ** 3))


def getDiskRead() -> float:
"""
Returns
Expand Down
32 changes: 31 additions & 1 deletion coretex/utils/docker.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from typing import Dict, Any, List, Tuple
from typing import Dict, Any, List, Tuple, Optional
from pathlib import Path

import json
import platform

from .process import command, CommandException
from ..statistics import getTotalSwapMemory


def isDockerAvailable() -> None:
Expand Down Expand Up @@ -147,3 +150,30 @@ def getResourceLimits() -> Tuple[int, int]:
jsonOutput = json.loads(output)

return jsonOutput["NCPU"], round(jsonOutput["MemTotal"] / (1024 ** 3))


def getDockerConfigPath() -> Optional[Path]:
if platform.system() == "Darwin":
return Path.home().joinpath("Library", "Group Containers", "group.com.docker", "settings.json")
elif platform.system() == "Windows":
return Path.home().joinpath("AppData", "Roaming", "Docker", "settings.json")
elif platform.system() == "Linux":
return Path.home().joinpath(".docker", "desktop", "settings.json")
else:
return None


def getDockerSwapLimit() -> int:
configPath = getDockerConfigPath()

if configPath is None or not configPath.exists():
return getTotalSwapMemory()

with configPath.open("r") as configFile:
configJson = json.load(configFile)

swapLimit = configJson.get("swapMiB")
if not isinstance(swapLimit, int):
return getTotalSwapMemory()

return int(swapLimit / 1024)

0 comments on commit f4f3def

Please sign in to comment.