feat(*): initialize new Snix infrastructure
Co-Authored-By: edef <edef@edef.eu> Co-Authored-by: Ryan Lahfa <raito@lix.systems> Change-Id: Ica1cda177a236814de900f50a8a61d288f58f519
This commit is contained in:
parent
067eff3427
commit
a52ea3675c
124 changed files with 27723 additions and 1631 deletions
305
ops/modules/forgejo.nix
Normal file
305
ops/modules/forgejo.nix
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
#
|
||||
# Forgejo Git Backend taken from Lix configuration.
|
||||
# Thanks to all the Lix core developers for this!
|
||||
# vim: et:ts=2:sw=2:
|
||||
#
|
||||
{ depot, pkgs, lib, config, ... }:
|
||||
let
|
||||
cfg = config.services.depot.forgejo;
|
||||
inherit (lib) types mkEnableOption mkOption mkIf;
|
||||
emojo =
|
||||
let
|
||||
handlePostFetch = ''
|
||||
for i in $out/*_256.png; do
|
||||
mv $i $(echo $i | sed -E 's/_256//g')
|
||||
done
|
||||
'';
|
||||
drgn = pkgs.fetchzip {
|
||||
url = "https://volpeon.ink/emojis/drgn/drgn.zip";
|
||||
stripRoot = false;
|
||||
sha256 = "sha256-/2MpbxMJC92a4YhwG5rP6TsDC/q1Ng5fFq4xe2cBrrM=";
|
||||
postFetch = handlePostFetch;
|
||||
};
|
||||
neocat = pkgs.fetchzip {
|
||||
url = "https://volpeon.ink/emojis/neocat/neocat.zip";
|
||||
stripRoot = false;
|
||||
sha256 = "sha256-Irh6Mv6ICDkaaenIFf8Cm1AFkdZy0gRVbXqgnwpk3Qw=";
|
||||
postFetch = handlePostFetch;
|
||||
};
|
||||
neofox = pkgs.fetchzip {
|
||||
url = "https://volpeon.ink/emojis/neofox/neofox.zip";
|
||||
stripRoot = false;
|
||||
sha256 = "sha256-FSTVYP/Bt25JfLr/Ny1g9oI9aAvAYLYhct31j3XRXYc=";
|
||||
postFetch = handlePostFetch;
|
||||
};
|
||||
dragon = pkgs.fetchFromGitHub {
|
||||
owner = "chr-1x";
|
||||
repo = "dragn-emoji";
|
||||
rev = "969543d9918ce2f0794ccd1e41b276d1ab22f0d5";
|
||||
sha256 = "sha256-+40e9nKaIpQYZUiXh3Qe5jp2uvRbAQYDdXMGLEWHJio=";
|
||||
postFetch = ''
|
||||
for i in $out/*.svg; do
|
||||
${pkgs.librsvg}/bin/rsvg-convert -h 256 $i > a.png;
|
||||
mv a.png $(echo $i | sed -E "s/svg$/png/");
|
||||
rm $i
|
||||
done
|
||||
${pkgs.oxipng}/bin/oxipng -o max $out/*.png
|
||||
'';
|
||||
};
|
||||
in
|
||||
pkgs.symlinkJoin { name = "emojo"; paths = [ drgn neocat neofox dragon ]; };
|
||||
in
|
||||
{
|
||||
options.services.depot.forgejo = {
|
||||
enable = mkEnableOption "Forgejo Forge";
|
||||
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# we have to use redis since we apparently have a "large instance" which
|
||||
# "leaks hilarious amounts of memory if you use the default configuration"
|
||||
services.redis = {
|
||||
package = pkgs.valkey;
|
||||
|
||||
vmOverCommit = true;
|
||||
servers.forgejo = {
|
||||
enable = true;
|
||||
# disable persistence, so when redis inevitably OOMs due to
|
||||
# forgejo throwing to much in it, we don't restore the dataset
|
||||
# that caused the OOM, breaking the restart loop.
|
||||
save = [ ];
|
||||
};
|
||||
};
|
||||
systemd.services.redis-forgejo.serviceConfig = {
|
||||
Restart = "always";
|
||||
};
|
||||
systemd.services.forgejo = {
|
||||
after = [ "redis-forgejo.service" ];
|
||||
wants = [ "redis-forgejo.service" ];
|
||||
};
|
||||
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
|
||||
package = pkgs.forgejo.overrideAttrs (old: {
|
||||
patches = old.patches ++ (with depot.third_party.lix_forgejo.patches; [
|
||||
upstream_link
|
||||
signin_redirect
|
||||
api_dont_notify
|
||||
forgejo_is_now_gerrit_native
|
||||
forgejo_knows_about_gerrit
|
||||
]);
|
||||
});
|
||||
|
||||
# General settings.
|
||||
lfs.enable = true;
|
||||
|
||||
# Make our checkout paths more in line with expectations by calling our user "git".
|
||||
user = "git";
|
||||
group = "git";
|
||||
|
||||
# Secret mail config.
|
||||
# mailerPasswordFile = config.age.secrets.forgejoSmtpSecret.path;
|
||||
|
||||
# Server and database config.
|
||||
settings = {
|
||||
|
||||
# Sets the name in the titlebar, mostly.
|
||||
DEFAULT.APP_NAME = "Snix Project";
|
||||
|
||||
# Settings for how we serve things.
|
||||
server = {
|
||||
DOMAIN = cfg.domain;
|
||||
PROTOCOL = "http";
|
||||
ENABLE_ACME = true;
|
||||
ACME_ACCEPTTOS = true;
|
||||
ACME_EMAIL = "acme@snix.dev";
|
||||
LANDING_PAGE = "explore";
|
||||
ROOT_URL = "https://${cfg.domain}";
|
||||
|
||||
# open a server on localhost:6060 with pprof data
|
||||
# !! note: the documentation says that this causes forgejo serv to dump
|
||||
# random files in PPROF_DATA_PATH.
|
||||
# This documentation is wrong, ENABLE_PPROF only affects forgejo web,
|
||||
# and forgejo serv requires a --enable-pprof arg to do that. But it's
|
||||
# not causing perf problems right now so we don't care about that
|
||||
# anyway.
|
||||
ENABLE_PPROF = true;
|
||||
};
|
||||
|
||||
# openid is not used in our setup
|
||||
openid = {
|
||||
ENABLE_OPENID_SIGNIN = false;
|
||||
ENABLE_OPENID_SIGNUP = false;
|
||||
};
|
||||
|
||||
oauth2_client = {
|
||||
ENABLE_AUTO_REGISTRATION = true;
|
||||
REGISTER_EMAIL_CONFIRM = false;
|
||||
ACCOUNT_LINKING = "login";
|
||||
USERNAME = "nickname";
|
||||
OPENID_CONNECT_SCOPES = "email profile";
|
||||
};
|
||||
|
||||
cache = {
|
||||
ADAPTER = "redis";
|
||||
HOST = "redis+socket://${config.services.redis.servers.forgejo.unixSocket}";
|
||||
};
|
||||
"cache.last_commit" = {
|
||||
ITEM_TTL = "24h"; # from default 8760h (1 year)
|
||||
};
|
||||
|
||||
service = {
|
||||
# We previously ran with "disable registration" which doesn't actually
|
||||
# do anything to the OAuth login form, just the link account form. We
|
||||
# suspect that if the account has all the required metadata like email
|
||||
# to register cleanly, it doesn't use DISABLE_REGISTRATION at all.
|
||||
#
|
||||
# However this was probably relying on forgejo bugs, let's set it
|
||||
# unambiguously.
|
||||
DISABLE_REGISTRATION = false;
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
||||
|
||||
#REQUIRE_SIGNIN_VIEW = false;
|
||||
ENABLE_NOTIFY_MAIL = true;
|
||||
|
||||
# Don't add org members as watchers on all repos, or indeed on new
|
||||
# repos either.
|
||||
#
|
||||
# See: https://github.com/bmackinney/gitea/commit/a9eb2167536cfa8f7b7a23f73e11c8edf5dc0dc0
|
||||
AUTO_WATCH_NEW_REPOS = false;
|
||||
};
|
||||
|
||||
session = {
|
||||
# Put sessions in the DB so they survive restarts
|
||||
PROVIDER = "db";
|
||||
PROVIDER_CONFIG = "";
|
||||
|
||||
# Cookie only works over https
|
||||
COOKIE_SECURE = true;
|
||||
|
||||
# 5 day sessions
|
||||
SESSION_LIFE_TIME = 86400 * 5;
|
||||
};
|
||||
|
||||
# Careful with these!
|
||||
security = {
|
||||
# Don't allow access to the install page; manage exclusively via Nix.
|
||||
INSTALL_LOCK = true;
|
||||
|
||||
# Allow internal users with the right permissions to set up Git hooks.
|
||||
DISABLE_GIT_HOOKS = false;
|
||||
};
|
||||
|
||||
# Note: PASSWD is set by NixOS up.
|
||||
# mailer = {
|
||||
# ENABLED = true;
|
||||
# PROTOCOL = "smtps";
|
||||
# SMTP_ADDR = "";
|
||||
# SMTP_PORT = 465;
|
||||
# USER = "";
|
||||
# FROM = "";
|
||||
# };
|
||||
|
||||
ui = {
|
||||
# Add the used emojis from https://volpeon.ink/emojis/ as well as https://github.com/chr-1x/dragn-emoji
|
||||
CUSTOM_EMOJIS = builtins.readFile depot.third_party.lix_forgejo.custom_emojis;
|
||||
# Normal reaction emoji people always need.
|
||||
REACTIONS = "+1, -1, laugh, confused, heart, hooray, eyes, melting_face, neocat_scream_scared, neofox_scream_scared, drgn_scream, neocat_heart, neofox_heart, drgn_heart, neocat_floof_reach, neocat_pleading, neofox_floof_reach, neofox_pleading, drgn_pleading";
|
||||
|
||||
# To protect privacy of users.
|
||||
SHOW_USER_EMAIL = false;
|
||||
};
|
||||
|
||||
# No runners are configured.
|
||||
actions.ENABLED = false;
|
||||
};
|
||||
|
||||
# Use a MySQL database, which we enable below.
|
||||
database = {
|
||||
type = "mysql";
|
||||
user = config.services.forgejo.user;
|
||||
};
|
||||
};
|
||||
|
||||
# Inspired from Gerrit's way of doing things (from Lix).
|
||||
# Before starting Forgejo, we will re-converge any required information.
|
||||
# TODO: learn how to use update-oauth as well?
|
||||
systemd.services.forgejo-keys = {
|
||||
enable = true;
|
||||
|
||||
before = [ "forgejo.service" ];
|
||||
wantedBy = [ "forgejo.service" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "true";
|
||||
WorkingDirectory = "/var/lib/forgejo";
|
||||
User = "git";
|
||||
Group = "git";
|
||||
Environment = [
|
||||
"FORGEJO_WORK_DIR=/var/lib/forgejo"
|
||||
];
|
||||
};
|
||||
|
||||
path = [ config.services.forgejo.package ];
|
||||
|
||||
script = ''
|
||||
NAME="Snix project"
|
||||
PROVIDER="openidConnect"
|
||||
CLIENT_ID="forgejo"
|
||||
CLIENT_SECRET=$(cat ${config.age.secrets.forgejo-oauth-secret.path})
|
||||
DISCOVERY_URL="https://auth.snix.dev/realms/snix-project/.well-known/openid-configuration"
|
||||
SCOPES=("openid" "profile" "email")
|
||||
|
||||
# Check if the OAuth2 source already exists
|
||||
if gitea admin auth list | grep -q "$NAME"; then
|
||||
echo "OAuth2 source '$NAME' already exists. Skipping creation."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Add the OAuth2 source
|
||||
gitea admin auth add-oauth \
|
||||
--name "$NAME" \
|
||||
--provider "$PROVIDER" \
|
||||
--key "$CLIENT_ID" \
|
||||
--secret "$CLIENT_SECRET" \
|
||||
--auto-discover-url "$DISCOVERY_URL" \
|
||||
$(printf -- '--scopes "%s" ' "''${SCOPES[@]}") \
|
||||
--icon-url "$ICON_URL"
|
||||
|
||||
echo "OAuth2 source '$NAME' added successfully."
|
||||
'';
|
||||
};
|
||||
|
||||
# Create our user an group. This is necessary for any name that's
|
||||
# not "forgejo", due to the nix module config.
|
||||
users.users."${config.services.forgejo.group}" = {
|
||||
description = "Gitea Service";
|
||||
useDefaultShell = true;
|
||||
|
||||
home = config.services.forgejo.stateDir;
|
||||
group = config.services.forgejo.group;
|
||||
|
||||
# redis instance runs as redis-forgejo, so we need to be in that group to be able to connect
|
||||
extraGroups = [ "redis-forgejo" ];
|
||||
|
||||
isSystemUser = true;
|
||||
};
|
||||
users.groups."${config.services.forgejo.group}" = { };
|
||||
|
||||
# Enable the mysql server, which will provide the forgejo backing store.
|
||||
services.mysql.enable = lib.mkForce true;
|
||||
services.mysql.package = lib.mkForce pkgs.mariadb;
|
||||
|
||||
systemd.tmpfiles.rules = let cfg = config.services.forgejo; in [
|
||||
"d '${cfg.customDir}/public/assets' 0750 ${cfg.user} ${cfg.group} - -"
|
||||
"d '${cfg.customDir}/public/assets/img' 0750 ${cfg.user} ${cfg.group} - -"
|
||||
"L+ '${cfg.customDir}/public/assets/img/emoji' - - - - ${emojo}"
|
||||
];
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue