|
| 1 | +from ast import Str |
| 2 | +from turtle import st |
| 3 | +from rich import print |
| 4 | +from rich.table import Table |
| 5 | +from rich.console import Console |
| 6 | +from rich.layout import Layout |
| 7 | +from rich.panel import Panel |
| 8 | +from rich import box |
| 9 | +from dataclasses import dataclass |
| 10 | +from typing import List |
| 11 | + |
| 12 | +@dataclass |
| 13 | +class RayCluster: |
| 14 | + name: str |
| 15 | + status: str |
| 16 | + min_workers: int |
| 17 | + max_workers: int |
| 18 | + worker_mem_min: str |
| 19 | + worker_mem_max: str |
| 20 | + worker_cpu: int |
| 21 | + worker_gpu: int |
| 22 | + |
| 23 | +def print_clusters(clusters:List[RayCluster], verbose=True): |
| 24 | + console = Console() |
| 25 | + |
| 26 | + title_printed = False |
| 27 | + |
| 28 | + for cluster in clusters: |
| 29 | + status = "Active :white_heavy_check_mark:" if cluster.status.lower() == 'ready' else "InActive :x:" |
| 30 | + name = cluster.name |
| 31 | + dashboard = f"https://codeflare-raydashboard.research.ibm.com?rayclustername={name}" |
| 32 | + mincount = str(cluster.min_workers) |
| 33 | + maxcount = str(cluster.max_workers) |
| 34 | + memory = cluster.worker_mem_min+"~"+cluster.worker_mem_max |
| 35 | + cpu = str(cluster.worker_cpu) |
| 36 | + gpu = str(cluster.worker_mem_max) |
| 37 | + #owned = bool(cluster["userOwned"]) |
| 38 | + owned = True |
| 39 | + |
| 40 | + #'table0' to display the cluster name, status, url, and dashboard link |
| 41 | + table0 = Table(box=None, show_header=False) |
| 42 | + if owned: |
| 43 | + table0.add_row("[white on green][bold]Owner") |
| 44 | + else: |
| 45 | + table0.add_row("") |
| 46 | + table0.add_row("[bold underline]"+name,status) |
| 47 | + table0.add_row() |
| 48 | + table0.add_row(f"[bold]URI:[/bold] ray://{name}-head.codeflare.svc:1001") |
| 49 | + table0.add_row() |
| 50 | + table0.add_row(f"[link={dashboard} blue underline]Dashboard:link:[/link]") |
| 51 | + table0.add_row("") #empty row for spacing |
| 52 | + |
| 53 | + |
| 54 | + #'table1' to display the worker counts |
| 55 | + table1 = Table(box=None) |
| 56 | + table1.add_row() |
| 57 | + table1.add_column("Min", style="cyan", no_wrap=True) |
| 58 | + table1.add_column("Max", style="magenta") |
| 59 | + table1.add_row() |
| 60 | + table1.add_row(mincount,maxcount) |
| 61 | + table1.add_row() |
| 62 | + |
| 63 | + #'table2' to display the worker resources |
| 64 | + table2 = Table(box=None) |
| 65 | + table2.add_column("Memory", style="cyan", no_wrap=True, min_width=10) |
| 66 | + table2.add_column("CPU", style="magenta", min_width=10) |
| 67 | + table2.add_column("GPU", style="magenta", min_width=10) |
| 68 | + table2.add_row() |
| 69 | + table2.add_row(memory, cpu, gpu) |
| 70 | + table2.add_row() |
| 71 | + |
| 72 | + #panels to encompass table1 and table2 into separate cards |
| 73 | + panel_1 = Panel.fit(table1,title="Workers") |
| 74 | + panel_2 = Panel.fit(table2, title="Worker specs(each)") |
| 75 | + |
| 76 | + #table3 to display panel_1 and panel_2 side-by-side in a single row |
| 77 | + table3 = Table(box=None, show_header=False, title="Cluster Resources") |
| 78 | + table3.add_row(panel_1,panel_2) |
| 79 | + |
| 80 | + #table4 to display table0 and table3, one below the other |
| 81 | + table4 = Table(box=None, show_header=False) |
| 82 | + table4.add_row(table0) |
| 83 | + table4.add_row(table3) |
| 84 | + |
| 85 | + # Encompass all details of the cluster in a single panel |
| 86 | + if not title_printed: |
| 87 | + #If first cluster in the list, then create a table with title "Codeflare clusters". |
| 88 | + #This is done to ensure the title is center aligned on the cluster display tables, rather |
| 89 | + #than being center aligned on the console/terminal if we simply use console.print(title) |
| 90 | + |
| 91 | + table5 = Table(box=None, title="[bold] :rocket: List of CodeFlare clusters :rocket:") |
| 92 | + table5.add_row(Panel.fit(table4)) |
| 93 | + console.print(table5) |
| 94 | + title_printed = True |
| 95 | + else: |
| 96 | + console.print(Panel.fit(table4)) |
0 commit comments