Merge remote-tracking branch 'lass/master'

This commit is contained in:
makefu 2023-01-30 23:43:04 +01:00
commit 369fa6b7eb
No known key found for this signature in database
GPG Key ID: 36F7711F3FC0F225
75 changed files with 1567 additions and 272 deletions

39
kartei/lass/aergia.nix Normal file
View File

@ -0,0 +1,39 @@
{ r6, w6, ... }:
{
nets = {
retiolum = {
ip4.addr = "10.243.0.1";
ip6.addr = r6 "ae12";
aliases = [
"aergia.r"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAqLtEUExq0qmXbi3aykdoW1WIneePfmm1SnFxCVcEBecJ1z326cNl
EIhYFSzhctwui0vG1dscmNMXHJ0rRQ0QHks1kp/x2MNMlun3Wl8Md9PQrTRGqZOf
ltdlNKzn8QbqcQQa9BYMgnFRzhbzzsSO3q5xqncJJ8qSxxWy/boIR9fO+OI/aUfe
rVLVHj/i5TTAmov5johqQZOyb7ydEbLiTbaaPSo1H/I/as0iv2jaDRdoVBL5/r+q
JvYFfhcdePjpwjRVNohdRwPquyM2ut91e2UyxD5N5eUoQBn+Xr18f6CQlyfJmMrc
/oGL+DScrDzFQ/ezCzks3O02dWAmgJsU6odUyNqtdU2x+0lhSqTRH0IXfdkj5n3k
K5U340/84e8Bn/1BJQoaGpBZJbK8RHdZd/0r+9+aXcI5tm2YAGaPPYzgLUYg06NZ
fMES28iByiCecIPci4vUZ50oOQFGQYaBNA12JC4TRbL/EfLlaax9bRAaUQr7qIXS
OBmKrC8eN9QO53T2d2w8Llk5d1rwq0TE3lyJEFLt7sqrHvlBFJ4fpeC+JqZAObqf
AJlCvFrqDYXBPzuNC2cZQX9QJ4FlGBpOObGg5KtkY0hPUyBO96OMxIDQ2+Jqc7F0
isAUVvn23h6i3m77jRE1AGFyIC/ReMaCH70/83AJQxRpTkzKcF98xU8CAwEAAQ==
-----END RSA PUBLIC KEY-----
'';
tinc.pubkey_ed25519 = "Jb8RJkm+ufh8o0acM31P2BolEUneYFB4xbtyoLQywLG";
};
wiregrill = {
ip6.addr = w6 "ae12";
aliases = [
"aergia.w"
];
wireguard.pubkey = ''
h2GFkqW1ThHpDiALrLkJEsR5NU1lXHvwk0Kers1vIxg=
'';
};
};
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPAGcqlL5fcxT3iCTlOm5rNPGKZmx1SEDWS71d3Tvbs/";
syncthing.id = "K5G46ZC-AKEG3WE-MQTG6MB-PC3ZA7O-C2BOKW6-KCXTSEW-RWHKP4B-Q7FCRQ7";
}

View File

@ -1,6 +1,20 @@
{ r6, w6, ... }:
{
nets = {
nets = rec {
internet = {
ip4 = rec {
addr = "95.217.192.59";
prefix = "${addr}/32";
};
ip6 = rec {
addr = "2a01:4f9:4a:4f1a::1";
prefix = "${addr}/64";
};
aliases = [
"neoprism.i"
];
ssh.port = 45621;
};
retiolum = {
ip4.addr = "10.243.0.99";
ip6.addr = r6 "99";

38
kartei/lass/orange.nix Normal file
View File

@ -0,0 +1,38 @@
{ r6, w6, ... }:
{
nets = {
retiolum = {
ip4.addr = "10.243.0.15";
ip6.addr = r6 "012a";
aliases = [
"orange.r"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAlnHedIf4f3/6Wfl5PSSz+7KvdIMkygp5m/U270sdPBh46MqYa8cn
OfPq40LcbWIZqAVex7mP+fK7vq8LTIr+sCKvzY46o3ZLbQQ7cCtQi02GFnSAPhVT
4XEmPn9dX/nRmI8xQqzh5jRMpgeOKE+xY6QfgkERD9mflkJi5dGYCOVW1UUK7pHR
7giCrUiLuQbUeIz+G7KOeIRHxU8dwD8it1Jk6KxdM3MW6HwFsuqZu0qjbBPKhTEe
fgzSTDtZEGmcQw5vA/RwjxoRvKYThbK/lLoVJItFAhUCWUJA8bJuIanwzPfOF0JO
xWkxiY3ntvn5ykbvhF6LoHE+kEfcBJzBfRFRSXV5qU5wW1FC4AQylUDrest/qXQh
DY8boUqK/hi/MlC2ciPH+DlBOi5wduWty8F0KqNzjg1IIEOk8H+z9hgBDbdJnYHH
MBjYOZ3MFpoNb2VCJTE7dlIarVdH1OOO2KkzX/GGW7wGQK94iqLHjBcGl15GcGOz
EOivq+783VOtzZGS4jd8D0OcCo725FzhuWi6KR5QTljwrd5C1gGFoAW7RCsUiveZ
0by9aB+G2DWmSRWZsmPnnbYo6yPvp+WR2yfPu1pKwjyNsmAgTYm4bkwRIvODb6Xk
ShgawP5V8RDp+hUmr27KgJvUJnQbVeJf9SO1pT7IfNOjLwHv26iOo7UCAwEAAQ==
-----END RSA PUBLIC KEY-----
'';
tinc.pubkey_ed25519 = "dVIOgHjuKLDJ+QB+sDjL9Pk3pXs8wKo+gemGvNG3z1H";
};
wiregrill = {
ip6.addr = w6 "012a";
aliases = [
"orange.w"
];
wireguard.pubkey = ''
NP8zM9+ocwsHhY9Rn6tFqIU1FR8JidqtDs7IKpl3yU8=
'';
};
};
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDnHnTPPwMW1Oy3DBuaT4fG5ryhWmVS9Y8Sw0ezUGuLn";
}

38
kartei/lass/ubik.nix Normal file
View File

@ -0,0 +1,38 @@
{ r6, w6, ... }:
{
nets = {
retiolum = {
ip4.addr = "10.243.0.12";
ip6.addr = r6 "0b1c";
aliases = [
"ubik.r"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAnWJKDrDmmGZbwVeaBhvOdTR4nsumo1yzOR2Iu+SMTOH6fbgJM5cW
WtlgPhrdOMrBYR956SBiBNkvsdczRrOF7F6hvXyDwwoGdWGsZXzaTMJlNAYjP5Y4
fbJlDq8/QV/SvVFGeu4XP3g2yuU/aNu/4FkU4jlysX+8wo9qGpIFPLpLvqfuU247
jHCatNzHfLK60fx7yt57iDhuX2plyFfQVX7xPTxudfGZKD7rEDEnKX4Ghd5dUkOA
z0lr0B1AOrkZgrnajU0ZmkjnNy8lrylCWDOnEPhJdao53gL4XFmUcZaR4uFsWuS7
V1VM+VivuMTAXRUnJScyLap2mo6dcr9h11kas70c/R7tI2pGmxlNk9t2uYy/jQnC
WmyzNCcqpPSfKikx5sRVAVIuv2wtAKYDuZg+1D4YEfeklA0+ZZlHO43NnRnIoKeO
Za0SNUE6vtd/EPoiifMkOWtHaO0LppgOxMTk8OgUxR6dcTmbuL0Roz3aY0rSW3EG
+li3yjS3YAtMtvhQwuqooVrkBFrcGQLjTnAfCeUHbCjZidGAHnqhESA+Aj+LKx32
0ALQY439xAs6Vf3rICs93cO4Yxa8W1F5sHE6ANOGU+jCmSkCWI2hdHGbckD3L0AQ
NBJ+jyXm0kFfVgqRS2i17JPz2ZZxhAHw3KH13Ef1KI4tMdzCvFSayW0CAwEAAQ==
-----END RSA PUBLIC KEY-----
'';
tinc.pubkey_ed25519 = "BcbZOID7dipWNH0/uowqCF7Ivqm4QktMoz11Yv249tG";
};
wiregrill = {
ip6.addr = w6 "0b1c";
aliases = [
"ubik.w"
];
wireguard.pubkey = ''
JakWwg7Rq76jjzLFWPBQJPpzRHbIEbb46VLsSUOKI2I=
'';
};
};
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHlqW8zqJpjbva0NTty9Ex7R/Jk2emDxHJNpaM3WPt5L";
}

View File

@ -9,6 +9,7 @@
"jelly.r"
"radar.r"
"sonar.r"
"transmission.r"
];
tinc = {
pubkey = ''

View File

@ -502,6 +502,40 @@ in {
};
};
doctor = {
owner = config.krebs.users.mic92;
nets = rec {
internet = {
# monitoring.dse.in.tum.de
ip4.addr = "131.159.102.4";
ip6.addr = "2a09:80c0:102::4";
aliases = [ "doctor.i" ];
};
retiolum = {
via = internet;
aliases = [
"doctor.r"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAuXYfR5PRMcJkJG6yjxw0tQvjtzRwZI/k2ks1SBgVhtCh1TcMFraq
/u367B6E9BrGHhPZNtTcceMunC+Tow1+JIAHQPQU1+l1w+6n3esNgYUvakv0C/Dj
opOh5mWzS81UL1r+ifXKdEs4/u561GPUdhhScxnk2lsudh0fem0Rn7yDXuGofrIo
kAD49TLV0ZEflCQLe9/ck+qvzM8yPOnDsCZlCdCZJVpOW0Aq1cfghI6BiStVkDDU
DaBj74m3eK0wtPJlj0flebF91VNMsmQ4XSmFZeDtdx/xOJmqzB29C7tTynuPD5FV
zREKo5wxgvaf/J3da5K5nCP/sOBIishlYVBNZeJqwQiTze405ycdglNiYVISpYaF
8ikv0w19E9nI3GVjwm6mYH29eKbHuEJSou5J/7lS2tlyVaGI9opGRLV+X7GLwE1D
01uaQsyTYB7mK33broIABp5Mu/Il1+Mi3uwMKzCL/ciPMMFoSbR+zth2QoU1wRUz
A6OK3t6w5//ufq9bKGcZ3rhU/rYzfk8nHY1F/5QBPM95WTGZZ7CjAMPzyc6Is/CL
+7jtPZPrT05yc9HKPqG2RPWP3dziw4l1TX6NXstMzizyaayeF0yPQ6chNTqgvfFJ
s3ABq1R8UV0LUBmdDAxeyKOOEqrqBcShHFxWmEzk95ghdT6P5XSMMCUCAwEAAQ==
-----END RSA PUBLIC KEY-----
'';
tinc.pubkey_ed25519 = "StFqqnSArvIfK07//ejbxkP3V4nnXsj8vu5km8LcM/P";
};
};
};
eva = {
owner = config.krebs.users.mic92;
nets = rec {

24
kartei/tv/hosts/ru.nix Normal file
View File

@ -0,0 +1,24 @@
{
ci = true;
nets = {
retiolum = {
ip4.addr = "10.243.13.42";
aliases = [
"ru.r"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAr4xgpXPr/OGrLO5vwur35esesbAwREwShGJf9btt65UQXst090tD
GWev8Yfi3Mr241r1TG7zpW3Idh5nth2yhzVvqGc9m6QmK27v2MKpb+ppjOKab7RL
1KfdBAwjdrWdL2xO3XAYOUljxWoIV4VKX8kEBvjJEDOwl/u+g5mB3yLWebtIT7Wk
EneMU6wvCVKhOPeqyXmbqO/+j6+bqxkKP2/5hHcX3a91+15YbR3SvREK2rUm9stx
Rc3kmGUO/DiGK6MmUmt+qieGo/4vheK8hij57dY0uXFIC7U680QzV7jsUmtlKGBL
PoK/Xn6TLLG6nozgmF+q8esYyaYQFrwU2QIDAQAB
-----END RSA PUBLIC KEY-----
'';
tinc.pubkey_ed25519 = "Eg9l+RxFSNrQ9RkTd8tSkoTIG2m7zhQpjUJBWJRft1J";
};
};
secure = true;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIcNClgsey79WzdEQs/8qkLMHzc1SCU/MqyMerPcUi8X root@ru";
}

View File

@ -52,7 +52,7 @@ let
};
confuse = {
pattern = "^!confuse (.*)$";
pattern = "!confuse (.*)$";
activate = "match";
arguments = [1];
command = {
@ -90,7 +90,7 @@ let
};
confuse_hackint = {
pattern = "^!confuse (.*)$";
pattern = "!confuse (.*)$";
activate = "match";
arguments = [1];
command = {

View File

@ -53,6 +53,7 @@ let
./sitemap.nix
./ssl.nix
./sync-containers.nix
./sync-containers3.nix
./systemd.nix
./tinc.nix
./tinc_graphs.nix

View File

@ -3,8 +3,7 @@
hostNames =
["github.com"]
++
# List generated with (IPv6 addresses are currently ignored):
# curl -sS https://api.github.com/meta | jq -r .git[] | grep -v : | nix-shell -p cidr2glob --run cidr2glob | jq -Rs 'split("\n")|map(select(.!=""))' > known-hosts.json
# update known-hosts.json using ./update
lib.importJSON ./known-hosts.json
;
publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";

15
krebs/3modules/github/update Executable file
View File

@ -0,0 +1,15 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p cidr2glob curl git jq
# update known-hosts.json
#
# usage: ./update
set -efu
# XXX IPv6 addresses are currently ignored
curl -sS https://api.github.com/meta | jq -r .git[] | grep -v : | cidr2glob | jq -Rs 'split("\n")|map(select(.!=""))' > known-hosts.json
if git diff --exit-code known-hosts.json; then
echo known-hosts.json is up to date: nothing to do >&2
fi

View File

@ -1,8 +1,8 @@
{ config, lib, pkgs, ... }: let
cfg = config.lass.sync-containers3;
cfg = config.krebs.sync-containers3;
slib = pkgs.stockholm.lib;
in {
options.lass.sync-containers3 = {
options.krebs.sync-containers3 = {
inContainer = {
enable = lib.mkEnableOption "container config for syncing";
pubkey = lib.mkOption {
@ -104,9 +104,8 @@ in {
consul lock sync_${ctr.name} ${pkgs.writers.writeDash "${ctr.name}-sync" ''
set -efux
if /run/wrappers/bin/ping -c 1 ${ctr.name}.r; then
touch "$HOME"/incomplete
rsync -a -e "ssh -i $CREDENTIALS_DIRECTORY/ssh_key" --timeout=30 --inplace container_sync@${ctr.name}.r:disk "$HOME"/disk
rm "$HOME"/incomplete
nice --adjustment=30 rsync -a -e "ssh -i $CREDENTIALS_DIRECTORY/ssh_key" --timeout=30 container_sync@${ctr.name}.r:disk "$HOME"/disk
rm -f "$HOME"/incomplete
fi
''}
'';
@ -218,10 +217,6 @@ in {
exit 0
;;
esac
if test -e /var/lib/sync-containers3/${ctr.name}/incomplete; then
echo 'data is inconistent, start aborted'
exit 1
fi
consul kv put containers/${ctr.name} "$(jq -cn '{host: "${config.networking.hostName}", time: now}')" >/dev/null
consul lock -verbose -monitor-retry=100 -timeout 30s -name container_${ctr.name} container_${ctr.name} ${pkgs.writers.writeBash "${ctr.name}-start" ''
set -efu
@ -230,8 +225,8 @@ in {
mountpoint /var/lib/sync-containers3/${ctr.name}/state || mount /dev/mapper/${ctr.name} /var/lib/sync-containers3/${ctr.name}/state
/run/current-system/sw/bin/nixos-container start ${ctr.name}
# wait for system to become reachable for the first time
retry -t 10 -d 10 -- /run/wrappers/bin/ping -q -c 1 ${ctr.name}.r > /dev/null
systemctl start ${ctr.name}_watcher.service
retry -t 10 -d 10 -- /run/wrappers/bin/ping -q -c 1 ${ctr.name}.r > /dev/null
while systemctl is-active container@${ctr.name}.service >/devnull && /run/wrappers/bin/ping -q -c 3 ${ctr.name}.r >/dev/null; do
consul kv put containers/${ctr.name} "$(jq -cn '{host: "${config.networking.hostName}", time: now}')" >/dev/null
sleep 10
@ -240,6 +235,13 @@ in {
'';
};
}; }
{ "container@${ctr.name}" = lib.mkIf ctr.runContainer {
serviceConfig = {
ExecStop = pkgs.writers.writeDash "remove_interface" ''
${pkgs.iproute2}/bin/ip link del vb-${ctr.name}
'';
};
}; }
]) (lib.attrValues cfg.containers)));
systemd.timers = lib.mapAttrs' (n: ctr: lib.nameValuePair "${ctr.name}_syncer" {
@ -280,14 +282,19 @@ in {
})
(lib.mkIf (cfg.containers != {}) {
# networking
# needed because otherwise we lose local dns
environment.etc."resolv.conf".source = lib.mkForce "/run/systemd/resolve/resolv.conf";
boot.kernel.sysctl."net.ipv4.ip_forward" = lib.mkForce 1;
systemd.network.networks.ctr0 = {
name = "ctr0";
address = [
"10.233.0.1/24"
];
networkConfig = {
IPForward = "yes";
IPMasquerade = "both";
# IPForward = "yes";
# IPMasquerade = "both";
ConfigureWithoutCarrier = true;
DHCPServer = "yes";
};
@ -304,6 +311,9 @@ in {
{ predicate = "-i ctr0"; target = "ACCEPT"; }
{ predicate = "-o ctr0"; target = "ACCEPT"; }
];
krebs.iptables.tables.nat.POSTROUTING.rules = [
{ v6 = false; predicate = "-s 10.233.0.0/24"; target = "MASQUERADE"; }
];
})
(lib.mkIf cfg.inContainer.enable {
users.groups.container_sync = {};

View File

@ -125,17 +125,13 @@ with import <stockholm/lib>;
hostsPackage = mkOption {
type = types.package;
default = pkgs.stdenv.mkDerivation {
name = "${tinc.config.netname}-tinc-hosts";
phases = [ "installPhase" ];
installPhase = ''
mkdir $out
${concatStrings (mapAttrsToList (_: host: ''
echo ${shell.escape host.nets."${tinc.config.netname}".tinc.config} \
> $out/${shell.escape host.name}
'') tinc.config.hosts)}
'';
};
default =
pkgs.write "${tinc.config.netname}-tinc-hosts"
(mapAttrs'
(_: host: (nameValuePair "/${host.name}" {
text = host.nets.${tinc.config.netname}.tinc.config;
}))
tinc.config.hosts);
defaultText = "netname-tinc-hosts";
description = ''
Package of tinc host configuration files. By default, a package will

View File

@ -1,12 +1,13 @@
{ openssl, writePython2Bin }:
{ openssl, writePython3Bin }:
writePython2Bin "syncthing-device-id" {
writePython3Bin "syncthing-device-id" {
flakeIgnore = [
"E226"
"E302"
"E305"
"E501"
"F401"
"W504"
];
} /* python */ ''
import base64

View File

@ -1,9 +1,9 @@
{
"url": "https://github.com/NixOS/nixpkgs",
"rev": "64e0bf055f9d25928c31fb12924e59ff8ce71e60",
"date": "2022-12-11T09:33:23+00:00",
"path": "/nix/store/lmiwldi32kcc2qgm68swxgb3xzba0ayc-nixpkgs",
"sha256": "1hmx7hhjr74fqmxhb49yfyrpqhzwayrq48xwjv3a117czpb0gnjx",
"rev": "befc83905c965adfd33e5cae49acb0351f6e0404",
"date": "2023-01-13T18:32:21+01:00",
"path": "/nix/store/bwpp6fchhfw699jn9hsdypyc7ggb72gx-nixpkgs",
"sha256": "0m0ik7z06q3rshhhrg2p0vsrkf2jnqcq5gq1q6wb9g291rhyk6h2",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,

View File

@ -1,9 +1,9 @@
{
"url": "https://github.com/NixOS/nixpkgs",
"rev": "9d692a724e74d2a49f7c985132972f991d144254",
"date": "2022-12-16T13:36:40-05:00",
"path": "/nix/store/76wc0ymx7rw348hpl0bp0yb77sf40xd6-nixpkgs",
"sha256": "1byh49p3kwi6adb1izaalj2ab9disfzq1cx526gwgv20ilmphvnr",
"rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
"date": "2023-01-15T13:38:37-03:00",
"path": "/nix/store/mn2dwzki0d159fl09y87jrvyvcjgyy03-nixpkgs",
"sha256": "0w3ysrhbqhgr1qnh0r9miyqd7yf7vsd4wcd21dffwjlb99lynla8",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,

View File

@ -0,0 +1,76 @@
{ config, lib, pkgs, ... }:
{
imports = [
<stockholm/lass>
<stockholm/lass/2configs/retiolum.nix>
<stockholm/lass/2configs/exim-retiolum.nix>
<stockholm/lass/2configs/baseX.nix>
<stockholm/lass/2configs/pipewire.nix>
<stockholm/lass/2configs/browsers.nix>
<stockholm/lass/2configs/programs.nix>
<stockholm/lass/2configs/network-manager.nix>
<stockholm/lass/2configs/syncthing.nix>
<stockholm/lass/2configs/sync/sync.nix>
<stockholm/lass/2configs/games.nix>
<stockholm/lass/2configs/steam.nix>
<stockholm/lass/2configs/wine.nix>
<stockholm/lass/2configs/fetchWallpaper.nix>
<stockholm/lass/2configs/yellow-mounts/samba.nix>
<stockholm/lass/2configs/pass.nix>
<stockholm/lass/2configs/mail.nix>
<stockholm/lass/2configs/bitcoin.nix>
# <stockholm/lass/2configs/xonsh.nix>
<stockholm/lass/2configs/review.nix>
<stockholm/lass/2configs/dunst.nix>
<stockholm/lass/2configs/print.nix>
<stockholm/lass/2configs/br.nix>
];
system.stateVersion = "22.11";
krebs.build.host = config.krebs.hosts.aergia;
environment.systemPackages = with pkgs; [
brain
bank
l-gen-secrets
generate-secrets
];
programs.adb.enable = true;
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
};
hardware.pulseaudio.package = pkgs.pulseaudioFull;
lass.browser.config = {
fy = { browser = "chromium"; groups = [ "audio" "video" ]; hidden = true; };
qt = { browser = "qutebrowser"; groups = [ "audio" "video" ]; hidden = true; };
};
nix.trustedUsers = [ "root" "lass" ];
# nix.extraOptions = ''
# extra-experimental-features = nix-command flakes
# '';
services.tor = {
enable = true;
client.enable = true;
};
documentation.nixos.enable = true;
boot.binfmt.emulatedSystems = [
"aarch64-linux"
];
boot.cleanTmpDir = true;
# vbox
virtualisation.virtualbox.host.enable = true;
users.users.mainUser.extraGroups = [ "vboxusers" ];
}

View File

@ -0,0 +1,64 @@
{ lib, ... }:
{
disk = {
main = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "table";
format = "gpt";
partitions = [
{
name = "boot";
type = "partition";
start = "0";
end = "1M";
part-type = "primary";
flags = ["bios_grub"];
}
{
type = "partition";
name = "ESP";
start = "1MiB";
end = "1GiB";
fs-type = "fat32";
bootable = true;
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
}
{
name = "root";
type = "partition";
start = "1GiB";
end = "100%";
content = {
type = "luks";
name = "aergia1";
content = {
type = "btrfs";
extraArgs = "-f"; # Override existing partition
subvolumes = {
# Subvolume name is different from mountpoint
"/rootfs" = {
mountpoint = "/";
};
# Mountpoints inferred from subvolume name
"/home" = {
mountOptions = [];
};
"/nix" = {
mountOptions = [];
};
};
};
};
}
];
};
};
};
}

View File

@ -0,0 +1,3 @@
#!/bin/sh
target=$1

View File

@ -0,0 +1,86 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
./config.nix
(modulesPath + "/installer/scan/not-detected.nix")
];
disko.devices = import ./disk.nix;
networking.hostId = "deadbeef";
# boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub = {
enable = true;
device = "/dev/nvme0n1";
efiSupport = true;
efiInstallAsRemovable = true;
};
boot.kernelPackages = pkgs.linuxPackages_latest;
boot.kernelParams = [
# Enable energy savings during sleep
"mem_sleep_default=deep"
"initcall_blacklist=acpi_cpufreq_init"
# for ryzenadj -i
"iomem=relaxed"
];
# Enables the amd cpu scaling https://www.kernel.org/doc/html/latest/admin-guide/pm/amd-pstate.html
# On recent AMD CPUs this can be more energy efficient.
boot.kernelModules = [ "amd-pstate" "kvm-amd" ];
# hardware.cpu.amd.updateMicrocode = true;
services.xserver.videoDrivers = [
"amdgpu"
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
environment.systemPackages = [
pkgs.vulkan-tools
pkgs.ryzenadj
(pkgs.writers.writeDashBin "set_tdp" ''
set -efux
watt=$1
value=$(( $watt * 1000 ))
${pkgs.ryzenadj}/bin/ryzenadj --stapm-limit="$value" --fast-limit="$value" --slow-limit="$value"
'')
];
# textsize
services.xserver.dpi = 200;
hardware.video.hidpi.enable = lib.mkDefault true;
# corectrl
programs.corectrl.enable = true;
users.users.mainUser.extraGroups = [ "corectrl" ];
# use newer ryzenadj
nixpkgs.config.packageOverrides = super: {
ryzenadj = super.ryzenadj.overrideAttrs (old: {
version = "unstable-2023-01-15";
src = pkgs.fetchFromGitHub {
owner = "FlyGoat";
repo = "RyzenAdj";
rev = "1052fb52b2c0e23ac4cd868c4e74d4a9510be57c"; # unstable on 2023-01-15
sha256 = "sha256-/IxkbQ1XrBrBVrsR4EdV6cbrFr1m+lGwz+rYBqxYG1k=";
};
});
};
# keyboard quirks
services.xserver.displayManager.sessionCommands = ''
xmodmap -e 'keycode 96 = F12 Insert F12 F12' # rebind shift + F12 to shift + insert
'';
services.udev.extraHwdb = /* sh */ ''
# disable back buttons
evdev:input:b0003v2F24p0135* # /dev/input/event2
KEYBOARD_KEY_70026=reserved
KEYBOARD_KEY_70027=reserved
'';
# ignore power key
services.logind.extraConfig = "HandlePowerKey=ignore";
}

View File

@ -0,0 +1,21 @@
{ lib, pkgs, test, ... }: let
npkgs = lib.importJSON ../../../krebs/nixpkgs-unstable.json;
in {
nixpkgs = (if test then lib.mkForce ({ derivation = let
rev = npkgs.rev;
sha256 = npkgs.sha256;
in ''
with import (builtins.fetchTarball {
url = "https://github.com/nixos/nixpkgs/archive/${rev}.tar.gz";
sha256 = "${sha256}";
}) {};
pkgs.fetchFromGitHub {
owner = "nixos";
repo = "nixpkgs";
rev = "${rev}";
sha256 = "${sha256}";
}
''; }) else {
git.ref = lib.mkForce npkgs.rev;
});
}

View File

@ -27,7 +27,7 @@ with import <stockholm/lib>;
krebs.build.host = config.krebs.hosts.green;
lass.sync-containers3.inContainer = {
krebs.sync-containers3.inContainer = {
enable = true;
pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFlUMf943qEQG64ob81p6dgoHq4jUjq7tSvmSdEOEU2y";
};

View File

@ -0,0 +1,53 @@
{ lib, disk, keyFile, ... }:
{
disk = {
main = {
type = "disk";
device = disk;
content = {
type = "table";
format = "gpt";
partitions = [
{
name = "boot";
type = "partition";
start = "0";
end = "1M";
part-type = "primary";
flags = ["bios_grub"];
}
{
type = "partition";
name = "ESP";
start = "1MiB";
end = "50%";
fs-type = "fat32";
bootable = true;
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
}
{
name = "root";
type = "partition";
start = "50%";
end = "100%";
content = {
type = "luks";
name = "hilum_luks";
keyFile = keyFile;
content = {
type = "filesystem";
format = "xfs";
mountpoint = "/";
};
};
}
];
};
};
};
}

View File

@ -0,0 +1,37 @@
#!/bin/sh
set -efux
disk=$1
export NIXPKGS_ALLOW_UNFREE=1
(umask 077; pass show admin/hilum/luks > /tmp/hilum.luks)
trap 'rm -f /tmp/hilum.luks' EXIT
stockholm_root=$(git rev-parse --show-toplevel)
ssh root@localhost -t -- $(nix-build \
--no-out-link \
-I nixpkgs=/var/src/nixpkgs \
-I stockholm="$stockholm_root" \
-I secrets="$stockholm_root"/lass/2configs/tests/dummy-secrets \
-E "with import <nixpkgs> {}; (pkgs.nixos [
{
luksPassFile = \"/tmp/hilum.luks\";
mainDisk = \"$disk\";
disko.rootMountPoint = \"/mnt/hilum\";
}
./physical.nix
]).disko"
)
rm -f /tmp/hilum.luks
$(nix-build \
--no-out-link \
-I nixpkgs=/var/src/nixpkgs \
"$stockholm_root"/lass/krops.nix -A populate \
--argstr name hilum \
--argstr target "root@localhost/mnt/hilum/var/src" \
--arg force true
)
ssh root@localhost << SSH
NIXOS_CONFIG=/mnt/hilum/var/src/nixos-config nixos-install --no-root-password --root /mnt/hilum -I /var/src
nixos-enter --root /mnt/hilum -- nixos-rebuild -I /var/src switch --install-bootloader
umount -Rv /mnt/hilum
SSH

View File

@ -1,11 +1,38 @@
{ lib, pkgs, ... }:
{ config, lib, pkgs, ... }:
{
imports = [
./config.nix
<nixpkgs/nixos/modules/installer/scan/not-detected.nix>
{
# nice hack to carry around state passed impurely at the beginning
options.mainDisk = let
tryFile = path: default:
if lib.elem (builtins.baseNameOf path) (lib.attrNames (builtins.readDir (builtins.dirOf path))) then
builtins.readFile path
else
default
;
in lib.mkOption {
type = lib.types.str;
default = tryFile "/etc/hilum-disk" "/dev/sdz";
};
config.environment.etc.hilum-disk.text = config.mainDisk;
}
{
options.luksPassFile = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
};
}
];
disko.devices = import ./disk.nix {
inherit lib;
disk = config.mainDisk;
keyFile = config.luksPassFile;
};
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "xhci_pci" "usb_storage" "sd_mod" "sdhci_pci" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-intel" ];
@ -13,21 +40,9 @@
boot.loader.grub.enable = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "/dev/disk/by-id/usb-General_USB_Flash_Disk_0374116060006128-0:0";
boot.loader.grub.device = config.mainDisk;
boot.loader.grub.efiInstallAsRemovable = true;
fileSystems."/" =
{ device = "/dev/disk/by-uuid/6db29cdd-ff64-496d-b541-5f1616665dc2";
fsType = "ext4";
};
boot.initrd.luks.devices."usb_nix".device = "/dev/disk/by-uuid/3c8ab3af-57fb-4564-9e27-b2766404f5d4";
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/2B9E-5131";
fsType = "vfat";
};
swapDevices = [ ];
nix.maxJobs = lib.mkDefault 4;

View File

@ -9,10 +9,16 @@
<stockholm/lass/2configs/consul.nix>
<stockholm/lass/2configs/yellow-host.nix>
<stockholm/lass/2configs/radio/container-host.nix>
<stockholm/lass/2configs/ubik-host.nix>
# other containers
<stockholm/lass/2configs/riot.nix>
];
krebs.build.host = config.krebs.hosts.neoprism;
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx.enable = true;
security.acme.acceptTerms = true;
security.acme.defaults.email = "acme@lassul.us";
}

View File

@ -0,0 +1,21 @@
with import <stockholm/lib>;
{ config, lib, pkgs, ... }:
{
imports = [
<stockholm/lass>
<stockholm/lass/2configs>
<stockholm/lass/2configs/retiolum.nix>
];
krebs.build.host = config.krebs.hosts.orange;
security.acme = {
acceptTerms = true;
defaults.email = "acme@lassul.us";
};
krebs.sync-containers3.inContainer = {
enable = true;
pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFQWzKuXrwQopBc1mzb2VpljmwAs7Y8bRl9a8hBXLC+l";
};
}

View File

@ -0,0 +1,7 @@
{
imports = [
./config.nix
];
boot.isContainer = true;
networking.useDHCP = true;
}

View File

@ -17,7 +17,7 @@ with import <stockholm/lib>;
defaults.email = "acme@lassul.us";
};
lass.sync-containers3.inContainer = {
krebs.sync-containers3.inContainer = {
enable = true;
pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOvPKdbVwMEFCDMyNAzR8NdVjTbQL2G+03Xomxn6KKFt";
};

View File

@ -0,0 +1,33 @@
with import <stockholm/lib>;
{ config, lib, pkgs, ... }:
{
imports = [
<stockholm/lass>
<stockholm/lass/2configs>
<stockholm/lass/2configs/retiolum.nix>
];
krebs.build.host = config.krebs.hosts.ubik;
krebs.sync-containers3.inContainer = {
enable = true;
pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPBFGMjH0+Dco6DVFZbByENMci8CFTLXCL7j53yctPnM";
};
networking.firewall.allowedTCPPorts = [ 80 ];
services.nextcloud = {
enable = true;
hostName = "c.apanowicz.de";
package = pkgs.nextcloud25;
config.adminpassFile = "/run/nextcloud.pw";
https = true;
};
systemd.services.nextcloud-setup.serviceConfig.ExecStartPre = [
"+${pkgs.writeDash "copy-pw" ''
${pkgs.rsync}/bin/rsync \
--chown nextcloud:nextcloud \
--chmod 0700 \
/var/src/secrets/nextcloud.pw /run/nextcloud.pw
''}"
];
}

View File

@ -0,0 +1,7 @@
{
imports = [
./config.nix
];
boot.isContainer = true;
networking.useDHCP = true;
}

View File

@ -9,7 +9,7 @@ in {
krebs.build.host = config.krebs.hosts.yellow;
lass.sync-containers3.inContainer = {
krebs.sync-containers3.inContainer = {
enable = true;
pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN737BAP36KiZO97mPKTIUGJUcr97ps8zjfFag6cUiYL";
};
@ -40,6 +40,7 @@ in {
security.acme.certs."jelly.r".server = config.krebs.ssl.acmeURL;
security.acme.certs."radar.r".server = config.krebs.ssl.acmeURL;
security.acme.certs."sonar.r".server = config.krebs.ssl.acmeURL;
security.acme.certs."transmission.r".server = config.krebs.ssl.acmeURL;
services.nginx = {
enable = true;
package = pkgs.nginx.override {
@ -152,6 +153,14 @@ in {
proxy_set_header Accept-Encoding "";
'';
};
virtualHosts."transmission.r" = {
enableACME = true;
addSSL = true;
locations."/".extraConfig = ''
proxy_pass http://localhost:9091/;
proxy_set_header Accept-Encoding "";
'';
};
virtualHosts."radar.r" = {
enableACME = true;
addSSL = true;

View File

@ -2,17 +2,19 @@
with import <stockholm/lib>;
{
# ipv6 from vodafone is really really flaky
boot.kernel.sysctl."net.ipv6.conf.et0.disable_ipv6" = 1;
systemd.network.networks."50-et0" = {
matchConfig.Name = "et0";
DHCP = "yes";
DHCP = "ipv4";
# dhcpV4Config.UseDNS = false;
# dhcpV6Config.UseDNS = false;
linkConfig = {
RequiredForOnline = "routable";
};
# networkConfig = {
# LinkLocalAddressing = "no";
# };
networkConfig = {
LinkLocalAddressing = "no";
};
# dhcpV6Config = {
# PrefixDelegationHint = "::/60";
# };
@ -23,14 +25,15 @@ with import <stockholm/lib>;
# Managed = true;
# };
};
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
systemd.network.networks."50-int0" = {
name = "int0";
address = [
"10.42.0.1/24"
];
networkConfig = {
IPForward = "yes";
IPMasquerade = "both";
# IPForward = "yes";
# IPMasquerade = "both";
ConfigureWithoutCarrier = true;
DHCPServer = "yes";
# IPv6SendRA = "yes";
@ -49,9 +52,16 @@ with import <stockholm/lib>;
krebs.iptables.tables.nat.PREROUTING.rules = mkBefore [
{ v6 = false; predicate = "-s 10.42.0.0/24"; target = "ACCEPT"; }
];
krebs.iptables.tables.nat.POSTROUTING.rules = [
{ v6 = false; predicate = "-s 10.42.0.0/24"; target = "MASQUERADE"; }
];
networking.domain = "gg23";
networking.useHostResolvConf = false;
services.resolved.extraConfig = ''
DNSStubListener=no
'';
services.dnsmasq = {
enable = true;
resolveLocalQueries = false;
@ -64,4 +74,12 @@ with import <stockholm/lib>;
interface=int0
'';
};
environment.systemPackages = [
(pkgs.writers.writeDashBin "restart_router" ''
${pkgs.mosquitto}/bin/mosquitto_pub -h localhost -t 'cmnd/router/POWER' -u gg23 -P gg23-mqtt -m OFF
sleep 2
${pkgs.mosquitto}/bin/mosquitto_pub -h localhost -t 'cmnd/router/POWER' -u gg23 -P gg23-mqtt -m ON
'')
];
}

View File

@ -1,10 +1,6 @@
{ config, pkgs, ... }:
{
imports = [
<stockholm/lass/2configs/container-networking.nix>
];
lass.sync-containers3.containers.green = {
krebs.sync-containers3.containers.green = {
sshKey = "${toString <secrets>}/green.sync.key";
};
}

View File

@ -1,5 +1,4 @@
with import <stockholm/lib>;
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
let
@ -14,7 +13,6 @@ let
port 465
tls on
tls_starttls off
tls_fingerprint 9C:82:3B:0F:31:CE:1B:8E:96:00:CC:C9:FF:E7:BE:66:95:92:4F:22:DD:D6:2E:0E:1D:90:76:BE:8E:9E:8E:16
auth on
user lassulus
passwordeval pass show c-base/pass
@ -24,11 +22,12 @@ let
notmuch-config = pkgs.writeText "notmuch-config" ''
[database]
path=/home/lass/Maildir
mail_root=/home/lass/Maildir
[user]
name=lassulus
primary_email=lassulus@lassul.us
other_email=lass@mors.r;${concatStringsSep ";" (flatten (attrValues mailboxes))}
other_email=lass@mors.r;${lib.concatStringsSep ";" (lib.flatten (lib.attrValues mailboxes))}
[new]
tags=unread;inbox;
@ -93,11 +92,37 @@ let
tag-new-mails = pkgs.writeDashBin "nm-tag-init" ''
${pkgs.notmuch}/bin/notmuch new
${concatMapStringsSep "\n" (i: ''${pkgs.notmuch}/bin/notmuch tag -inbox +${i.name} -- tag:inbox ${concatMapStringsSep " or " (f: "${f}") i.value}'') (mapAttrsToList nameValuePair mailboxes)}
${lib.concatMapStringsSep "\n" (i: ''
'') (lib.mapAttrsToList lib.nameValuePair mailboxes)}
${lib.concatMapStringsSep "\n" (i: ''
mkdir -p "$HOME/Maildir/.${i.name}/cur"
for mail in $(${pkgs.notmuch}/bin/notmuch search --output=files 'tag:inbox and (${lib.concatMapStringsSep " or " (f: "${f}") i.value})'); do
if test -e "$mail"; then
mv "$mail" "$HOME/Maildir/.${i.name}/cur/"
else
echo "$mail does not exist"
fi
done
${pkgs.notmuch}/bin/notmuch tag -inbox +${i.name} -- tag:inbox ${lib.concatMapStringsSep " or " (f: "${f}") i.value}
'') (lib.mapAttrsToList lib.nameValuePair mailboxes)}
${pkgs.notmuch}/bin/notmuch new
${pkgs.notmuch}/bin/notmuch dump > "$HOME/Maildir/notmuch.backup"
'';
tag-old-mails = pkgs.writeDashBin "nm-tag-old" ''
${concatMapStringsSep "\n" (i: ''${pkgs.notmuch}/bin/notmuch tag -inbox -archive +${i.name} -- ${concatMapStringsSep " or " (f: "${f}") i.value}'') (mapAttrsToList nameValuePair mailboxes)}
set -efux
${lib.concatMapStringsSep "\n" (i: ''
${pkgs.notmuch}/bin/notmuch tag -inbox -archive +${i.name} -- ${lib.concatMapStringsSep " or " (f: "${f}") i.value}
mkdir -p "$HOME/Maildir/.${i.name}/cur"
for mail in $(${pkgs.notmuch}/bin/notmuch search --output=files ${lib.concatMapStringsSep " or " (f: "${f}") i.value}); do
if test -e "$mail"; then
mv "$mail" "$HOME/Maildir/.${i.name}/cur/"
else
echo "$mail does not exist"
fi
done
'') (lib.mapAttrsToList lib.nameValuePair mailboxes)}
${pkgs.notmuch}/bin/notmuch new --no-hooks
'';
muttrc = pkgs.writeText "muttrc" ''
@ -110,17 +135,6 @@ let
set crypt_verify_sig = yes
set pgp_verify_command = "gpg --no-verbose --batch --output - --verify %s %f"
macro index \Cv \
"<enter-command> set my_crypt_verify_sig=\$crypt_verify_sig<enter> \
<enter-command> set crypt_verify_sig=yes<enter> \
<display-message><enter-command> set crypt_verify_sig=\$my_crypt_verify_sig<enter>" \
'Verify PGP signature and open the message'
macro pager \Cv \
"<exit><enter-command> set my_crypt_verify_sig=\$crypt_verify_sig<enter> \
<enter-command> set crypt_verify_sig=yes<enter> \
<display-message><enter-command> set crypt_verify_sig=\$my_crypt_verify_sig<enter>" \
'Verify PGP signature'
# read html mails
auto_view text/html
@ -138,8 +152,8 @@ let
set sendmail="${msmtp}/bin/msmtp" # enables parsing of outgoing mail
set from="lassulus@lassul.us"
alternates ^.*@lassul\.us$ ^.*@.*\.r$
set use_from=yes
set envelope_from=yes
unset envelope_from_address
set use_envelope_from
set reverse_name
set sort=threads
@ -148,7 +162,7 @@ let
virtual-mailboxes "Unread" "notmuch://?query=tag:unread"
virtual-mailboxes "INBOX" "notmuch://?query=tag:inbox"
${concatMapStringsSep "\n" (i: ''${" "}virtual-mailboxes "${i.name}" "notmuch://?query=tag:${i.name}"'') (mapAttrsToList nameValuePair mailboxes)}
${lib.concatMapStringsSep "\n" (i: ''${" "}virtual-mailboxes "${i.name}" "notmuch://?query=tag:${i.name}"'') (lib.mapAttrsToList lib.nameValuePair mailboxes)}
virtual-mailboxes "TODO" "notmuch://?query=tag:TODO"
virtual-mailboxes "Starred" "notmuch://?query=tag:*"
virtual-mailboxes "Archive" "notmuch://?query=tag:archive"
@ -166,6 +180,15 @@ let
macro index + "<modify-labels>+*\n<sync-mailbox>" # tag as starred
macro index - "<modify-labels>-*\n<sync-mailbox>" # tag as unstarred
# muchsync
bind index \Cr noop
macro index \Cr \
"<enter-command>unset wait_key<enter> \
<shell-escape>${pkgs.writeDash "muchsync" ''
set -efu
${pkgs.muchsync}/bin/muchsync -F lass@green.r
''}<enter> \
'run muchsync to green.r'
#killed
bind index d noop
@ -213,6 +236,9 @@ let
macro pager ,@3 "<enter-command> set pager_index_lines=7; macro pager ] ,@1 'Toggle indexbar<Enter>"
macro pager ] ,@1 'Toggle indexbar
# urlview
macro pager \cb <pipe-entry>'${pkgs.urlview}/bin/urlview'<enter> 'Follow links with urlview'
# sidebar
set sidebar_divider_char = ''
set sidebar_delim_chars = "/"

View File

@ -0,0 +1,15 @@
{ config, pkgs, ... }:
{
krebs.sync-containers3.containers.orange = {
sshKey = "${toString <secrets>}/orange.sync.key";
};
services.nginx.virtualHosts."lassul.us" = {
# enableACME = config.security;
# forceSSL = true;
locations."/" = {
recommendedProxySettings = true;
proxyWebsockets = true;
proxyPass = "http://orange.r";
};
};
}

View File

@ -1,6 +1,6 @@
{ config, pkgs, ... }:
{
lass.sync-containers3.containers.radio = {
krebs.sync-containers3.containers.radio = {
sshKey = "${toString <secrets>}/radio.sync.key";
};
containers.radio = {

View File

@ -8,7 +8,7 @@ in
];
lass.sync-containers3.containers.red = {
krebs.sync-containers3.containers.red = {
sshKey = "${toString <secrets>}/containers/red/sync.key";
ephemeral = true;
};

View File

@ -31,27 +31,31 @@
privateNetwork = true;
hostAddress = "10.233.1.1";
localAddress = "10.233.1.2";
forwardPorts = [
{ hostPort = 45622; containerPort = 22; }
];
};
systemd.network.networks."50-ve-riot" = {
matchConfig.Name = "ve-riot";
networkConfig = {
IPForward = "yes";
# weirdly we have to use POSTROUTING MASQUERADE here
# and set ip_forward manually
# IPForward = "yes";
# IPMasquerade = "both";
LinkLocalAddressing = "no";
KeepConfiguration = "static";
};
};
# networking.nat can be used instead of this
boot.kernel.sysctl."net.ipv4.ip_forward" = lib.mkDefault 1;
krebs.iptables.tables.nat.POSTROUTING.rules = [
{ v6 = false; predicate = "-s ${config.containers.riot.localAddress}"; target = "MASQUERADE"; }
];
# networking.nat can be used instead of this
krebs.iptables.tables.nat.PREROUTING.rules = [
{ predicate = "-p tcp --dport 45622"; target = "DNAT --to-destination ${config.containers.riot.localAddress}:22"; v6 = false; }
];
krebs.iptables.tables.filter.FORWARD.rules = [
{ predicate = "-i ve-riot"; target = "ACCEPT"; }
{ predicate = "-o ve-riot"; target = "ACCEPT"; }

View File

@ -0,0 +1,26 @@
{ config, pkgs, ... }:
{
krebs.sync-containers3.containers.ubik = {
sshKey = "${toString <secrets>}/ubik.sync.key";
};
containers.ubik.bindMounts."/var/lib" = {
hostPath = "/var/lib/sync-containers3/ubik/state";
isReadOnly = false;
};
containers.ubik.bindMounts."/var/lib/nextcloud/data" = {
hostPath = "/var/ubik";
isReadOnly = false;
};
services.nginx.virtualHosts."c.apanowicz.de" = {
enableACME = true;
forceSSL = true;
locations."/" = {
recommendedProxySettings = true;
proxyWebsockets = true;
proxyPass = "http://ubik.r";
extraConfig = ''
client_max_body_size 9001M;
'';
};
};
}

View File

@ -53,6 +53,7 @@ import XMonad.Util.EZConfig (additionalKeysP)
import XMonad.Util.NamedWindows (getName)
import XMonad.Util.Run (safeSpawn)
import XMonad.Util.Ungrab (unGrab)
import XMonad.Util.Paste (pasteSelection)
data LibNotifyUrgencyHook = LibNotifyUrgencyHook deriving (Read, Show)
@ -105,11 +106,9 @@ floatHooks = composeAll
myKeyMap :: [([Char], X ())]
myKeyMap =
[ ("M4-C-p", forkFile "${pkgs.scrot}/bin/scrot" [ "~/public_html/scrot.png" ] Nothing )
, ("M4-p", forkFile "${pkgs.pass}/bin/passmenu" [ "--type" ] Nothing)
[ ("M4-p", forkFile "${pkgs.pass}/bin/passmenu" [ "--type" ] Nothing)
, ("M4-S-p", forkFile "${pkgs.otpmenu}/bin/otpmenu" [] Nothing)
, ("M4-o", forkFile "${pkgs.brain}/bin/brainmenu --type" [] Nothing)
, ("M4-z", forkFile "${pkgs.emot-menu}/bin/emoticons" [] Nothing)
, ("M4-z", forkFile "${pkgs.unimenu}/bin/unimenu" [] Nothing)
, ("M4-S-q", restart "xmonad" True)
@ -177,13 +176,13 @@ myKeyMap =
, ("M4-<F10>", spawn "${pkgs.redshift}/bin/redshift -x")
, ("M4-<F11>", spawn "${config.lass.screenlock.command}")
, ("M4-<F12>", spawn "${pkgs.systemd}/bin/systemctl suspend -i")
, ("M4-u", spawn "${pkgs.xcalib}/bin/xcalib -invert -alter")
, ("M4-y", spawn "/run/current-system/sw/bin/switch-theme toggle")
, ("M4-s", spawn "${pkgs.knav}/bin/knav")
${lib.optionalString (builtins.hasAttr "warpd" pkgs) '', ("M4-s", spawn "${pkgs.warpd}/bin/warpd --hint")''}
, ("M4-i", spawn "/run/current-system/sw/bin/screenshot")
, ("S-<F12>", pasteSelection)
--, ("M4-w", screenWorkspace 0 >>= (windows . W.greedyView))
--, ("M4-e", screenWorkspace 1 >>= (windows . W.greedyView))

View File

@ -1,6 +1,6 @@
{ config, pkgs, ... }:
{
lass.sync-containers3.containers.yellow = {
krebs.sync-containers3.containers.yellow = {
sshKey = "${toString <secrets>}/yellow.sync.key";
};
containers.yellow.bindMounts."/var/lib" = {

View File

@ -3,6 +3,7 @@
environment.systemPackages = with pkgs; [
yubikey-personalization
yubikey-manager
pinentry-curses pinentry-qt
];
services.udev.packages = with pkgs; [ yubikey-personalization ];
@ -11,6 +12,7 @@
services.pcscd.enable = true;
systemd.user.services.gpg-agent.serviceConfig.ExecStartPre = pkgs.writers.writeDash "init_gpg" ''
set -x
mkdir -p $HOME/.gnupg
${pkgs.coreutils}/bin/ln -sf ${pkgs.writeText "scdaemon.conf" ''
disable-ccid
pcsc-driver ${pkgs.pcsclite.out}/lib/libpcsclite.so.1
@ -25,6 +27,10 @@
reader-port Yubico YubiKey
''} $HOME/.gnupg/scdaemon.conf
'';
systemd.user.services.gpg-agent.serviceConfig.ExecStartPost = pkgs.writers.writeDash "init_gpg" ''
${pkgs.gnupg}/bin/gpg --import ${../../kartei/lass/pgp/yubikey.pgp} >/dev/null
echo -e '5\ny\n' | gpg --command-fd 0 --expert --edit-key DBCD757846069B392EA9401D6657BE8A8D1EE807 trust >/dev/null || :
'';
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
@ -38,13 +44,14 @@
}
});
polkit.addRule(function(action, subject) {
polkit.log("subject: " + subject + " action: " + action);
polkit.log("subject: " + subject + " action: " + action);
});
'';
environment.shellInit = ''
if [ "$UID" -eq 1337 ] && [ -z "$SSH_CONNECTION" ]; then
export GPG_TTY="$(tty)"
mkdir -p $HOME/.gnupg
gpg-connect-agent --quiet updatestartuptty /bye > /dev/null
export SSH_AUTH_SOCK="/run/user/$UID/gnupg/S.gpg-agent.ssh"
if [ -z "$SSH_AUTH_SOCK" ]; then
@ -61,6 +68,7 @@
ssh.startAgent = false;
gnupg.agent = {
enable = true;
pinentryFlavor = "qt";
# enableSSHSupport = true;
};
};

View File

@ -15,6 +15,5 @@ _:
./xjail.nix
./autowifi.nix
./browsers.nix
./sync-containers3.nix
];
}

View File

@ -5,13 +5,21 @@ pkgs.writers.writeDashBin "install-system" ''
TARGET=$2
# format
if ! (sshn "$TARGET" -- mountpoint /mnt); then
nix run github:numtide/nixos-remote -- --stop-after-disko --store-paths "$(nix-build --no-out-link -I stockholm="$HOME"/sync/stockholm -I nixos-config="$HOME"/sync/stockholm/lass/1systems/"$SYSTEM"/physical.nix '<nixpkgs/nixos>' -A config.system.build.diskoNoDeps)" /dev/null "$TARGET"
if ! (sshn "$TARGET" -- type -p nix); then
nix run github:numtide/nixos-remote -- --stop-after-disko --store-paths "$(nix-build --no-out-link -I stockholm="$HOME"/sync/stockholm -I nixos-config="$HOME"/sync/stockholm/lass/1systems/"$SYSTEM"/physical.nix '<nixpkgs/nixos>' -A config.system.build.diskoNoDeps)" /dev/null "$TARGET"
else
disko=$(nix-build -I stockholm=$HOME/sync/stockholm -I secrets=$HOME/sync/stockholm/lass/2configs/tests/dummy-secrets -I nixos-config=$HOME/sync/stockholm/lass/1systems/$SYSTEM/physical.nix '<nixpkgs/nixos>' -A config.system.build.disko)
NIX_SSHOPTS='-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' nix-copy-closure --to "$TARGET" "$disko"
sshn -t "$TARGET" -- "$disko"
fi
fi
# install dependencies
sshn "$TARGET" << SSH
nix-channel --update
nix-env -iA nixos.git
if ! type -p git; then
nix-channel --update
nix-env -iA nixos.git
fi
SSH
# populate
@ -19,8 +27,9 @@ pkgs.writers.writeDashBin "install-system" ''
# install
sshn "$TARGET" << SSH
ln -s /mnt/var/src /var/src
NIXOS_CONFIG=/var/src/nixos-config nixos-install --no-root-password -I /var/src
NIXOS_CONFIG=/var/src/nixos-config nixos-install --no-root-password -I /mnt/var/src
nixos-enter -- nixos-rebuild -I /var/src switch --install-bootloader
umount -R /mnt
zpool export -fa
SSH
''

View File

@ -0,0 +1,91 @@
{
lib,
runCommand,
fetchurl,
writeText,
writers,
coreutils,
dmenu,
gnused,
libnotify,
xclip,
xdotool,
gawk,
}: let
unicode-file = runCommand "unicode.txt" {} ''
${
writers.writePython3 "generate.py" {flakeIgnore = ["E501" "E722"];} ''
import csv
with open("${
fetchurl {
url = "https://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt";
sha256 = "sha256-NgGOaGV/3LNIX2NmMP/oyFMuAcl3cD0oA/W4nWxf6vs=";
}
}", "r") as unicode_data:
reader = csv.reader(unicode_data, delimiter=";")
next(reader) # skip first row containing \0
for row in reader:
codepoint = row[0]
name = row[1]
alternate_name = row[10]
try:
print(chr(int(codepoint, 16)), codepoint, name, alternate_name, sep=" ")
except:
continue
''
} > $out
'';
kaomoji-file = writeText "kaomoji.txt" ''
¯\(°_o)/¯ dunno lol shrug dlol
¯\_()_/¯ dunno lol shrug dlol
( ͡° ͜ʖ ͡°) lenny
¯\_( ͡° ͜ʖ ͡°)_/¯ lenny shrug dlol
( д) aaah sad noo
(^o^)丿 hi yay hello
(^o^: ups hehe
(^^) yay
(´) angry argh
(^_^) byebye!! bye
<(^.^<) <(^.^)> (>^.^)> (7^.^)7 (>^.^<) dance
(-.-)Zzz... sleep
() oh noes woot
(°° table flip
() why woot
(___) gloom I see you
sad
(\/) (°,,,,°) (\/) krebs
(ل͜) putting table back
\(°°)/ flip all dem tablez
(`ω´) bear look
(ل͜) strong flex muscle bicep
(ò_óˇ) strong flex muscle bicep
(><) excite
( ` -´).* wizard spell magic
puss in boots big eye
̯̫̯̫(ˆ̮ ̮ˆ) nyan cat
ʕʔ bear
(ԾɷԾ) adventure time
() happy yay
() happy yay
(º º )/ panic
𓂺 penis
𓂸 penis
'';
in
# ref https://github.com/LukeSmithxyz/voidrice/blob/9fe6802122f6e0392c7fe20eefd30437771d7f8e/.local/bin/dmenuunicode
writers.writeDashBin "unimenu" ''
history_file=$HOME/.cache/unimenu
PATH=${lib.makeBinPath [coreutils dmenu gnused libnotify xclip xdotool]}
chosen=$(cat "$history_file" ${kaomoji-file} ${unicode-file} | dmenu -p unicode -i -l 10 | tee --append "$history_file" | sed "s/ .*//")
[ "$chosen" != "" ] || exit
echo "$chosen" | tr -d '\n' | xclip -selection clipboard
if [ -n "$1" ]; then
xdotool key Shift+Insert
else
notify-send --app-name="$(basename "$0")" "'$chosen' copied to clipboard." &
fi
''

View File

@ -11,8 +11,6 @@ with import ./lib;
<stockholm/tv/2configs/xsessions>
];
environment.homeBinInPath = true;
krebs.build.host = config.krebs.hosts.bu;
networking.hostId = lib.mkDefault "00000000";

View File

@ -41,8 +41,6 @@ with import ./lib;
fsType = "btrfs";
};
environment.homeBinInPath = true;
environment.systemPackages = with pkgs; [
(writeDashBin "play" ''
set -euf

View File

@ -39,6 +39,10 @@ with import ./lib;
esac
${pkgs.bash-fzf-history.bind}
if test -n "''${BASH_EXTRA_INIT-}"; then
. "$BASH_EXTRA_INIT"
fi
'';
promptInit = /* sh */ ''
case $UID in

View File

@ -1,8 +1,8 @@
with import ./lib;
{ config, pkgs, ... }: {
{ config, modulesPath, pkgs, ... }: {
imports = [
<nixpkgs/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix>
(modulesPath + "/services/hardware/sane_extra_backends/brscan4.nix")
];
krebs.nixpkgs.allowUnfreePredicate = pkg: any (eq (packageName pkg)) [

View File

@ -16,6 +16,7 @@ with import ./lib;
./nets/hkw.nix
./networkd.nix
./nginx
./nix.nix
./pki
./ssh.nix
./sshd.nix
@ -44,21 +45,12 @@ with import ./lib;
time.timeZone = "Europe/Berlin";
}
{
nix.extraOptions = ''
auto-optimise-store = true
'';
# TODO check if both are required:
nix.settings.extra-sandbox-paths = [
"/etc/protocols"
pkgs.iana-etc.outPath
];
}
{
nixpkgs.config.allowUnfree = false;
}
{
environment.homeBinInPath = true;
environment.profileRelativeEnvVars.PATH = mkForce [ "/bin" ];
environment.systemPackages = with pkgs; [
@ -137,4 +129,11 @@ with import ./lib;
];
}
];
nixpkgs.overlays =
mkAfter (optional config.hardware.video.hidpi.enable (self: super: {
alacritty-tv = super.alacritty-tv.override {
variant = "hidpi";
};
}));
}

View File

@ -4,8 +4,8 @@ with import ./lib;
../smartd.nix
{
nix.buildCores = 2;
nix.maxJobs = 2;
nix.settings.cores = 2;
nix.settings.max-jobs = 2;
}
(if lib.versionAtLeast (lib.versions.majorMinor lib.version) "21.11" then {
nix.daemonCPUSchedPolicy = "batch";

View File

@ -0,0 +1,32 @@
{ pkgs, ... }: {
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usbhid" ];
boot.initrd.kernelModules = [ "amdgpu" ];
boot.kernelModules = [ "kvm-amd" ];
hardware.cpu.amd.updateMicrocode = true;
hardware.enableRedistributableFirmware = true;
hardware.opengl.enable = true;
hardware.opengl.extraPackages = [
pkgs.amdvlk
pkgs.rocm-opencl-icd
pkgs.rocm-opencl-runtime
];
hardware.video.hidpi.enable = true;
networking.wireless.enable = true;
networking.wireless.interfaces = [
"wlp1s0"
];
networking.interfaces.wlp1s0.useDHCP = true;
nixpkgs.hostPlatform = "x86_64-linux";
services.illum.enable = true;
tv.lidControl.enable = true;
tv.hw.screens.primary.width = 2560;
tv.hw.screens.primary.height = 1600;
}

9
tv/2configs/nix.nix Normal file
View File

@ -0,0 +1,9 @@
{ pkgs, ... }: {
nix.settings.auto-optimise-store = true;
# TODO check if both are required:
nix.settings.extra-sandbox-paths = [
"/etc/protocols"
pkgs.iana-etc.outPath
];
}

View File

@ -1,24 +0,0 @@
{ pkgs, ... }:
with builtins;
let
users = [ "tv" ];
urxvt = pkgs.rxvt_unicode;
mkService = user: {
description = "urxvt terminal daemon";
wantedBy = [ "multi-user.target" ];
restartIfChanged = false;
serviceConfig = {
Restart = "always";
User = user;
ExecStart = "${urxvt}/bin/urxvtd";
};
};
in
{
environment.systemPackages = [ urxvt ];
systemd.services = listToAttrs (map (u: { name = "${u}-urxvtd"; value = mkService u; }) users);
}

View File

@ -11,18 +11,31 @@ with import ./lib;
environment.variables.VIMINIT = ":so /etc/vimrc";
};
extra-runtimepath = pkgs.tv.vim.makeRuntimePath [
pkgs.tv.vimPlugins.elixir
base-plugins = [
pkgs.tv.vimPlugins.file-line
pkgs.tv.vimPlugins.fzf
pkgs.tv.vimPlugins.hack
pkgs.vimPlugins.undotree
(pkgs.tv.vim.makePlugin (pkgs.write "vim-tv-base" {
"/ftplugin/haskell.vim".text = ''
if exists("g:vim_tv_ftplugin_haskell_loaded")
finish
endif
let g:vim_tv_ftplugin_haskell_loaded = 1
setlocal iskeyword+='
'';
}))
];
extra-plugins = [
pkgs.tv.vimPlugins.elixir
pkgs.tv.vimPlugins.fzf
pkgs.tv.vimPlugins.jq
pkgs.tv.vimPlugins.nix
pkgs.tv.vimPlugins.showsyntax
pkgs.tv.vimPlugins.tv
pkgs.tv.vimPlugins.vim
pkgs.vimPlugins.fzfWrapper
pkgs.vimPlugins.undotree
pkgs.vimPlugins.vim-nftables
];
@ -58,7 +71,9 @@ with import ./lib;
];
};
vimrc = pkgs.writeText "vimrc" ''
vimrc = pkgs.writeText "vimrc" /* vim */ ''
vim9script
set nocompatible
set autoindent
@ -71,7 +86,7 @@ with import ./lib;
set mouse=a
set noruler
set pastetoggle=<INS>
set runtimepath=${extra-runtimepath},$VIMRUNTIME
set runtimepath=${pkgs.tv.vim.makeRuntimePath base-plugins},$VIMRUNTIME
set shortmess+=I
set showcmd
set showmatch
@ -88,13 +103,15 @@ with import ./lib;
set wildmenu
set wildmode=longest,full
set runtimepath^=${pkgs.tv.vim.makeRuntimePath extra-plugins}
syntax on
set et ts=2 sts=2 sw=2
filetype plugin indent on
set t_Co=256
colorscheme hack
syntax on
au Syntax * syn match Garbage containedin=ALL /\s\+$/
\ | syn match TabStop containedin=ALL /\t\+/
@ -115,30 +132,52 @@ with import ./lib;
nnoremap <f1> :tabp<cr>
nnoremap <f2> :tabn<cr>
inoremap <f1> <esc>:tabp<cr>
inoremap <f2> <esc>:tabn<cr>
imap <f1> <esc><f1>
imap <f2> <esc><f2>
nnoremap <S-f1> :tabm -1<cr>
nnoremap <S-f2> :tabm +1<cr>
imap <S-f1> <esc><S-f1>
imap <S-f2> <esc><S-f2>
noremap <f3> :ShowSyntax<cr>
" <C-{Up,Down,Right,Left>
# <C-{Up,Down,Right,Left}>
noremap <esc>Oa <nop> | noremap! <esc>Oa <nop>
noremap <esc>Ob <nop> | noremap! <esc>Ob <nop>
noremap <esc>Oc <nop> | noremap! <esc>Oc <nop>
noremap <esc>Od <nop> | noremap! <esc>Od <nop>
" <[C]S-{Up,Down,Right,Left>
# <[C]S-{Up,Down,Right,Left}>
noremap <esc>[a <nop> | noremap! <esc>[a <nop>
noremap <esc>[b <nop> | noremap! <esc>[b <nop>
noremap <esc>[c <nop> | noremap! <esc>[c <nop>
noremap <esc>[d <nop> | noremap! <esc>[d <nop>
vnoremap u <nop>
" fzf
# fzf
nnoremap <esc>q :Buffers<cr>
nnoremap <esc>f :Files<cr>
nnoremap <esc>w :Rg<cr>
" edit alternate buffer
" For some reason neither putting <ctrl>6 nor <ctrl>^ works here...
# edit alternate buffer
# For some reason neither putting <ctrl>6 nor <ctrl>^ works here...
nnoremap <esc>a 
if $TOUCHSCREEN == "1"
nnoremap <ScrollWheelUp> <C-y>
nnoremap <ScrollWheelDown> <C-e>
nnoremap <C-ScrollWheelUp> 3<C-y>
nnoremap <C-ScrollWheelDown> 3<C-e>
nnoremap <S-ScrollWheelUp> 3<C-y>
nnoremap <S-ScrollWheelDown> 3<C-e>
nnoremap <C-S-ScrollWheelUp> <PageUp>
nnoremap <C-S-ScrollWheelDown> <PageDown>
endif
# remember last position
autocmd BufReadPost *
\ if line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "normal! g`\"" |
\ endif
'';
}

View File

@ -8,9 +8,12 @@
./hw.nix
./im.nix
./iptables.nix
./lidControl.nix
./org.freedesktop.machine1.host-shell.nix
./systemd.nix
./slock.nix
./x0vncserver.nix
./Xresources.nix
./wwan.nix
];
}

View File

@ -34,6 +34,10 @@ with import ./lib;
type = with types; listOf str;
default = [];
};
filter.Wiregrill = mkOption {
type = with types; listOf str;
default = [];
};
};
};
};
@ -66,6 +70,16 @@ with import ./lib;
default = [];
};
input-wiregrill-accept-tcp = mkOption {
type = with types; listOf (either int str);
default = [];
};
input-wiregrill-accept-udp = mkOption {
type = with types; listOf (either int str);
default = [];
};
extra = mkOption {
default = {};
type = extraTypes.rules;
@ -141,6 +155,7 @@ with import ./lib;
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:Retiolum - [0:0]
:Wiregrill - [0:0]
${concatMapStringsSep "\n" (rule: "-A INPUT ${rule}") ([]
++ [
"-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT"
@ -150,6 +165,7 @@ with import ./lib;
++ map accept-tcp (unique (map toString cfg.input-internet-accept-tcp))
++ map accept-udp (unique (map toString cfg.input-internet-accept-udp))
++ ["-i retiolum -j Retiolum"]
++ ["-i wiregrill -j Wiregrill"]
)}
${formatTable cfg.extra.filter}
${formatTable cfg."extra${toString iptables-version}".filter}
@ -170,6 +186,23 @@ with import ./lib;
];
}."ip${toString iptables-version}tables"
)}
${concatMapStringsSep "\n" (rule: "-A Wiregrill ${rule}") ([]
++ optional (cfg.accept-echo-request == "wiregrill") accept-echo-request
++ map accept-tcp (unique (map toString cfg.input-wiregrill-accept-tcp))
++ map accept-udp (unique (map toString cfg.input-wiregrill-accept-udp))
++ {
ip4tables = [
"-p tcp -j REJECT --reject-with tcp-reset"
"-p udp -j REJECT --reject-with icmp-port-unreachable"
"-j REJECT --reject-with icmp-proto-unreachable"
];
ip6tables = [
"-p tcp -j REJECT --reject-with tcp-reset"
"-p udp -j REJECT --reject-with icmp6-port-unreachable"
"-j REJECT"
];
}."ip${toString iptables-version}tables"
)}
COMMIT
'';
}

View File

@ -0,0 +1,45 @@
with import ./lib;
{ config, pkgs, ... }: {
options = {
tv.lidControl.enable = mkEnableOption "tv.lidControl";
};
config = let
cfg = config.tv.lidControl;
in mkIf cfg.enable {
services.acpid.enable = true;
services.acpid.lidEventCommands = /* sh */ ''
set -- $1
# usage: vt_is_xserver NUMBER
vt_is_xserver() {
${pkgs.iproute}/bin/ss -lp src unix:/tmp/.X11-unix/X* |
${pkgs.gnused}/bin/sed -n 's|.*/tmp/.X11-unix/X\([0-9]\+\)\>.*|\1|p' |
${pkgs.gnugrep}/bin/grep -Fqx "$1"
}
console=$(${pkgs.kbd}/bin/fgconsole)
if vt_is_xserver "$console"; then
# usage: run_on_display COMMAND [ARG...]
run_on_display() {
owner=$(${pkgs.coreutils}/bin/stat -c %u /tmp/.X11-unix/X$console)
${pkgs.systemd}/bin/systemd-run -GPq \
-E DISPLAY=:$console \
--uid=$owner \
"$@"
}
case $3 in
open)
run_on_display ${pkgs.xorg.xset}/bin/xset dpms force on
;;
close)
run_on_display ${pkgs.xorg.xset}/bin/xset dpms force off
;;
esac
fi
'';
services.logind.lidSwitch = "ignore";
services.logind.lidSwitchDocked = "ignore";
services.logind.lidSwitchExternalPower = "ignore";
};
}

47
tv/3modules/systemd.nix Normal file
View File

@ -0,0 +1,47 @@
with import ./lib;
{ config, ... }: let
normalUsers = filterAttrs (_: getAttr "isNormalUser") config.users.users;
in {
options = {
tv.systemd.services = mkOption {
type = types.attrsOf (types.submodule (self: {
options = {
operators = mkOption {
type = with types; listOf (enum (attrNames normalUsers));
default = [];
};
};
}));
default = {};
};
};
config = {
security.polkit.extraConfig = let
access =
mapAttrs'
(name: cfg:
nameValuePair "${name}.service"
(genAttrs cfg.operators (const true))
)
config.tv.systemd.services;
in optionalString (access != {}) /* js */ ''
polkit.addRule(function () {
const access = ${lib.toJSON access};
return function (action, subject) {
if (action.id === "org.freedesktop.systemd1.manage-units") {
const unit = action.lookup("unit");
if (
(access[unit]||{})[subject.user] ||
(
unit.includes("@") &&
(access[unit.replace(/@[^.]+/, "@")]||{})[subject.user]
)
) {
return polkit.Result.YES;
}
}
}
}());
'';
};
}

181
tv/3modules/wwan.nix Normal file
View File

@ -0,0 +1,181 @@
with import ./lib;
{ config, pkgs, ... }: {
options = {
tv.wwan.enable = mkEnableOption "tv.wwan";
tv.wwan.apn = mkOption {
type = with types; filename;
};
tv.wwan.device = mkOption {
type = with types; pathname;
default = "/dev/cdc-wdm0";
};
tv.wwan.interface = mkOption {
type = with types; nullOr filename;
default = null;
};
tv.wwan.operators = mkOption {
type = with types; listOf username;
default = [];
};
tv.wwan.secrets = mkOption {
type = with types; pathname;
default = toString <secrets/wwan.json>;
# format: {"pin1":number}
};
};
config = let
cfg = config.tv.wwan;
in mkIf cfg.enable {
nixpkgs.overlays = singleton (self: super: {
uqmi-wrapper = pkgs.symlinkJoin {
name = "uqmi-wrapper";
paths = [
(pkgs.writeDashBin "uqmi" ''
exec ${pkgs.uqmi}/bin/uqmi --device=${cfg.device} "$@"
'')
(pkgs.writeTextDir "share/bash-completion/completions/uqmi" /* sh */''
_uqmi_complete() {
case ''${#COMP_WORDS[@]} in
2)
COMPREPLY=($(compgen -W "$(
${pkgs.uqmi}/bin/uqmi --help 2>&1 |
${pkgs.coreutils}/bin/tr , \\n |
${pkgs.gnused}/bin/sed -nr 's/^ *(-[a-z-]+).*/\1/p'
)" -- "''${COMP_WORDS[1]}"))
;;
esac
}
complete -F _uqmi_complete uqmi
'')
pkgs.uqmi
];
};
});
systemd.services.wwan = {
environment = {
SECRETS = "%d/secrets";
};
path = [
pkgs.busybox
pkgs.coreutils
pkgs.iproute2
pkgs.jq
pkgs.uqmi-wrapper
(pkgs.writeDashBin "get-interface" (
if cfg.interface != null then /* sh */ ''
echo ${cfg.interface}
'' else /* sh */ ''
exec ${pkgs.libqmi}/bin/qmicli -d ${cfg.device} -p --get-wwan-iface
''
))
];
serviceConfig = {
LoadCredential = [
"secrets:${cfg.secrets}"
];
Type = "oneshot";
RemainAfterExit = true;
SyslogIdentifier = "wwan";
ExecStart = pkgs.writeDash "tv.wwan.start.sh" ''
set -efu
interface=$(get-interface)
pin1_status=$(
uqmi --uim-get-sim-state |
jq -r '"\(.pin1_status)/\(.pin1_verify_tries)"'
)
case $pin1_status in
verified/*)
:
;;
not_verified/3)
pin1=$(jq .pin1 "$SECRETS")
echo "verifying PIN1" >&2
if ! uqmi --uim-verify-pin1 "$pin1"; then
echo "error: failed to verify PIN1" >&2
exit 1
fi
;;
not_verified/*)
echo "error: not trying to verify PIN1: not enough tries left" >&2
echo \
"please check your configuration in ${cfg.secrets}" \
" and verify if manually using:" \
" ${pkgs.uqmi}/bin/uqmi -d $device --uim-veriy-pin1 XXXX" \
>&2
exit 1
esac
raw_ip_path=/sys/class/net/$interface/qmi/raw_ip
raw_ip=$(cat "$raw_ip_path")
if [ "$raw_ip" != Y ]; then
echo "enabling raw-ip" >&2
if ! echo Y > "$raw_ip_path"; then
echo "error: failed to enable raw-ip" >&2
exit 1
fi
fi
operating_mode=$(uqmi --get-device-operating-mode | tr -d \")
case $operating_mode in
online)
:
;;
persistent_low_power|low_power)
echo "settings device operating mode to online" >&2
uqmi --set-device-operating-mode online
operating_mode=$(uqmi --get-device-operating-mode | tr -d \")
if test "$operating_mode" != online; then
echo "error: failed to set device operating mode to online" >&2
exit 1
fi
;;
*)
echo "error: don't know how to change device operating mode to online: $operating_mode" >&2
exit 1
esac
ip link set dev "$interface" up
data_status=$(uqmi --get-data-status | tr -d \")
case $data_status in
connected)
:
;;
disconnected)
echo "starting network (APN=${cfg.apn})" >&2
sleep 1
uqmi \
--start-network \
--autoconnect \
--apn ${cfg.apn} \
--ip-family ipv4
sleep 1
;;
*)
echo "error: unsupported data status: $data_status" >&2
exit 1
esac
udhcpc -q -f -n -i "$interface"
'';
Restart = "on-failure";
ExecStop = pkgs.writeDash "tv.wwan.stop.sh" ''
set -efu
interface=$(get-interface)
ip link set dev "$interface" down
uqmi --stop-network 0xFFFFFFFF --autoconnect
uqmi --sync
uqmi --set-device-operating-mode persistent_low_power
'';
};
};
users.users.root.packages = [
pkgs.uqmi-wrapper
];
tv.systemd.services.wwan.operators = cfg.operators;
};
}

View File

@ -1,24 +0,0 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
module Build where
import XMonad (Dimension)
import THEnv.JSON (getCompileEnvJSONExp)
myFont :: String
myFont =
"-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*"
myScreenWidth :: Dimension
myScreenWidth =
$(getCompileEnvJSONExp (id @Dimension) "XMONAD_BUILD_SCREEN_WIDTH")
myTermFontWidth :: Dimension
myTermFontWidth =
$(getCompileEnvJSONExp (id @Dimension) "XMONAD_BUILD_TERM_FONT_WIDTH")
myTermPadding :: Dimension
myTermPadding =
2

View File

@ -1,18 +0,0 @@
{-# LANGUAGE ScopedTypeVariables #-}
module THEnv.JSON where
import Data.Aeson (eitherDecode,FromJSON)
import Data.ByteString.Lazy.Char8 (pack)
import Language.Haskell.TH.Syntax (Exp,Lift(lift),Q)
import THEnv (getCompileEnv)
import Control.Monad
getCompileEnvJSON :: (FromJSON a) => String -> Q a
getCompileEnvJSON name =
either error (id :: a -> a) . eitherDecode . pack <$> getCompileEnv name
getCompileEnvJSONExp ::
forall proxy a. (FromJSON a, Lift a) => proxy a -> String -> Q Exp
getCompileEnvJSONExp _ =
(lift :: a -> Q Exp) <=< getCompileEnvJSON

View File

@ -1,12 +1,18 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
module Main (main) where
import System.Exit (exitFailure)
import XMonad.Hooks.EwmhDesktops (ewmh)
import XMonad.Hooks.RefocusLast (refocusLastLayoutHook, toggleFocus)
import Control.Exception
import Control.Monad.Extra (whenJustM)
import qualified Data.Aeson
import qualified Data.ByteString.Char8
import qualified Data.List
import qualified Data.Maybe
import Graphics.X11.ExtraTypes.XF86
import Text.Read (readEither)
import XMonad
@ -20,11 +26,18 @@ import XMonad.Actions.CycleWS (toggleWS)
import XMonad.Layout.NoBorders ( smartBorders )
import XMonad.Layout.ResizableTile (ResizableTall(ResizableTall))
import XMonad.Layout.ResizableTile (MirrorResize(MirrorExpand,MirrorShrink))
import XMonad.Layout.StateFull (pattern StateFull)
import qualified XMonad.Prompt
import qualified XMonad.StackSet as W
import Data.Map (Map)
import qualified Data.Map as Map
import XMonad.Hooks.UrgencyHook (SpawnUrgencyHook(..), withUrgencyHook)
import XMonad.Hooks.UrgencyHook
( BorderUrgencyHook(BorderUrgencyHook,urgencyBorderColor)
, RemindWhen(Dont)
, SuppressWhen(Never)
, UrgencyConfig(UrgencyConfig,remindWhen,suppressWhen)
, withUrgencyHookC
)
import XMonad.Hooks.ManageHelpers (doCenterFloat,doRectFloat)
import Data.Ratio
import XMonad.Hooks.Place (placeHook, smart)
@ -32,8 +45,6 @@ import XMonad.Actions.PerWorkspaceKeys (chooseAction)
import Shutdown (shutdown, newShutdownEventHandler)
import Build (myFont, myScreenWidth, myTermFontWidth, myTermPadding)
main :: IO ()
main = getArgs >>= \case
@ -45,21 +56,39 @@ main = getArgs >>= \case
(=??) :: Query a -> (a -> Bool) -> Query Bool
(=??) x p = fmap p x
readEnv :: Data.Aeson.FromJSON b => String -> IO b
readEnv name =
Data.Maybe.fromJust
. Data.Aeson.decodeStrict'
. Data.ByteString.Char8.pack
<$> getEnv name
mainNoArgs :: IO ()
mainNoArgs = do
myScreenWidth <- readEnv "XMONAD_SCREEN_WIDTH" :: IO Dimension
myTermFont <- getEnv "XMONAD_TERM_FONT"
myTermFontWidth <- readEnv "XMONAD_TERM_FONT_WIDTH" :: IO Dimension
myTermPadding <- readEnv "XMONAD_TERM_PADDING" :: IO Dimension
workspaces0 <- getWorkspaces0
handleShutdownEvent <- newShutdownEventHandler
let
config =
id
$ withUrgencyHook (SpawnUrgencyHook "echo emit Urgency ")
ewmh
$ withUrgencyHookC
BorderUrgencyHook
{ urgencyBorderColor = "#ff0000"
}
UrgencyConfig
{ remindWhen = Dont
, suppressWhen = Never
}
$ def
{ terminal = {-pkg:rxvt_unicode-}"urxvtc"
{ terminal = {-pkg:alacritty-tv-}"alacritty"
, modMask = mod4Mask
, keys = myKeys
, keys = myKeys myTermFont
, workspaces = workspaces0
, layoutHook =
refocusLastLayoutHook $
smartBorders $
ResizableTall
1
@ -67,7 +96,7 @@ mainNoArgs = do
(fromIntegral (80 * myTermFontWidth + 2 * (myTermPadding + borderWidth def)) / fromIntegral myScreenWidth)
[]
|||
Full
StateFull
, manageHook =
composeAll
[ appName =? "fzmenu-urxvt" --> doCenterFloat
@ -113,20 +142,20 @@ forkFile path args env =
spawnRootTerm :: X ()
spawnRootTerm =
forkFile
{-pkg:rxvt_unicode-}"urxvtc"
["-name", "root-urxvt", "-e", "/run/wrappers/bin/su", "-"]
{-pkg:alacritty-tv-}"alacritty"
["--profile=root", "-e", "/run/wrappers/bin/su", "-"]
Nothing
myKeys :: XConfig Layout -> Map (KeyMask, KeySym) (X ())
myKeys conf = Map.fromList $
myKeys :: String -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
myKeys font conf = Map.fromList $
[ ((_4 , xK_Escape ), forkFile {-pkg-}"slock" [] Nothing)
, ((_4S , xK_c ), kill)
, ((_4 , xK_o ), forkFile {-pkg:fzmenu-}"otpmenu" [] Nothing)
, ((_4 , xK_p ), forkFile {-pkg:fzmenu-}"passmenu" [] Nothing)
, ((_4 , xK_x ), forkFile {-pkg:rxvt_unicode-}"urxvtc" [] Nothing)
, ((_4 , xK_x ), forkFile {-pkg:alacritty-tv-}"alacritty" ["--singleton"] Nothing)
, ((_4C , xK_x ), spawnRootTerm)
, ((_C , xK_Menu ), toggleWS)
@ -134,6 +163,8 @@ myKeys conf = Map.fromList $
, ((_4 , xK_space ), withFocused $ \w -> ifM (isFloatingX w) xdeny $ sendMessage NextLayout)
, ((_4M , xK_space ), withFocused $ \w -> ifM (isFloatingX w) xdeny $ resetLayout)
, ((_4 , xK_l ), toggleFocus)
, ((_4 , xK_m ), windows W.focusMaster)
, ((_4 , xK_j ), windows W.focusDown)
, ((_4 , xK_k ), windows W.focusUp)
@ -162,6 +193,7 @@ myKeys conf = Map.fromList $
, ((0, xF86XK_AudioLowerVolume), audioLowerVolume)
, ((0, xF86XK_AudioRaiseVolume), audioRaiseVolume)
, ((0, xF86XK_AudioMute), audioMute)
, ((0, xF86XK_AudioMicMute), audioMicMute)
, ((_4, xF86XK_AudioMute), pavucontrol [])
, ((_4, xK_Prior), forkFile {-pkg-}"xcalib" ["-invert", "-alter"] Nothing)
@ -188,21 +220,20 @@ myKeys conf = Map.fromList $
audioLowerVolume = amixer ["-q", "sset", "Master", "5%-"]
audioRaiseVolume = amixer ["-q", "sset", "Master", "5%+"]
audioMute = amixer ["-q", "sset", "Master", "toggle"]
audioMicMute = amixer ["-q", "sset", "Capture", "toggle"]
resetLayout = setLayout $ XMonad.layoutHook conf
promptXPConfig =
def { XMonad.Prompt.font = myFont }
def { XMonad.Prompt.font = font }
xdeny :: X ()
xdeny =
forkFile
{-pkg-}"xterm"
[ "-fn", myFont
, "-geometry", "300x100"
, "-name", "AlertFloat"
, "-bg", "#E4002B"
, "-e", "sleep", "0.05"
]
Nothing
xdeny =
forkFile
{-pkg-}"xterm"
[ "-fn", font
, "-geometry", "300x100"
, "-name", "AlertFloat"
, "-bg", "#E4002B"
, "-e", "sleep", "0.05"
]
Nothing

View File

@ -23,7 +23,6 @@ executable xmonad
xmonad,
xmonad-contrib
other-modules:
Shutdown,
THEnv.JSON
Shutdown
default-language: Haskell2010
ghc-options: -O2 -Wall -threaded

View File

@ -0,0 +1,14 @@
self: super:
super.alacritty.overrideAttrs (old:
assert self.lib.versions.majorMinor old.version == "0.11";
{
version = "${old.version}-tv";
src = self.fetchFromGitHub {
owner = "4z3";
repo = "alacritty";
rev = "touchscreen-support-0.11";
hash = "sha256-oA4earrJ7lPVSBm9vRccWatAQ49hfDKsa7M72B5uQpY=";
};
}
)

View File

@ -0,0 +1,10 @@
self: super:
super.uqmi.overrideAttrs (old: {
version = "unstable-2022-05-04";
src = self.fetchgit {
url = "https://git.openwrt.org/project/uqmi.git";
rev = "56cb2d4056fef132ccf78dfb6f3074ae5d109992";
hash = "sha256-PwnR24PbNKfLrsBlU5JTOHDzs/9Wgcuwfnu3dJuuZcM=";
};
})

View File

@ -1,4 +1,6 @@
{ pkgs }:
{ pkgs
, variant ? "x220"
}:
let
lib = import ./lib;
@ -6,7 +8,7 @@ let
program = "${pkgs.font-size-alacritty}/bin/font-size-alacritty";
args = [arg];
};
config = {
configs.default = lib.recursiveUpdate variants.${variant} {
bell.animation = "EaseOut";
bell.duration = 50;
bell.color = "#ff00ff";
@ -30,10 +32,6 @@ let
colors.bright.cyan = "#72fbfb";
colors.bright.white = "#fbfbfb";
draw_bold_text_with_bright_colors = true;
font.normal.family = "Clean";
font.bold.family = "Clean";
font.bold.style = "Regular";
font.size = 10;
hints.enabled = [
{
regex = "(ipfs:|ipns:|magnet:|mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)[^\\u0000-\\u001F\\u007F-\\u009F<>\"\\s{-}\\^`]+";
@ -42,15 +40,73 @@ let
action = "Select";
}
];
scrolling.multiplier = 8;
};
configs.root = lib.recursiveUpdate configs.default {
colors.primary.background = "#230000";
colors.primary.foreground = "#e0c0c0";
colors.normal.black = "#800000";
};
configs.fzmenu = lib.recursiveUpdate configs.default {
colors.primary.background = "#2A172A";
window.dimensions.columns = 70;
window.dimensions.lines = 9;
};
variants.hidpi = {
font.normal.family = "iosevka-tv-1";
font.bold.family = "iosevka-tv-1";
font.italic.family = "iosevka-tv-1";
font.bold_italic.family = "iosevka-tv-1";
font.size = 5;
key_bindings = [
{ key = "Up"; mods = "Control"; action = "IncreaseFontSize"; }
{ key = "Down"; mods = "Control"; action = "DecreaseFontSize"; }
{ key = "Down"; mods = "Shift|Control"; action = "ResetFontSize"; }
];
};
variants.x220 = {
font.normal.family = "Clean";
font.bold.family = "Clean";
font.bold.style = "Regular";
font.size = 10;
key_bindings = [
{ key = "Up"; mods = "Shift|Control"; command = font-size "=14"; }
{ key = "Up"; mods = "Control"; command = font-size "+1"; }
{ key = "Down"; mods = "Control"; command = font-size "-1"; }
{ key = "Down"; mods = "Shift|Control"; command = font-size "=0"; }
];
scrolling.multiplier = 8;
};
config-file = pkgs.writeJSON "alacritty-tv.json" config;
writeProfile = name: config: let
config-file =
assert lib.types.filename.check name;
pkgs.writeJSON "alacritty-tv-${name}.json" config;
in pkgs.writeText "alacritty-tv-${name}.profile" /* sh */ ''
# Use home so Alacritty can find the configuration without arguments.
# HOME will be reset once in Alacritty.
HOME=$XDG_RUNTIME_DIR/Alacritty-${name}
export HOME
# Tell Alacritty via XDG_RUNTIME_DIR where to create sockets.
# XDG_RUNTIME_DIR needs to be reset manually.
export ALACRITTY_XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR"
export BASH_EXTRA_INIT=${pkgs.writeDash "alacritty-tv.cleanup.sh" ''
XDG_RUNTIME_DIR=$ALACRITTY_XDG_RUNTIME_DIR
unset ALACRITTY_XDG_RUNTIME_DIR
unset BASH_EXTRA_INIT
''}
export XDG_RUNTIME_DIR="$HOME"
# Install stored configuration if it has changed.
# This allows for both declarative updates and runtime modifications.
# rust-xdg requires XDG_RUNTIME_DIR to be secure:
# https://docs.rs/xdg/2.4.1/src/xdg/lib.rs.html#311
${pkgs.coreutils}/bin/mkdir -m 0700 -p "$HOME"
ref=$(! test -e "$HOME"/ref || ${pkgs.coreutils}/bin/cat "$HOME"/ref)
if test "$ref" != ${config-file}; then
echo ${config-file} > "$HOME"/ref
${pkgs.coreutils}/bin/cp ${config-file} "$HOME"/.alacritty.yml
fi
'';
in
pkgs.symlinkJoin {
@ -58,31 +114,35 @@ pkgs.symlinkJoin {
paths = [
(pkgs.writeDashBin "alacritty" ''
# usage:
# alacritty [--singleton] [ARGS...]
# alacritty [--profile=PROFILE] [--singleton] [ARGS...]
# where
# PROFILE one of ${lib.toJSON (lib.attrNames configs)}
set -efu
# Use home so Alacritty can find the configuration without arguments.
# HOME will be reset once in Alacritty.
HOME=$TMPDIR/Alacritty
export HOME
case ''${1-} in
${lib.concatMapStringsSep "\n" (name: /* sh */ ''
--${lib.shell.escape name}|--profile=${lib.shell.escape name})
shift
profile=${writeProfile name configs.${name}}
;;
'') (lib.attrNames configs)}
*)
profile=${writeProfile "default" configs.default}
;;
esac
# Install stored configuration if it has changed.
# This allows for both declarative updates and runtime modifications.
${pkgs.coreutils}/bin/mkdir -p "$HOME"
if test "$(${pkgs.coreutils}/bin/cat "$HOME"/ref)" != ${config-file}; then
echo ${config-file} > "$HOME"/ref
${pkgs.coreutils}/bin/cp ${config-file} "$HOME"/.alacritty.yml
fi
case ''${1-} in
--singleton)
shift
if ! ${pkgs.alacritty}/bin/alacritty msg create-window "$@"; then
. "$profile"
${pkgs.alacritty}/bin/alacritty "$@" &
fi
;;
*)
. "$profile"
exec ${pkgs.alacritty}/bin/alacritty "$@"
;;
esac

View File

@ -6,7 +6,7 @@ set -efu
case ${FZMENU_PHASE-0} in
0)
export FZMENU_PHASE=1
exec setsid -f urxvt -name fzmenu-urxvt -e dash "$0"
exec setsid -f terminal dash "$0"
;;
1)
if result=$(

View File

@ -6,7 +6,7 @@ set -efu
case ${FZMENU_PHASE-0} in
0)
export FZMENU_PHASE=1
exec setsid -f urxvt -name fzmenu-urxvt -e dash "$0"
exec setsid -f terminal dash "$0"
;;
1)
if result=$(

View File

@ -1,5 +1,15 @@
{ lib, pkgs, stdenv }:
let
terminal = pkgs.writeDashBin "terminal" ''
# usage: terminal COMMAND [ARGS...]
exec ${pkgs.alacritty-tv}/bin/alacritty \
--profile=fzmenu \
--class AlacrittyFzmenuFloat \
-e "$@"
'';
in
pkgs.runCommand "fzmenu" {
} /* sh */ ''
mkdir $out
@ -16,9 +26,9 @@ pkgs.runCommand "fzmenu" {
(pkgs.pass.withExtensions (ext: [
ext.pass-otp
]))
pkgs.rxvt_unicode
pkgs.utillinux
pkgs.xdotool
terminal
]}
substituteInPlace $out/bin/passmenu \
@ -31,8 +41,8 @@ pkgs.runCommand "fzmenu" {
(pkgs.pass.withExtensions (ext: [
ext.pass-otp
]))
pkgs.rxvt_unicode
pkgs.utillinux
pkgs.xdotool
terminal
]}
''

View File

@ -0,0 +1,18 @@
{ pkgs }:
pkgs.iosevka.override {
# https://typeof.net/Iosevka/customizer
privateBuildPlan = {
family = "iosevka-tv-1";
spacing = "term";
serifs = "sans";
export-glyph-names = true;
no-ligation = true;
no-cv-ss = false;
widths.normal.shape = 600;
widths.normal.menu = 5;
widths.normal.css = "normal";
};
set = "iosevka-tv-1";
}

View File

@ -2,10 +2,10 @@
# cannot use pkgs.vimPlugins.fzf-vim as it's missing :Rg
pkgs.vimUtils.buildVimPlugin {
name = "fzf-2018-11-14";
name = "fzf-2023-01-16";
src = pkgs.fetchgit {
url = https://github.com/junegunn/fzf.vim;
rev = "ad1833ecbc9153b6e34a4292dc089a58c4bcb8dc";
sha256 = "1z2q71q6l9hq9fqfqpj1svhyk4yk1bzw1ljhksx4bnpz8gkfbx2m";
rev = "bdf48c282ad2174c25c059b3cdb7956427b07a99";
hash = "sha256-eCCk+Q596Ljjdtjd0cYGqR77K3Me5gf+ts5icP22S3Y=";
};
}

View File

@ -42,5 +42,8 @@ in {
hi diffRemoved ctermfg=009
hi Search cterm=NONE ctermbg=216
hi TabLine cterm=underline guifg=#424242 guibg=#232323
hi TabLineFill cterm=underline guifg=#424242 guibg=#232323
'';
}))

View File

@ -1,17 +1,6 @@
{ pkgs }:
pkgs.tv.vim.makePlugin (pkgs.write "vim-tv" {
#
# Haskell
#
"/ftplugin/haskell.vim".text = ''
if exists("g:vim_tv_ftplugin_haskell_loaded")
finish
endif
let g:vim_tv_ftplugin_haskell_loaded = 1
setlocal iskeyword+='
'';
#
# TODO
#