Skip to content

Commit 8574558

Browse files
committed
feat: add ui cluster creation and deletion buttons
Signed-off-by: Bobbins228 <[email protected]>
1 parent e1c1b97 commit 8574558

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

src/codeflare_sdk/cluster/cluster.py

+14
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
RayCluster,
4343
RayClusterStatus,
4444
)
45+
from .widgets import (
46+
cluster_up_down_buttons,
47+
is_notebook,
48+
)
4549
from kubernetes import client, config
4650
from kubernetes.utils import parse_quantity
4751
import yaml
@@ -71,6 +75,8 @@ def __init__(self, config: ClusterConfiguration):
7175
self.app_wrapper_yaml = self.create_app_wrapper()
7276
self._job_submission_client = None
7377
self.app_wrapper_name = self.config.name
78+
if is_notebook():
79+
cluster_up_down_buttons(self)
7480

7581
@property
7682
def _client_headers(self):
@@ -156,8 +162,12 @@ def up(self):
156162
plural="appwrappers",
157163
body=aw,
158164
)
165+
print(f"AppWrapper: '{self.config.name}' has successfully been created")
159166
else:
160167
self._component_resources_up(namespace, api_instance)
168+
print(
169+
f"Ray Cluster: '{self.config.name}' has successfully been created"
170+
)
161171
except Exception as e: # pragma: no cover
162172
return _kube_api_error_handling(e)
163173

@@ -198,8 +208,12 @@ def down(self):
198208
plural="appwrappers",
199209
name=self.app_wrapper_name,
200210
)
211+
print(f"AppWrapper: '{self.config.name}' has successfully been deleted")
201212
else:
202213
self._component_resources_down(namespace, api_instance)
214+
print(
215+
f"Ray Cluster: '{self.config.name}' has successfully been deleted"
216+
)
203217
except Exception as e: # pragma: no cover
204218
return _kube_api_error_handling(e)
205219

src/codeflare_sdk/cluster/widgets.py

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Copyright 2022 IBM, Red Hat
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
The widgets sub-module contains the ui widgets created using the ipywidgets package.
17+
"""
18+
import ipywidgets as widgets
19+
from IPython.display import display
20+
import os
21+
import codeflare_sdk
22+
23+
24+
def cluster_up_down_buttons(cluster: "codeflare_sdk.cluster.Cluster") -> widgets.Button:
25+
"""
26+
The cluster_up_down_buttons function returns two button widgets for a create and delete button.
27+
The function uses the appwrapper bool to distinguish between resource type for the tool tip.
28+
"""
29+
resource = "Ray Cluster"
30+
if cluster.config.appwrapper:
31+
resource = "AppWrapper"
32+
33+
up_button = widgets.Button(
34+
description="Cluster Up",
35+
tooltip=f"Create the {resource}",
36+
icon="play",
37+
)
38+
39+
delete_button = widgets.Button(
40+
description="Cluster Down",
41+
tooltip=f"Delete the {resource}",
42+
icon="trash",
43+
)
44+
45+
wait_ready_check = wait_ready_check_box()
46+
output = widgets.Output()
47+
48+
# Display the buttons in an HBox wrapped in a VBox which includes the wait_ready Checkbox
49+
button_display = widgets.HBox([up_button, delete_button])
50+
display(widgets.VBox([button_display, wait_ready_check]), output)
51+
52+
def on_up_button_clicked(b): # Handle the up button click event
53+
with output:
54+
output.clear_output()
55+
cluster.up()
56+
57+
# If the wait_ready Checkbox is clicked(value == True) trigger the wait_ready function
58+
if wait_ready_check.value:
59+
cluster.wait_ready()
60+
61+
def on_down_button_clicked(b): # Handle the down button click event
62+
with output:
63+
output.clear_output()
64+
cluster.down()
65+
66+
up_button.on_click(on_up_button_clicked)
67+
delete_button.on_click(on_down_button_clicked)
68+
69+
70+
def wait_ready_check_box():
71+
"""
72+
The wait_ready_check_box function will return a checkbox widget used for waiting for the resource to be in the state READY.
73+
"""
74+
wait_ready_check_box = widgets.Checkbox(
75+
False,
76+
description="Wait for Cluster?",
77+
)
78+
return wait_ready_check_box
79+
80+
81+
def is_notebook() -> bool:
82+
"""
83+
The is_notebook function checks if Jupyter Notebook environment variables exist in the given environment and return True/False based on that.
84+
"""
85+
if (
86+
"PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING" in os.environ
87+
or "JPY_SESSION_NAME" in os.environ
88+
): # If running Jupyter NBs in VsCode or RHOAI/ODH display UI buttons
89+
return True
90+
else:
91+
return False

tests/unit_test.py

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
gen_names,
7777
is_openshift_cluster,
7878
)
79+
from codeflare_sdk.cluster.widgets import cluster_up_down_buttons
7980

8081
import openshift
8182
from openshift.selector import Selector

0 commit comments

Comments
 (0)