Skip to content

Commit e7c89db

Browse files
committed
toasts and admin
1 parent 8badedd commit e7c89db

6 files changed

Lines changed: 563 additions & 133 deletions

File tree

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ REST API endpoints (web mode):
154154
- `GET /` - Web dashboard
155155
- `GET /api/status` - Current GPU metrics
156156
- `GET /api/history` - Historical data
157+
158+
### Admin mode
159+
160+
If you need the web dashboard to perform privileged actions (terminate processes, restart services), start the server with the `--admin` flag. This signals the application that it should enable administrative actions and the dashboard will show admin controls.
161+
162+
```powershell
163+
python health_monitor.py web --port 8890 --admin
164+
```
157165
- `POST /api/benchmark/start` - Start benchmark
158166
- `GET /api/benchmark/status` - Benchmark progress
159167
- `POST /api/benchmark/stop` - Stop benchmark

health_monitor.py

Lines changed: 168 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,74 @@ async def run_cli_monitor(config: dict):
255255

256256
def _run_app(config_path, port, nodes, once, web_mode=False, cli_mode=False):
257257
"""Helper to run main application logic."""
258+
# If the user requested admin mode via --admin in argv, and the process is not elevated,
259+
# attempt to relaunch elevated (UAC on Windows, sudo on POSIX). This check is done here
260+
# to cover both top-level and subcommand usages (e.g. `health_monitor.py web --admin`).
261+
try:
262+
import sys, platform, os
263+
def _is_elevated():
264+
try:
265+
if platform.system() == 'Windows':
266+
import ctypes
267+
return bool(ctypes.windll.shell32.IsUserAnAdmin())
268+
else:
269+
return (os.geteuid() == 0)
270+
except Exception:
271+
return False
272+
273+
if '--admin' in (sys.argv[1:] if len(sys.argv) > 1 else []) and not _is_elevated():
274+
# Attempt relaunch elevated. Use ShellExecuteW on Windows, fallback to PowerShell;
275+
# on POSIX try sudo exec.
276+
try:
277+
if platform.system() == 'Windows':
278+
try:
279+
import ctypes
280+
params = '"' + os.path.abspath(sys.argv[0]) + '"'
281+
other_args = [a for a in sys.argv[1:]]
282+
if other_args:
283+
params += ' ' + ' '.join(str(a) for a in other_args)
284+
ret = ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, params, None, 1)
285+
try:
286+
ok = int(ret) > 32
287+
except Exception:
288+
ok = False
289+
if ok:
290+
print('Relaunching elevated, exiting original process')
291+
try: os._exit(0)
292+
except Exception: pass
293+
except Exception:
294+
pass
295+
296+
# PowerShell fallback
297+
try:
298+
import subprocess
299+
def _ps_quote(s):
300+
return "'" + str(s).replace("'", "''") + "'"
301+
ps_args = [os.path.abspath(sys.argv[0])] + list(sys.argv[1:])
302+
arglist_literal = ','.join(_ps_quote(a) for a in ps_args)
303+
ps_cmd = [
304+
'powershell', '-NoProfile', '-NonInteractive', '-Command',
305+
f"Start-Process -FilePath '{sys.executable}' -ArgumentList {arglist_literal} -Verb RunAs"
306+
]
307+
proc = subprocess.run(ps_cmd, capture_output=True, text=True, timeout=15)
308+
if proc.returncode == 0:
309+
try: os._exit(0)
310+
except Exception: pass
311+
except Exception:
312+
pass
313+
314+
else:
315+
# POSIX: try exec via sudo
316+
try:
317+
print('Attempting to relaunch with sudo...')
318+
os.execvp('sudo', ['sudo', sys.executable, os.path.abspath(sys.argv[0])] + list(sys.argv[1:]))
319+
except Exception:
320+
pass
321+
except Exception:
322+
pass
323+
except Exception:
324+
pass
325+
258326
console.print(BANNER, style="bold cyan")
259327

260328
# Load configuration
@@ -299,9 +367,91 @@ async def main():
299367
@click.option('--config', '-c', type=click.Path(), help='Configuration file path.')
300368
@click.option('--port', '-p', type=int, help='Web server port (default: 8090).')
301369
@click.option('--update', is_flag=True, help='Check for and install updates.')
370+
@click.option('--admin', is_flag=True, help='Start in administrative mode (enables privileged dashboard actions).')
302371
@click.pass_context
303-
def cli(ctx, config, port, update):
372+
def cli(ctx, config, port, update, admin):
304373
"""Cluster Health Monitor: Real-time GPU and system health monitoring."""
374+
# If the user requested admin mode, attempt to relaunch this process elevated
375+
# on platforms that support elevation (Windows -> UAC, POSIX -> sudo).
376+
def _is_elevated():
377+
try:
378+
import platform
379+
if platform.system() == 'Windows':
380+
import ctypes
381+
return bool(ctypes.windll.shell32.IsUserAnAdmin())
382+
else:
383+
import os
384+
return (os.geteuid() == 0)
385+
except Exception:
386+
return False
387+
388+
def _relaunch_elevated():
389+
try:
390+
import platform, sys, os, subprocess, shlex
391+
script = os.path.abspath(sys.argv[0])
392+
args = sys.argv[1:]
393+
# Ensure --admin present
394+
if '--admin' not in args:
395+
args = args + ['--admin']
396+
397+
if platform.system() == 'Windows':
398+
try:
399+
import ctypes
400+
params = '"' + script + '"'
401+
if args:
402+
params += ' ' + ' '.join(str(a) for a in args)
403+
ret = ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, params, None, 1)
404+
try:
405+
ok = int(ret) > 32
406+
except Exception:
407+
ok = False
408+
if ok:
409+
# launched elevated; exit current process
410+
print('Relaunching elevated, exiting original process')
411+
try: os._exit(0)
412+
except SystemExit: raise
413+
except Exception: pass
414+
else:
415+
print('ShellExecuteW failed to elevate (ret=' + str(ret) + ')')
416+
except Exception as e:
417+
print('Windows elevation exception:', e)
418+
419+
# PowerShell fallback
420+
try:
421+
def _ps_quote(s):
422+
return "'" + str(s).replace("'", "''") + "'"
423+
ps_args = [script] + list(args)
424+
arglist_literal = ','.join(_ps_quote(a) for a in ps_args)
425+
ps_cmd = [
426+
'powershell', '-NoProfile', '-NonInteractive', '-Command',
427+
f"Start-Process -FilePath '{sys.executable}' -ArgumentList {arglist_literal} -Verb RunAs"
428+
]
429+
proc = subprocess.run(ps_cmd, capture_output=True, text=True, timeout=15)
430+
if proc.returncode == 0:
431+
try: os._exit(0)
432+
except Exception: pass
433+
else:
434+
print('PowerShell elevation failed:', proc.returncode, proc.stderr)
435+
except Exception as e:
436+
print('PowerShell fallback exception:', e)
437+
438+
else:
439+
# POSIX: try exec via sudo
440+
try:
441+
print('Attempting to relaunch with sudo...')
442+
os.execvp('sudo', ['sudo', sys.executable, script] + list(args))
443+
except Exception as e:
444+
print('sudo relaunch failed:', e)
445+
446+
except Exception as e:
447+
print('Relaunch elevation error:', e)
448+
449+
# If admin requested and not already elevated, attempt to relaunch elevated
450+
try:
451+
if admin and not _is_elevated():
452+
_relaunch_elevated()
453+
except Exception:
454+
pass
305455
if update:
306456
from monitor.utils import check_for_updates, perform_update
307457
console.print("\n[cyan]Checking for updates...[/cyan]")
@@ -328,15 +478,30 @@ def cli(ctx, config, port, update):
328478
console.print("[red]Update failed. Try again later.[/red]")
329479
return
330480

331-
ctx.obj = {'config_path': config}
481+
ctx.obj = {'config_path': config, 'admin': admin}
332482
if ctx.invoked_subcommand is None:
483+
# If admin flag set, append to sys.argv so server.detect features and app.state see it
484+
if admin and '--admin' not in sys.argv:
485+
sys.argv.append('--admin')
333486
_run_app(config, port=port, nodes=None, once=False, web_mode=True)
334487

335488
@cli.command()
336489
@click.option('--port', '-p', type=int, help='Web server port (overrides config).')
490+
@click.option('--admin', is_flag=True, help='Start web server in administrative mode (enables privileged actions).')
337491
@click.pass_context
338-
def web(ctx, port):
492+
def web(ctx, port, admin):
339493
"""Launch the web dashboard."""
494+
# If called as a subcommand with --admin, ensure argv contains --admin so server detection sees it
495+
import sys
496+
if admin and '--admin' not in sys.argv:
497+
sys.argv.append('--admin')
498+
# Also propagate admin from top-level invocation if present in ctx.obj
499+
try:
500+
if not admin and ctx and isinstance(ctx.obj, dict) and ctx.obj.get('admin'):
501+
if '--admin' not in sys.argv:
502+
sys.argv.append('--admin')
503+
except Exception:
504+
pass
340505
_run_app(ctx.obj['config_path'], port, nodes=None, once=False, web_mode=True)
341506

342507
@cli.command(name="cli")

0 commit comments

Comments
 (0)