mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 19:42:37 +02:00
212 lines
5.5 KiB
Python
212 lines
5.5 KiB
Python
import os
|
|
import sys
|
|
from io import StringIO
|
|
|
|
import minicli
|
|
from usine import chown, config, connect, env, exists, mkdir, put, run, sudo, template
|
|
|
|
|
|
@minicli.cli
|
|
def pip(*command):
|
|
"""Run a pip command on the remote server.
|
|
"""
|
|
with sudo(user="copanier"):
|
|
run(f"/srv/copanier/venv/bin/pip {' '.join(command)}")
|
|
|
|
|
|
@minicli.cli
|
|
def system():
|
|
"""Setup the system."""
|
|
with sudo():
|
|
run("apt update")
|
|
run(
|
|
"apt install -y nginx git software-properties-common gcc "
|
|
"python3.7 python3.7-dev python3.7-venv pkg-config"
|
|
)
|
|
mkdir("/srv/copanier/logs")
|
|
run("useradd -N copanier -d /srv/copanier/ || exit 0")
|
|
chown("copanier:users", "/srv/copanier/")
|
|
run("chsh -s /bin/bash copanier")
|
|
|
|
|
|
@minicli.cli
|
|
def venv():
|
|
"""Setup the python virtualenv."""
|
|
path = "/srv/copanier/venv/"
|
|
if not exists(path):
|
|
with sudo(user="copanier"):
|
|
run(f"python3.7 -m venv {path}")
|
|
pip("install pip -U")
|
|
|
|
|
|
@minicli.cli
|
|
def http():
|
|
"""Configure Nginx and letsencrypt."""
|
|
# When we'll have a domain.
|
|
put("remote/nginx-snippet.conf", "/etc/nginx/snippets/copanier.conf")
|
|
put("remote/letsencrypt.conf", "/etc/nginx/snippets/letsencrypt.conf")
|
|
put("remote/ssl.conf", "/etc/nginx/snippets/ssl.conf")
|
|
domain = config.domains[0]
|
|
pempath = f"/etc/letsencrypt/live/{domain}/fullchain.pem"
|
|
with sudo():
|
|
if exists(pempath):
|
|
print(f"{pempath} found, using https configuration")
|
|
conf = template(
|
|
"remote/nginx-https.conf",
|
|
domains=" ".join(config.domains),
|
|
domain=domain,
|
|
)
|
|
else:
|
|
print(f"{pempath} not found, using http configuration")
|
|
# Before letsencrypt.
|
|
conf = template(
|
|
"remote/nginx-http.conf",
|
|
domains=" ".join(config.domains),
|
|
domain=domain,
|
|
)
|
|
put(conf, "/etc/nginx/sites-enabled/copanier.conf")
|
|
restart("nginx")
|
|
|
|
|
|
@minicli.cli
|
|
def letsencrypt():
|
|
"""Configure letsencrypt."""
|
|
with sudo():
|
|
run("add-apt-repository --yes ppa:certbot/certbot")
|
|
run("apt update")
|
|
run("apt install -y certbot")
|
|
mkdir("/var/www/letsencrypt/.well-known/acme-challenge")
|
|
domains = ",".join(list(config.domains))
|
|
certbot_conf = template("remote/certbot.ini", domains=domains)
|
|
put(certbot_conf, "/var/www/certbot.ini")
|
|
run("certbot certonly -c /var/www/certbot.ini --non-interactive " "--agree-tos")
|
|
|
|
|
|
@minicli.cli
|
|
def bootstrap():
|
|
"""Bootstrap the system."""
|
|
system()
|
|
venv()
|
|
service()
|
|
http()
|
|
|
|
|
|
@minicli.cli
|
|
def cli(command):
|
|
"""Run the copanier executable on the remote server.
|
|
"""
|
|
with sudo(user="copanier"), env(COPANIER_DATA_ROOT="/srv/copanier/data"):
|
|
run(f"/srv/copanier/venv/bin/copanier {command}")
|
|
|
|
|
|
@minicli.cli
|
|
def service():
|
|
"""Deploy/update the copanier systemd service."""
|
|
with sudo():
|
|
put("remote/copanier.service", "/etc/systemd/system/copanier.service")
|
|
systemctl("enable copanier.service")
|
|
|
|
|
|
@minicli.cli
|
|
def deploy():
|
|
"""Deploy/update the copanier code base."""
|
|
with sudo(user="copanier"):
|
|
put("remote/gunicorn.conf", "/srv/copanier/gunicorn.conf")
|
|
pip("install gunicorn")
|
|
base = "https://framagit.org/ybon/copanier"
|
|
pip(f"install -U git+{base}")
|
|
restart()
|
|
|
|
|
|
@minicli.cli
|
|
def restart(*services):
|
|
"""Restart the systemd services."""
|
|
services = services or ["copanier", "nginx"]
|
|
with sudo():
|
|
systemctl(f"restart {' '.join(services)}")
|
|
|
|
|
|
@minicli.cli
|
|
def systemctl(*args):
|
|
"""Run a systemctl command on the remote server.
|
|
|
|
:command: the systemctl command to run.
|
|
"""
|
|
run(f'systemctl {" ".join(args)}')
|
|
|
|
|
|
@minicli.cli
|
|
def logs(lines=50):
|
|
"""Display the copanier logs.
|
|
|
|
:lines: number of lines to retrieve
|
|
"""
|
|
with sudo():
|
|
run(f"journalctl --lines {lines} --unit copanier --follow")
|
|
|
|
|
|
@minicli.cli
|
|
def status():
|
|
"""Get the services status."""
|
|
systemctl("status nginx copanier")
|
|
|
|
|
|
@minicli.cli
|
|
def access_logs():
|
|
"""See the nginx access logs."""
|
|
with sudo():
|
|
run("tail -F /var/log/nginx/access.log")
|
|
|
|
|
|
@minicli.cli
|
|
def error_logs():
|
|
"""See the nginx error logs."""
|
|
with sudo():
|
|
run("tail -F /var/log/nginx/error.log")
|
|
|
|
|
|
@minicli.cli
|
|
def data_logs():
|
|
"""See the app data logs."""
|
|
with sudo():
|
|
run("tail -F /srv/copanier/logs/copanier-requests.log")
|
|
|
|
|
|
@minicli.cli
|
|
def upload_env():
|
|
"""Upload environment vars to the server.
|
|
|
|
Use those to deal with info not commitable.
|
|
"""
|
|
vars_ = {
|
|
"COPANIER_DATA_ROOT": "/srv/copanier/data",
|
|
"COPANIER_LOG_ROOT": "/srv/copanier/logs",
|
|
"COPANIER_SEND_EMAILS": "1",
|
|
"COPANIER_SMTP_PASSWORD": None,
|
|
"COPANIER_SMTP_LOGIN": None,
|
|
"COPANIER_STAFF": None,
|
|
}
|
|
content = ""
|
|
table = str.maketrans({'"': r"\""})
|
|
for key, value in vars_.items():
|
|
value = value or os.environ[key]
|
|
try:
|
|
content += f'{key}="{str(value).translate(table)}"\n'
|
|
except KeyError:
|
|
sys.exit(f"The {key} environment variable does not exist.")
|
|
path = "/srv/copanier/env"
|
|
if exists(path):
|
|
run(f"cat {path}")
|
|
put(StringIO(content), path)
|
|
if exists(path):
|
|
run(f"cat {path}")
|
|
|
|
|
|
@minicli.wrap
|
|
def wrapper(hostname, configpath):
|
|
with connect(hostname=hostname, configpath=configpath):
|
|
yield
|
|
|
|
|
|
if __name__ == "__main__":
|
|
minicli.run(hostname="qa", configpath="remote/config.yml")
|