2020-07-13 21:14:13 +01:00
|
|
|
import inspect
|
2020-07-15 06:09:00 +01:00
|
|
|
import itertools
|
2020-07-10 07:01:28 +01:00
|
|
|
import os
|
2020-07-10 16:32:47 +01:00
|
|
|
import sys
|
2020-07-15 06:09:00 +01:00
|
|
|
import threading
|
|
|
|
import time
|
|
|
|
from contextlib import contextmanager
|
2020-07-10 16:32:47 +01:00
|
|
|
from enum import Enum
|
2020-07-13 21:14:13 +01:00
|
|
|
from pathlib import Path
|
|
|
|
from tempfile import NamedTemporaryFile
|
2020-09-26 17:42:15 +01:00
|
|
|
from typing import Optional, List
|
2020-07-10 07:01:28 +01:00
|
|
|
|
2020-07-10 16:32:47 +01:00
|
|
|
from invoke import task, Context
|
2020-06-02 22:48:57 +01:00
|
|
|
|
2020-07-10 16:32:47 +01:00
|
|
|
DAEMON_DIR: str = "daemon"
|
2020-07-13 22:13:32 +01:00
|
|
|
DEFAULT_PREFIX: str = "/usr/local"
|
2022-10-14 16:56:33 +01:00
|
|
|
OSPFMDR_CHECKOUT: str = "63f07596268873aeff86f252cbc27901369ad50a"
|
2020-09-26 17:42:15 +01:00
|
|
|
REDHAT_LIKE = {
|
|
|
|
"redhat",
|
|
|
|
"fedora",
|
|
|
|
}
|
|
|
|
DEBIAN_LIKE = {
|
|
|
|
"ubuntu",
|
|
|
|
"debian",
|
|
|
|
}
|
2022-09-29 21:58:09 +01:00
|
|
|
SUDOP: str = "sudo -E env PATH=$PATH"
|
|
|
|
VENV_PATH: str = "/opt/core/venv"
|
|
|
|
VENV_PYTHON: str = f"{VENV_PATH}/bin/python"
|
|
|
|
ACTIVATE_VENV: str = f". {VENV_PATH}/bin/activate"
|
2020-07-10 07:01:28 +01:00
|
|
|
|
|
|
|
|
2020-07-15 06:09:00 +01:00
|
|
|
class Progress:
|
|
|
|
cycles = itertools.cycle(["-", "/", "|", "\\"])
|
|
|
|
|
|
|
|
def __init__(self, verbose: bool) -> None:
|
|
|
|
self.verbose: bool = verbose
|
|
|
|
self.thread: Optional[threading.Thread] = None
|
|
|
|
self.running: bool = False
|
|
|
|
|
|
|
|
@contextmanager
|
|
|
|
def start(self, message: str) -> None:
|
|
|
|
if not self.verbose:
|
|
|
|
print(f"{message} ... ", end="")
|
|
|
|
self.running = True
|
|
|
|
self.thread = threading.Thread(target=self.run, daemon=True)
|
|
|
|
self.thread.start()
|
|
|
|
yield
|
|
|
|
self.stop()
|
|
|
|
|
|
|
|
def run(self) -> None:
|
|
|
|
while self.running:
|
|
|
|
sys.stdout.write(next(self.cycles))
|
|
|
|
sys.stdout.flush()
|
|
|
|
sys.stdout.write("\b")
|
|
|
|
time.sleep(0.1)
|
|
|
|
|
|
|
|
def stop(self) -> None:
|
|
|
|
if not self.verbose:
|
|
|
|
print("done")
|
|
|
|
if self.thread:
|
|
|
|
self.running = False
|
|
|
|
self.thread.join()
|
|
|
|
self.thread = None
|
|
|
|
|
|
|
|
|
2020-07-10 16:32:47 +01:00
|
|
|
class OsName(Enum):
|
|
|
|
UBUNTU = "ubuntu"
|
|
|
|
CENTOS = "centos"
|
2020-09-26 17:42:15 +01:00
|
|
|
UNKNOWN = "unknown"
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get(cls, name: str) -> "OsName":
|
|
|
|
try:
|
|
|
|
return OsName(name)
|
|
|
|
except ValueError:
|
|
|
|
return OsName.UNKNOWN
|
2020-07-10 16:32:47 +01:00
|
|
|
|
|
|
|
|
|
|
|
class OsLike(Enum):
|
|
|
|
DEBIAN = "debian"
|
2020-09-26 17:42:15 +01:00
|
|
|
REDHAT = "rhel"
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get(cls, values: List[str]) -> Optional["OsLike"]:
|
|
|
|
for value in values:
|
|
|
|
if value in DEBIAN_LIKE:
|
|
|
|
return OsLike.DEBIAN
|
|
|
|
elif value in REDHAT_LIKE:
|
|
|
|
return OsLike.REDHAT
|
|
|
|
return None
|
2020-07-10 16:32:47 +01:00
|
|
|
|
|
|
|
|
|
|
|
class OsInfo:
|
2020-07-10 18:45:03 +01:00
|
|
|
def __init__(self, name: OsName, like: OsLike, version: float) -> None:
|
2020-07-10 16:32:47 +01:00
|
|
|
self.name: OsName = name
|
|
|
|
self.like: OsLike = like
|
2020-07-10 18:45:03 +01:00
|
|
|
self.version: float = version
|
2020-07-10 16:32:47 +01:00
|
|
|
|
2020-09-26 17:42:15 +01:00
|
|
|
@classmethod
|
|
|
|
def get(cls, name: str, like: List[str], version: Optional[str]) -> "OsInfo":
|
|
|
|
os_name = OsName.get(name)
|
|
|
|
os_like = OsLike.get(like)
|
|
|
|
if not os_like:
|
|
|
|
like = " ".join(like)
|
|
|
|
print(f"unsupported os install type({like})")
|
2020-12-12 02:46:29 +00:00
|
|
|
print("trying using the -i option to specify an install type")
|
2020-09-26 17:42:15 +01:00
|
|
|
sys.exit(1)
|
|
|
|
if version:
|
|
|
|
try:
|
|
|
|
version = float(version)
|
|
|
|
except ValueError:
|
|
|
|
print(f"os version is not a float: {version}")
|
|
|
|
sys.exit(1)
|
|
|
|
return OsInfo(os_name, os_like, version)
|
|
|
|
|
2020-07-10 16:32:47 +01:00
|
|
|
|
2022-05-10 19:51:36 +01:00
|
|
|
def get_env_python() -> str:
|
|
|
|
return os.environ.get("PYTHON", "python3")
|
|
|
|
|
|
|
|
|
2022-05-28 04:10:48 +01:00
|
|
|
def get_env_python_dep() -> str:
|
|
|
|
return os.environ.get("PYTHON_DEP", "python3")
|
|
|
|
|
|
|
|
|
2020-07-10 16:32:47 +01:00
|
|
|
def get_pytest(c: Context) -> str:
|
2020-07-10 07:01:28 +01:00
|
|
|
with c.cd(DAEMON_DIR):
|
|
|
|
venv = c.run("poetry env info -p", hide=True).stdout.strip()
|
|
|
|
return os.path.join(venv, "bin", "pytest")
|
|
|
|
|
|
|
|
|
2020-09-26 17:42:15 +01:00
|
|
|
def get_os(install_type: Optional[str]) -> OsInfo:
|
|
|
|
if install_type:
|
|
|
|
name_value = OsName.UNKNOWN.value
|
|
|
|
like_value = install_type
|
|
|
|
version_value = None
|
|
|
|
else:
|
|
|
|
d = {}
|
|
|
|
with open("/etc/os-release", "r") as f:
|
|
|
|
for line in f.readlines():
|
|
|
|
line = line.strip()
|
|
|
|
if not line:
|
|
|
|
continue
|
|
|
|
key, value = line.split("=")
|
2023-06-14 05:49:50 +01:00
|
|
|
d[key] = value.strip('"')
|
2020-09-26 17:42:15 +01:00
|
|
|
name_value = d["ID"]
|
2020-12-12 02:46:29 +00:00
|
|
|
like_value = d.get("ID_LIKE", "")
|
2020-09-26 17:42:15 +01:00
|
|
|
version_value = d["VERSION_ID"]
|
|
|
|
return OsInfo.get(name_value, like_value.split(), version_value)
|
2020-07-10 16:32:47 +01:00
|
|
|
|
|
|
|
|
2020-07-16 18:35:16 +01:00
|
|
|
def check_existing_core(c: Context, hide: bool) -> None:
|
2023-06-14 05:49:50 +01:00
|
|
|
if c.run('python -c "import core"', warn=True, hide=hide):
|
2022-10-13 18:15:38 +01:00
|
|
|
raise SystemError("existing python core installation detected, please remove")
|
2022-05-28 04:10:48 +01:00
|
|
|
python_bin = get_env_python()
|
2023-06-14 05:49:50 +01:00
|
|
|
if c.run(f'{python_bin} -c "import core"', warn=True, hide=hide):
|
2022-05-28 04:10:48 +01:00
|
|
|
raise SystemError(
|
|
|
|
f"existing {python_bin} core installation detected, please remove"
|
|
|
|
)
|
2020-07-16 18:35:16 +01:00
|
|
|
if c.run("which core-daemon", warn=True, hide=hide):
|
|
|
|
raise SystemError("core scripts found, please remove old installation")
|
|
|
|
|
|
|
|
|
2022-07-21 23:35:31 +01:00
|
|
|
def install_system(c: Context, os_info: OsInfo, hide: bool, no_python: bool) -> None:
|
2022-05-28 04:10:48 +01:00
|
|
|
python_dep = get_env_python_dep()
|
2020-07-10 16:32:47 +01:00
|
|
|
if os_info.like == OsLike.DEBIAN:
|
2020-07-10 07:01:28 +01:00
|
|
|
c.run(
|
2021-05-10 23:07:42 +01:00
|
|
|
"sudo apt install -y automake pkg-config gcc libev-dev nftables "
|
2022-07-21 23:35:31 +01:00
|
|
|
f"iproute2 ethtool tk bash",
|
2023-06-14 05:49:50 +01:00
|
|
|
hide=hide,
|
2020-07-10 19:20:27 +01:00
|
|
|
)
|
2022-07-21 23:35:31 +01:00
|
|
|
if not no_python:
|
|
|
|
c.run(f"sudo apt install -y {python_dep}-tk", hide=hide)
|
2020-07-10 19:20:27 +01:00
|
|
|
elif os_info.like == OsLike.REDHAT:
|
|
|
|
c.run(
|
2020-07-15 06:09:00 +01:00
|
|
|
"sudo yum install -y automake pkgconf-pkg-config gcc gcc-c++ "
|
2022-07-21 23:35:31 +01:00
|
|
|
f"libev-devel nftables iproute tk ethtool make bash",
|
|
|
|
hide=hide,
|
2020-07-10 07:01:28 +01:00
|
|
|
)
|
2022-07-21 23:35:31 +01:00
|
|
|
if not no_python:
|
|
|
|
c.run(
|
|
|
|
f"sudo yum install -y {python_dep}-devel {python_dep}-tkinter ",
|
|
|
|
hide=hide,
|
|
|
|
)
|
2020-07-11 00:50:37 +01:00
|
|
|
# centos 8+ does not support netem by default
|
|
|
|
if os_info.name == OsName.CENTOS and os_info.version >= 8:
|
|
|
|
c.run("sudo yum install -y kernel-modules-extra", hide=hide)
|
2020-07-11 01:56:30 +01:00
|
|
|
if not c.run("sudo modprobe sch_netem", warn=True, hide=hide):
|
2020-07-15 06:09:00 +01:00
|
|
|
print("\nERROR: you need to install the latest kernel")
|
2020-07-11 01:56:30 +01:00
|
|
|
print("run the following, restart, and try again")
|
|
|
|
print("sudo yum update")
|
|
|
|
sys.exit(1)
|
2020-07-15 06:09:00 +01:00
|
|
|
|
2020-07-10 16:32:47 +01:00
|
|
|
|
2020-07-10 19:20:27 +01:00
|
|
|
def install_grpcio(c: Context, hide: bool) -> None:
|
2022-05-10 19:51:36 +01:00
|
|
|
python_bin = get_env_python()
|
2020-07-10 20:09:04 +01:00
|
|
|
c.run(
|
2022-10-14 20:14:20 +01:00
|
|
|
f"{python_bin} -m pip install --user grpcio==1.49.1 grpcio-tools==1.49.1",
|
2020-07-15 06:09:00 +01:00
|
|
|
hide=hide,
|
2020-07-10 20:09:04 +01:00
|
|
|
)
|
2020-07-10 16:32:47 +01:00
|
|
|
|
|
|
|
|
2020-07-15 06:09:00 +01:00
|
|
|
def build_core(c: Context, hide: bool, prefix: str = DEFAULT_PREFIX) -> None:
|
2020-07-10 16:51:40 +01:00
|
|
|
c.run("./bootstrap.sh", hide=hide)
|
2020-07-14 18:01:57 +01:00
|
|
|
c.run(f"./configure --prefix={prefix}", hide=hide)
|
2020-07-10 20:20:27 +01:00
|
|
|
c.run("make -j$(nproc)", hide=hide)
|
2020-07-10 16:32:47 +01:00
|
|
|
|
|
|
|
|
2020-07-10 16:51:40 +01:00
|
|
|
def install_core(c: Context, hide: bool) -> None:
|
2020-07-14 21:42:59 +01:00
|
|
|
c.run("sudo make install", hide=hide)
|
2020-07-10 16:32:47 +01:00
|
|
|
|
|
|
|
|
2020-09-11 23:05:49 +01:00
|
|
|
def install_poetry(c: Context, dev: bool, local: bool, hide: bool) -> None:
|
2022-05-28 04:10:48 +01:00
|
|
|
python_bin = get_env_python()
|
2020-09-11 23:05:49 +01:00
|
|
|
if local:
|
|
|
|
with c.cd(DAEMON_DIR):
|
|
|
|
c.run("poetry build -f wheel", hide=hide)
|
2023-03-09 18:49:11 +00:00
|
|
|
c.run(f"sudo {python_bin} -m pip install dist/*")
|
2020-09-11 23:05:49 +01:00
|
|
|
else:
|
2023-02-27 19:08:51 +00:00
|
|
|
args = "" if dev else "--only main"
|
2020-09-11 23:05:49 +01:00
|
|
|
with c.cd(DAEMON_DIR):
|
2022-09-29 21:58:09 +01:00
|
|
|
c.run("sudo mkdir -p /opt/core", hide=hide)
|
|
|
|
c.run(f"sudo {python_bin} -m venv {VENV_PATH}")
|
|
|
|
c.run(f"{ACTIVATE_VENV} && {SUDOP} poetry install {args}", hide=hide)
|
2020-09-11 23:05:49 +01:00
|
|
|
if dev:
|
2022-09-29 21:58:09 +01:00
|
|
|
c.run(f"{ACTIVATE_VENV} && poetry run pre-commit install", hide=hide)
|
2020-07-10 16:32:47 +01:00
|
|
|
|
|
|
|
|
2020-07-10 16:51:40 +01:00
|
|
|
def install_ospf_mdr(c: Context, os_info: OsInfo, hide: bool) -> None:
|
2022-02-18 23:25:41 +00:00
|
|
|
if c.run("sudo which zebra", warn=True, hide=hide):
|
2020-07-15 06:09:00 +01:00
|
|
|
print("\nquagga already installed, skipping ospf mdr")
|
2020-07-10 16:32:47 +01:00
|
|
|
return
|
2020-07-15 06:26:39 +01:00
|
|
|
if os_info.like == OsLike.DEBIAN:
|
|
|
|
c.run("sudo apt install -y libtool gawk libreadline-dev git", hide=hide)
|
|
|
|
elif os_info.like == OsLike.REDHAT:
|
|
|
|
c.run("sudo yum install -y libtool gawk readline-devel git", hide=hide)
|
2020-09-10 00:17:29 +01:00
|
|
|
ospf_dir = "../ospf-mdr"
|
|
|
|
ospf_url = "https://github.com/USNavalResearchLaboratory/ospf-mdr.git"
|
|
|
|
c.run(f"git clone {ospf_url} {ospf_dir}", hide=hide)
|
|
|
|
with c.cd(ospf_dir):
|
2020-09-10 00:52:35 +01:00
|
|
|
c.run(f"git checkout {OSPFMDR_CHECKOUT}", hide=hide)
|
2020-07-15 06:26:39 +01:00
|
|
|
c.run("./bootstrap.sh", hide=hide)
|
2020-07-10 16:32:47 +01:00
|
|
|
c.run(
|
2020-07-15 06:26:39 +01:00
|
|
|
"./configure --disable-doc --enable-user=root --enable-group=root "
|
|
|
|
"--with-cflags=-ggdb --sysconfdir=/usr/local/etc/quagga --enable-vtysh "
|
|
|
|
"--localstatedir=/var/run/quagga",
|
2023-06-14 05:49:50 +01:00
|
|
|
hide=hide,
|
2020-07-10 16:32:47 +01:00
|
|
|
)
|
2020-07-15 06:26:39 +01:00
|
|
|
c.run("make -j$(nproc)", hide=hide)
|
|
|
|
c.run("sudo make install", hide=hide)
|
2020-07-10 16:32:47 +01:00
|
|
|
|
|
|
|
|
2020-07-14 17:42:14 +01:00
|
|
|
def install_service(c, verbose=False, prefix=DEFAULT_PREFIX):
|
2020-07-14 17:24:59 +01:00
|
|
|
"""
|
|
|
|
install systemd core service
|
|
|
|
"""
|
2020-07-14 17:42:14 +01:00
|
|
|
hide = not verbose
|
2020-07-14 17:24:59 +01:00
|
|
|
bin_dir = Path(prefix).joinpath("bin")
|
|
|
|
systemd_dir = Path("/lib/systemd/system/")
|
|
|
|
service_file = systemd_dir.joinpath("core-daemon.service")
|
|
|
|
if systemd_dir.exists():
|
2023-06-14 05:49:50 +01:00
|
|
|
service_data = inspect.cleandoc(
|
|
|
|
f"""
|
2020-07-14 17:24:59 +01:00
|
|
|
[Unit]
|
|
|
|
Description=Common Open Research Emulator Service
|
|
|
|
After=network.target
|
|
|
|
|
|
|
|
[Service]
|
|
|
|
Type=simple
|
|
|
|
ExecStart={bin_dir}/core-daemon
|
|
|
|
TasksMax=infinity
|
|
|
|
|
|
|
|
[Install]
|
|
|
|
WantedBy=multi-user.target
|
2023-06-14 05:49:50 +01:00
|
|
|
"""
|
|
|
|
)
|
2020-07-14 17:24:59 +01:00
|
|
|
temp = NamedTemporaryFile("w", delete=False)
|
|
|
|
temp.write(service_data)
|
|
|
|
temp.close()
|
|
|
|
c.run(f"sudo cp {temp.name} {service_file}", hide=hide)
|
|
|
|
else:
|
|
|
|
print(f"ERROR: systemd service path not found: {systemd_dir}")
|
|
|
|
|
|
|
|
|
2021-05-12 05:10:56 +01:00
|
|
|
def install_core_files(c, local=False, verbose=False, prefix=DEFAULT_PREFIX):
|
2020-07-14 17:24:59 +01:00
|
|
|
"""
|
2021-05-12 05:10:56 +01:00
|
|
|
install core files (scripts, examples, and configuration)
|
2020-07-14 17:24:59 +01:00
|
|
|
"""
|
2020-07-14 17:42:14 +01:00
|
|
|
hide = not verbose
|
2020-07-13 21:14:13 +01:00
|
|
|
bin_dir = Path(prefix).joinpath("bin")
|
2020-08-05 05:11:17 +01:00
|
|
|
# setup core python helper
|
2020-09-11 23:05:49 +01:00
|
|
|
if not local:
|
|
|
|
core_python = bin_dir.joinpath("core-python")
|
|
|
|
temp = NamedTemporaryFile("w", delete=False)
|
2023-06-14 05:49:50 +01:00
|
|
|
temp.writelines(
|
|
|
|
[
|
|
|
|
"#!/bin/bash\n",
|
|
|
|
f'exec "{VENV_PYTHON}" "$@"\n',
|
|
|
|
]
|
|
|
|
)
|
2020-09-11 23:05:49 +01:00
|
|
|
temp.close()
|
|
|
|
c.run(f"sudo cp {temp.name} {core_python}", hide=hide)
|
|
|
|
c.run(f"sudo chmod 755 {core_python}", hide=hide)
|
|
|
|
os.unlink(temp.name)
|
2020-07-13 21:14:13 +01:00
|
|
|
# install core configuration file
|
|
|
|
config_dir = "/etc/core"
|
|
|
|
c.run(f"sudo mkdir -p {config_dir}", hide=hide)
|
2022-07-28 00:00:10 +01:00
|
|
|
c.run(f"sudo cp -n package/etc/core.conf {config_dir}", hide=hide)
|
|
|
|
c.run(f"sudo cp -n package/etc/logging.conf {config_dir}", hide=hide)
|
2021-05-12 05:10:56 +01:00
|
|
|
# install examples
|
|
|
|
examples_dir = f"{prefix}/share/core"
|
|
|
|
c.run(f"sudo mkdir -p {examples_dir}", hide=hide)
|
2022-07-28 00:00:10 +01:00
|
|
|
c.run(f"sudo cp -r package/examples {examples_dir}", hide=hide)
|
2020-07-13 21:14:13 +01:00
|
|
|
|
|
|
|
|
2022-07-29 22:12:17 +01:00
|
|
|
@task(
|
|
|
|
help={
|
|
|
|
"verbose": "enable verbose",
|
|
|
|
"install-type": "used to force an install type, "
|
2023-06-14 05:49:50 +01:00
|
|
|
"can be one of the following (redhat, debian)",
|
2022-07-29 22:12:17 +01:00
|
|
|
"no-python": "avoid installing python system dependencies",
|
|
|
|
},
|
|
|
|
)
|
|
|
|
def build(
|
|
|
|
c,
|
|
|
|
verbose=False,
|
|
|
|
install_type=None,
|
|
|
|
no_python=False,
|
|
|
|
):
|
|
|
|
print("setting up to build core packages")
|
|
|
|
c.run("sudo -v", hide=True)
|
|
|
|
p = Progress(verbose)
|
|
|
|
hide = not verbose
|
|
|
|
os_info = get_os(install_type)
|
|
|
|
with p.start("installing system dependencies"):
|
|
|
|
install_system(c, os_info, hide, no_python)
|
|
|
|
with p.start("installing system grpcio-tools"):
|
|
|
|
install_grpcio(c, hide)
|
|
|
|
with p.start("building core"):
|
|
|
|
build_core(c, hide)
|
|
|
|
with p.start(f"building rpm/deb packages"):
|
|
|
|
c.run("make fpm", hide=hide)
|
|
|
|
|
|
|
|
|
2020-07-16 16:42:36 +01:00
|
|
|
@task(
|
|
|
|
help={
|
|
|
|
"dev": "install development mode",
|
|
|
|
"verbose": "enable verbose",
|
2020-09-11 23:05:49 +01:00
|
|
|
"local": "determines if core will install to local system, default is False",
|
|
|
|
"prefix": f"prefix where scripts are installed, default is {DEFAULT_PREFIX}",
|
2020-09-26 17:42:15 +01:00
|
|
|
"install-type": "used to force an install type, "
|
2023-06-14 05:49:50 +01:00
|
|
|
"can be one of the following (redhat, debian)",
|
2021-04-17 07:43:25 +01:00
|
|
|
"ospf": "disable ospf installation",
|
2022-07-21 23:35:31 +01:00
|
|
|
"no-python": "avoid installing python system dependencies",
|
2020-07-16 16:42:36 +01:00
|
|
|
},
|
|
|
|
)
|
2020-09-26 17:42:15 +01:00
|
|
|
def install(
|
2021-04-17 07:43:25 +01:00
|
|
|
c,
|
|
|
|
dev=False,
|
|
|
|
verbose=False,
|
|
|
|
local=False,
|
|
|
|
prefix=DEFAULT_PREFIX,
|
|
|
|
install_type=None,
|
|
|
|
ospf=True,
|
2022-07-21 23:35:31 +01:00
|
|
|
no_python=False,
|
2020-09-26 17:42:15 +01:00
|
|
|
):
|
2020-07-10 16:32:47 +01:00
|
|
|
"""
|
2020-07-14 17:24:59 +01:00
|
|
|
install core, poetry, scripts, service, and ospf mdr
|
2020-07-10 16:32:47 +01:00
|
|
|
"""
|
2022-09-29 21:58:09 +01:00
|
|
|
python_bin = get_env_python()
|
|
|
|
venv_path = None if local else VENV_PATH
|
|
|
|
print(
|
|
|
|
f"installing core using python({python_bin}) venv({venv_path}) prefix({prefix})"
|
|
|
|
)
|
2020-07-16 19:04:52 +01:00
|
|
|
c.run("sudo -v", hide=True)
|
2020-07-15 06:09:00 +01:00
|
|
|
p = Progress(verbose)
|
2020-07-10 16:51:40 +01:00
|
|
|
hide = not verbose
|
2020-09-26 17:42:15 +01:00
|
|
|
os_info = get_os(install_type)
|
|
|
|
if not c["run"]["dry"]:
|
|
|
|
with p.start("checking for old installations"):
|
|
|
|
check_existing_core(c, hide)
|
2020-07-15 06:09:00 +01:00
|
|
|
with p.start("installing system dependencies"):
|
2022-07-21 23:35:31 +01:00
|
|
|
install_system(c, os_info, hide, no_python)
|
2020-07-15 06:09:00 +01:00
|
|
|
with p.start("installing system grpcio-tools"):
|
|
|
|
install_grpcio(c, hide)
|
|
|
|
with p.start("building core"):
|
|
|
|
build_core(c, hide, prefix)
|
2022-03-08 20:00:42 +00:00
|
|
|
with p.start("installing vnoded/vcmd"):
|
2020-07-15 06:09:00 +01:00
|
|
|
install_core(c, hide)
|
2022-09-29 21:58:09 +01:00
|
|
|
with p.start(f"installing core"):
|
2020-09-11 23:05:49 +01:00
|
|
|
install_poetry(c, dev, local, hide)
|
2021-05-12 05:10:56 +01:00
|
|
|
with p.start("installing scripts, examples, and configuration"):
|
|
|
|
install_core_files(c, local, hide, prefix)
|
2020-07-15 06:09:00 +01:00
|
|
|
with p.start("installing systemd service"):
|
|
|
|
install_service(c, hide, prefix)
|
2021-04-17 07:43:25 +01:00
|
|
|
if ospf:
|
|
|
|
with p.start("installing ospf mdr"):
|
|
|
|
install_ospf_mdr(c, os_info, hide)
|
2020-08-03 18:40:48 +01:00
|
|
|
print("\ninstall complete!")
|
2020-07-10 07:01:28 +01:00
|
|
|
|
2020-06-02 22:48:57 +01:00
|
|
|
|
2020-07-16 16:42:36 +01:00
|
|
|
@task(
|
|
|
|
help={
|
2021-11-17 23:55:05 +00:00
|
|
|
"emane-version": "version of emane install",
|
2020-07-16 16:42:36 +01:00
|
|
|
"verbose": "enable verbose",
|
2020-09-26 17:42:15 +01:00
|
|
|
"install-type": "used to force an install type, "
|
2023-06-14 05:49:50 +01:00
|
|
|
"can be one of the following (redhat, debian)",
|
2020-07-16 16:42:36 +01:00
|
|
|
},
|
|
|
|
)
|
2021-11-17 23:55:05 +00:00
|
|
|
def install_emane(c, emane_version, verbose=False, install_type=None):
|
2020-07-16 00:50:04 +01:00
|
|
|
"""
|
2021-11-17 23:55:05 +00:00
|
|
|
install emane python bindings into the core virtual environment
|
2020-07-16 00:50:04 +01:00
|
|
|
"""
|
|
|
|
c.run("sudo -v", hide=True)
|
|
|
|
p = Progress(verbose)
|
|
|
|
hide = not verbose
|
2020-09-26 17:42:15 +01:00
|
|
|
os_info = get_os(install_type)
|
2022-05-28 04:10:48 +01:00
|
|
|
python_dep = get_env_python_dep()
|
2020-07-16 00:50:04 +01:00
|
|
|
with p.start("installing system dependencies"):
|
|
|
|
if os_info.like == OsLike.DEBIAN:
|
|
|
|
c.run(
|
2020-07-16 01:52:34 +01:00
|
|
|
"sudo apt install -y gcc g++ automake libtool libxml2-dev "
|
|
|
|
"libprotobuf-dev libpcap-dev libpcre3-dev uuid-dev pkg-config "
|
2022-05-28 04:10:48 +01:00
|
|
|
f"protobuf-compiler git {python_dep}-protobuf {python_dep}-setuptools",
|
2020-07-16 00:50:04 +01:00
|
|
|
hide=hide,
|
|
|
|
)
|
|
|
|
elif os_info.like == OsLike.REDHAT:
|
2020-07-16 19:04:52 +01:00
|
|
|
if os_info.name == OsName.CENTOS and os_info.version >= 8:
|
|
|
|
c.run("sudo yum config-manager --set-enabled PowerTools", hide=hide)
|
2020-07-16 00:50:04 +01:00
|
|
|
c.run(
|
2020-07-16 01:52:34 +01:00
|
|
|
"sudo yum install -y autoconf automake git libtool libxml2-devel "
|
2020-07-16 05:50:35 +01:00
|
|
|
"libpcap-devel pcre-devel libuuid-devel make gcc-c++ protobuf-compiler "
|
2022-05-28 04:10:48 +01:00
|
|
|
f"protobuf-devel {python_dep}-setuptools",
|
2020-07-16 00:50:04 +01:00
|
|
|
hide=hide,
|
|
|
|
)
|
2020-09-10 02:42:26 +01:00
|
|
|
emane_dir = "../emane"
|
|
|
|
emane_python_dir = Path(emane_dir).joinpath("src/python")
|
2020-09-10 00:52:35 +01:00
|
|
|
emane_url = "https://github.com/adjacentlink/emane.git"
|
2020-07-16 00:50:04 +01:00
|
|
|
with p.start("cloning emane"):
|
2020-09-10 00:52:35 +01:00
|
|
|
c.run(f"git clone {emane_url} {emane_dir}", hide=hide)
|
2021-11-17 23:55:05 +00:00
|
|
|
with p.start("setup emane"):
|
2022-05-28 04:10:48 +01:00
|
|
|
python_bin = get_env_python()
|
2020-07-16 00:50:04 +01:00
|
|
|
with c.cd(emane_dir):
|
2021-11-17 23:55:05 +00:00
|
|
|
c.run(f"git checkout {emane_version}", hide=hide)
|
2020-07-16 00:50:04 +01:00
|
|
|
c.run("./autogen.sh", hide=hide)
|
2022-05-28 04:10:48 +01:00
|
|
|
c.run(f"PYTHON={python_bin} ./configure --prefix=/usr", hide=hide)
|
2021-11-17 23:55:05 +00:00
|
|
|
with p.start("build emane python bindings"):
|
|
|
|
with c.cd(str(emane_python_dir)):
|
2020-07-16 00:50:04 +01:00
|
|
|
c.run("make -j$(nproc)", hide=hide)
|
2021-11-17 23:55:05 +00:00
|
|
|
with p.start("installing emane python bindings for core virtual environment"):
|
|
|
|
with c.cd(DAEMON_DIR):
|
2023-06-14 05:49:50 +01:00
|
|
|
c.run(f"poetry run pip install {emane_python_dir.absolute()}", hide=hide)
|
2020-07-16 00:50:04 +01:00
|
|
|
|
|
|
|
|
2020-07-16 16:42:36 +01:00
|
|
|
@task(
|
|
|
|
help={
|
|
|
|
"dev": "uninstall development mode",
|
|
|
|
"verbose": "enable verbose",
|
2020-09-12 00:33:21 +01:00
|
|
|
"local": "determines if core was installed local to system, default is False",
|
2021-04-17 07:43:25 +01:00
|
|
|
"prefix": f"prefix where scripts are installed, default is {DEFAULT_PREFIX}",
|
2020-07-16 16:42:36 +01:00
|
|
|
},
|
|
|
|
)
|
2021-04-17 07:43:25 +01:00
|
|
|
def uninstall(
|
|
|
|
c,
|
|
|
|
dev=False,
|
|
|
|
verbose=False,
|
|
|
|
local=False,
|
|
|
|
prefix=DEFAULT_PREFIX,
|
|
|
|
):
|
2020-07-13 21:48:27 +01:00
|
|
|
"""
|
2020-07-16 16:47:18 +01:00
|
|
|
uninstall core, scripts, service, virtual environment, and clean build directory
|
2020-07-13 21:48:27 +01:00
|
|
|
"""
|
2022-09-29 21:58:09 +01:00
|
|
|
python_bin = get_env_python()
|
|
|
|
venv_path = None if local else VENV_PATH
|
|
|
|
print(
|
|
|
|
f"uninstalling core using python({python_bin}) "
|
|
|
|
f"venv({venv_path}) prefix({prefix})"
|
|
|
|
)
|
2020-07-13 21:48:27 +01:00
|
|
|
hide = not verbose
|
2020-07-15 06:09:00 +01:00
|
|
|
p = Progress(verbose)
|
|
|
|
c.run("sudo -v", hide=True)
|
|
|
|
with p.start("uninstalling core"):
|
|
|
|
c.run("sudo make uninstall", hide=hide)
|
|
|
|
with p.start("cleaning build directory"):
|
|
|
|
c.run("make clean", hide=hide)
|
|
|
|
c.run("./bootstrap.sh clean", hide=hide)
|
2022-09-29 21:58:09 +01:00
|
|
|
with p.start(f"uninstalling core"):
|
|
|
|
if local:
|
2022-05-28 04:10:48 +01:00
|
|
|
python_bin = get_env_python()
|
|
|
|
c.run(f"sudo {python_bin} -m pip uninstall -y core", hide=hide)
|
2022-09-29 21:58:09 +01:00
|
|
|
else:
|
|
|
|
if Path(VENV_PYTHON).is_file():
|
|
|
|
with c.cd(DAEMON_DIR):
|
|
|
|
if dev:
|
2023-06-14 05:49:50 +01:00
|
|
|
c.run(
|
|
|
|
f"{ACTIVATE_VENV} && poetry run pre-commit uninstall",
|
|
|
|
hide=hide,
|
|
|
|
)
|
2022-09-29 21:58:09 +01:00
|
|
|
c.run(f"sudo {VENV_PYTHON} -m pip uninstall -y core", hide=hide)
|
2020-07-13 21:48:27 +01:00
|
|
|
# remove installed files
|
|
|
|
bin_dir = Path(prefix).joinpath("bin")
|
2021-05-12 05:10:56 +01:00
|
|
|
with p.start("uninstalling examples"):
|
|
|
|
examples_dir = Path(prefix).joinpath("share/core")
|
|
|
|
c.run(f"sudo rm -rf {examples_dir}")
|
2020-08-05 05:11:17 +01:00
|
|
|
# remove core-python symlink
|
2020-09-12 00:33:21 +01:00
|
|
|
if not local:
|
|
|
|
core_python = bin_dir.joinpath("core-python")
|
|
|
|
c.run(f"sudo rm -f {core_python}", hide=hide)
|
|
|
|
# remove service
|
2020-07-13 21:48:27 +01:00
|
|
|
systemd_dir = Path("/lib/systemd/system/")
|
|
|
|
service_name = "core-daemon.service"
|
|
|
|
service_file = systemd_dir.joinpath(service_name)
|
|
|
|
if service_file.exists():
|
2020-07-15 06:09:00 +01:00
|
|
|
with p.start(f"uninstalling service {service_file}"):
|
|
|
|
c.run(f"sudo systemctl disable {service_name}", hide=hide)
|
|
|
|
c.run(f"sudo rm -f {service_file}", hide=hide)
|
2020-07-13 21:48:27 +01:00
|
|
|
|
|
|
|
|
2020-07-16 18:35:16 +01:00
|
|
|
@task(
|
|
|
|
help={
|
|
|
|
"dev": "reinstall development mode",
|
|
|
|
"verbose": "enable verbose",
|
2020-09-12 00:26:13 +01:00
|
|
|
"local": "determines if core will install to local system, default is False",
|
2020-07-16 18:35:16 +01:00
|
|
|
"prefix": f"prefix where scripts are installed, default is {DEFAULT_PREFIX}",
|
2020-09-26 17:42:15 +01:00
|
|
|
"branch": "branch to install latest code from, default is current branch",
|
|
|
|
"install-type": "used to force an install type, "
|
2023-06-14 05:49:50 +01:00
|
|
|
"can be one of the following (redhat, debian)",
|
2020-07-16 18:35:16 +01:00
|
|
|
},
|
|
|
|
)
|
2020-09-12 00:26:13 +01:00
|
|
|
def reinstall(
|
2020-09-26 17:42:15 +01:00
|
|
|
c,
|
|
|
|
dev=False,
|
|
|
|
verbose=False,
|
|
|
|
local=False,
|
|
|
|
prefix=DEFAULT_PREFIX,
|
|
|
|
branch=None,
|
2023-06-14 05:49:50 +01:00
|
|
|
install_type=None,
|
2020-09-12 00:26:13 +01:00
|
|
|
):
|
2020-07-16 18:35:16 +01:00
|
|
|
"""
|
|
|
|
run the uninstall task, get latest from specified branch, and run install task
|
|
|
|
"""
|
2020-09-12 00:33:21 +01:00
|
|
|
uninstall(c, dev, verbose, local, prefix)
|
2020-07-16 18:35:16 +01:00
|
|
|
hide = not verbose
|
|
|
|
p = Progress(verbose)
|
|
|
|
with p.start("pulling latest code"):
|
|
|
|
current = c.run("git rev-parse --abbrev-ref HEAD", hide=hide).stdout.strip()
|
|
|
|
if branch and branch != current:
|
|
|
|
c.run(f"git checkout {branch}")
|
|
|
|
else:
|
|
|
|
branch = current
|
|
|
|
c.run("git pull", hide=hide)
|
|
|
|
if not Path("tasks.py").exists():
|
|
|
|
raise FileNotFoundError(f"missing tasks.py on branch: {branch}")
|
2020-09-26 17:42:15 +01:00
|
|
|
install(c, dev, verbose, local, prefix, install_type)
|
2020-07-16 18:35:16 +01:00
|
|
|
|
|
|
|
|
2020-07-08 07:38:12 +01:00
|
|
|
@task
|
|
|
|
def test(c):
|
|
|
|
"""
|
2020-07-10 07:01:28 +01:00
|
|
|
run core tests
|
2020-07-08 07:38:12 +01:00
|
|
|
"""
|
2020-07-10 07:01:28 +01:00
|
|
|
pytest = get_pytest(c)
|
|
|
|
with c.cd(DAEMON_DIR):
|
|
|
|
c.run(f"sudo {pytest} -v --lf -x tests", pty=True)
|
2020-07-08 07:38:12 +01:00
|
|
|
|
|
|
|
|
|
|
|
@task
|
|
|
|
def test_mock(c):
|
|
|
|
"""
|
2020-07-10 07:01:28 +01:00
|
|
|
run core tests using mock to avoid running as sudo
|
2020-07-08 07:38:12 +01:00
|
|
|
"""
|
2020-07-10 07:01:28 +01:00
|
|
|
with c.cd(DAEMON_DIR):
|
2020-07-08 07:38:12 +01:00
|
|
|
c.run("poetry run pytest -v --mock --lf -x tests", pty=True)
|
|
|
|
|
|
|
|
|
|
|
|
@task
|
|
|
|
def test_emane(c):
|
|
|
|
"""
|
2020-07-10 07:01:28 +01:00
|
|
|
run core emane tests
|
2020-07-08 07:38:12 +01:00
|
|
|
"""
|
2020-07-10 07:01:28 +01:00
|
|
|
pytest = get_pytest(c)
|
|
|
|
with c.cd(DAEMON_DIR):
|
2020-09-02 01:47:24 +01:00
|
|
|
c.run(f"sudo {pytest} -v --lf -x tests/emane", pty=True)
|