ansible
This commit is contained in:
parent
dfb2b9d956
commit
7aa8886b07
|
@ -0,0 +1,10 @@
|
|||
.venv
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
__pycache__
|
||||
*.egg-info
|
||||
.env
|
||||
.vimrc
|
||||
.ycm_extra_conf.py
|
||||
*.db
|
|
@ -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")
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -12,7 +12,7 @@ from .database import Database, Node, SERVER_NODE_ID
|
|||
IFNAME = 'leyline-wg'
|
||||
DEFAULT_PORT = 31337
|
||||
API_PORT = 31338
|
||||
db = Database("leylines.db")
|
||||
db = Database()
|
||||
|
||||
|
||||
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"AllowedIPs={interface.network}\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 = {
|
||||
"public_key": seckey_to_pubkey(node.seckey),
|
||||
"persistent_keepalive": 60,
|
||||
"persistent_keepalive": 25,
|
||||
"allowed_ips": [f"{node.ip}/32"]
|
||||
}
|
||||
wg.set(IFNAME, peer=peer)
|
||||
|
|
|
@ -48,7 +48,8 @@ elif args.cmd == "status":
|
|||
print("SERVER: <not defined. run leylines init>")
|
||||
else:
|
||||
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:
|
||||
if node.id == SERVER_NODE_ID:
|
||||
continue
|
||||
|
|
|
@ -2,11 +2,14 @@ import binascii
|
|||
import ipaddress
|
||||
import secrets
|
||||
import sqlite3
|
||||
import os
|
||||
from typing import Iterable, List, NamedTuple, Optional, Set
|
||||
|
||||
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"
|
||||
SERVER_NODE_ID = 1
|
||||
|
||||
|
|
Loading…
Reference in New Issue