Skip to content

Commit 171e91a

Browse files
Set Cluster Configuration to operate in memory by default
1 parent 0c014f1 commit 171e91a

File tree

8 files changed

+432
-91
lines changed

8 files changed

+432
-91
lines changed

src/codeflare_sdk/cluster/cluster.py

Lines changed: 119 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,7 @@ def __init__(self, config: ClusterConfiguration):
7373
self.config = config
7474
self.app_wrapper_yaml = self.create_app_wrapper()
7575
self._job_submission_client = None
76-
self.app_wrapper_name = self.app_wrapper_yaml.replace(".yaml", "").split("/")[
77-
-1
78-
]
76+
self.app_wrapper_name = self.config.name
7977

8078
@property
8179
def _client_headers(self):
@@ -192,6 +190,7 @@ def create_app_wrapper(self):
192190
dispatch_priority = self.config.dispatch_priority
193191
ingress_domain = self.config.ingress_domain
194192
ingress_options = self.config.ingress_options
193+
write_to_file = self.config.write_to_file
195194
return generate_appwrapper(
196195
name=name,
197196
namespace=namespace,
@@ -217,6 +216,7 @@ def create_app_wrapper(self):
217216
openshift_oauth=self.config.openshift_oauth,
218217
ingress_domain=ingress_domain,
219218
ingress_options=ingress_options,
219+
write_to_file=write_to_file,
220220
)
221221

222222
# creates a new cluster with the provided or default spec
@@ -235,15 +235,25 @@ def up(self):
235235
config_check()
236236
api_instance = client.CustomObjectsApi(api_config_handler())
237237
if self.config.mcad:
238-
with open(self.app_wrapper_yaml) as f:
239-
aw = yaml.load(f, Loader=yaml.FullLoader)
240-
api_instance.create_namespaced_custom_object(
241-
group="workload.codeflare.dev",
242-
version="v1beta1",
243-
namespace=namespace,
244-
plural="appwrappers",
245-
body=aw,
246-
)
238+
if self.config.write_to_file:
239+
with open(self.app_wrapper_yaml) as f:
240+
aw = yaml.load(f, Loader=yaml.FullLoader)
241+
api_instance.create_namespaced_custom_object(
242+
group="workload.codeflare.dev",
243+
version="v1beta1",
244+
namespace=namespace,
245+
plural="appwrappers",
246+
body=aw,
247+
)
248+
else:
249+
aw = yaml.safe_load(self.app_wrapper_yaml)
250+
api_instance.create_namespaced_custom_object(
251+
group="workload.codeflare.dev",
252+
version="v1beta1",
253+
namespace=namespace,
254+
plural="appwrappers",
255+
body=aw,
256+
)
247257
else:
248258
self._component_resources_up(namespace, api_instance)
249259
except Exception as e: # pragma: no cover
@@ -492,7 +502,9 @@ def torchx_config(
492502
to_return["requirements"] = requirements
493503
return to_return
494504

495-
def from_k8_cluster_object(rc, mcad=True, ingress_domain=None, ingress_options={}):
505+
def from_k8_cluster_object(
506+
rc, mcad=True, ingress_domain=None, ingress_options={}, write_to_file=False
507+
):
496508
machine_types = (
497509
rc["metadata"]["labels"]["orderedinstance"].split("_")
498510
if "orderedinstance" in rc["metadata"]["labels"]
@@ -538,6 +550,7 @@ def from_k8_cluster_object(rc, mcad=True, ingress_domain=None, ingress_options={
538550
mcad=mcad,
539551
ingress_domain=ingress_domain,
540552
ingress_options=ingress_options,
553+
write_to_file=write_to_file,
541554
)
542555
return Cluster(cluster_config)
543556

@@ -551,79 +564,25 @@ def local_client_url(self):
551564
def _component_resources_up(
552565
self, namespace: str, api_instance: client.CustomObjectsApi
553566
):
554-
with open(self.app_wrapper_yaml) as f:
555-
yamls = yaml.load_all(f, Loader=yaml.FullLoader)
556-
for resource in yamls:
557-
if resource["kind"] == "RayCluster":
558-
api_instance.create_namespaced_custom_object(
559-
group="ray.io",
560-
version="v1",
561-
namespace=namespace,
562-
plural="rayclusters",
563-
body=resource,
564-
)
565-
elif resource["kind"] == "Ingress":
566-
api_instance.create_namespaced_custom_object(
567-
group="networking.k8s.io",
568-
version="v1",
569-
namespace=namespace,
570-
plural="ingresses",
571-
body=resource,
572-
)
573-
elif resource["kind"] == "Route":
574-
api_instance.create_namespaced_custom_object(
575-
group="route.openshift.io",
576-
version="v1",
577-
namespace=namespace,
578-
plural="routes",
579-
body=resource,
580-
)
581-
elif resource["kind"] == "Secret":
582-
secret_instance = client.CoreV1Api(api_config_handler())
583-
secret_instance.create_namespaced_secret(
584-
namespace=namespace,
585-
body=resource,
586-
)
567+
if self.config.write_to_file:
568+
with open(self.app_wrapper_yaml) as f:
569+
yamls = yaml.load_all(f, Loader=yaml.FullLoader)
570+
_create_resources(yamls, namespace, api_instance)
571+
else:
572+
yamls = yaml.load_all(self.app_wrapper_yaml, Loader=yaml.FullLoader)
573+
_create_resources(yamls, namespace, api_instance)
587574

588575
def _component_resources_down(
589576
self, namespace: str, api_instance: client.CustomObjectsApi
590577
):
591-
with open(self.app_wrapper_yaml) as f:
592-
yamls = yaml.load_all(f, Loader=yaml.FullLoader)
593-
for resource in yamls:
594-
if resource["kind"] == "RayCluster":
595-
api_instance.delete_namespaced_custom_object(
596-
group="ray.io",
597-
version="v1",
598-
namespace=namespace,
599-
plural="rayclusters",
600-
name=self.app_wrapper_name,
601-
)
602-
elif resource["kind"] == "Ingress":
603-
name = resource["metadata"]["name"]
604-
api_instance.delete_namespaced_custom_object(
605-
group="networking.k8s.io",
606-
version="v1",
607-
namespace=namespace,
608-
plural="ingresses",
609-
name=name,
610-
)
611-
elif resource["kind"] == "Route":
612-
name = resource["metadata"]["name"]
613-
api_instance.delete_namespaced_custom_object(
614-
group="route.openshift.io",
615-
version="v1",
616-
namespace=namespace,
617-
plural="routes",
618-
name=name,
619-
)
620-
elif resource["kind"] == "Secret":
621-
name = resource["metadata"]["name"]
622-
secret_instance = client.CoreV1Api(api_config_handler())
623-
secret_instance.delete_namespaced_secret(
624-
namespace=namespace,
625-
name=name,
626-
)
578+
cluster_name = self.config.name
579+
if self.config.write_to_file:
580+
with open(self.app_wrapper_yaml) as f:
581+
yamls = yaml.load_all(f, Loader=yaml.FullLoader)
582+
_delete_resources(yamls, namespace, api_instance, cluster_name)
583+
else:
584+
yamls = yaml.safe_load_all(self.app_wrapper_yaml)
585+
_delete_resources(yamls, namespace, api_instance, cluster_name)
627586

628587

629588
def list_all_clusters(namespace: str, print_to_console: bool = True):
@@ -675,7 +634,9 @@ def get_current_namespace(): # pragma: no cover
675634
return None
676635

677636

678-
def get_cluster(cluster_name: str, namespace: str = "default"):
637+
def get_cluster(
638+
cluster_name: str, namespace: str = "default", write_to_file: bool = False
639+
):
679640
try:
680641
config_check()
681642
api_instance = client.CustomObjectsApi(api_config_handler())
@@ -746,13 +707,88 @@ def get_cluster(cluster_name: str, namespace: str = "default"):
746707
mcad=mcad,
747708
ingress_domain=ingress_domain,
748709
ingress_options=ingress_options,
710+
write_to_file=write_to_file,
749711
)
750712
raise FileNotFoundError(
751713
f"Cluster {cluster_name} is not found in {namespace} namespace"
752714
)
753715

754716

755717
# private methods
718+
def _delete_resources(
719+
yamls, namespace: str, api_instance: client.CustomObjectsApi, cluster_name: str
720+
):
721+
for resource in yamls:
722+
if resource["kind"] == "RayCluster":
723+
name = resource["metadata"]["name"]
724+
api_instance.delete_namespaced_custom_object(
725+
group="ray.io",
726+
version="v1",
727+
namespace=namespace,
728+
plural="rayclusters",
729+
name=name,
730+
)
731+
elif resource["kind"] == "Ingress":
732+
name = resource["metadata"]["name"]
733+
api_instance.delete_namespaced_custom_object(
734+
group="networking.k8s.io",
735+
version="v1",
736+
namespace=namespace,
737+
plural="ingresses",
738+
name=name,
739+
)
740+
elif resource["kind"] == "Route":
741+
name = resource["metadata"]["name"]
742+
api_instance.delete_namespaced_custom_object(
743+
group="route.openshift.io",
744+
version="v1",
745+
namespace=namespace,
746+
plural="routes",
747+
name=name,
748+
)
749+
elif resource["kind"] == "Secret":
750+
name = resource["metadata"]["name"]
751+
secret_instance = client.CoreV1Api(api_config_handler())
752+
secret_instance.delete_namespaced_secret(
753+
namespace=namespace,
754+
name=name,
755+
)
756+
757+
758+
def _create_resources(yamls, namespace: str, api_instance: client.CustomObjectsApi):
759+
for resource in yamls:
760+
if resource["kind"] == "RayCluster":
761+
api_instance.create_namespaced_custom_object(
762+
group="ray.io",
763+
version="v1",
764+
namespace=namespace,
765+
plural="rayclusters",
766+
body=resource,
767+
)
768+
elif resource["kind"] == "Ingress":
769+
api_instance.create_namespaced_custom_object(
770+
group="networking.k8s.io",
771+
version="v1",
772+
namespace=namespace,
773+
plural="ingresses",
774+
body=resource,
775+
)
776+
elif resource["kind"] == "Route":
777+
api_instance.create_namespaced_custom_object(
778+
group="route.openshift.io",
779+
version="v1",
780+
namespace=namespace,
781+
plural="routes",
782+
body=resource,
783+
)
784+
elif resource["kind"] == "Secret":
785+
secret_instance = client.CoreV1Api(api_config_handler())
786+
secret_instance.create_namespaced_secret(
787+
namespace=namespace,
788+
body=resource,
789+
)
790+
791+
756792
def _check_aw_exists(name: str, namespace: str) -> bool:
757793
try:
758794
config_check()

src/codeflare_sdk/cluster/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,4 @@ class ClusterConfiguration:
5555
openshift_oauth: bool = False # NOTE: to use the user must have permission to create a RoleBinding for system:auth-delegator
5656
ingress_options: dict = field(default_factory=dict)
5757
ingress_domain: str = None
58+
write_to_file: bool = False

src/codeflare_sdk/utils/generate_yaml.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,27 @@ def write_components(user_yaml: dict, output_file_name: str):
640640
print(f"Written to: {output_file_name}")
641641

642642

643+
def load_components(user_yaml: dict, name: str):
644+
component_list = []
645+
components = user_yaml.get("spec", "resources")["resources"].get("GenericItems")
646+
for component in components:
647+
if "generictemplate" in component:
648+
component_list.append(component["generictemplate"])
649+
650+
resources = "---\n" + "---\n".join(
651+
[yaml.dump(component) for component in component_list]
652+
)
653+
user_yaml = resources
654+
print(f"Yaml resources loaded for {name}")
655+
return user_yaml
656+
657+
658+
def load_appwrapper(user_yaml: dict, name: str):
659+
user_yaml = yaml.dump(user_yaml)
660+
print(f"Yaml resources loaded for {name}")
661+
return user_yaml
662+
663+
643664
def generate_appwrapper(
644665
name: str,
645666
namespace: str,
@@ -665,6 +686,7 @@ def generate_appwrapper(
665686
openshift_oauth: bool,
666687
ingress_domain: str,
667688
ingress_options: dict,
689+
write_to_file: bool,
668690
):
669691
user_yaml = read_template(template)
670692
appwrapper_name, cluster_name = gen_names(name)
@@ -724,8 +746,16 @@ def generate_appwrapper(
724746

725747
directory_path = os.path.expanduser("~/.codeflare/appwrapper/")
726748
outfile = os.path.join(directory_path, appwrapper_name + ".yaml")
727-
if not mcad:
728-
write_components(user_yaml, outfile)
749+
750+
if write_to_file:
751+
if mcad:
752+
write_user_appwrapper(user_yaml, outfile)
753+
else:
754+
write_components(user_yaml, outfile)
755+
return outfile
729756
else:
730-
write_user_appwrapper(user_yaml, outfile)
731-
return outfile
757+
if mcad:
758+
user_yaml = load_appwrapper(user_yaml, name)
759+
else:
760+
user_yaml = load_components(user_yaml, name)
761+
return user_yaml

tests/e2e/mnist_raycluster_sdk_oauth_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def run_mnist_raycluster_sdk_oauth(self):
4545
instascale=False,
4646
image=ray_image,
4747
openshift_oauth=True,
48+
write_to_file=True,
4849
)
4950
)
5051

tests/e2e/mnist_raycluster_sdk_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def run_mnist_raycluster_sdk(self):
7070
instascale=False,
7171
image=ray_image,
7272
ingress_options=ingress_options,
73+
write_to_file=True,
7374
)
7475
)
7576

0 commit comments

Comments
 (0)