Files

182 lines
4.8 KiB
Python
Raw Permalink Normal View History

2020-01-21 01:08:28 -07:00
"""CLI utility functions."""
2020-02-03 02:35:11 -07:00
# Standard Library
2020-02-14 16:27:08 -07:00
import os
from pathlib import Path
2020-02-03 02:35:11 -07:00
# Third Party
2020-02-14 16:27:08 -07:00
from click import echo, style
2020-01-21 01:08:28 -07:00
2020-02-03 02:35:11 -07:00
# Project
from hyperglass.cli.echo import info, error, status, success
2020-02-14 16:27:08 -07:00
from hyperglass.cli.static import CL, NL, WS, E
2020-01-21 01:08:28 -07:00
PROJECT_ROOT = Path(__file__).parent.parent
2020-01-21 01:08:28 -07:00
def async_command(func) -> None:
2020-02-14 16:27:08 -07:00
"""Decororator for to make async functions runable from synchronous code."""
2020-09-28 14:55:09 -07:00
# Standard Library
2020-01-21 01:08:28 -07:00
import asyncio
from functools import update_wrapper
func = asyncio.coroutine(func)
def wrapper(*args, **kwargs):
loop = asyncio.get_event_loop()
return loop.run_until_complete(func(*args, **kwargs))
return update_wrapper(wrapper, func)
def start_web_server(start, params):
"""Start web server."""
msg_start = "Starting hyperglass web server on"
msg_uri = "http://"
msg_host = str(params["host"])
msg_port = str(params["port"])
msg_len = len("".join([msg_start, WS[1], msg_uri, msg_host, CL[1], msg_port]))
try:
2020-02-14 16:27:08 -07:00
echo(
2020-01-21 01:08:28 -07:00
NL[1]
+ WS[msg_len + 8]
+ E.ROCKET
+ NL[1]
+ E.CHECK
2020-02-14 16:27:08 -07:00
+ style(msg_start, fg="green", bold=True)
2020-01-21 01:08:28 -07:00
+ WS[1]
2020-02-14 16:27:08 -07:00
+ style(msg_uri, fg="white")
+ style(msg_host, fg="blue", bold=True)
+ style(CL[1], fg="white")
+ style(msg_port, fg="magenta", bold=True)
2020-01-21 01:08:28 -07:00
+ WS[1]
+ E.ROCKET
+ NL[1]
+ WS[1]
+ NL[1]
)
start()
except Exception as e:
2020-02-14 16:27:08 -07:00
error("Failed to start web server: {e}", e=e)
2020-01-21 01:08:28 -07:00
def build_ui(timeout: int) -> None:
"""Create a new UI build."""
2020-01-21 17:28:32 -07:00
try:
2020-09-28 14:55:09 -07:00
# Project
from hyperglass.configuration import CONFIG_PATH, params, frontend_params
from hyperglass.util.frontend import build_frontend
2020-09-28 14:55:09 -07:00
from hyperglass.compat._asyncio import aiorun
2020-01-21 17:28:32 -07:00
except ImportError as e:
2020-02-14 16:27:08 -07:00
error("Error importing UI builder: {e}", e=e)
2020-01-21 17:28:32 -07:00
status("Starting new UI build with a {t} second timeout...", t=timeout)
2020-01-21 17:28:32 -07:00
2020-01-28 12:03:47 -07:00
if params.developer_mode:
2020-01-21 17:28:32 -07:00
dev_mode = "development"
2020-03-19 09:26:20 -07:00
else:
dev_mode = "production"
2020-01-21 17:28:32 -07:00
try:
2020-02-16 00:52:29 -07:00
build_success = aiorun(
2020-01-21 17:28:32 -07:00
build_frontend(
2020-01-28 12:03:47 -07:00
dev_mode=params.developer_mode,
2020-02-14 16:27:08 -07:00
dev_url=f"http://localhost:{str(params.listen_port)}/",
2020-01-21 17:28:32 -07:00
prod_url="/api/",
params=frontend_params,
force=True,
2020-02-14 16:27:08 -07:00
app_path=CONFIG_PATH,
2020-01-21 17:28:32 -07:00
)
)
2020-02-14 16:27:08 -07:00
if build_success:
success("Completed UI build in {m} mode", m=dev_mode)
2020-01-21 17:28:32 -07:00
except Exception as e:
2020-02-14 16:27:08 -07:00
error("Error building UI: {e}", e=e)
return True
def create_dir(path, **kwargs) -> bool:
2020-02-14 16:27:08 -07:00
"""Validate and attempt to create a directory, if it does not exist."""
2020-02-15 21:56:40 -07:00
# If input path is not a path object, try to make it one
2020-02-14 16:27:08 -07:00
if not isinstance(path, Path):
try:
path = Path(path)
except TypeError:
error("{p} is not a valid path", p=path)
2020-02-15 21:56:40 -07:00
# If path does not exist, try to create it
2020-02-14 16:27:08 -07:00
if not path.exists():
try:
path.mkdir(**kwargs)
except PermissionError:
error(
"{u} does not have permission to create {p}. Try running with sudo?",
u=os.getlogin(),
p=path,
)
2020-02-15 21:56:40 -07:00
# Verify the path was actually created
2020-02-14 16:27:08 -07:00
if path.exists():
success("Created {p}", p=path)
2020-02-15 21:56:40 -07:00
# If the path already exists, inform the user
2020-02-14 16:27:08 -07:00
elif path.exists():
info("{p} already exists", p=path)
return True
def write_to_file(file, data) -> bool:
"""Write string data to a file."""
2020-02-14 16:27:08 -07:00
try:
with file.open("w+") as f:
f.write(data.strip())
except PermissionError:
error(
"{u} does not have permission to write to {f}. Try running with sudo?",
u=os.getlogin(),
f=file,
)
if not file.exists():
error("Error writing file {f}", f=file)
elif file.exists():
success("Wrote systemd file {f}", f=file)
2020-01-21 17:28:32 -07:00
return True
2020-02-15 20:02:47 -07:00
2021-07-03 23:02:14 -07:00
def system_info() -> None:
"""Create a markdown table of various system information."""
2020-09-28 14:55:09 -07:00
# Project
from hyperglass.util.system_info import get_system_info
2021-07-03 23:02:14 -07:00
data = get_system_info()
def _code(val):
return f"`{str(val)}`"
def _bold(val):
return f"**{str(val)}**"
2021-07-03 23:02:14 -07:00
md_table_lines = ("| Metric | Value |", "| :----- | :---- |")
for title, metric in data.items():
value, mod = metric
title = _bold(title)
if mod == "code":
value = _code(value)
md_table_lines += (f"| {title} | {value} |",)
md_table = "\n".join(md_table_lines)
info("Please copy & paste this table in your bug report:\n")
echo(md_table + "\n")
2021-07-03 23:02:14 -07:00
return None