This commit is contained in:
xenia 2021-06-15 04:37:57 -04:00
parent dfb2b9d956
commit 7aa8886b07
9 changed files with 197 additions and 4 deletions

10
leylines-ansible/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
.venv
*.pyc
*.pyo
*.pyd
__pycache__
*.egg-info
.env
.vimrc
.ycm_extra_conf.py
*.db

View File

@ -0,0 +1,59 @@
#!/usr/bin/env python3
import argparse
import json
import os
import sys
from leylines import db, SERVER_NODE_ID
XDG_CACHE_HOME = os.path.expanduser(os.environ.get("XDG_CACHE_HOME", "~/.cache"))
CACHE_DIR = os.path.join(XDG_CACHE_HOME, "leylines")
if not os.path.isdir(CACHE_DIR):
os.mkdir(CACHE_DIR, 0o700)
def get_ansible_config():
server_node = db.get_server_node()
nodes = [node for node in db.get_nodes() if node.ssh_key is not None]
for node in nodes:
nid = node.id
ssh_key = node.ssh_key
ssh_key_path = os.path.join(CACHE_DIR, f"{nid}.key")
if not os.path.isfile(ssh_key_path):
with open(ssh_key_path, "w") as f:
f.write(ssh_key)
return {
"leylines": {
"hosts": [node.name for node in nodes],
"vars": {
"ansible_ssh_user": "haskal",
"ansible_python_interpreter": "auto"
}
},
"_meta": {
"hostvars": {
node.name: {
"ansible_host": str(node.ip),
"ansible_ssh_private_key_file": os.path.join(CACHE_DIR, f"{node.id}.key"),
"leylines_resources":
" ".join([f"{res}=1" for res in db.get_node_resources(node.id)]),
"leylines_ip": str(node.ip),
"leylines_server_addr": str(server_node.ip),
"leylines_is_server": "yes" if node.id == server_node.id else "no"
} for node in nodes
}
}
}
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="leylines ansible inventory plugin")
parser.add_argument("--list", action="store_true", help="List inventory")
args = parser.parse_args()
if args.list:
json.dump(get_ansible_config(), sys.stdout)
else:
raise Exception("no action specified")

View File

@ -0,0 +1,94 @@
---
- hosts: all
vars:
python_version: 3.9.5
tasks:
- name: install prerequisite packages
become: yes
apt:
name: ["build-essential", "wget", "software-properties-common", "libnss3-dev", "zlib1g-dev",
"libgdbm-dev", "libncurses5-dev", "libssl-dev", "libffi-dev", "libreadline-dev",
"libsqlite3-dev", "libbz2-dev", "libopenblas-dev"]
state: present
update_cache: yes
- name: download build and install python {{ python_version }}
register: pyinstall
changed_when: "'NO_COMPILE_NEEDED' not in pyinstall.stdout"
args:
executable: "/bin/bash"
shell: |
set -eo pipefail
export PATH=$HOME/.local/bin:$PATH
export LD_LIBRARY_PATH=$HOME/.local/lib:$LD_LIBRARY_PATH
existing_ver="$(python3 -c 'import sys;print(f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")')"
if [ "$existing_ver" == "{{ python_version }}" ]; then
echo "NO_COMPILE_NEEDED"
exit
fi
if [ ! -d $HOME/python ]; then
mkdir $HOME/python
fi
cd $HOME/python
wget -O python.tgz https://www.python.org/ftp/python/{{ python_version }}/Python-{{ python_version }}.tgz
tar xf python.tgz
cd Python-{{ python_version }}
# https://bugs.python.org/issue41346
sed -i 's/-j0 //' Makefile.pre.in
# Speed up LTO
sed -i -e "s|-flto |-flto=4 |g" configure configure.ac
export CFLAGS="-O3 -fno-semantic-interposition"
export LDFLAGS="-fno-semantic-interposition"
./configure --prefix=$HOME/.local/ \
--enable-shared \
--with-computed-gotos \
--enable-optimizations \
--with-lto \
--enable-ipv6 \
--with-dbmliborder=gdbm:ndbm \
--enable-loadable-sqlite-extensions \
--with-tzpath=/usr/share/zoneinfo
make -j$(nproc) EXTRA_CFLAGS="$CFLAGS"
make EXTRA_CFLAGS="$CFLAGS" install
- name: Setup dask directory and venv
register: pysetup
changed_when: false # lol
args:
executable: "/bin/bash"
shell: |
set -eo pipefail
export PATH=$HOME/.local/bin:$PATH
export LD_LIBRARY_PATH=$HOME/.local/lib:$LD_LIBRARY_PATH
if [ ! -d $HOME/dask ]; then
mkdir $HOME/dask
fi
cd $HOME/dask
python3 -m venv dask-venv
. dask-venv/bin/activate
pip3 install --upgrade dask distributed
if [ "{{ leylines_is_server }}" == "no" ]; then
pip3 install --upgrade numpy scipy pandas scikit-image matplotlib
else
pip3 install --upgrade bokeh jupyter-server-proxy
fi
- name: Setup systemd user dir
file:
path: /home/{{ ansible_user }}/.config/systemd/user
mode: 0755
state: directory
- name: Install systemd task
template:
mode: 0644
src: templates/leylines-{% if leylines_is_server == "yes" %}scheduler{% else %}worker{% endif %}.service
dest: /home/{{ ansible_user }}/.config/systemd/user
- name: Enable and start systemd task
systemd:
scope: user
daemon_reload: true
name: leylines-{% if leylines_is_server == "yes" %}scheduler{% else %}worker{% endif %}
enabled: yes
state: restarted

View File

@ -0,0 +1,12 @@
[Unit]
Description=Dask scheduler for leylines
[Service]
Type=simple
Environment=PATH=%h/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Environment=LD_LIBRARY_PATH=%h/.local/lib:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/bin/bash -c 'source dask-venv/bin/activate && exec dask-scheduler --host {{leylines_ip}} --port 31337 --protocol tcp --dashboard-address={{leylines_ip}}:31336 --dashboard --no-show --use-xheaders true'
WorkingDirectory=%h/dask
[Install]
WantedBy=default.target

View File

@ -0,0 +1,13 @@
[Unit]
Description=Dask worker for leylines
[Service]
Type=simple
Environment=PATH=%h/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Environment=LD_LIBRARY_PATH=%h/.local/lib:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/bin/bash -c 'source dask-venv/bin/activate && exec dask-worker --dashboard-address {{leylines_ip}}:31336 --host {{leylines_ip}} --protocol tcp --nthreads 1 --nprocs auto --name {{inventory_hostname}} --local-directory $CACHE_DIRECTORY --resources "{{leylines_resources}}" {{leylines_server_addr}}:31337'
WorkingDirectory=%h/dask
CacheDirectory=leylines-worker
[Install]
WantedBy=default.target

View File

@ -12,7 +12,7 @@ from .database import Database, Node, SERVER_NODE_ID
IFNAME = 'leyline-wg' IFNAME = 'leyline-wg'
DEFAULT_PORT = 31337 DEFAULT_PORT = 31337
API_PORT = 31338 API_PORT = 31338
db = Database("leylines.db") db = Database()
async def client_connected(reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None: async def client_connected(reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None:
@ -67,6 +67,7 @@ def generate_node_config(id: int) -> Optional[str]:
f"PublicKey={seckey_to_pubkey(server_node.seckey)}\n" f"PublicKey={seckey_to_pubkey(server_node.seckey)}\n"
f"AllowedIPs={interface.network}\n" f"AllowedIPs={interface.network}\n"
f"Endpoint={server_node.public_ip}:{DEFAULT_PORT}\n" f"Endpoint={server_node.public_ip}:{DEFAULT_PORT}\n"
f"PersistentKeepalive=25\n"
) )
@ -76,7 +77,7 @@ def add_node_to_wg(wg: WireGuard, node: Node) -> None:
peer = { peer = {
"public_key": seckey_to_pubkey(node.seckey), "public_key": seckey_to_pubkey(node.seckey),
"persistent_keepalive": 60, "persistent_keepalive": 25,
"allowed_ips": [f"{node.ip}/32"] "allowed_ips": [f"{node.ip}/32"]
} }
wg.set(IFNAME, peer=peer) wg.set(IFNAME, peer=peer)

View File

@ -48,7 +48,8 @@ elif args.cmd == "status":
print("SERVER: <not defined. run leylines init>") print("SERVER: <not defined. run leylines init>")
else: else:
print("SERVER:", server_node.name, server_node.ip, server_node.public_ip, print("SERVER:", server_node.name, server_node.ip, server_node.public_ip,
seckey_to_pubkey(server_node.seckey)) seckey_to_pubkey(server_node.seckey),
"<Have SSH Key>" if server_node.ssh_key is not None else "")
for node in nodes: for node in nodes:
if node.id == SERVER_NODE_ID: if node.id == SERVER_NODE_ID:
continue continue

View File

@ -2,11 +2,14 @@ import binascii
import ipaddress import ipaddress
import secrets import secrets
import sqlite3 import sqlite3
import os
from typing import Iterable, List, NamedTuple, Optional, Set from typing import Iterable, List, NamedTuple, Optional, Set
import monocypher import monocypher
DEFAULT_DB_PATH = "/var/lib/leylines/leylines.db" XDG_CONFIG_HOME = os.path.expanduser(os.environ.get("XDG_CONFIG_HOME", "~/.config"))
DEFAULT_DB_PATH = os.environ.get("LEYLINES_DB",
os.path.join(XDG_CONFIG_HOME, "leylines", "leylines.db"))
DEFAULT_SUBNET = "172.16.10.1/24" DEFAULT_SUBNET = "172.16.10.1/24"
SERVER_NODE_ID = 1 SERVER_NODE_ID = 1

View File