mirror of
https://github.com/checktheroads/hyperglass
synced 2024-05-11 05:55:08 +00:00
detect & give user option to set app runtime directory
This commit is contained in:
@@ -37,23 +37,62 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
# Standard Library
|
||||
# Standard Library Imports
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
import getpass
|
||||
from pathlib import Path
|
||||
|
||||
# Third Party
|
||||
import uvloop
|
||||
|
||||
# Third Party Imports
|
||||
import stackprinter
|
||||
|
||||
# Project
|
||||
# Project Imports
|
||||
# flake8: noqa: F401
|
||||
from hyperglass import api, cli, util, constants, execution, exceptions, configuration
|
||||
from hyperglass.constants import METADATA
|
||||
|
||||
stackprinter.set_excepthook()
|
||||
try:
|
||||
import stackprinter
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
if sys.stdout.isatty():
|
||||
_style = "darkbg2"
|
||||
else:
|
||||
_style = "plaintext"
|
||||
stackprinter.set_excepthook(style=_style)
|
||||
|
||||
config_path = None
|
||||
|
||||
_CONFIG_PATHS = (Path.home() / "hyperglass", Path("/etc/hyperglass/"))
|
||||
|
||||
for path in _CONFIG_PATHS:
|
||||
try:
|
||||
if not isinstance(path, Path):
|
||||
path = Path(path)
|
||||
|
||||
if path.exists():
|
||||
tmp = path / "test.tmp"
|
||||
tmp.touch()
|
||||
if tmp.exists():
|
||||
config_path = path
|
||||
tmp.unlink()
|
||||
break
|
||||
except Exception:
|
||||
config_path = None
|
||||
|
||||
if config_path is None:
|
||||
raise RuntimeError(
|
||||
"""
|
||||
No configuration directories were determined to both exist and be readable
|
||||
by hyperglass. hyperglass is running as user '{un}' (UID '{uid}'), and tried to access
|
||||
the following directories:
|
||||
{dir}""".format(
|
||||
un=getpass.getuser(),
|
||||
uid=os.getuid(),
|
||||
dir="\n".join([" - " + str(p) for p in _CONFIG_PATHS]),
|
||||
)
|
||||
)
|
||||
|
||||
os.environ["hyperglass_directory"] = str(config_path)
|
||||
|
||||
uvloop.install()
|
||||
|
||||
__name__, __version__, __author__, __copyright__, __license__ = constants.METADATA
|
||||
__name__, __version__, __author__, __copyright__, __license__ = METADATA
|
||||
|
@@ -19,7 +19,7 @@ from hyperglass.constants import __version__
|
||||
from hyperglass.api.events import on_startup, on_shutdown
|
||||
from hyperglass.api.routes import docs, query, queries, routers
|
||||
from hyperglass.exceptions import HyperglassError
|
||||
from hyperglass.configuration import URL_DEV, params
|
||||
from hyperglass.configuration import URL_DEV, STATIC_PATH, params
|
||||
from hyperglass.api.error_handlers import (
|
||||
app_handler,
|
||||
http_handler,
|
||||
@@ -35,10 +35,12 @@ from hyperglass.api.models.response import (
|
||||
|
||||
WORKING_DIR = Path(__file__).parent
|
||||
STATIC_DIR = WORKING_DIR.parent / "static"
|
||||
UI_DIR = STATIC_DIR / "ui"
|
||||
IMAGES_DIR = STATIC_DIR / "images"
|
||||
EXAMPLES_DIR = WORKING_DIR / "examples"
|
||||
|
||||
UI_DIR = STATIC_PATH / "ui"
|
||||
CUSTOM_DIR = STATIC_PATH / "custom"
|
||||
|
||||
EXAMPLE_DEVICES_PY = EXAMPLES_DIR / "devices.py"
|
||||
EXAMPLE_QUERIES_PY = EXAMPLES_DIR / "queries.py"
|
||||
EXAMPLE_QUERY_PY = EXAMPLES_DIR / "query.py"
|
||||
@@ -59,6 +61,11 @@ if params.docs.enable:
|
||||
elif params.docs.mode == "swagger":
|
||||
DOCS_PARAMS.update({"docs_url": params.docs.uri, "redoc_url": None})
|
||||
|
||||
for directory in (UI_DIR, IMAGES_DIR):
|
||||
if not directory.exists():
|
||||
log.warning("Directory '{d}' does not exist, creating...", d=str(directory))
|
||||
directory.mkdir()
|
||||
|
||||
# Main App Definition
|
||||
app = FastAPI(
|
||||
debug=params.debug,
|
||||
@@ -200,6 +207,7 @@ if params.docs.enable:
|
||||
log.debug(f"API Docs config: {app.openapi()}")
|
||||
|
||||
app.mount("/images", StaticFiles(directory=IMAGES_DIR), name="images")
|
||||
app.mount("/custom", StaticFiles(directory=CUSTOM_DIR), name="custom")
|
||||
app.mount("/", StaticFiles(directory=UI_DIR, html=True), name="ui")
|
||||
|
||||
|
||||
|
@@ -14,6 +14,7 @@ from hyperglass.exceptions import HyperglassError
|
||||
from hyperglass.configuration import (
|
||||
URL_DEV,
|
||||
URL_PROD,
|
||||
CONFIG_PATH,
|
||||
REDIS_CONFIG,
|
||||
params,
|
||||
frontend_params,
|
||||
@@ -66,6 +67,7 @@ async def build_ui():
|
||||
dev_url=URL_DEV,
|
||||
prod_url=URL_PROD,
|
||||
params=frontend_params,
|
||||
app_path=CONFIG_PATH,
|
||||
)
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(detail=str(e), status_code=500)
|
||||
|
@@ -5,7 +5,6 @@ import os
|
||||
import copy
|
||||
import math
|
||||
import asyncio
|
||||
import getpass
|
||||
from pathlib import Path
|
||||
|
||||
# Third Party
|
||||
@@ -32,15 +31,11 @@ from hyperglass.configuration.models import routers as _routers
|
||||
from hyperglass.configuration.models import commands as _commands
|
||||
from hyperglass.configuration.markdown import get_markdown
|
||||
|
||||
CONFIG_PATH = Path(os.environ["hyperglass_directory"])
|
||||
log.info("Configuration directory: {d}", d=str(CONFIG_PATH))
|
||||
|
||||
# Project Directories
|
||||
WORKING_DIR = Path(__file__).resolve().parent
|
||||
CONFIG_PATHS = (
|
||||
Path("/etc/hyperglass/"),
|
||||
Path.home() / "hyperglass",
|
||||
WORKING_DIR.parent.parent,
|
||||
WORKING_DIR.parent,
|
||||
WORKING_DIR,
|
||||
)
|
||||
CONFIG_FILES = (
|
||||
("hyperglass.yaml", False),
|
||||
("devices.yaml", True),
|
||||
@@ -48,30 +43,6 @@ CONFIG_FILES = (
|
||||
)
|
||||
|
||||
|
||||
async def _check_config_paths():
|
||||
"""Verify supported configuration directories exist and are readable."""
|
||||
config_path = None
|
||||
for path in CONFIG_PATHS:
|
||||
checked = await check_path(path)
|
||||
if checked is not None:
|
||||
config_path = checked
|
||||
break
|
||||
if config_path is None:
|
||||
raise ConfigError(
|
||||
"""
|
||||
No configuration directories were determined to both exist and be readable
|
||||
by hyperglass. hyperglass is running as user '{un}' (UID '{uid}'), and tried to access
|
||||
the following directories:
|
||||
{dir}""".format(
|
||||
un=getpass.getuser(),
|
||||
uid=os.getuid(),
|
||||
dir="\n".join([" - " + str(p) for p in CONFIG_PATHS]),
|
||||
)
|
||||
)
|
||||
log.info("Configuration directory: {d}", d=str(config_path))
|
||||
return config_path
|
||||
|
||||
|
||||
async def _check_config_files(directory):
|
||||
"""Verify config files exist and are readable.
|
||||
|
||||
@@ -105,7 +76,7 @@ async def _check_config_files(directory):
|
||||
return files
|
||||
|
||||
|
||||
CONFIG_PATH = asyncio.run(_check_config_paths())
|
||||
STATIC_PATH = CONFIG_PATH / "static"
|
||||
|
||||
CONFIG_MAIN, CONFIG_DEVICES, CONFIG_COMMANDS = asyncio.run(
|
||||
_check_config_files(CONFIG_PATH)
|
||||
@@ -171,7 +142,7 @@ async def _config_commands():
|
||||
async with AIOFile(CONFIG_COMMANDS, "r") as cf:
|
||||
raw = await cf.read()
|
||||
config = yaml.safe_load(raw) or {}
|
||||
log.debug(f"Unvalidated commands: {config}")
|
||||
log.debug("Unvalidated commands: {c}", c=config)
|
||||
except (yaml.YAMLError, yaml.MarkedYAMLError) as yaml_error:
|
||||
raise ConfigError(error_msg=str(yaml_error)) from None
|
||||
return config
|
||||
@@ -187,7 +158,7 @@ async def _config_devices():
|
||||
async with AIOFile(CONFIG_DEVICES, "r") as cf:
|
||||
raw = await cf.read()
|
||||
config = yaml.safe_load(raw)
|
||||
log.debug(f"Unvalidated device config: {config}")
|
||||
log.debug("Unvalidated device config: {c}", c=config)
|
||||
except (yaml.YAMLError, yaml.MarkedYAMLError) as yaml_error:
|
||||
raise ConfigError(error_msg=str(yaml_error)) from None
|
||||
return config
|
||||
@@ -197,7 +168,7 @@ user_config = asyncio.run(_config_main())
|
||||
|
||||
# Logging Config
|
||||
try:
|
||||
_debug = user_config["general"]["debug"]
|
||||
_debug = user_config["debug"]
|
||||
except KeyError:
|
||||
_debug = True
|
||||
|
||||
@@ -454,6 +425,7 @@ frontend_networks = _build_frontend_networks()
|
||||
frontend_devices = _build_frontend_devices()
|
||||
_frontend_fields = {
|
||||
"debug": ...,
|
||||
"developer_mode": ...,
|
||||
"primary_asn": ...,
|
||||
"request_timeout": ...,
|
||||
"org_name": ...,
|
||||
@@ -479,7 +451,7 @@ _frontend_params.update(
|
||||
)
|
||||
frontend_params = _frontend_params
|
||||
|
||||
URL_DEV = f"http://localhost:{str(params.listen_port)}/api/"
|
||||
URL_DEV = f"http://localhost:{str(params.listen_port)}/"
|
||||
URL_PROD = "/api/"
|
||||
|
||||
REDIS_CONFIG = {
|
||||
|
Reference in New Issue
Block a user