Skip to content

Commit c5f121e

Browse files
chipspeakopenshift-merge-bot[bot]
authored andcommitted
feat(RHOAIENG-29391): Store entrypoint scripts in configMaps
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
1 parent 331e2f3 commit c5f121e

File tree

4 files changed

+1143
-2
lines changed

4 files changed

+1143
-2
lines changed

src/codeflare_sdk/ray/rayjobs/config.py

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import pathlib
2222
from dataclasses import dataclass, field, fields
23-
from typing import Dict, List, Optional, Union, get_args, get_origin, Any
23+
from typing import Dict, List, Optional, Union, get_args, get_origin, Any, Tuple
2424
from kubernetes.client import (
2525
V1ConfigMapVolumeSource,
2626
V1KeyToPath,
@@ -517,3 +517,95 @@ def _build_gcs_ft_options(self) -> Dict[str, Any]:
517517
}
518518

519519
return gcs_ft_options
520+
521+
def add_script_volumes(
522+
self, configmap_name: str, mount_path: str = "/home/ray/scripts"
523+
):
524+
"""
525+
Add script volume and mount references to cluster configuration.
526+
527+
Args:
528+
configmap_name: Name of the ConfigMap containing scripts
529+
mount_path: Where to mount scripts in containers (default: /home/ray/scripts)
530+
"""
531+
# Check if script volume already exists
532+
volume_name = "ray-job-scripts"
533+
existing_volume = next(
534+
(v for v in self.volumes if getattr(v, "name", None) == volume_name), None
535+
)
536+
if existing_volume:
537+
logger.debug(f"Script volume '{volume_name}' already exists, skipping...")
538+
return
539+
540+
# Check if script mount already exists
541+
existing_mount = next(
542+
(m for m in self.volume_mounts if getattr(m, "name", None) == volume_name),
543+
None,
544+
)
545+
if existing_mount:
546+
logger.debug(
547+
f"Script volume mount '{volume_name}' already exists, skipping..."
548+
)
549+
return
550+
551+
# Add script volume to cluster configuration
552+
script_volume = V1Volume(
553+
name=volume_name, config_map=V1ConfigMapVolumeSource(name=configmap_name)
554+
)
555+
self.volumes.append(script_volume)
556+
557+
# Add script volume mount to cluster configuration
558+
script_mount = V1VolumeMount(name=volume_name, mount_path=mount_path)
559+
self.volume_mounts.append(script_mount)
560+
561+
logger.info(
562+
f"Added script volume '{configmap_name}' to cluster config: mount_path={mount_path}"
563+
)
564+
565+
def validate_configmap_size(self, scripts: Dict[str, str]) -> None:
566+
total_size = sum(len(content.encode("utf-8")) for content in scripts.values())
567+
if total_size > 1024 * 1024: # 1MB
568+
raise ValueError(
569+
f"ConfigMap size exceeds 1MB limit. Total size: {total_size} bytes"
570+
)
571+
572+
def build_script_configmap_spec(
573+
self, job_name: str, namespace: str, scripts: Dict[str, str]
574+
) -> Dict[str, Any]:
575+
"""
576+
Build ConfigMap specification for scripts
577+
578+
Args:
579+
job_name: Name of the RayJob (used for ConfigMap naming)
580+
namespace: Kubernetes namespace
581+
scripts: Dictionary of script_name -> script_content
582+
583+
Returns:
584+
Dict: ConfigMap specification ready for Kubernetes API
585+
"""
586+
configmap_name = f"{job_name}-scripts"
587+
return {
588+
"apiVersion": "v1",
589+
"kind": "ConfigMap",
590+
"metadata": {"name": configmap_name, "namespace": namespace},
591+
"data": scripts,
592+
}
593+
594+
def build_script_volume_specs(
595+
self, configmap_name: str, mount_path: str = "/home/ray/scripts"
596+
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
597+
"""
598+
Build volume and mount specifications for scripts
599+
600+
Args:
601+
configmap_name: Name of the ConfigMap containing scripts
602+
mount_path: Where to mount scripts in containers
603+
604+
Returns:
605+
Tuple of (volume_spec, mount_spec) as dictionaries
606+
"""
607+
volume_spec = {"name": "ray-job-scripts", "configMap": {"name": configmap_name}}
608+
609+
mount_spec = {"name": "ray-job-scripts", "mountPath": mount_path}
610+
611+
return volume_spec, mount_spec

0 commit comments

Comments
 (0)