Compare commits

...

32 commits

Author SHA1 Message Date
Jean-Marie 'Histausse' Mineau d3e61d3b89
add module for node exporter 2025-02-23 13:08:05 +01:00
Jean-Marie 'Histausse' Mineau 6b24432c10
remove custom theme 2024-07-11 23:50:34 +02:00
Jean-Marie 'Histausse' Mineau 2a49b7afd8
fix typo 2024-02-12 23:35:26 +01:00
Jean-Marie 'Histausse' Mineau 0727843360
create group 2024-02-12 23:34:14 +01:00
Jean-Marie 'Histausse' Mineau e75cce74b8
fix typo 2024-02-12 23:33:08 +01:00
Jean-Marie 'Histausse' Mineau c1a5ba6a20
create user 2024-02-12 23:32:11 +01:00
Jean-Marie 'Histausse' Mineau 670404c5a1
rename forgejo user to 'git' 2024-02-12 23:24:00 +01:00
Jean-Marie 'Histausse' Mineau 3d62d3a0e5
fix scheme 2024-02-12 23:08:04 +01:00
Jean-Marie 'Histausse' Mineau dd1495ebf4
fix token file 2024-02-12 23:04:12 +01:00
Jean-Marie 'Histausse' Mineau e108f7410c
fix typo 2024-02-12 23:00:04 +01:00
Jean-Marie 'Histausse' Mineau e1f483126c
fix typo 2024-02-12 22:57:56 +01:00
Jean-Marie 'Histausse' Mineau 63a5f9973e
fix typo 2024-02-12 22:57:09 +01:00
Jean-Marie 'Histausse' Mineau 1f86334c19
fix typo 2024-02-12 22:56:22 +01:00
Jean-Marie 'Histausse' Mineau 0f55fc4762
fix typo 2024-02-12 22:54:53 +01:00
Jean-Marie 'Histausse' Mineau e271cb5954
add forgejo runner 2024-02-12 22:49:23 +01:00
Jean-Marie 'Histausse' Mineau a8ed56ac64
add instruction for migration from gitea 2024-02-10 20:42:50 +01:00
Jean-Marie 'Histausse' Mineau 8416ffacad
update var name 2024-02-10 19:05:52 +01:00
Jean-Marie 'Histausse' Mineau 64c8eb3a95
add push to create 2024-02-10 18:34:12 +01:00
Jean-Marie 'Histausse' Mineau 296af70aab
Merge branch 'master' of git.pains-perdus.fr:Pains-Perdus/nixos-modules 2024-02-10 18:32:21 +01:00
Jean-Marie 'Histausse' Mineau 41ee11094f
add config for forgejo 2024-02-10 18:31:53 +01:00
Vi Retault b71ced5fbf updated upstream hash 2023-10-03 16:56:18 -04:00
Vi Retault f72e74d4ae updated upstream hash 2023-10-03 16:32:12 -04:00
Jean-Marie 'Histausse' Mineau 60f8eab05a
add push to create 2023-08-19 23:51:07 +02:00
Histausse 7a2d7a0e75 add hostname resolution 2023-05-27 23:40:57 +02:00
Histausse 42ba7665f2 remove max body size for registry 2023-05-21 01:08:36 +02:00
Histausse 952e70dcd8 well I think not 2023-05-21 00:41:09 +02:00
Histausse 257e36d819 in fact, yes it is 2023-05-21 00:27:13 +02:00
Histausse 3fcc08557e not necessary? 2023-05-21 00:22:15 +02:00
Histausse 2f7d5273d7 enable packages (?) 2023-05-21 00:02:43 +02:00
Histausse bc70008a90 add swap size param 2023-05-07 00:11:54 +02:00
Histausse 2a9fcd451e remove user config from modules 2023-05-06 23:34:55 +02:00
Histausse 41dfde7216 add config for woodpeecker 2023-05-06 22:36:46 +02:00
6 changed files with 376 additions and 8 deletions

View file

@ -19,13 +19,19 @@ in {
example = "example@example.com";
description = "Email of the admin, use for ACME and stuff";
};
swapSize = mkOption {
type = types.int;
default = 1024;
example = 2048;
description = "Size of the swap file";
};
};
config = {
swapDevices = [
{
device = "/swapfile";
priority = 0;
size = 1024;
size = cfg.swapSize;
}
];
@ -44,13 +50,6 @@ in {
keyMap = "fr";
};
users.users.histausse = {
isNormalUser = true;
extraGroups = [
"wheel"
];
};
environment.systemPackages = with pkgs; [
vim
git

41
pp-forgejo-runner.nix Normal file
View file

@ -0,0 +1,41 @@
{ lib, config, pkgs, ... }:
with lib;
let
cfgBase = config.base;
cfg = config.services.ppForgejoRunner;
in
{
options.services.ppForgejoRunner = {
forgeUrl = mkOption {
type = types.str;
default = "https://git.${cfgBase.domainName}";
example = "https://git.example.com";
description = "The domain of the forgejo server";
};
runnerName = mkOption {
type = types.str;
default = "${cfgBase.name}.${cfgBase.domainName}";
example = "git-runner.example.com";
description = "The name of the runner";
};
tokenFile = mkOption {
type = types.str;
default = "/etc/forgejo_runner_token";
description = "The file containing the token to access forgejo. Be sure to secure it. The content of the file must be of the form TOKEN=<token>";
};
};
config = {
virtualisation.podman.enable = true;
services.gitea-actions-runner.package = pkgs.forgejo-actions-runner;
services.gitea-actions-runner.instances."${cfg.runnerName}" = {
enable = true;
name = cfg.runnerName;
url = cfg.forgeUrl;
tokenFile = cfg.tokenFile;
labels = [
"debian:docker://debian:bookworm"
];
};
};
}

129
pp-forgejo.nix Normal file
View file

@ -0,0 +1,129 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfgBase = config.base;
cfg = config.services.ppForgejo;
in
{
options.services.ppForgejo = {
domain = mkOption {
type = types.str;
default = "git.${cfgBase.domainName}";
example = "git.example.com";
description = "The domain of the server";
};
openIdEnabled = mkOption {
type = types.bool;
default = false;
description = "If OpenId provider is setup and should be used exclusively.";
};
openIdClientName = mkOption {
type = types.str;
default = "";
description = "The name (id) of the openId client to use exclusively.";
};
dbPasswordFile = mkOption {
type = types.str;
default = "/etc/forgejo_db_pwd";
description = "The file containing the database password. Be sure to secure it.";
};
actionsEnabled = mkOption {
type = types.bool;
default = false;
description = "Enable the use of actions";
};
};
config = {
services.forgejo.settings.DEFAULT.APP_NAME = "git";
services.forgejo.stateDir = "/var/lib/forgejo"; # default value, /var/lib/gitea in gitea, move it before migration!
# carefull to change ownership from gitea to forgejo
# and to move /var/lib/forgejo/data/gitea.db to /var/lib/forgejo/data/forgejo.db
services.forgejo.enable = true;
services.forgejo.settings.server.ROOT_URL = "https://${cfg.domain}/";
services.forgejo.settings.session.COOKIE_SECURE = lib.mkForce true; # Why do I need to override this???
services.forgejo.user = "git";
users.users.git = {
home = config.services.forgejo.stateDir;
useDefaultShell = true;
isSystemUser = true;
group = "git";
};
users.groups.git = {};
# If true, openid users cannot create new account
#services.forgejo.settings.service.DISABLE_REGISTRATION = lib.mkForce (!cfg.openIdEnabled);
services.forgejo.settings.service.DISABLE_REGISTRATION = lib.mkForce false;
services.forgejo.settings.service.ALLOW_ONLY_EXTERNAL_REGISTRATION = cfg.openIdEnabled;
services.forgejo.lfs.enable = true;
services.forgejo.settings.server.DOMAIN = cfg.domain;
# services.forgejo.database.type = "postgres"; # Default is sqlite3, probably better for a small instance
services.forgejo.database.passwordFile = cfg.dbPasswordFile;
services.forgejo.settings.repository.ENABLE_PUSH_CREATE_USER = true;
services.forgejo.settings.repository.ENABLE_PUSH_CREATE_ORG = true;
services.forgejo.settings.repository.DEFAULT_REPO_UNITS = "repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages,repo.actions";
# Set the permittions for the db file
system.activationScripts = {
forgejoDbFilePermission.text =
''
chmod 400 ${cfg.dbPasswordFile}
chown ${config.services.forgejo.user} ${cfg.dbPasswordFile}
'';
};
environment.systemPackages = with pkgs; [
forgejo
];
systemd.services.forgejo.environment.FORGEJO_CUSTOM = "${config.services.forgejo.stateDir}/custom";
services.forgejo.settings = {
ui = {
THEMES = "forgejo-auto,forgejo-light,forgejo-dark,auto,gitea,arc-green";
DEFAULT_THEME = "forgejo-auto";
};
"ui.meta" = {
DESCRIPTION = "Code everywhere";
};
};
services.forgejo.settings.actions = lib.mkIf (cfg.actionsEnabled) {
ENABLED = true;
DEFAULT_ACTION_URL = "https://${cfg.domain}";
};
# NGINX
security.acme.acceptTerms = true;
security.acme.defaults.email = cfgBase.adminEmail;
services.nginx = {
enable = true;
virtualHosts = {
"${cfg.domain}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:3000";
extraConfig = ''
client_max_body_size 0;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass_request_headers on;
'';
};
locations."/user/login" = lib.mkIf (cfg.openIdEnabled) {
return = "301 https://$host/user/oauth2/${cfg.openIdClientName}";
};
};
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
};
}

View file

@ -54,6 +54,10 @@ in
services.gitea.domain = cfg.domain;
# services.gitea.database.type = "postgres"; # Default is sqlite3, probably better for a small instance
services.gitea.database.passwordFile = cfg.dbPasswordFile;
services.gitea.settings.repository.ENABLE_PUSH_CREATE_USER = true;
services.gitea.settings.repository.ENABLE_PUSH_CREATE_ORG = true;
# Set the permittions for the db file
system.activationScripts = {
giteaDbFilePermission.text =
@ -93,6 +97,7 @@ in
locations."/" = {
proxyPass = "http://127.0.0.1:3000";
extraConfig = ''
client_max_body_size 0;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;

77
pp-node-exporter.nix Normal file
View file

@ -0,0 +1,77 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.ppNodeExporter;
prometheusCaFile = pkgs.writeTextFile {
name = "prometheus_ca.pem";
text = cfg.prometheusCa;
};
yaml = pkgs.formats.yaml { };
nodeWebConfig = yaml.generate "prometheus-node-exporter-webconfig.yml" {
tls_server_config = {
client_ca_file = prometheusCaFile;
cert_file = cfg.prometheusNodeExporterCertFile;
key_file = cfg.prometheusNodeExporterCertKeyFile;
client_auth_type = "RequireAndVerifyClientCert";
client_allowed_sans = lib.mkIf (cfg.prometheusNodeExporterAllowScrapperSans != null) cfg.prometheusNodeExporterAllowScrapperSans;
};
};
in {
options.services.ppNodeExporter = {
prometheusCa = lib.mkOption {
type = lib.types.str;
example = ''
-----BEGIN CERTIFICATE-----
MIIBaTCCAQ6gAwIBAgIUccDw/Xe2RC4p9gwdQMkcbPlS740wCgYIKoZIzj0EAwIw
EjEQMA4GA1UEAwwHZXhhbXBsZTAeFw0yNTAyMjMxMTQzMTlaFw0zNTAyMjExMTQz
MTlaMBIxEDAOBgNVBAMMB2V4YW1wbGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AARk2SGMdAzOR+I+xAJDXO2nm8N4oa8V/kqstJrvd3gGTVsk8b0/EA+6ZrFISL0t
MroC27QCybMwRol9oalSVnoCo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
/wQEAwIBhjAdBgNVHQ4EFgQUy13fD60aREMworuMEulXdkvTKOwwCgYIKoZIzj0E
AwIDSQAwRgIhALcoP/hicosVELvPfnomcEsWXTkkIVGbu1NeS5I2L72YAiEAi3AG
7/hpeMxkaE0d2D8pr6exVlZR7kDa9FgDpfu/+a0=
-----END CERTIFICATE-----
'';
description = "The CA that issues the prometheus scrapper certificate";
};
prometheusNodeExporterCertFile = lib.mkOption {
type = lib.types.path;
default = "/etc/prometheus-node-exporter/node-exporter.pem";
description = "The file of the certificate use by prometheus node exporter.";
};
prometheusNodeExporterCertKeyFile = lib.mkOption {
type = lib.types.path;
default = "/etc/prometheus-node-exporter/node-exporter.key";
description = "The file of the key for the certificate used by prometheus node exporter.";
};
prometheusNodeExporterAllowScrapperSans = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = null;
example = [ "prometheus.example.com" ];
description = "The list of Subject Alternative Names allowed to scrape node exporter. If not set, do not check Subject Names.";
};
};
config = {
system.activationScripts = {
prometheusNodeExporterFilePermission.text =
''
chmod 640 ${cfg.prometheusNodeExporterCertFile}
chmod 640 ${cfg.prometheusNodeExporterCertKeyFile}
chown root:${config.services.prometheus.exporters.node.group} ${cfg.prometheusNodeExporterCertFile}
chown root:${config.services.prometheus.exporters.node.group} ${cfg.prometheusNodeExporterCertKeyFile}
'';
};
services.prometheus = {
exporters = {
node = {
enable = true;
port = 9100; # default
enabledCollectors = [ "systemd" ]; # logind ?
extraFlags = [
"--web.config.file=${nodeWebConfig}"
];
};
};
};
};
}

117
pp-woodpecker.nix Normal file
View file

@ -0,0 +1,117 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfgBase = config.base;
cfg = config.services.ppWoodpecker;
in
{
imports = [
# Woodpeeker is not in stable yet but the module is good enought
(builtins.fetchurl {
url = "https://github.com/NixOS/nixpkgs/raw/nixos-unstable/nixos/modules/services/continuous-integration/woodpecker/server.nix";
sha256 = "13dzbcb0fi0bwam0mlf6d6ly0x90pr8sq68kzs65mszbvsd5lqjb";
})
(builtins.fetchurl {
url = "https://github.com/NixOS/nixpkgs/raw/nixos-unstable/nixos/modules/services/continuous-integration/woodpecker/agents.nix";
sha256 = "14kjj9ybahmfqflvsa8p0va1z3zhliybggxd148fzz4bnjsqpsla";
})
];
options.services.ppWoodpecker = {
serverEnvFile = mkOption {
type = types.str;
default = "/etc/woodpecker_server_env";
description = "The file containing the env secrets WOODPECKER_AGENT_SECRET and WOODPECKER_GITEA_SECRET, cf https://woodpecker-ci.org/docs/administration/vcs/gitea#configuration for gitea";
};
agentEnvFile = mkOption {
type = types.str;
default = "/etc/woodpecker_agent_env";
description = "The file containing the env secrets WOODPECKER_AGENT_SECRET";
};
domain = mkOption {
type = types.str;
default = "ci.${cfgBase.domainName}";
example = "ci.example.com";
description = "The domain of the server";
};
giteaDomain = mkOption {
type = types.str;
default = "git.${cfgBase.domainName}";
example = "git.example.com";
description = "The domain of the gitea server";
};
giteaClientId = mkOption {
type = types.str;
example = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
description = "The domain of the gitea server";
};
admins = mkOption {
type = lib.types.listOf lib.types.string;
default = [];
example = [ "user1" "user2" ];
description = "List of admins";
};
maxProcsPerAgent = mkOption {
type = types.int;
default = 1;
example = 4;
description = "Number of possible paralle process per agent";
};
};
config = {
services.woodpecker-server.enable = true;
# To put in woodpecker_server_env:
# ```
# WOODPECKER_AGENT_SECRET=XXXXXX
# WOODPECKER_GITEA_SECRET=gto_XXXXXX
# ```
services.woodpecker-server.environmentFile = "${cfg.serverEnvFile}";
services.woodpecker-server.environment = {
WOODPECKER_HOST = "https://${cfg.domain}";
WOODPECKER_OPEN = "true"; # This means user of gitea can connect to the ci
WOODPECKER_GITEA = "true";
WOODPECKER_GITEA_CLIENT = "${cfg.giteaClientId}";
WOODPECKER_GITEA_URL = "https://${cfg.giteaDomain}";
WOODPECKER_ADMIN = lib.mkIf (cfg.admins != []) (lib.concatStringsSep "," cfg.admins);
};
virtualisation.podman.enable = true;
virtualisation.podman.defaultNetwork.dnsname.enable = true;
services.woodpecker-agents.agents.podman = {
enable = true;
extraGroups = [ "podman" ];
environmentFile = [ "${cfg.agentEnvFile}" ];
environment = {
WOODPECKER_BACKEND = "docker";
DOCKER_HOST = "unix:////run/podman/podman.sock";
WOODPECKER_MAX_PROCS = builtins.toString cfg.maxProcsPerAgent;
};
};
security.acme.acceptTerms = true;
security.acme.defaults.email = cfgBase.adminEmail;
services.nginx = {
enable = true;
virtualHosts = {
"${cfg.domain}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:8000";
extraConfig = ''
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass_request_headers on;
'';
};
};
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
};
}