Skip to content

Commit e7a1745

Browse files
make namespace configurable
1 parent cbf5e90 commit e7a1745

File tree

3 files changed

+32
-21
lines changed

3 files changed

+32
-21
lines changed

src/codeflare_sdk/cluster/cluster.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def __init__(self, config: ClusterConfiguration):
1818

1919
def create_app_wrapper(self):
2020
name=self.config.name
21+
namespace=self.config.namespace
2122
min_cpu=self.config.min_cpus
2223
max_cpu=self.config.max_cpus
2324
min_memory=self.config.min_memory
@@ -29,21 +30,23 @@ def create_app_wrapper(self):
2930
instascale=self.config.instascale
3031
instance_types=self.config.machine_types
3132
env=self.config.envs
32-
return generate_appwrapper(name=name, min_cpu=min_cpu, max_cpu=max_cpu, min_memory=min_memory,
33+
return generate_appwrapper(name=name, namespace=namespace, min_cpu=min_cpu, max_cpu=max_cpu, min_memory=min_memory,
3334
max_memory=max_memory, gpu=gpu, workers=workers, template=template,
3435
image=image, instascale=instascale, instance_types=instance_types, env=env)
3536

36-
# creates a new cluster with the provided or default spec
37-
def up(self, namespace='default'):
37+
# creates a new cluster with the provided or default spec
38+
def up(self):
39+
namespace = self.config.namespace
3840
with oc.project(namespace):
3941
oc.invoke("apply", ["-f", self.app_wrapper_yaml])
4042

41-
def down(self, namespace='default'):
43+
def down(self):
44+
namespace = self.config.namespace
4245
with oc.project(namespace):
4346
oc.invoke("delete", ["AppWrapper", self.app_wrapper_name])
4447

4548
def status(self, print_to_console=True):
46-
cluster = _ray_cluster_status(self.config.name)
49+
cluster = _ray_cluster_status(self.config.name, self.config.namespace)
4750
if cluster:
4851
#overriding the number of gpus with requested
4952
cluster.worker_gpu = self.config.gpu
@@ -55,8 +58,8 @@ def status(self, print_to_console=True):
5558
pretty_print.print_no_resources_found()
5659
return None
5760

58-
def cluster_uri(self, namespace='default'):
59-
return f'ray://{self.config.name}-head-svc.{namespace}.svc:10001'
61+
def cluster_uri(self):
62+
return f'ray://{self.config.name}-head-svc.{self.config.namespace}.svc:10001'
6063

6164
def cluster_dashboard_uri(self, namespace='default'):
6265
try:
@@ -68,13 +71,12 @@ def cluster_dashboard_uri(self, namespace='default'):
6871
return "Dashboard route not available yet. Did you run cluster.up()?"
6972

7073

71-
7274
# checks whether the ray cluster is ready
7375
def is_ready(self, print_to_console=True):
7476
ready = False
7577
status = CodeFlareClusterStatus.UNKNOWN
7678
# check the app wrapper status
77-
appwrapper = _app_wrapper_status(self.config.name)
79+
appwrapper = _app_wrapper_status(self.config.name, self.config.namespace)
7880
if appwrapper:
7981
if appwrapper.status in [AppWrapperStatus.RUNNING, AppWrapperStatus.COMPLETED, AppWrapperStatus.RUNNING_HOLD_COMPLETION]:
8082
ready = False
@@ -91,7 +93,7 @@ def is_ready(self, print_to_console=True):
9193
return ready, status# no need to check the ray status since still in queue
9294

9395
# check the ray cluster status
94-
cluster = _ray_cluster_status(self.config.name)
96+
cluster = _ray_cluster_status(self.config.name, self.config.namespace)
9597
if cluster:
9698
if cluster.status == RayClusterStatus.READY:
9799
ready = True
@@ -106,16 +108,19 @@ def is_ready(self, print_to_console=True):
106108
pretty_print.print_clusters([cluster])
107109
return status, ready
108110

111+
def get_current_namespace():
112+
namespace = oc.invoke("project",["-q"]).actions()[0].out.strip()
113+
return namespace
109114

110-
def list_all_clusters(print_to_console=True):
111-
clusters = _get_ray_clusters()
115+
def list_all_clusters(namespace, print_to_console=True):
116+
clusters = _get_ray_clusters(namespace)
112117
if print_to_console:
113118
pretty_print.print_clusters(clusters)
114119
return clusters
115120

116121

117-
def list_all_queued(print_to_console=True):
118-
app_wrappers = _get_app_wrappers(filter=[AppWrapperStatus.RUNNING, AppWrapperStatus.PENDING])
122+
def list_all_queued(namespace, print_to_console=True):
123+
app_wrappers = _get_app_wrappers( namespace, filter=[AppWrapperStatus.RUNNING, AppWrapperStatus.PENDING])
119124
if print_to_console:
120125
pretty_print.print_app_wrappers_status(app_wrappers)
121126
return app_wrappers
@@ -158,7 +163,7 @@ def _get_ray_clusters(namespace='default') -> List[RayCluster]:
158163

159164

160165

161-
def _get_app_wrappers(filter:List[AppWrapperStatus], namespace='default') -> List[AppWrapper]:
166+
def _get_app_wrappers(namespace='default', filter=List[AppWrapperStatus]) -> List[AppWrapper]:
162167
list_of_app_wrappers = []
163168

164169
with oc.project(namespace), oc.timeout(10*60):

src/codeflare_sdk/cluster/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
@dataclass
77
class ClusterConfiguration:
88
name: str
9+
namespace: str = "default"
910
head_info: list = field(default_factory=list)
1011
machine_types: list = field(default_factory=list) #["m4.xlarge", "g4dn.xlarge"]
1112
min_cpus: int = 1

src/codeflare_sdk/utils/generate_yaml.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,22 @@ def gen_names(name):
1919
else:
2020
return name, name
2121

22-
def update_dashboard_route(route_item, cluster_name):
22+
def update_dashboard_route(route_item, cluster_name, namespace):
2323
metadata = route_item.get("generictemplate", {}).get("metadata")
2424
metadata["name"] = f'ray-dashboard-{cluster_name}'
25+
metadata["namespace"] = namespace
2526
metadata["labels"]["odh-ray-cluster-service"] = f'{cluster_name}-head-svc'
2627
spec = route_item.get("generictemplate", {}).get("spec")
2728
spec["to"]["name"] = f'{cluster_name}-head-svc'
2829

29-
def update_names(yaml, item, appwrapper_name, cluster_name):
30+
def update_names(yaml, item, appwrapper_name, cluster_name, namespace):
3031
metadata = yaml.get("metadata")
3132
metadata["name"] = appwrapper_name
33+
metadata["namespace"] = namespace
3234
lower_meta = item.get("generictemplate", {}).get("metadata")
3335
lower_meta["labels"]["appwrapper.mcad.ibm.com"] = appwrapper_name
3436
lower_meta["name"] = cluster_name
37+
lower_meta["namespace"] = namespace
3538

3639
def update_labels(yaml, instascale, instance_types):
3740
metadata = yaml.get("metadata")
@@ -140,17 +143,17 @@ def write_user_appwrapper(user_yaml, output_file_name):
140143
yaml.dump(user_yaml, outfile, default_flow_style=False)
141144
print(f"Written to: {output_file_name}")
142145

143-
def generate_appwrapper(name, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, template, image, instascale, instance_types, env):
146+
def generate_appwrapper(name, namespace, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, template, image, instascale, instance_types, env):
144147
user_yaml = read_template(template)
145148
appwrapper_name, cluster_name = gen_names(name)
146149
resources = user_yaml.get("spec","resources")
147150
item = resources["resources"].get("GenericItems")[0]
148151
route_item = resources["resources"].get("GenericItems")[1]
149-
update_names(user_yaml, item, appwrapper_name, cluster_name)
152+
update_names(user_yaml, item, appwrapper_name, cluster_name, namespace)
150153
update_labels(user_yaml, instascale, instance_types)
151154
update_custompodresources(item, min_cpu, max_cpu, min_memory, max_memory, gpu, workers)
152155
update_nodes(item, appwrapper_name, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, image, instascale, env)
153-
update_dashboard_route(route_item, cluster_name)
156+
update_dashboard_route(route_item, cluster_name, namespace)
154157
outfile = appwrapper_name + ".yaml"
155158
write_user_appwrapper(user_yaml, outfile)
156159
return outfile
@@ -169,6 +172,7 @@ def main():
169172
parser.add_argument("--image", required=False, default="rayproject/ray:latest", help="Ray image to be used (defaults to rayproject/ray:latest)")
170173
parser.add_argument("--instascale", default=False, required=False, action='store_true', help="Indicates that instascale is installed on the cluster")
171174
parser.add_argument("--instance-types", type=str, nargs='+', default=[], required=False, help="Head,worker instance types (space separated)")
175+
parser.add_argument("--namespace", required=False, default="default", help="Set the kubernetes namespace you want to deploy your cluster to. Default. If left blank, uses the 'default' namespace")
172176

173177
args = parser.parse_args()
174178
name = args.name
@@ -182,9 +186,10 @@ def main():
182186
image = args.image
183187
instascale = args.instascale
184188
instance_types = args.instance_types
189+
namespace = args.namespace
185190
env = {}
186191

187-
outfile = generate_appwrapper(name, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, template, image, instascale, instance_types, env)
192+
outfile = generate_appwrapper(name, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, template, image, instascale, instance_types, namespace, env)
188193
return outfile
189194

190195
if __name__=="__main__":

0 commit comments

Comments
 (0)