tower-of-babel-public/tasks/pleroma.py
2023-02-22 00:01:21 -03:00

184 lines
5.2 KiB
Python

from pyinfra import host
from pyinfra.operations import dnf, server, files, systemd, postgresql
from pyinfra.api import deploy
from pyinfra.facts.server import Which
from .secrets import secrets
from .operations.git import repo
from tasks.elixir import install as install_elixir
from .install_consul_server import template_and_install_systemd
from tasks.rpmfusion import install as install_rpmfusion
from tasks.postgresql import install as install_postgresql
class WithSecrets:
def __init__(self, secrets_fields):
self._secrets_values = {}
for field in secrets_fields:
secret_value = secrets.field(field)
self._secrets_values[field] = secret_value
def __getattr__(self, field):
if field in self._secrets_values:
return self._secrets_values[field]
return getattr(host.data, field)
@deploy("install pleroma")
def install():
install_elixir()
install_rpmfusion()
install_postgresql()
dnf.packages(
name="install system depedencies",
packages=[
"sudo",
"git",
"make",
"automake",
"gcc",
"gcc-c++",
"kernel-devel",
"cmake",
"file-libs",
"file-devel",
"ImageMagick",
"ImageMagick-libs",
"ffmpeg",
"perl-Image-ExifTool",
"erlang-parsetools",
],
)
files.directory(path="/opt/pleroma", present=True, mode=755, recursive=True)
runner_user = "pleroma"
server.group(runner_user)
remote_main_home_path = f"/opt/pleroma"
remote_main_pleroma_path = f"/opt/pleroma/pleroma"
server.user(
user=runner_user,
present=True,
home=remote_main_home_path,
shell="/bin/false",
group=runner_user,
ensure_home=True,
)
# commit pinning is done by having a separate branch on a mirror repo
repo_output = repo(
name="clone pleroma repo",
src="https://gitlab.com/luna/pleroma.git",
dest=remote_main_pleroma_path,
branch="securomoe/develop",
user=runner_user,
group=runner_user,
)
remote_config_path = f"{remote_main_pleroma_path}/config/prod.secret.exs"
with_secrets = WithSecrets(
(
"pleroma_secret_key_base",
"pleroma_db_password",
"pleroma_webpush_public_key",
"pleroma_webpush_private_key",
)
)
config_output = files.template(
"./files/pleroma/prod.secret.exs",
dest=remote_config_path,
user=runner_user,
group=runner_user,
mode=500,
cfg=with_secrets,
)
# download pleroma deps via mix
server.shell(
name="download pleroma deps",
_chdir=remote_main_pleroma_path,
_sudo=True,
_sudo_user=runner_user,
_env={"MIX_ENV": "prod"},
commands=[
"mix local.hex --if-missing --force",
"mix local.rebar --if-missing --force",
"mix deps.get",
],
)
# compile deps and compile pleroma
server.shell(
name="compile pleroma",
_chdir=remote_main_pleroma_path,
_sudo=True,
_sudo_user=runner_user,
_env={"MIX_ENV": "prod"},
commands=["mix deps.compile", "mix compile"],
)
# map the following sql script into pyinfra
# CREATE USER pleroma WITH ENCRYPTED PASSWORD 'aaa' CREATEDB;
# CREATE DATABASE pleroma_dev;
# ALTER DATABASE pleroma_dev OWNER TO pleroma;
# \c pleroma_dev;
# --Extensions made by ecto.migrate that need superuser access
# CREATE EXTENSION IF NOT EXISTS citext;
# CREATE EXTENSION IF NOT EXISTS pg_trgm;
# hacky as we need postgres user but also the fact will fail if postgres
# isnt initialized...
has_postgres = host.get_fact(Which, command="psql")
postgres_kwargs = {}
if has_postgres:
postgres_kwargs = {"_sudo": True, "_sudo_user": "postgres"}
postgresql.role(
role=host.data.pleroma_db_user,
password=with_secrets.pleroma_db_password,
login=True,
**postgres_kwargs,
)
db_result = postgresql.database(
database=host.data.pleroma_db_name,
owner=host.data.pleroma_db_user,
encoding="UTF8",
**postgres_kwargs,
)
# is it possible to configure pg_hba.conf to add md5 auth to local v4/v6
if db_result.changed:
postgresql.sql(
"""
CREATE EXTENSION IF NOT EXISTS citext;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
""",
database=host.data.pleroma_db_name,
**postgres_kwargs,
)
server.shell(
name="migrate database",
_chdir=remote_main_pleroma_path,
_sudo=True,
_sudo_user=runner_user,
_env={"MIX_ENV": "prod"},
commands=["mix ecto.migrate"],
)
template_and_install_systemd(
"./files/pleroma/pleroma.service.j2",
env_dict={
"user": runner_user,
"remote_main_home_path": remote_main_home_path,
"remote_main_pleroma_path": remote_main_pleroma_path,
},
restarted=repo_output.changed or config_output.changed,
)