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, )