Compare commits

...
Sign in to create a new pull request.

5 commits

Author SHA1 Message Date
Jakob Lechner
37d4428fda
Add pretix VM 2023-02-22 23:58:18 +00:00
Jakob Lechner
83a30d6bae
Add pretix module 2023-02-22 23:57:27 +00:00
Jakob Lechner
e08237c633
Ignore qcow2 files (QEMU disk images) 2023-02-22 22:41:52 +00:00
Jakob Lechner
0573e301fb
Add sops instructions 2023-02-22 22:39:07 +00:00
Jakob Lechner
337c2598b6
Add pretix package 2023-02-22 02:24:06 +00:00
22 changed files with 4737 additions and 1 deletions

3
.gitignore vendored
View file

@ -1,4 +1,5 @@
result*
*.qcow2
.pre-commit-config.yaml
/.direnv
.direnv
__pycache__

View file

@ -3,6 +3,7 @@ keys:
- &admin_jalr_tb FE170812543DF81393EA56BA5042B8317A10617E
- &host_hafnium age1ahnfjspcpwxxk7getcxkj3fypwt37rr6p3xsmp8n2tqqqz8jtg7q2am0et
- &host_aluminium age1ne08hny30vrkejqhh7dcx4ql6dmkx6jw9dqkf3cz7mzvt53njy0qh59w44
- &host_pretix age139r3v2yy7ea205pauchgnggq6qqdpgc5fy7mv49wc5cw58p6hpdqltpkzn
creation_rules:
- path_regex: hosts/hafnium/secrets\.yaml$
key_groups:
@ -16,6 +17,12 @@ creation_rules:
- *admin_jalr
age:
- *host_aluminium
- path_regex: hosts/pretix/secrets\.yaml$
key_groups:
- pgp:
- *admin_jalr
age:
- *host_pretix
- path_regex: secrets\.yaml$
key_groups:
- pgp:

View file

@ -13,6 +13,19 @@ This installs nixos on host `somehost`:
nix-shell -p nixUnstable --run 'nixos-install --flake https://gitlab.jalr.de/jalr/nixos-configuration#somehost --no-channel-copy'
```
### setting up sops
Get the host key and convert it.
```bash
ssh-keyscan -t ed25519 $host | ssh-to-age
```
Then add the key to `.sops.yaml`
If the key changed, you might want to run
```bash
sops updatekeys hosts/$host/secrets.yaml
```
## nix repl
start an interactive environment for evaluating Nix expressions

View file

@ -13,4 +13,7 @@
hafnium = {
system = "x86_64-linux";
};
pretix = {
system = "x86_64-linux";
};
}

View file

@ -0,0 +1,32 @@
{ config, pkgs, ... }:
{
imports = [
./services
];
networking.firewall.allowedTCPPorts = [ 8000 ];
networking.hostName = "pretix";
services.getty.autologinUser = "root";
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.05"; # Did you read the comment?
services.openssh.enable = true;
boot.loader.grub.devices = [
"/dev/fd0"
];
fileSystems."/" =
{
device = "/dev/vda";
fsType = "ext4";
options = [ "rw,relatime" ];
};
}

32
hosts/pretix/secrets.yaml Normal file
View file

@ -0,0 +1,32 @@
pretix-cfg: ENC[AES256_GCM,data:G3anJGQ/f441EllA7aZxcKF/ts8yxJrMGhJDMBnJQcLk4jNT5ODOs3Ws01vmxEvBuHtsBSwXhA/8viFJ/5dsv7KkRZ20telFlVsZhfJDkHi3HhQkKX8M8lsZ3lLEPBezIA==,iv:EWlnqkzNrYMwKQMykfKHWgQ96v1T+ZBOUkxzEH5rm60=,tag:nXFOC3U3N0X3DlavC7CpMg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age139r3v2yy7ea205pauchgnggq6qqdpgc5fy7mv49wc5cw58p6hpdqltpkzn
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6cVdPci9DSis1RVJ4c2k3
RnFRMU85UDRJS09laGdsUVhzQ1RmNVNWdUc4CjRZY1NEVnJCeUl1OEY5cGFOL1V4
eUR0amp4QjV6NW1QVW4vc1cyd0s4ZmsKLS0tIDBhYXZEcUFXaEk1dGU0WFhuRGds
MzVFWnVFd2RteTlPTlU3cVh1dzREemMKBRUgxNfgivCZxvF7SzeSfDBMjiDLoK2E
rBrg/Pf+nb8eW2+iKEQOr92W6qDclmpyW7kyPhrpKd2XH6Wv8bYNlw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-02-22T23:04:36Z"
mac: ENC[AES256_GCM,data:1TKPZtRDJ1GDZPsraYfkjQ2se45Cf3cBK+oY7UZ+Gxc8jyasLMO16e+In94vWej0FAnmIOjvIxB7e5wU6IKBf6mJi6gfAXByxyoljwRBH0YKyVRFG2ZQ6cIGkqf2tGwyasQqeRxsjDqaAqlAh82a1idhoLs6gNrzZiua+F0jLeM=,iv:q2jEezVKJ2+EA6tI1lvDdBMH5XhM7uLd03F5Nec9Fb0=,tag:zEp7r6UBiRkHFyUdJkL5+Q==,type:str]
pgp:
- created_at: "2023-02-22T22:45:23Z"
enc: |
-----BEGIN PGP MESSAGE-----
hF4D3ylLYNOsO+0SAQdA1GDmHtEufAAPHfV63IdRTToPc9k5g6icNG8Of12ChGgw
5SSsWckNxb8Pb/M4AeUlXhVdjE2NruZJWDjsiCyvTC0W8VciaHiX/1r+O6OPT+dW
0l4BoXqtH3Q64tpVDpwOglUuXPYadNZ2BYGCef4tRPbBSbD2KegV4fvrEFpj8HOj
jEWtgvD5M2M+0r9BOVHM+B4rF4JOgWVJuMXH7wIUKj77d862TbwVE+z9nREICvC0
=GoJv
-----END PGP MESSAGE-----
fp: 66FB54F6081375106EEBF651A222365EB448F934
unencrypted_suffix: _unencrypted
version: 3.7.3

View file

@ -0,0 +1,5 @@
{
imports = [
./pretix.nix
];
}

View file

@ -0,0 +1,14 @@
{ config, pkgs, ... }:
{
services.pretix = {
enable = true;
instanceName = "Pretix test installation";
domain = "pretix.example.com";
enableTls = false;
enableRegistration = true;
passwordReset = true;
locale = "de";
timezone = "Europe/Berlin";
secretsFile = ../secrets.yaml;
};
}

View file

@ -7,6 +7,7 @@
};
imports = [
../pkgs/modules.nix
./autologin.nix
./aws.nix
./bootloader

View file

@ -3,6 +3,8 @@ let
inherit (prev) callPackage;
in
{
pretix = callPackage ./pretix/pretix.nix { };
pretix-static = callPackage ./pretix/pretix-static.nix { };
fpvout = callPackage ./fpvout { };
mute-indicator = callPackage ./mute-indicator { };
tabbed-box-maker = callPackage ./tabbed-box-maker { };

7
pkgs/modules.nix Normal file
View file

@ -0,0 +1,7 @@
{ pkgs, ... }:
{
imports = [
./pretix/module.nix
];
}

1
pkgs/pretix/.envrc Normal file
View file

@ -0,0 +1 @@
use nix

211
pkgs/pretix/module.nix Normal file
View file

@ -0,0 +1,211 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.pretix;
name = "pretix";
user = "pretix";
group = "pretix";
bind = {
host = "127.0.0.1";
port = 8000;
};
postgresql = {
database = "pretix";
user = "pretix";
password = "pretix";
};
redisPort = 6379;
urlScheme = if cfg.enableTls then "https" else "http";
url = "${urlScheme}://${cfg.domain}";
toBool = x: if x then "on" else "off";
pythonPackages = pkgs.pretix.passthru.pythonModule.passthru.pkgs;
python = pkgs.pretix.passthru.python;
runCommandArgs = {
# Sets PYTHONPATH in derivation
buildInputs = [
pkgs.pretix
pythonPackages.gunicorn
pythonPackages.celery
];
};
staticRoot = pkgs.pretix-static;
environmentFile = pkgs.runCommand "pretix-environ" runCommandArgs ''
cat > $out <<EOF
DATA_DIR = /var/pretix
DJANGO_SETTINGS_MODULE=pretix_wrapper.settings
PRETIX_CELERY_BACKEND=redis://127.0.0.1:${toString redisPort}/2
PRETIX_CELERY_BROKER=redis://127.0.0.1:${toString redisPort}/1
PRETIX_DATABASE_BACKEND=postgresql
PRETIX_DATABASE_HOST=localhost
PRETIX_DATABASE_NAME=${postgresql.database}
PRETIX_DATABASE_PASSWORD=${postgresql.password}
PRETIX_DATABASE_USER=${postgresql.user}
PRETIX_LOCALE_DEFAULT=${cfg.locale}
PRETIX_LOCALE_TIMEZONE=${cfg.timezone}
PRETIX_PRETIX_INSTANCE_NAME=${cfg.instanceName}
PRETIX_PRETIX_PASSWORD_RESET=${toBool cfg.passwordReset}
PRETIX_PRETIX_REGISTRATION=${toBool cfg.enableRegistration}
PRETIX_PRETIX_URL=${url}
PRETIX_REDIS_LOCATION=redis://127.0.0.1:${toString redisPort}/0
PRETIX_REDIS_SESSIONS=true
PRETIX_STATIC_ROOT=${staticRoot}
PYTHONPATH=$PYTHONPATH
EOF
'';
mkTimer = { description, unit, onCalendar }: {
inherit description;
requires = [ "pretix-migrate.service" ];
after = [ "network.target" ];
wantedBy = [ "timers.target" ];
timerConfig = {
Persistent = true;
OnCalendar = onCalendar;
Unit = unit;
};
};
in
{
options.services.pretix = with lib; {
enable = mkEnableOption "Enable pretix ticket shop application";
instanceName = mkOption {
type = types.str;
description = "The name of this installation.";
};
domain = mkOption {
type = types.str;
description = "The installations domain";
};
enableTls = mkEnableOption "Whether to use TLS or not";
enableRegistration = mkEnableOption "Enables or disables the registration of new admin users.";
passwordReset = mkEnableOption "Enables or disables password reset.";
locale = mkOption {
type = types.str;
description = "The systems default locale.";
};
timezone = mkOption {
type = types.str;
description = "The systems default timezone as a pytz name.";
};
secretsFile = mkOption {
type = types.path;
description = "Path to the sops secrets file which stores pretix.cfg settings.";
};
};
config = lib.mkIf cfg.enable {
sops.secrets.pretix-cfg = {
sopsFile = cfg.secretsFile;
};
users.users."${user}" = {
createHome = true;
description = "Pretix user";
home = "/var/pretix";
isNormalUser = false;
isSystemUser = true;
group = group;
};
users.groups."${group}" = { };
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts."${cfg.domain}" = {
enableACME = cfg.enableTls;
forceSSL = cfg.enableTls;
locations."/" = {
proxyPass = "http://${bind.host}:${toString bind.port}";
};
};
};
services.postgresql = {
enable = true;
enableTCPIP = true;
authentication = pkgs.lib.mkOverride 10 ''
local all all trust
host all all ::1/128 trust
'';
initialScript = pkgs.writeText "backend-initScript" ''
CREATE ROLE ${postgresql.user} WITH LOGIN PASSWORD '${postgresql.password}' CREATEDB;
CREATE DATABASE ${postgresql.database};
GRANT ALL PRIVILEGES ON DATABASE ${postgresql.database} TO ${postgresql.user};
'';
};
services.redis.servers.pretix = {
enable = true;
port = redisPort;
databases = 3;
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
environment.etc."pretix/pretix.cfg".source = config.sops.secrets.pretix-cfg.path;
systemd.services.pretix-migrate = {
description = "Pretix DB Migrations";
serviceConfig = {
Type = "oneshot";
EnvironmentFile = environmentFile;
User = user;
};
script = "${pkgs.pretix}/bin/pretix migrate";
};
systemd.services.pretix-web = {
description = "Pretix Web Service";
serviceConfig = {
Type = "simple";
Restart = "on-failure";
EnvironmentFile = environmentFile;
User = user;
ExecStart = pkgs.writeScript "webserver" ''
#!${pkgs.runtimeShell}
set -euo pipefail
exec ${pythonPackages.gunicorn}/bin/gunicorn pretix.wsgi --name ${name} \
--workers 3 \
--log-level=info \
--bind=${bind.host}:${toString bind.port}
'';
};
wantedBy = [ "multi-user.target" ];
requires = [ "pretix-migrate.service" ];
after = [ "network.target" ];
};
systemd.services.pretix-worker = {
description = "Pretix Celery (Worker) Service";
serviceConfig = {
Type = "simple";
Restart = "on-failure";
EnvironmentFile = environmentFile;
User = user;
ExecStart = "${pythonPackages.celery}/bin/celery -A pretix.celery_app worker -l info";
};
wantedBy = [ "multi-user.target" ];
requires = [ "pretix-migrate.service" ];
after = [ "network.target" ];
};
systemd.services.pretix-runperiodic = {
description = "Pretix periodic tasks";
serviceConfig = {
Type = "oneshot";
EnvironmentFile = environmentFile;
User = user;
};
script = "${pkgs.pretix}/bin/pretix runperiodic";
};
# Once every 5 minutes
systemd.timers.pretix-runperiodic = mkTimer {
description = "Run pretix tasks";
unit = "pretix-runperiodic.service";
onCalendar = "*:0/5";
};
};
}

2749
pkgs/pretix/poetry.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,48 @@
{ stdenvNoCC
, pretix
, buildNpmPackage
, makeWrapper
}:
let
nodeEnv = buildNpmPackage rec {
name = "pretix-nodejs";
src = "${pretix.passthru.pythonModule.pkgs.pretix}/lib/python3.10/site-packages/pretix/static/npm_dir";
npmDepsHash = "sha256-bRy3Elof7daxv0dD93SnPcJ0fT19Mkq81gZPJduMCC4=";
dontNpmBuild = true;
installPhase = ''
mkdir -p $out
cp -r node_modules $out/
mkdir -p $out/bin
ln -s $out/node_modules/rollup/dist/bin/rollup $out/bin/rollup
'';
postFixup = ''
wrapProgram $out/bin/rollup --prefix NODE_PATH : $out
'';
nativeBuildInputs = [
makeWrapper
];
};
in
stdenvNoCC.mkDerivation {
name = "pretix-static";
src = ./.;
buildPhase = ''
mkdir $out
export PRETIX_STATIC_ROOT=$out
export DJANGO_SETTINGS_MODULE=pretix_wrapper.settings
${pretix}/bin/pretix collectstatic --noinput
mkdir -p $PRETIX_STATIC_ROOT/node_prefix
ln -s ${nodeEnv}/node_modules $PRETIX_STATIC_ROOT/node_prefix/node_modules
echo ${nodeEnv}/bin/rollup
${pretix}/bin/pretix compress
'';
installPhase = ''
runHook preInstall
runHook postInstall
'';
nativeBuildInputs = [
nodeEnv
];
}

52
pkgs/pretix/pretix.nix Normal file
View file

@ -0,0 +1,52 @@
{ lib
, poetry2nix
, pkgs
, tlds-alpha-by-domain ? ./tlds-alpha-by-domain.txt
}:
let
tlds = pkgs.fetchurl {
url = "https://data.iana.org/TLD/tlds-alpha-by-domain.txt";
sha256 = "0153py77ll759jacq41dp2z2ksr08pdcfic0rwjd6pr84dk89y9v";
};
pkgsRequiringSetuptools = [
"dj-static"
"django-jquery-js"
"paypal-checkout-serversdk"
"python-u2flib-server"
"slimit"
"static3"
];
in
poetry2nix.mkPoetryApplication rec {
projectDir = ./.;
#python = pkgs.python310;
preferWheels = true;
overrides = poetry2nix.defaultPoetryOverrides.extend
(
self: super: lib.attrsets.genAttrs pkgsRequiringSetuptools
(
pythonPackage:
super."${pythonPackage}".overridePythonAttrs (
old: {
buildInputs = (old.buildInputs or [ ]) ++ [ super.setuptools ];
}
)
) // {
tlds = super.tlds.overridePythonAttrs (
old: {
buildInputs = (old.buildInputs or [ ]) ++ [ super.setuptools ];
patches = [
./tlds-read-domains-from-file.patch
];
# https://data.iana.org/TLD/tlds-alpha-by-domain.txt
preBuild = "cp ${tlds-alpha-by-domain} ./tlds-alpha-by-domain.txt";
}
);
}
);
}
# .overrideAttrs(old: {
# inherit (old.passthru.pythonPackages.pretix) pname name version;
# })

View file

@ -0,0 +1,9 @@
import sys
import os
module_name = "pretix"
def main():
os.environ["PYTHONPATH"] = ":".join(sys.path)
os.execv(sys.executable, [sys.executable, "-m", module_name, *sys.argv[1:]])

View file

@ -0,0 +1,4 @@
import os
from pretix.settings import *
STATIC_ROOT = os.getenv("PRETIX_STATIC_ROOT")

View file

@ -0,0 +1,19 @@
[tool.poetry]
name = "pretix_wrapper"
version = "1.0.0"
description = ""
authors = ["Jakob Lechner <mail@jalr.de>"]
license = "MIT"
[tool.poetry.dependencies]
python = "^3.10"
pretix = "^4.16"
[tool.poetry.dev-dependencies]
[tool.poetry.scripts]
pretix = "pretix_wrapper.__main__:main"
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

8
pkgs/pretix/shell.nix Normal file
View file

@ -0,0 +1,8 @@
with import <nixpkgs> { };
mkShell {
buildInputs = [
poetry
];
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,36 @@
From 40544e83b5920c84a4565c2bf8dc29fc381d5796 Mon Sep 17 00:00:00 2001
From: Jakob Lechner <mail@jalr.de>
Date: Tue, 21 Feb 2023 21:25:06 +0000
Subject: [PATCH] read static file
---
setup.py | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/setup.py b/setup.py
index 6b4653c..13b6ad4 100644
--- a/setup.py
+++ b/setup.py
@@ -8,16 +8,9 @@ from setuptools import setup, find_packages
if sys.version_info.major >= 3:
import urllib.request
- r = urllib.request.urlopen('https://data.iana.org/TLD/tlds-alpha-by-domain.txt')
- assert r.status == 200
- data = r.read().decode('utf-8').split('\n')
-else:
- import urllib
-
- r = urllib.urlopen('https://data.iana.org/TLD/tlds-alpha-by-domain.txt')
- assert r.getcode() == 200
- data = r.read().split('\n')
-
+ with open("tlds-alpha-by-domain.txt", 'r') as f:
+ data = f.read().split('\n')
+
version = re.match('^# Version (?P<version>[0-9]+).*$', data[0]).group('version')
tlds = [i.lower() for i in data[1:] if i and not i.startswith('#')]
--
2.38.3