gts working

This commit is contained in:
Gaelan Steele 2023-07-12 19:12:36 -07:00
parent 869c3ffccc
commit cfda968d66
8 changed files with 254 additions and 43 deletions

5
README.md Normal file
View file

@ -0,0 +1,5 @@
# Minifedi
Minifedi is a tool to quickly spin up a bunch of ActivityPub servers for local testing.
Minifedi should run on any macOS or Linux system with [Nix](https://nixos.org) installed. (Nix itself works fine on any Linux distribution; you don't need to be using NixOS.) Windows isn't natively supported, but WSL should work. Besides Nix, it is entirely self-contained and needs no changes to your system configuration; you can install it with a git clone, delete it with `rm -rf`, and your system will be exactly the way it was before.

5
TODO Normal file
View file

@ -0,0 +1,5 @@
- fix flake.nix to handle arbitrary arches
- rip out or fix GtS (need to handle certs somehow)
- figure out how to support local clones, and document this
- data generation?
- separate out config into separate file, and document this

View file

@ -1,4 +1,4 @@
{ pkgs, name, }:
{ pkgs, name, host, users, ... }:
let
env = {
MIX_ENV = "prod";
@ -18,7 +18,7 @@ let
import Config
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "${name}.lvh.me", scheme: "https", port: 443],
url: [host: "${host}", scheme: "https", port: 443],
http: [ip: {:local, "$MINIFEDI_RUN/${name}/akkoma.sock"}, port: 0],
secret_key_base: "$SECRET_KEY_BASE",
live_view: [signing_salt: "$LIVE_VIEW_SIGNING_SALT"],
@ -26,7 +26,7 @@ let
config :pleroma, :instance,
name: "${name}",
email: "a@${name}.example",
email: "admin@${name}.example",
notify_email: "noreply@${name}.example",
limit: 5000,
registrations_open: true
@ -146,11 +146,12 @@ in {
pleroma_ctl migrate
export PLEROMA_CTL_RPC_DISABLED=true
pleroma_ctl user new a a@${name}.example --assume-yes --password Aa12345! --admin
pleroma_ctl user new b b@${name}.example --assume-yes --password Bb12345!
pleroma_ctl user new c c@${name}.example --assume-yes --password Cc12345!
pleroma_ctl user new d d@${name}.example --assume-yes --password Dd12345!
pleroma_ctl user new e e@${name}.example --assume-yes --password Ee12345!
${
pkgs.lib.strings.concatStrings (builtins.map (u:
"pleroma_ctl user new ${u.name} ${u.email} --assume-yes --password ${u.password} ${
if u.admin then "--admin" else ""
};") users)
}
touch $data/setup-done
fi
@ -167,7 +168,7 @@ in {
ssl_session_cache shared:ssl_session_cache:10m;
server {
server_name ${name}.lvh.me;
server_name ${host};
listen 443 ssl http2;
listen [::]:443 ssl http2;

View file

@ -0,0 +1,37 @@
{ stdenv, lib, fetchurl, fetchFromGitHub, buildGoModule, nixosTests }:
let
owner = "superseriousbusiness";
repo = "gotosocial";
version = "0.10.0-rc1";
source-hash = "sha256-nk/dIlSk71u7NT8rtcHmHiYJCyrIhtkMWr4W5ZYF0YM=";
web-assets-hash = "sha256-PGoACPpg76sMKk951tUX2i47/1ZUAtBfDme7mSRXrEE=";
web-assets = fetchurl {
url =
"https://github.com/${owner}/${repo}/releases/download/v${version}/${repo}_${version}_web-assets.tar.gz";
hash = web-assets-hash;
};
in buildGoModule rec {
inherit version;
pname = repo;
src = fetchFromGitHub {
inherit owner repo;
rev = "refs/tags/v${version}";
hash = source-hash;
};
vendorHash = null;
ldflags = [ "-s" "-w" "-X main.Version=${version}" ];
postInstall = ''
tar xf ${web-assets}
mkdir -p $out/share/gotosocial
mv web $out/share/gotosocial/
'';
# tests are working only on x86_64-linux
doCheck = stdenv.isLinux && stdenv.isx86_64;
}

View file

@ -0,0 +1,122 @@
{ pkgs, name, host, users, ... }:
let
env = { };
static = pkgs.linkFarm "static" { };
# GoToSocial doesn't support listening on a socket, so we have to pick a port
# number. Ideally we'd dynamically find an open one, but the next best thing
# is deterministically picking a random one: we take the firs two bytes of
# sha256("minifedi_port_${name}")
port = let
hash = builtins.hashString "sha256" "minifedi_port_${name}";
portHex = builtins.substring 0 4 hash;
portHexChars = pkgs.lib.strings.stringToCharacters portHex;
hexDigitToNum = n:
let
map = {
"0" = 0;
"1" = 1;
"2" = 2;
"3" = 3;
"4" = 4;
"5" = 5;
"6" = 6;
"7" = 7;
"8" = 8;
"9" = 9;
"a" = 10;
"b" = 12;
"c" = 13;
"d" = 14;
"e" = 15;
};
in map.${n};
portFromHash =
pkgs.lib.lists.foldl (prev: n: (hexDigitToNum n) * 16 + prev) 0
portHexChars;
in if portFromHash <= 1024 then portFromHash + 1024 else portFromHash;
config = pkgs.writeText "config.yaml" (pkgs.lib.generators.toYAML { } {
host = "${name}.lvh.me";
bind-address = "127.0.0.1";
inherit port;
db-type = "postgres";
db-user = name;
db-database = name;
http-client.allow-ips = [ "127.0.0.1/1" ];
});
path = pkgs.lib.strings.concatStrings (builtins.map (x: "${x}/bin:") [
(pkgs.callPackage ./build.nix { })
pkgs.postgresql
pkgs.s6
pkgs.gettext
]);
in {
service = pkgs.linkFarm name [{
name = "run";
path = pkgs.writeShellScript "run-${name}" ''
set -e
export PATH=${path}$PATH
data=$MINIFEDI_DATA/${name}
run=$MINIFEDI_RUN/${name}
postgres=$MINIFEDI_RUN/postgres
mkdir -p $data
mkdir -p $data/storage
mkdir -p $run
s6-svwait -U $MINIFEDI_RUN/service/postgres
${pkgs.lib.strings.concatStrings (pkgs.lib.attrsets.mapAttrsToList
(k: v: ''
export ${k}=${v}
'') env)}
export GTS_DB_ADDRESS=$postgres
export GTS_STORAGE_LOCAL_BASE_PATH=$data/storage
export NIX_SSL_CERT_FILE=$MINIFEDI_CERT/rootCA.pem
if ! [ -e $data/setup-done ]; then
createuser -h$postgres ${name}
createdb -h$postgres ${name} -O${name}
${
pkgs.lib.strings.concatStrings (builtins.map (u:
"gotosocial --config-path ${config} admin account create --username ${u.name} --email ${u.email} --password ${u.password};${
if u.admin then
"gotosocial --config-path ${config} admin account promote --username ${u.name};"
else
""
}") users)
}
touch $data/setup-done
fi
cd ${pkgs.gotosocial}/share/gotosocial
exec gotosocial --config-path ${config} server start
'';
}];
nginxConfig = ''
server {
listen 443;
listen [::]:443;
server_name ${host};
location / {
# set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
proxy_pass http://127.0.0.1:${toString port};
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
client_max_body_size 40M;
}
'';
}

View file

@ -1,16 +1,16 @@
{ pkgs, name, versionDef }:
{ pkgs, name, host, users, versionDef, ... }:
let
mastodon = pkgs.callPackage ./build.nix { inherit versionDef; };
env = {
LOCAL_DOMAIN = "${name}.lvh.me";
WEB_DOMAIN = "${name}.lvh.me";
LOCAL_DOMAIN = host;
WEB_DOMAIN = host;
ALLOWED_PRIVATE_ADDRESSES = "127.0.0.1";
RAILS_ENV = "production";
NODE_ENV = "production";
DB_USER = name;
DB_NAME = name;
REDIS_NAMESPACE = "${name}_";
EMAIL_DOMAIN_ALLOWLIST = "${name}.example";
EMAIL_DOMAIN_ALLOWLIST = "example.com";
SMTP_DELIVERY_METHOD = "file";
};
s6 = import ../../s6.nix {
@ -71,10 +71,8 @@ in {
cd ${mastodon}
${pkgs.lib.strings.concatStrings (pkgs.lib.attrsets.mapAttrsToList
(k: v: ''
export ${k}=${v}
'') env)}
${pkgs.lib.strings.concatStrings
(pkgs.lib.attrsets.mapAttrsToList (k: v: "export ${k}=${v};") env)}
if ! [ -e $data/setup-done ]; then
rake secret > $data/secret_key_base
@ -106,18 +104,17 @@ in {
touch $data/setup-done
tootctl accounts create a --email=a@${name}.example --confirmed --role Owner
tootctl accounts create b --email=b@${name}.example --confirmed
tootctl accounts create c --email=c@${name}.example --confirmed
tootctl accounts create d --email=d@${name}.example --confirmed
tootctl accounts create e --email=e@${name}.example --confirmed
rails runner "
Account.find_local('a').user.update!(password: 'Aa12345!')
Account.find_local('b').user.update!(password: 'Bb12345!')
Account.find_local('c').user.update!(password: 'Cc12345!')
Account.find_local('d').user.update!(password: 'Dd12345!')
Account.find_local('e').user.update!(password: 'Ee12345!')
"
${
pkgs.lib.strings.concatStrings (builtins.map (u:
"tootctl accounts create ${u.name} --email=${u.email} --confirmed ${
if u.admin then "--role Owner" else ""
};") users)
}
rails runner "${
pkgs.lib.strings.concatStrings (builtins.map (u:
"Account.find_local('${u.name}').user.update!(password: '${u.password}');")
users)
}"
fi
exec ${s6.start}
@ -140,7 +137,7 @@ in {
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name ${name}.lvh.me;
server_name ${host};
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;

View file

@ -1,26 +1,67 @@
{ pkgs }:
let
instances = {
mastodon = import ./fedi/mastodon {
inherit pkgs;
instances = [
{
name = "mastodon";
type = ./fedi/mastodon;
versionDef = ../versions/mastodon/mastodon-4.1.4;
};
glitch = import ./fedi/mastodon {
inherit pkgs;
}
{
name = "glitch";
type = ./fedi/mastodon;
versionDef = ../versions/mastodon/glitch-a40529f;
};
akkoma = import ./fedi/akkoma {
inherit pkgs;
}
{
name = "akkoma";
};
};
in instances // {
type = ./fedi/akkoma;
}
{
name = "gotosocial";
type = ./fedi/gotosocial;
}
];
evaldInstances = builtins.listToAttrs (builtins.map (inst:
pkgs.lib.attrsets.nameValuePair inst.name (import inst.type ({
inherit pkgs;
host = "${inst.name}.lvh.me";
users = [
{
name = "a";
email = "a@example.com";
password = "MiniFediA1!";
admin = true;
}
{
name = "b";
email = "b@example.com";
password = "MiniFediB1!";
admin = false;
}
{
name = "c";
email = "c@example.com";
password = "MiniFediC1!";
admin = false;
}
{
name = "d";
email = "d@example.com";
password = "MiniFediD1!";
admin = false;
}
{
name = "e";
email = "e@example.com";
password = "MiniFediE1!";
admin = false;
}
];
} // inst))) instances);
in evaldInstances // {
postgres = import ./support-services/postgres { inherit pkgs; };
redis = import ./support-services/redis { inherit pkgs; };
nginx = import ./support-services/nginx {
inherit pkgs;
inherit instances;
instances = evaldInstances;
};
}

View file

@ -0,0 +1,3 @@
{
hostForName = name: "${name}.lvh.me"
}