Skip to content

Commit 4545406

Browse files
ihsaan-ullahDidayolo
authored andcommitted
gathered all env settings in a new Settings class
1 parent f967e22 commit 4545406

1 file changed

Lines changed: 81 additions & 69 deletions

File tree

compute_worker/compute_worker.py

Lines changed: 81 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,56 @@
3737

3838

3939
# -----------------------------------------------
40-
# CONSTANTS
40+
# Env Settings
41+
# -----------------------------------------------
42+
class Settings:
43+
44+
@staticmethod
45+
def get(key, default=None):
46+
"""
47+
Return the env var value if set, else default; returns None if not set and no default.
48+
"""
49+
val = os.getenv(key)
50+
51+
if val is not None:
52+
return val
53+
54+
if default is not None:
55+
return default
56+
57+
logger.warning(f"Environment variable '{key}' not found and no default provided.")
58+
return None
59+
60+
# Defaults
61+
DEFAULT_SOCKETS = {
62+
"docker": "unix:///var/run/docker.sock",
63+
"podman": "unix:///run/user/1000/podman/podman.sock",
64+
}
65+
66+
# Settings variables
67+
LOG_LEVEL = get("LOG_LEVEL", "INFO")
68+
SERIALIZED = get("SERIALIZED", "false")
69+
70+
USE_GPU = get("USE_GPU", "false")
71+
CONTAINER_ENGINE_EXECUTABLE = get("CONTAINER_ENGINE_EXECUTABLE", "docker")
72+
GPU_DEVICE = get("GPU_DEVICE", "nvidia.com/gpu=all")
73+
74+
CONTAINER_SOCKET = get("CONTAINER_SOCKET", DEFAULT_SOCKETS.get(CONTAINER_ENGINE_EXECUTABLE))
75+
76+
HOST_DIRECTORY = get("HOST_DIRECTORY", "/tmp/codabench/")
77+
MAX_CACHE_DIR_SIZE_GB = get("MAX_CACHE_DIR_SIZE_GB", 10)
78+
79+
COMPETITION_CONTAINER_NETWORK_DISABLED = get("COMPETITION_CONTAINER_NETWORK_DISABLED", "False")
80+
COMPETITION_CONTAINER_HTTP_PROXY = get("COMPETITION_CONTAINER_HTTP_PROXY", "")
81+
COMPETITION_CONTAINER_HTTPS_PROXY = get("COMPETITION_CONTAINER_HTTPS_PROXY", "")
82+
83+
CODALAB_IGNORE_CLEANUP_STEP = get("CODALAB_IGNORE_CLEANUP_STEP")
84+
85+
WORKER_BUNDLE_URL_REWRITE = get("WORKER_BUNDLE_URL_REWRITE", "")
86+
87+
88+
# -----------------------------------------------
89+
# Program Kind
4190
# -----------------------------------------------
4291
class ProgramKind:
4392
INGESTION_PROGRAM = "ingestion_program"
@@ -74,43 +123,24 @@ class SubmissionStatus:
74123
# Logging
75124
# -----------------------------------------------
76125
configure_logging(
77-
os.environ.get("LOG_LEVEL", "INFO"), os.environ.get("SERIALIZED", "false")
126+
Settings.LOG_LEVEL, Settings.SERIALIZED
78127
)
79128

80129
# -----------------------------------------------
81130
# Initialize Docker or Podman depending on .env
82131
# -----------------------------------------------
83-
if os.environ.get("USE_GPU", "false").lower() == "true":
84-
logger.info(
85-
"Using "
86-
+ os.environ.get("CONTAINER_ENGINE_EXECUTABLE", "docker").upper()
87-
+ "with GPU capabilites : "
88-
+ os.environ.get("GPU_DEVICE", "nvidia.com/gpu=all")
89-
+ " network_disabled for the competition container is set to "
90-
+ os.environ.get("COMPETITION_CONTAINER_NETWORK_DISABLED", "False")
91-
)
92-
else:
93-
logger.info(
94-
"Using "
95-
+ os.environ.get("CONTAINER_ENGINE_EXECUTABLE", "docker").upper()
96-
+ " without GPU capabilities. "
97-
+ "network_disabled for the competition container is set to "
98-
+ os.environ.get("COMPETITION_CONTAINER_NETWORK_DISABLED", "False")
99-
)
100-
101-
if os.environ.get("CONTAINER_ENGINE_EXECUTABLE", "docker").lower() == "docker":
102-
client = docker.APIClient(
103-
base_url=os.environ.get("CONTAINER_SOCKET", "unix:///var/run/docker.sock"),
104-
version="auto",
105-
)
106-
elif os.environ.get("CONTAINER_ENGINE_EXECUTABLE").lower() == "podman":
107-
client = docker.APIClient(
108-
base_url=os.environ.get(
109-
"CONTAINER_SOCKET", "unix:///run/user/1000/podman/podman.sock"
110-
),
111-
version="auto",
112-
)
132+
logger.info(
133+
f"Using {Settings.CONTAINER_ENGINE_EXECUTABLE.upper()} "
134+
f"{'with GPU capabilities: ' + Settings.GPU_DEVICE if Settings.USE_GPU.lower() == 'true' else 'without GPU capabilities'}. "
135+
f"Network disabled for the competition container is set to {Settings.COMPETITION_CONTAINER_NETWORK_DISABLED}"
136+
)
113137

138+
# Intializing client
139+
# NOTE: CONTAINER_SOCKET is set in Settings based on CONTAINER_ENGINE_EXECUTABLE which must has either podman or docker
140+
client = docker.APIClient(
141+
base_url=Settings.CONTAINER_SOCKET,
142+
version="auto",
143+
)
114144

115145
# -----------------------------------------------
116146
# Show Progress bar on downloading images
@@ -178,8 +208,8 @@ def show_progress(line, progress):
178208
total=total,
179209
)
180210
except Exception as e:
181-
if os.environ.get("LOG_LEVEL", "info").lower() == "debug":
182-
logger.exception("There was an error showing the progress bar")
211+
if Settings.LOG_LEVEL.lower() == "debug":
212+
logger.exception(f"There was an error showing the progress bar: {e}")
183213

184214

185215
# -----------------------------------------------
@@ -206,11 +236,11 @@ def setup_celery_logging(**kwargs):
206236
# Directories
207237
# -----------------------------------------------
208238
# Setup base directories used by all submissions
209-
# note: we need to pass this directory to docker/podman so it knows where to store things!
210-
HOST_DIRECTORY = os.environ.get("HOST_DIRECTORY", "/tmp/codabench/")
239+
# NOTE: we need to pass this directory to docker/podman so it knows where to store things!
240+
HOST_DIRECTORY = Settings.HOST_DIRECTORY
211241
BASE_DIR = "/codabench/" # base directory inside the container
212242
CACHE_DIR = os.path.join(BASE_DIR, "cache")
213-
MAX_CACHE_DIR_SIZE_GB = float(os.environ.get("MAX_CACHE_DIR_SIZE_GB", 10))
243+
MAX_CACHE_DIR_SIZE_GB = float(Settings.MAX_CACHE_DIR_SIZE_GB)
214244

215245

216246
# -----------------------------------------------
@@ -239,7 +269,7 @@ def rewrite_bundle_url_if_needed(url):
239269
240270
Example: http://localhost:9000|http://minio:9000
241271
"""
242-
rule = os.getenv("WORKER_BUNDLE_URL_REWRITE", "").strip()
272+
rule = Settings.WORKER_BUNDLE_URL_REWRITE.strip()
243273
if not rule or "|" not in rule:
244274
return url
245275
src, dst = rule.split("|", 1)
@@ -757,14 +787,14 @@ def _create_container(
757787
]
758788

759789
# Configure whether or not we use the GPU. Also setting auto_remove to False because
760-
if os.environ.get("CONTAINER_ENGINE_EXECUTABLE", "docker").lower() == "docker":
790+
if Settings.CONTAINER_ENGINE_EXECUTABLE.lower() == "docker":
761791
security_options = ["no-new-privileges"]
762792
else:
763793
security_options = ["label=disable"]
764794

765795
# Setting the device ID like this allows users to specify which gpu to use in the .env file, with all being the default if no value is given
766-
device_id = [os.environ.get("GPU_DEVICE", "nvidia.com/gpu=all")]
767-
if os.environ.get("USE_GPU", "false").lower() == "true":
796+
device_id = [Settings.GPU_DEVICE]
797+
if Settings.USE_GPU.lower() == "true":
768798
logger.info("Container configured with GPU capabilities")
769799
host_config = client.create_host_config(
770800
auto_remove=False,
@@ -789,27 +819,9 @@ def _create_container(
789819
security_opt=security_options,
790820
)
791821

792-
# Disable or not the competition container access to Internet (False by default)
793-
container_network_disabled = os.environ.get(
794-
"COMPETITION_CONTAINER_NETWORK_DISABLED", ""
795-
)
796-
797-
# HTTP and HTTPS proxy for the competition container if needed
798-
competition_container_proxy_http = os.environ.get(
799-
"COMPETITION_CONTAINER_HTTP_PROXY", ""
800-
)
801-
competition_container_proxy_http = (
802-
"http_proxy=" + competition_container_proxy_http
803-
)
804-
805-
competition_container_proxy_https = os.environ.get(
806-
"COMPETITION_CONTAINER_HTTPS_PROXY", ""
807-
)
808-
competition_container_proxy_https = (
809-
"https_proxy=" + competition_container_proxy_https
810-
)
811-
812822
# Creating container
823+
# COMPETITION_CONTAINER_NETWORK_DISABLED: Disable or not the competition container access to Internet (False by default)
824+
# HTTP and HTTPS proxy for the competition container if needed
813825
container = client.create_container(
814826
self.container_image,
815827
name=container_name,
@@ -820,10 +832,10 @@ def _create_container(
820832
working_dir="/app/program",
821833
environment=[
822834
"PYTHONUNBUFFERED=1",
823-
competition_container_proxy_http,
824-
competition_container_proxy_https,
835+
"http_proxy=" + Settings.COMPETITION_CONTAINER_HTTP_PROXY,
836+
"https_proxy=" + Settings.COMPETITION_CONTAINER_HTTPS_PROXY,
825837
],
826-
network_disabled=container_network_disabled.lower() == "true",
838+
network_disabled=Settings.COMPETITION_CONTAINER_NETWORK_DISABLED.lower() == "true",
827839
)
828840

829841
return container
@@ -868,7 +880,7 @@ async def _run_container_engine_cmd(self, container, kind):
868880
logger.error(
869881
f"There was an error trying to connect to the websocket on the codabench instance: {e}"
870882
)
871-
if os.environ.get("LOG_LEVEL", "info").lower() == "debug":
883+
if Settings.LOG_LEVEL.lower() == "debug":
872884
logger.exception(e)
873885

874886
start = time.time()
@@ -922,7 +934,7 @@ async def _run_container_engine_cmd(self, container, kind):
922934
logger.error(
923935
f"There was an error while starting the container and getting the logs: {e}"
924936
)
925-
if os.environ.get("LOG_LEVEL", "info").lower() == "debug":
937+
if Settings.LOG_LEVEL.lower() == "debug":
926938
logger.exception(e)
927939

928940
# Get the return code of the competition container once done
@@ -1316,7 +1328,7 @@ def start(self):
13161328
logger.error(
13171329
f"There was a problem killing {containers_to_kill}: {e}"
13181330
)
1319-
if os.environ.get("LOG_LEVEL", "info").lower() == "debug":
1331+
if Settings.LOG_LEVEL.lower() == "debug":
13201332
logger.exception(e)
13211333
# Send data to be written to ingestion/scoring std_err
13221334
self._update_submission(execution_time_limit_exceeded_data)
@@ -1368,7 +1380,7 @@ def start(self):
13681380
logger.error(
13691381
f"There was a problem killing {containers_to_kill}: {e}"
13701382
)
1371-
if os.environ.get("LOG_LEVEL", "info").lower() == "debug":
1383+
if Settings.LOG_LEVEL.lower() == "debug":
13721384
logger.exception(e)
13731385
if kind == "program":
13741386
self.program_exit_code = return_code
@@ -1486,7 +1498,7 @@ def push_output(self):
14861498
self._put_dir(self.scoring_result, self.output_dir)
14871499

14881500
def clean_up(self):
1489-
if os.environ.get("CODALAB_IGNORE_CLEANUP_STEP"):
1501+
if Settings.CODALAB_IGNORE_CLEANUP_STEP:
14901502
logger.warning(
14911503
f"CODALAB_IGNORE_CLEANUP_STEP mode enabled, ignoring clean up of: {self.root_dir}"
14921504
)

0 commit comments

Comments
 (0)