mirror of
https://github.com/goauthentik/authentik.git
synced 2026-06-17 19:09:11 +03:00
ca24943fb0
Agent-thread: https://sdko.org/internal/threads/019e93bf-9dbb-7ba2-9375-cb430876c101 A7k-product: product A7k-product-repo: 1 Co-authored-by: Agent <agent@svc.sdko.net>
191 lines
5.1 KiB
Python
191 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""Generate the Quadlet unit files under ``lifecycle/quadlet/``.
|
|
|
|
Mirrors ``scripts/generate_compose.py``: the authentik image tag is pinned to
|
|
``authentik_version()`` so ``make bump`` rewrites these unit files on every
|
|
release in lockstep with ``lifecycle/container/compose.yml``.
|
|
|
|
Quadlet does not expand ``${VAR}`` in ``Image=``, so the tag is written
|
|
literally rather than wrapped in a compose-style ``${AUTHENTIK_TAG:-...}``
|
|
fallback.
|
|
|
|
Two unit sets are emitted:
|
|
|
|
* ``lifecycle/quadlet/`` — rootful, dropped into ``/etc/containers/systemd/``.
|
|
* ``lifecycle/quadlet/rootless/`` — rootless, dropped into
|
|
``~/.config/containers/systemd/``. Uses systemd specifiers ``%h`` (home) and
|
|
``%t`` (``$XDG_RUNTIME_DIR``) so a single file works for any rootless user.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
|
|
from packaging.version import parse
|
|
|
|
from authentik import authentik_version
|
|
|
|
version = authentik_version()
|
|
version_parsed = parse(version)
|
|
version_split = version_parsed.base_version.split(".")
|
|
# Mirror generate_compose.py: for an rc on a patch release (e.g. 2026.2.2-rc1)
|
|
# fall back to the previous released patch so the pinned tag is always pullable.
|
|
if version_parsed.is_prerelease and version_split[-1] != "0":
|
|
previous_patch = int(version_split[-1]) - 1
|
|
version_split[-1] = str(previous_patch)
|
|
version = ".".join(version_split)
|
|
|
|
AUTHENTIK_IMAGE = f"ghcr.io/goauthentik/server:{version}"
|
|
POSTGRES_IMAGE = "docker.io/library/postgres:16-alpine"
|
|
|
|
OUTPUT_DIR = Path("lifecycle/quadlet")
|
|
ROOTLESS_DIR = OUTPUT_DIR / "rootless"
|
|
|
|
POD = """[Unit]
|
|
Description=authentik
|
|
|
|
[Pod]
|
|
PodName=authentik
|
|
PublishPort=9000:9000
|
|
PublishPort=9443:9443
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
"""
|
|
|
|
DATABASE_VOLUME = """[Volume]
|
|
VolumeName=authentik-database
|
|
"""
|
|
|
|
|
|
def postgresql_container(env_file: str) -> str:
|
|
return f"""[Unit]
|
|
Description=authentik PostgreSQL
|
|
|
|
[Container]
|
|
ContainerName=authentik-postgresql
|
|
Image={POSTGRES_IMAGE}
|
|
AutoUpdate=registry
|
|
Pod=authentik.pod
|
|
Volume=authentik-database.volume:/var/lib/postgresql/data
|
|
EnvironmentFile={env_file}
|
|
Environment=POSTGRES_DB=authentik
|
|
Environment=POSTGRES_USER=authentik
|
|
HealthCmd=pg_isready -d authentik -U authentik
|
|
HealthInterval=30s
|
|
HealthStartPeriod=20s
|
|
HealthTimeout=5s
|
|
HealthRetries=5
|
|
|
|
[Service]
|
|
Restart=always
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
"""
|
|
|
|
|
|
def server_container(env_file: str, data_dir: str) -> str:
|
|
return f"""[Unit]
|
|
Description=authentik server
|
|
Requires=authentik-postgresql.container
|
|
After=authentik-postgresql.container
|
|
|
|
[Container]
|
|
ContainerName=authentik-server
|
|
Image={AUTHENTIK_IMAGE}
|
|
AutoUpdate=registry
|
|
Pod=authentik.pod
|
|
Exec=server
|
|
EnvironmentFile={env_file}
|
|
Environment=AUTHENTIK_POSTGRESQL__HOST=localhost
|
|
Environment=AUTHENTIK_POSTGRESQL__NAME=authentik
|
|
Environment=AUTHENTIK_POSTGRESQL__USER=authentik
|
|
Volume={data_dir}/data:/data:Z
|
|
Volume={data_dir}/custom-templates:/templates:Z
|
|
PodmanArgs=--shm-size=512m
|
|
|
|
[Service]
|
|
Restart=always
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
"""
|
|
|
|
|
|
def worker_container(env_file: str, data_dir: str, podman_sock_dir: str) -> str:
|
|
return f"""[Unit]
|
|
Description=authentik worker
|
|
Requires=authentik-postgresql.container
|
|
After=authentik-postgresql.container
|
|
|
|
[Container]
|
|
ContainerName=authentik-worker
|
|
Image={AUTHENTIK_IMAGE}
|
|
AutoUpdate=registry
|
|
Pod=authentik.pod
|
|
Exec=worker
|
|
User=0:0
|
|
EnvironmentFile={env_file}
|
|
Environment=AUTHENTIK_POSTGRESQL__HOST=localhost
|
|
Environment=AUTHENTIK_POSTGRESQL__NAME=authentik
|
|
Environment=AUTHENTIK_POSTGRESQL__USER=authentik
|
|
Environment=AUTHENTIK_LISTEN__HTTP=0.0.0.0:9001
|
|
Environment=AUTHENTIK_LISTEN__METRICS=0.0.0.0:9301
|
|
Volume={podman_sock_dir}/podman/podman.sock:/run/podman/podman.sock:Z
|
|
Volume={data_dir}/data:/data:Z
|
|
Volume={data_dir}/certs:/certs:Z
|
|
Volume={data_dir}/custom-templates:/templates:Z
|
|
PodmanArgs=--shm-size=512m
|
|
|
|
[Service]
|
|
Restart=always
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
"""
|
|
|
|
|
|
ROOTFUL = {
|
|
"authentik.pod": POD,
|
|
"authentik-database.volume": DATABASE_VOLUME,
|
|
"authentik-postgresql.container": postgresql_container(
|
|
env_file="/etc/authentik/authentik.env",
|
|
),
|
|
"authentik-server.container": server_container(
|
|
env_file="/etc/authentik/authentik.env",
|
|
data_dir="/var/lib/authentik",
|
|
),
|
|
"authentik-worker.container": worker_container(
|
|
env_file="/etc/authentik/authentik.env",
|
|
data_dir="/var/lib/authentik",
|
|
podman_sock_dir="/run",
|
|
),
|
|
}
|
|
|
|
ROOTLESS = {
|
|
"authentik.pod": POD,
|
|
"authentik-database.volume": DATABASE_VOLUME,
|
|
"authentik-postgresql.container": postgresql_container(
|
|
env_file="%h/.config/authentik/authentik.env",
|
|
),
|
|
"authentik-server.container": server_container(
|
|
env_file="%h/.config/authentik/authentik.env",
|
|
data_dir="%h/.local/share/authentik",
|
|
),
|
|
"authentik-worker.container": worker_container(
|
|
env_file="%h/.config/authentik/authentik.env",
|
|
data_dir="%h/.local/share/authentik",
|
|
podman_sock_dir="%t",
|
|
),
|
|
}
|
|
|
|
|
|
def write(target: Path, units: dict[str, str]) -> None:
|
|
target.mkdir(parents=True, exist_ok=True)
|
|
for name, body in units.items():
|
|
(target / name).write_text(body)
|
|
|
|
|
|
write(OUTPUT_DIR, ROOTFUL)
|
|
write(ROOTLESS_DIR, ROOTLESS)
|