Skip to content

Commit 59ffc2d

Browse files
make namespace configurable (#23)
1 parent 755d8e4 commit 59ffc2d

File tree

3 files changed

+32
-21
lines changed

3 files changed

+32
-21
lines changed

Diff for: src/codeflare_sdk/cluster/cluster.py

+20-15
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def __init__(self, config: ClusterConfiguration):
3232

3333
def create_app_wrapper(self):
3434
name=self.config.name
35+
namespace=self.config.namespace
3536
min_cpu=self.config.min_cpus
3637
max_cpu=self.config.max_cpus
3738
min_memory=self.config.min_memory
@@ -43,21 +44,23 @@ def create_app_wrapper(self):
4344
instascale=self.config.instascale
4445
instance_types=self.config.machine_types
4546
env=self.config.envs
46-
return generate_appwrapper(name=name, min_cpu=min_cpu, max_cpu=max_cpu, min_memory=min_memory,
47+
return generate_appwrapper(name=name, namespace=namespace, min_cpu=min_cpu, max_cpu=max_cpu, min_memory=min_memory,
4748
max_memory=max_memory, gpu=gpu, workers=workers, template=template,
4849
image=image, instascale=instascale, instance_types=instance_types, env=env)
4950

50-
# creates a new cluster with the provided or default spec
51-
def up(self, namespace='default'):
51+
# creates a new cluster with the provided or default spec
52+
def up(self):
53+
namespace = self.config.namespace
5254
with oc.project(namespace):
5355
oc.invoke("apply", ["-f", self.app_wrapper_yaml])
5456

55-
def down(self, namespace='default'):
57+
def down(self):
58+
namespace = self.config.namespace
5659
with oc.project(namespace):
5760
oc.invoke("delete", ["AppWrapper", self.app_wrapper_name])
5861

5962
def status(self, print_to_console=True):
60-
cluster = _ray_cluster_status(self.config.name)
63+
cluster = _ray_cluster_status(self.config.name, self.config.namespace)
6164
if cluster:
6265
#overriding the number of gpus with requested
6366
cluster.worker_gpu = self.config.gpu
@@ -69,8 +72,8 @@ def status(self, print_to_console=True):
6972
pretty_print.print_no_resources_found()
7073
return None
7174

72-
def cluster_uri(self, namespace='default'):
73-
return f'ray://{self.config.name}-head-svc.{namespace}.svc:10001'
75+
def cluster_uri(self):
76+
return f'ray://{self.config.name}-head-svc.{self.config.namespace}.svc:10001'
7477

7578
def cluster_dashboard_uri(self, namespace='default'):
7679
try:
@@ -82,13 +85,12 @@ def cluster_dashboard_uri(self, namespace='default'):
8285
return "Dashboard route not available yet. Did you run cluster.up()?"
8386

8487

85-
8688
# checks whether the ray cluster is ready
8789
def is_ready(self, print_to_console=True):
8890
ready = False
8991
status = CodeFlareClusterStatus.UNKNOWN
9092
# check the app wrapper status
91-
appwrapper = _app_wrapper_status(self.config.name)
93+
appwrapper = _app_wrapper_status(self.config.name, self.config.namespace)
9294
if appwrapper:
9395
if appwrapper.status in [AppWrapperStatus.RUNNING, AppWrapperStatus.COMPLETED, AppWrapperStatus.RUNNING_HOLD_COMPLETION]:
9496
ready = False
@@ -105,7 +107,7 @@ def is_ready(self, print_to_console=True):
105107
return ready, status# no need to check the ray status since still in queue
106108

107109
# check the ray cluster status
108-
cluster = _ray_cluster_status(self.config.name)
110+
cluster = _ray_cluster_status(self.config.name, self.config.namespace)
109111
if cluster:
110112
if cluster.status == RayClusterStatus.READY:
111113
ready = True
@@ -120,16 +122,19 @@ def is_ready(self, print_to_console=True):
120122
pretty_print.print_clusters([cluster])
121123
return status, ready
122124

125+
def get_current_namespace():
126+
namespace = oc.invoke("project",["-q"]).actions()[0].out.strip()
127+
return namespace
123128

124-
def list_all_clusters(print_to_console=True):
125-
clusters = _get_ray_clusters()
129+
def list_all_clusters(namespace, print_to_console=True):
130+
clusters = _get_ray_clusters(namespace)
126131
if print_to_console:
127132
pretty_print.print_clusters(clusters)
128133
return clusters
129134

130135

131-
def list_all_queued(print_to_console=True):
132-
app_wrappers = _get_app_wrappers(filter=[AppWrapperStatus.RUNNING, AppWrapperStatus.PENDING])
136+
def list_all_queued(namespace, print_to_console=True):
137+
app_wrappers = _get_app_wrappers( namespace, filter=[AppWrapperStatus.RUNNING, AppWrapperStatus.PENDING])
133138
if print_to_console:
134139
pretty_print.print_app_wrappers_status(app_wrappers)
135140
return app_wrappers
@@ -172,7 +177,7 @@ def _get_ray_clusters(namespace='default') -> List[RayCluster]:
172177

173178

174179

175-
def _get_app_wrappers(filter:List[AppWrapperStatus], namespace='default') -> List[AppWrapper]:
180+
def _get_app_wrappers(namespace='default', filter=List[AppWrapperStatus]) -> List[AppWrapper]:
176181
list_of_app_wrappers = []
177182

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

Diff for: src/codeflare_sdk/cluster/config.py

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
@dataclass
2121
class ClusterConfiguration:
2222
name: str
23+
namespace: str = "default"
2324
head_info: list = field(default_factory=list)
2425
machine_types: list = field(default_factory=list) #["m4.xlarge", "g4dn.xlarge"]
2526
min_cpus: int = 1

Diff for: src/codeflare_sdk/utils/generate_yaml.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,22 @@ def gen_names(name):
3333
else:
3434
return name, name
3535

36-
def update_dashboard_route(route_item, cluster_name):
36+
def update_dashboard_route(route_item, cluster_name, namespace):
3737
metadata = route_item.get("generictemplate", {}).get("metadata")
3838
metadata["name"] = f'ray-dashboard-{cluster_name}'
39+
metadata["namespace"] = namespace
3940
metadata["labels"]["odh-ray-cluster-service"] = f'{cluster_name}-head-svc'
4041
spec = route_item.get("generictemplate", {}).get("spec")
4142
spec["to"]["name"] = f'{cluster_name}-head-svc'
4243

43-
def update_names(yaml, item, appwrapper_name, cluster_name):
44+
def update_names(yaml, item, appwrapper_name, cluster_name, namespace):
4445
metadata = yaml.get("metadata")
4546
metadata["name"] = appwrapper_name
47+
metadata["namespace"] = namespace
4648
lower_meta = item.get("generictemplate", {}).get("metadata")
4749
lower_meta["labels"]["appwrapper.mcad.ibm.com"] = appwrapper_name
4850
lower_meta["name"] = cluster_name
51+
lower_meta["namespace"] = namespace
4952

5053
def update_labels(yaml, instascale, instance_types):
5154
metadata = yaml.get("metadata")
@@ -154,17 +157,17 @@ def write_user_appwrapper(user_yaml, output_file_name):
154157
yaml.dump(user_yaml, outfile, default_flow_style=False)
155158
print(f"Written to: {output_file_name}")
156159

157-
def generate_appwrapper(name, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, template, image, instascale, instance_types, env):
160+
def generate_appwrapper(name, namespace, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, template, image, instascale, instance_types, env):
158161
user_yaml = read_template(template)
159162
appwrapper_name, cluster_name = gen_names(name)
160163
resources = user_yaml.get("spec","resources")
161164
item = resources["resources"].get("GenericItems")[0]
162165
route_item = resources["resources"].get("GenericItems")[1]
163-
update_names(user_yaml, item, appwrapper_name, cluster_name)
166+
update_names(user_yaml, item, appwrapper_name, cluster_name, namespace)
164167
update_labels(user_yaml, instascale, instance_types)
165168
update_custompodresources(item, min_cpu, max_cpu, min_memory, max_memory, gpu, workers)
166169
update_nodes(item, appwrapper_name, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, image, instascale, env)
167-
update_dashboard_route(route_item, cluster_name)
170+
update_dashboard_route(route_item, cluster_name, namespace)
168171
outfile = appwrapper_name + ".yaml"
169172
write_user_appwrapper(user_yaml, outfile)
170173
return outfile
@@ -183,6 +186,7 @@ def main():
183186
parser.add_argument("--image", required=False, default="rayproject/ray:latest", help="Ray image to be used (defaults to rayproject/ray:latest)")
184187
parser.add_argument("--instascale", default=False, required=False, action='store_true', help="Indicates that instascale is installed on the cluster")
185188
parser.add_argument("--instance-types", type=str, nargs='+', default=[], required=False, help="Head,worker instance types (space separated)")
189+
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")
186190

187191
args = parser.parse_args()
188192
name = args.name
@@ -196,9 +200,10 @@ def main():
196200
image = args.image
197201
instascale = args.instascale
198202
instance_types = args.instance_types
203+
namespace = args.namespace
199204
env = {}
200205

201-
outfile = generate_appwrapper(name, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, template, image, instascale, instance_types, env)
206+
outfile = generate_appwrapper(name,namespace, min_cpu, max_cpu, min_memory, max_memory, gpu, workers, template, image, instascale, instance_types, env)
202207
return outfile
203208

204209
if __name__=="__main__":

0 commit comments

Comments
 (0)