Reorganize repository

This commit is contained in:
Charlotte Van Petegem 2021-07-10 09:03:38 +02:00
parent da1824edb6
commit 0fc6c32a47
No known key found for this signature in database
GPG key ID: 019E764B7184435A
124 changed files with 16295 additions and 1229 deletions

View file

@ -24,3 +24,52 @@ files that end in `secret.nix`.
* Execute `ln -s /path/to/correct/file.nix shell.nix`.
* Execute `direnv allow` to load the `.envrc` file which in turn loads your environment.
## Setting up ZFS
1. Create three partitions:
* Boot
* Swap
* ZFS
For example:
```shell
sgdisk -n 0:0:+512MiB -t 0:EF00 -c 0:boot $DISK
sgdisk -n 0:0:+32GiB -t 0:8200 -c 0:swap $DISK
sgdisk -n 0:0:0 -t 0:BF01 -c 0:ZFS $DISK
```
2. Configure swap and boot as usual.
3. Create ZPool:
```shell
zpool create -O mountpoint=none -O encryption=aes-256-gcm -O keyformat=passphrase rpool $ZFS_PART
```
Leave out `-O encryption=aes-256-gcm -O keyformat=passphrase` if you don't want to fully encrypt the ZFS partition.
4. Create datasets:
```shell
zfs create -o mountpoint=legacy rpool/local/root
zfs snapshot rpool/local/root@blank
zfs create -o mountpoint=legacy rpool/local/nix
zfs set compression=lz4 rpool/local/nix
zfs create -o mountpoint=legacy rpool/local/cache
zfs set compression=lz4 rpool/local/cache
zfs create -o mountpoint=legacy rpool/safe/data
zfs set compression=lz4 rpool/local/data
```
5. Mount datasets:
```shell
mount -t zfs rpool/local/root /mnt
mkdir /mnt/nix
mount -t zfs rpool/local/nix /mnt/nix
mkdir /mnt/boot
mount $BOOT_PART /mnt/boot
mkdir /mnt/cache
mount -t zfs rpool/local/cache /mnt/cache
mkdir /mnt/data
mount -t zfs rpool/safe/data /mnt/data
```
6. Configure Host ID
Set `networking.hostid` in the nixos config to `head -c 8 /etc/machine-id`.

View file

@ -1,35 +0,0 @@
{ config, ... }:
{
imports = [ ./secret.nix ];
config = {
chvp.hasContainers = true;
containers.data-access = {
ephemeral = true;
autoStart = true;
bindMounts = {
"/home/data/data" = {
hostPath = "/srv/data";
isReadOnly = false;
};
"/run/secrets" = {
hostPath = "/run/secrets/data-access";
isReadOnly = true;
};
};
privateNetwork = true;
hostAddress = "192.168.100.10";
hostAddress6 = "fc00::1";
localAddress = "192.168.100.11";
localAddress6 = "fc00::2";
config = import ./config.nix;
};
age.secrets."data-access/ssh_host_rsa_key".file = ../../secrets/data-access/ssh_host_rsa_key.age;
age.secrets."data-access/ssh_host_rsa_key.pub".file = ../../secrets/data-access/ssh_host_rsa_key.pub.age;
age.secrets."data-access/ssh_host_ed25519_key".file = ../../secrets/data-access/ssh_host_ed25519_key.age;
age.secrets."data-access/ssh_host_ed25519_key.pub".file = ../../secrets/data-access/ssh_host_ed25519_key.pub.age;
};
}

Binary file not shown.

12
flake.lock generated
View file

@ -22,11 +22,11 @@
},
"emacs-overlay": {
"locked": {
"lastModified": 1625822801,
"narHash": "sha256-oX3Sd67LMcWj6U5lJgENmcNhQB85h3n6elOUsJM6yvU=",
"lastModified": 1625881195,
"narHash": "sha256-sY1tRB1hycOSHxPcHFmBxU2DWu+w5VCBOF1TCgih3W0=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "8925f488f042c17cb122e9f719e9f8ccdcd5b931",
"rev": "a95390c9b5ffe11b378a65c20886e59ee868ee6a",
"type": "github"
},
"original": {
@ -74,11 +74,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1625798263,
"narHash": "sha256-5/j8h2dWcYZhYGpIvFCiceK9XycKnwYToR2sHkTGwqw=",
"lastModified": 1625841043,
"narHash": "sha256-i3OdVSSGLCoamNeBAw1ybLr05AAS91og4D8Hdd0sBe4=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "53072cc0666112eebe9bc5d18dd46abb12f0dcbe",
"rev": "df0d321258a9b35c36cd9d8688985502d464105f",
"type": "github"
},
"original": {

View file

@ -23,8 +23,6 @@
}; in
utils.lib.systemFlake {
inherit self inputs;
# This config can only be evaluated on x86_64-linux because of IFD
supportedSystems = [ "x86_64-linux" ];
channels.nixpkgs = {
input = nixpkgs;
patches = map (patch: ./patches + "/${patch}") (builtins.filter (x: x != ".keep") (builtins.attrNames (builtins.readDir ./patches)));

View file

@ -10,21 +10,33 @@
# Machine-specific module settings
chvp = {
stateVersion = "20.09";
graphical = true;
bluetooth.enable = true;
git.email = "charlotte.vanpetegem@ugent.be";
zfs = {
enable = true;
encrypted = true;
backups = [
{
path = "rpool/safe/data";
remotePath = "zdata/recv/kharbranth/safe/data";
fast = true;
location = "lasting-integrity";
}
];
rootDataset = "rpool/local/root";
base = {
bluetooth.enable = true;
network.networkmanager.enable = true;
zfs = {
encrypted = true;
backups = [
{
path = "rpool/safe/data";
remotePath = "zdata/recv/kharbranth/safe/data";
fast = true;
location = "lasting-integrity";
}
];
rootDataset = "rpool/local/root";
};
};
development = {
enable = true;
android.enable = true;
git.email = "charlotte.vanpetegem@ugent.be";
};
graphical.enable = true;
programs = {
eid.enable = true;
hledger.enable = true;
obs.enable = true;
};
work.enable = true;
};
}

View file

@ -10,28 +10,37 @@
# Machine-specific module settings
chvp = {
stateVersion = "20.09";
graphical = true;
android.enable = true;
bluetooth.enable = true;
dropbox.enable = true;
git.email = "charlotte@vanpetegem.me";
minecraft.client = true;
mumble.enable = true;
obs.enable = true;
steam.enable = true;
zeroad.enable = true;
zfs = {
enable = true;
encrypted = true;
backups = [
{
path = "rpool/safe/data";
remotePath = "zdata/recv/kholinar/safe/data";
fast = true;
location = "lasting-integrity";
}
];
rootDataset = "rpool/local/root";
base = {
bluetooth.enable = true;
network.networkmanager.enable = true;
zfs = {
encrypted = true;
backups = [
{
path = "rpool/safe/data";
remotePath = "zdata/recv/kholinar/safe/data";
fast = true;
location = "lasting-integrity";
}
];
rootDataset = "rpool/local/root";
};
};
development = {
enable = true;
android.enable = true;
};
games.enable = true;
graphical.enable = true;
programs = {
calibre.enable = true;
deluge.enable = true;
dropbox.enable = true;
eid.enable = true;
hledger.enable = true;
obs.enable = true;
};
# It's a pandemic.
work.enable = true;
};
}

View file

@ -13,23 +13,23 @@
# Machine-specific module settings
chvp = {
stateVersion = "20.09";
docker.enable = true;
nginx.enable = true;
nextcloud.enable = true;
ovh.enable = true;
smartd.enable = true;
sshd.enable = true;
syncthing-server.enable = true;
tetris.enable = true;
zfs = {
enable = true;
backups = [{
path = "zroot/safe/data";
remotePath = "zdata/recv/lasting-integrity/safe/data";
fast = true;
location = "192.168.0.1";
}];
rootDataset = "zroot/local/root";
base = {
network.ovh.enable = true;
zfs = {
backups = [{
path = "zroot/safe/data";
remotePath = "zdata/recv/lasting-integrity/safe/data";
fast = true;
location = "192.168.0.1";
}];
rootDataset = "zroot/local/root";
};
};
development.enable = true;
games.tetris.server = true;
services = {
nextcloud.enable = true;
syncthing.enable = true;
};
};
}

View file

@ -4,7 +4,6 @@
imports = [
./hardware.nix
./secret.nix
../../containers/data-access
];
time.timeZone = "Europe/Berlin";
@ -17,33 +16,33 @@
# Machine-specific module settings
chvp = {
stateVersion = "20.09";
accentor.enable = true;
nginx.enable = true;
ovh.enable = true;
smartd.enable = true;
sshd.enable = true;
teeworlds.enable = false;
zeroad = {
enable = true;
asServer = true;
base = {
network.ovh.enable = true;
zfs = {
backups = [
{
path = "zroot/safe/data";
remotePath = "zdata/recv/urithiru/safe/data";
fast = true;
location = "192.168.0.2";
}
{
path = "zdata/data";
remotePath = "zdata/data";
fast = false;
location = "192.168.0.2";
}
];
rootDataset = "zroot/local/root";
};
};
zfs = {
enable = true;
backups = [
{
path = "zroot/safe/data";
remotePath = "zdata/recv/urithiru/safe/data";
fast = true;
location = "192.168.0.2";
}
{
path = "zdata/data";
remotePath = "zdata/data";
fast = false;
location = "192.168.0.2";
}
];
rootDataset = "zroot/local/root";
games = {
teeworlds.server = false;
zeroad.server = true;
};
services = {
accentor.enable = true;
data-access.enable = true;
};
};
}

Binary file not shown.

View file

@ -1,48 +0,0 @@
### Setting up ZFS
1. Create three partitions:
* Boot
* Swap
* ZFS
For example:
```shell
sgdisk -n 0:0:+512MiB -t 0:EF00 -c 0:boot $DISK
sgdisk -n 0:0:+32GiB -t 0:8200 -c 0:swap $DISK
sgdisk -n 0:0:0 -t 0:BF01 -c 0:ZFS $DISK
```
2. Configure swap and boot as usual.
3. Create ZPool:
```shell
zpool create -O mountpoint=none -O encryption=aes-256-gcm -O keyformat=passphrase rpool $ZFS_PART
```
Leave out `-O encryption=aes-256-gcm -O keyformat=passphrase` if you don't want to fully encrypt the ZFS partition.
4. Create datasets:
```shell
zfs create -o mountpoint=legacy rpool/local/root
zfs snapshot rpool/local/root@blank
zfs create -o mountpoint=legacy rpool/local/nix
zfs set compression=lz4 rpool/local/nix
zfs create -o mountpoint=legacy rpool/local/cache
zfs set compression=lz4 rpool/local/cache
zfs create -o mountpoint=legacy rpool/safe/data
zfs set compression=lz4 rpool/local/data
```
5. Mount datasets:
```shell
mount -t zfs rpool/local/root /mnt
mkdir /mnt/nix
mount -t zfs rpool/local/nix /mnt/nix
mkdir /mnt/boot
mount $BOOT_PART /mnt/boot
mkdir /mnt/cache
mount -t zfs rpool/local/cache /mnt/cache
mkdir /mnt/data
mount -t zfs rpool/safe/data /mnt/data
```
6. Configure Host ID
Set `networking.hostid` in the nixos config to `head -c 8 /etc/machine-id`.

View file

@ -1,14 +0,0 @@
{ config, lib, ... }:
{
options.chvp.android.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.android.enable {
chvp.zfs.homeLinks = [{ path = ".android"; type = "cache"; }];
programs.adb.enable = true;
users.users.charlotte.extraGroups = [ "adbusers" ];
};
}

View file

@ -0,0 +1,19 @@
{ config, lib, pkgs, ... }:
{
options.chvp.base.bluetooth.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.base.bluetooth.enable {
chvp.base.zfs.systemLinks = [{ path = "/var/lib/bluetooth"; type = "cache"; }];
hardware.bluetooth.enable = true;
services.blueman.enable = true;
home-manager.users.charlotte = lib.mkIf config.chvp.graphical.enable ({ ... }: {
services.blueman-applet.enable = true;
});
};
}

114
modules/base/default.nix Normal file
View file

@ -0,0 +1,114 @@
{ config, lib, pkgs, ... }:
{
imports = [
./bluetooth
./emacs
./mail
./network
./nix
./smartd
./ssh
./sshd
./tmux
./zfs
./zsh
];
options.chvp = {
stateVersion = lib.mkOption {
example = "20.09";
};
dataPrefix = lib.mkOption {
default = "";
example = "/data";
};
cachePrefix = lib.mkOption {
default = "";
example = "/cache";
};
};
config = {
home-manager.useGlobalPkgs = true;
system.stateVersion = config.chvp.stateVersion;
home-manager.users = {
charlotte = { ... }: {
home.stateVersion = config.chvp.stateVersion;
};
root = { ... }: {
home.stateVersion = config.chvp.stateVersion;
};
};
environment.systemPackages = with pkgs; [ htop moreutils ncdu ripgrep unzip zip ];
console = {
colors = [
"f8f8f8"
"a60000"
"005e00"
"813e00"
"0031a9"
"721045"
"00538b"
"282828"
"ffffff"
"972500"
"315b00"
"70480f"
"2544bb"
"8f0075"
"30517f"
"000000"
];
font = "Lat2-Terminus16";
keyMap = "us";
};
i18n = {
defaultLocale = "en_IE.UTF-8";
extraLocaleSettings = {
LC_TIME = "en_GB.UTF-8";
};
};
security = {
sudo.enable = false;
doas = {
enable = true;
extraRules = [
{
users = [ "charlotte" ];
noPass = true;
cmd = "nix-collect-garbage";
runAs = "root";
}
];
};
};
services.fwupd.enable = true;
users = {
mutableUsers = false;
defaultUserShell = pkgs.zsh;
users = {
charlotte = {
isNormalUser = true;
home = "/home/charlotte";
description = "Charlotte Van Petegem";
extraGroups = [ "systemd-journal" ];
passwordFile = config.age.secrets."passwords/users/charlotte".path;
};
root.passwordFile = config.age.secrets."passwords/users/root".path;
};
};
age.secrets."passwords/users/charlotte".file = ../../secrets/passwords/users/charlotte.age;
age.secrets."passwords/users/root".file = ../../secrets/passwords/users/root.age;
};
}

View file

@ -56,11 +56,6 @@
)
)
(use-package auth-source-pass
:ensure nil
:custom
(auth-source-pass-filename "~/repos/passwords"))
;; Better defaults that aren't defaults for some reason.
(use-package better-defaults
;; But don't enable ido-mode...
@ -91,16 +86,6 @@
)
)
;; Direnv integration in emacs.
(use-package direnv :config (direnv-mode))
;; Editorconfig
(use-package editorconfig
:diminish (editorconfig-mode)
:custom (editorconfig-get-properties-function 'editorconfig-get-properties)
:config (editorconfig-mode 1)
)
;; General emacs settings
(use-package emacs
:ensure nil ;; Not a real package, but a place to collect global settings
@ -113,7 +98,6 @@
((text-mode prog-mode) . electric-pair-mode)
:custom
(inhibit-startup-screen t "Don't show default startup screen")
(auth-sources '(password-store))
:config
;; Only ask for y/n, never for yes/no.
(defalias 'yes-or-no-p 'y-or-n-p)
@ -145,61 +129,12 @@
:config (evil-collection-init)
)
;; R language support
(use-package ess)
;; Ligatures in GUI mode
;; Should probably switch to ligature.el, but it isn't on MELPA (yet).
(use-package fira-code-mode :config (when window-system (global-fira-code-mode)))
;; Linting
(use-package flycheck
:diminish (flycheck-mode)
:config (global-flycheck-mode)
)
;; Magit GitHub/GitLab integration
(use-package forge
:after magit)
;; Groovy (gradle) language support
(use-package groovy-mode
:mode "\\.gradle\\'")
;; Haskell language support
(use-package haskell-mode
:mode "\\.hs\\'")
;; Kotlin language support
(use-package kotlin-mode
:mode "\\.kt\\'")
;; Ledger syntax support
(use-package ledger-mode
:mode "\\.journal\\'"
:custom
(ledger-binary-path "hledger" "Use hledger instead of ledger")
(ledger-highlight-xact-under-point nil "Remove distracting highlight")
(ledger-mode-should-check-version nil "Remove version check, since it doesn't work with hledger anyway")
(ledger-post-account-alignment-column 4 "Indent postings with 4 spaces")
(ledger-post-amount-alignment-at :decimal "Align on the decimal")
(ledger-post-amount-alignment-column 59 "Align on column 60")
(ledger-post-auto-align t "Align when moving to the next line")
)
;; Language server support
(use-package lsp-mode :commands (lsp))
;; Git integration
(use-package magit
:demand t
:general
(lmap
"g" '(:ignore t :which-key "git")
"gs" '(magit-status :which-key "status")
)
)
;; Annotations in selection interface
(use-package marginalia
:demand t
@ -212,14 +147,6 @@
(minibuffer-local-map "M-a" 'marginalia-cycle)
)
;; Markdown syntax support
(use-package markdown-mode
:commands (markdown-mode gfm-mode)
:mode ("README\\.md\\'" . gfm-mode)
:mode ("\\.md\\'" . markdown-mode)
:mode ("\\.markdown\\'" . markdown-mode)
)
;; Theming
(use-package modus-themes
:custom
@ -233,9 +160,6 @@
(modus-themes-load-operandi)
)
;; Nix syntax support
(use-package nix-mode :mode "\\.nix\\'")
;; Orderless filtering
(use-package orderless
:after (selectrum)
@ -258,38 +182,6 @@
:config (prescient-persist-mode 1)
)
;; Project management
(use-package projectile
:after (ripgrep selectrum)
:demand t
:diminish (projectile-mode)
:config (projectile-mode 1)
:general
(lmap
"p" '(:ignore t :which-key "project")
"pf" '(projectile-find-file :which-key "find")
"pp" '(projectile-switch-project :which-key "switch")
"pr" '(projectile-replace :which-key "replace")
"ps" '(consult-ripgrep :search "incsearch")
"pS" '(projectile-ripgrep :which-key "search")
"p!" '(projectile-run-shell-command-in-root :which-key "command")
"p&" '(projectile-run-async-shell-command-in-root :which-key "task")
)
)
;; Python syntax support
(use-package python-mode :mode "\\.py\\'")
;; Ruby language support
(use-package ruby-mode
:ensure nil ;; Included with emacs
:custom
(ruby-insert-encoding-magic-comment nil "Don't insert encoding magic comment")
)
;; Ripgrep support (needed for `projectile-ripgrep')
(use-package ripgrep)
;; List item selection interface
(use-package selectrum
:custom (selectrum-max-window-height 20 "Allow selector to be a bit higher")
@ -302,25 +194,9 @@
:custom (selectrum-prescient-enable-filtering nil "`orderless' manages the filtering part.")
:config (selectrum-prescient-mode 1))
;; TypeScript language support
(use-package typescript-mode
:mode "\\.ts\\'")
;; HTML (and HTML template) support
(use-package web-mode
:mode "\\.html\\'"
:mode "\\.html\\.erb\\'"
)
;; Show keybindings
(use-package which-key
:diminish (which-key-mode)
:config (which-key-mode)
)
;; YAML syntax support
(use-package yaml-mode
:mode "\\.yml\\'"
:mode "\\.yaml\\'"
)

View file

@ -0,0 +1,65 @@
{ config, lib, pkgs, ... }:
{
options.chvp.base.emacs = {
fullConfig = lib.mkOption {
readOnly = true;
default = builtins.readFile ./base-init.el + (lib.concatStringsSep "\n" config.chvp.base.emacs.extraConfig) + ''
(provide 'init)
;;; init.el ends here
'';
};
extraConfig = lib.mkOption {
default = [ ];
};
package = lib.mkOption {
readOnly = true;
default = pkgs.emacsWithPackagesFromUsePackage {
config = config.chvp.base.emacs.fullConfig;
package = pkgs.emacsPgtk;
alwaysEnsure = true;
# mu4e is included in the mu package and should be used from there
extraEmacsPackages = epkgs: lib.optional config.chvp.graphical.mail.enable pkgs.mu;
};
};
};
config = {
nixpkgs.overlays = [
(self: super: {
mu = super.mu.overrideAttrs (old: {
version = "1.5.13";
src = self.fetchFromGitHub {
owner = "djcb";
repo = "mu";
rev = "6d67e146fecb5aa512a7eff4b8044225af0dc5ce";
sha256 = "0ip7nd7z2l60a3dc1aic34hpab4alb0rmxlk9778nz3v88735iik";
};
});
})
];
chvp.base.zfs.homeLinks = [
{ path = ".emacs.d"; type = "cache"; }
];
home-manager.users.charlotte = { ... }: {
services.emacs = {
enable = true;
client.enable = true;
socketActivation.enable = true;
package = config.chvp.base.emacs.package;
};
home = {
file = {
".emacs.d/early-init.el".source = ./early-init.el;
".emacs.d/init.el".text = config.chvp.base.emacs.fullConfig;
};
packages = [
(pkgs.writeShellScriptBin "emacs" ''${config.chvp.base.emacs.package}/bin/emacsclient -c "$@"'')
(pkgs.writeShellScriptBin "emacsclient" ''${config.chvp.base.emacs.package}/bin/emacsclient "$@"'')
];
sessionVariables = { EDITOR = "emacs"; };
};
};
};
}

View file

@ -0,0 +1,16 @@
{ config, lib, pkgs, ... }:
{
services.ssmtp = {
enable = true;
authUser = "webmaster@vanpetegem.me";
authPassFile = config.age.secrets."passwords/services/ssmtp-pass".path;
domain = "${config.networking.hostName}.vanpetegem.me";
hostName = "mail.vanpetegem.me:465";
root = "webmaster@vanpetegem.me";
setSendmail = true;
useTLS = true;
};
age.secrets."passwords/services/ssmtp-pass".file = ../../../secrets/passwords/services/ssmtp-pass.age;
}

View file

@ -0,0 +1,8 @@
{ ... }:
{
imports = [
./ovh.nix
./networkmanager.nix
];
}

View file

@ -1,15 +1,16 @@
{ config, lib, pkgs, ... }:
{
options.chvp.networkmanager.enable = lib.mkOption {
options.chvp.base.network.networkmanager.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.networkmanager.enable {
chvp.zfs.systemLinks = [
config = lib.mkIf config.chvp.base.network.networkmanager.enable {
chvp.base.zfs.systemLinks = [
{ path = "/etc/NetworkManager/system-connections"; type = "data"; }
];
networking.networkmanager = {
enable = true;
wifi.macAddress = "random";

View file

@ -1,7 +1,7 @@
{ config, lib, ... }:
{
options.chvp.ovh = {
options.chvp.base.network.ovh = {
enable = lib.mkOption {
default = false;
example = true;
@ -23,8 +23,8 @@
};
};
config = lib.mkIf config.chvp.ovh.enable {
networking = with config.chvp.ovh; {
config = lib.mkIf config.chvp.base.network.ovh.enable {
networking = with config.chvp.base.network.ovh; {
useDHCP = false;
interfaces = {
eno1.useDHCP = false;

View file

@ -41,7 +41,7 @@ let
};
in
{
options.chvp.nix = {
options.chvp.base.nix = {
enableDirenv = lib.mkOption {
default = true;
example = false;
@ -58,11 +58,24 @@ in
};
config = {
chvp.zfs.homeLinks =
(lib.optional config.chvp.nix.enableDirenv { path = ".local/share/direnv"; type = "cache"; }) ++
(lib.optional config.chvp.nix.enableNixIndex { path = ".cache/nix-index"; type = "cache"; });
chvp.zfs.systemLinks =
(lib.optional config.chvp.nix.enableDirenv { path = "/root/.local/share/direnv"; type = "cache"; });
chvp.base = {
emacs.extraConfig = [
''
;; Nix syntax support
(use-package nix-mode :mode "\\.nix\\'")
''
] ++ lib.optional config.chvp.base.nix.enableDirenv ''
;; Direnv integration in emacs.
(use-package direnv :config (direnv-mode))
'';
zfs = {
homeLinks =
(lib.optional config.chvp.base.nix.enableDirenv { path = ".local/share/direnv"; type = "cache"; }) ++
(lib.optional config.chvp.base.nix.enableNixIndex { path = ".cache/nix-index"; type = "cache"; });
systemLinks =
(lib.optional config.chvp.base.nix.enableDirenv { path = "/root/.local/share/direnv"; type = "cache"; });
};
};
nix = {
gc = {
@ -78,13 +91,13 @@ in
extraOptions = ''
substituters = https://cache.nixos.org https://nix-community.cachix.org
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
'' + (lib.optionalString config.chvp.nix.enableDirenv ''
'' + (lib.optionalString config.chvp.base.nix.enableDirenv ''
keep-outputs = true
keep-derivations = true
'');
};
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) config.chvp.nix.unfreePackages;
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) config.chvp.base.nix.unfreePackages;
nixpkgs.overlays = [
(self: super: {
nix = super.nixUnstable;
@ -93,8 +106,8 @@ in
home-manager.users.charlotte = { ... }:
lib.recursiveUpdate
(lib.optionalAttrs config.chvp.nix.enableDirenv baseDirenv)
(lib.optionalAttrs config.chvp.nix.enableNixIndex baseNixIndex);
home-manager.users.root = { ... }: lib.optionalAttrs config.chvp.nix.enableDirenv baseDirenv;
(lib.optionalAttrs config.chvp.base.nix.enableDirenv baseDirenv)
(lib.optionalAttrs config.chvp.base.nix.enableNixIndex baseNixIndex);
home-manager.users.root = { ... }: lib.optionalAttrs config.chvp.base.nix.enableDirenv baseDirenv;
};
}

View file

@ -0,0 +1,17 @@
{ config, lib, pkgs, ... }:
{
environment.systemPackages = [ pkgs.smartmontools ];
services.smartd = {
enable = true;
autodetect = true;
notifications = {
mail = {
enable = true;
sender = "${config.networking.hostName}@vanpetegem.me";
recipient = "webmaster@vanpetegem.me";
};
wall.enable = false;
};
};
}

View file

@ -25,21 +25,12 @@ let
IdentityFile = "${config.chvp.dataPrefix}${home}/.ssh/id_ed25519";
HostKeyAlgorithms = "ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa";
};
matchBlocks = import ./ssh/hosts.secret.nix;
matchBlocks = import ./hosts.secret.nix;
};
home.packages = lib.mkIf config.chvp.graphical [ ssh ];
home.packages = lib.mkIf config.chvp.graphical.enable [ ssh ];
};
in
{
options.chvp.ssh = {
enable = lib.mkOption {
default = true;
example = false;
};
};
config = lib.mkIf config.chvp.ssh.enable {
home-manager.users.root = { ... }: (base "/root");
home-manager.users.charlotte = { ... }: (base "/home/charlotte");
};
home-manager.users.root = { ... }: (base "/root");
home-manager.users.charlotte = { ... }: (base "/home/charlotte");
}

View file

@ -0,0 +1,21 @@
{ config, lib, ... }:
{
chvp.base.zfs.ensureExists = [ "${config.chvp.dataPrefix}/etc/ssh" ];
services.openssh = {
enable = true;
passwordAuthentication = false;
permitRootLogin = "prohibit-password";
hostKeys = [
{ bits = 4096; path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_rsa_key"; type = "rsa"; }
{ path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; }
];
authorizedKeysFiles = [ "/run/secrets/authorized_keys/%u" ];
};
age.secrets."authorized_keys/root".file = ../../../secrets/authorized_keys/root.age;
age.secrets."authorized_keys/charlotte" = {
file = ../../../secrets/authorized_keys/charlotte.age;
owner = "charlotte";
};
}

View file

@ -1,4 +1,4 @@
{ config, lib, ... }:
{ ... }:
let
base = {
programs.tmux = {
@ -17,13 +17,6 @@ let
};
in
{
options.chvp.tmux.enable = lib.mkOption {
default = true;
example = false;
};
config = lib.mkIf config.chvp.tmux.enable {
home-manager.users.charlotte = { ... }: base;
home-manager.users.root = { ... }: base;
};
home-manager.users.charlotte = { ... }: base;
home-manager.users.root = { ... }: base;
}

View file

@ -1,11 +1,7 @@
{ config, lib, ... }:
{
options.chvp.zfs = {
enable = lib.mkOption {
default = false;
example = true;
};
options.chvp.base.zfs = {
encrypted = lib.mkOption {
default = false;
example = true;
@ -24,6 +20,10 @@
{ path = ".cache/nix-index"; type = "cache"; }
];
};
ensureExists = lib.mkOption {
default = [ ];
example = [ "/data/etc/ssh" ];
};
backups = lib.mkOption {
default = [ ];
example = [{
@ -38,21 +38,21 @@
};
};
config = lib.mkIf config.chvp.zfs.enable {
config = {
chvp.dataPrefix = lib.mkDefault "/data";
chvp.cachePrefix = lib.mkDefault "/cache";
boot = {
supportedFilesystems = [ "zfs" ];
zfs.requestEncryptionCredentials = config.chvp.zfs.encrypted;
zfs.requestEncryptionCredentials = config.chvp.base.zfs.encrypted;
initrd.postDeviceCommands = lib.mkAfter ''
zfs rollback -r ${config.chvp.zfs.rootDataset}@blank
zfs rollback -r ${config.chvp.base.zfs.rootDataset}@blank
'';
};
services = {
znapzend = {
enable = config.chvp.zfs.backups != [ ];
enable = config.chvp.base.zfs.backups != [ ];
pure = true;
autoCreation = true;
zetup = builtins.listToAttrs
@ -76,7 +76,7 @@
};
};
})
config.chvp.zfs.backups);
config.chvp.base.zfs.backups);
};
zfs = {
@ -87,9 +87,10 @@
systemd.services =
let
makeLinkScript = config: lib.strings.concatStringsSep "\n" (map (location: ''mkdir -p "${location.path}"'') config);
systemLinksScript = makeLinkScript config.chvp.zfs.systemLinks;
homeLinksScript = makeLinkScript config.chvp.zfs.homeLinks;
ensureExistsScript = lib.concatStringsSep "\n" (map (path: "mkdir -p ${path}") config.chvp.base.zfs.ensureExists);
makeLinkScript = config: lib.concatStringsSep "\n" (map (location: ''mkdir -p "${location.path}"'') config);
systemLinksScript = makeLinkScript config.chvp.base.zfs.systemLinks;
homeLinksScript = makeLinkScript config.chvp.base.zfs.homeLinks;
in
{
make-system-links-destinations = {
@ -150,7 +151,7 @@
DefaultDependencies = "no";
};
})
config.chvp.zfs.systemLinks) ++
config.chvp.base.zfs.systemLinks) ++
(map
(location: {
what = "/${location.type}/home/charlotte/${location.path}";
@ -166,6 +167,6 @@
DefaultDependencies = "no";
};
})
config.chvp.zfs.homeLinks);
config.chvp.base.zfs.homeLinks);
};
}

View file

@ -0,0 +1,49 @@
{ config, lib, pkgs, ... }:
let
base = (home: {
home.packages = [ pkgs.autojump ];
programs.zsh = {
enable = true;
enableAutosuggestions = true;
autocd = true;
dotDir = ".config/zsh";
history = {
expireDuplicatesFirst = true;
path = "${config.chvp.cachePrefix}${home}/.local/share/zsh/history";
};
initExtra = ''
${pkgs.any-nix-shell}/bin/any-nix-shell zsh --info-right | source /dev/stdin
'';
oh-my-zsh = {
enable = true;
plugins = [
"autojump"
"common-aliases"
"extract"
"history-substring-search"
"git"
"systemd"
"tmux"
];
theme = "robbyrussell";
};
plugins = [{
name = "zsh-syntax-highlighting";
src = pkgs.fetchFromGitHub {
owner = "zsh-users";
repo = "zsh-syntax-highlighting";
rev = "0.7.1";
sha256 = "03r6hpb5fy4yaakqm3lbf4xcvd408r44jgpv4lnzl9asp4sb9qc0";
};
}];
sessionVariables = { DEFAULT_USER = "charlotte"; };
};
});
in
{
chvp.base.zfs.systemLinks = [{ path = "/root/.local/share/autojump"; type = "cache"; }];
chvp.base.zfs.homeLinks = [{ path = ".local/share/autojump"; type = "cache"; }];
home-manager.users.charlotte = { ... }: (base "/home/charlotte");
home-manager.users.root = { ... }: (base "/root");
}

View file

@ -1,21 +0,0 @@
{ config, lib, pkgs, ... }:
{
options.chvp.bluetooth.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.bluetooth.enable {
chvp.zfs.systemLinks = [{ path = "/var/lib/bluetooth"; type = "cache"; }];
hardware.bluetooth.enable = true;
services.blueman.enable = true;
hardware.pulseaudio.extraModules = [ pkgs.pulseaudio-modules-bt ];
hardware.pulseaudio.package = pkgs.pulseaudioFull;
home-manager.users.charlotte = lib.mkIf config.chvp.bluetooth.enable ({ ... }: {
services.blueman-applet.enable = true;
});
};
}

View file

@ -1,160 +1,13 @@
{ config, lib, pkgs, ... }:
{ ... }:
{
imports = [
./accentor.nix
./android.nix
./bluetooth.nix
./calibre.nix
./docker.nix
./deluge-client.nix
./deluge-server.nix
./dropbox.nix
./eid.nix
./emacs.nix
./firefox.nix
./git.nix
./global-mailer.nix
./gnupg.nix
./graphical.nix
./hledger.nix
./mail-client.nix
./minecraft.nix
./mumble.nix
./networkmanager.nix
./nextcloud.nix
./nix.nix
./nginx.nix
./obs.nix
./ovh.nix
./pass.nix
./smartd.nix
./sound.nix
./ssh.nix
./sshd.nix
./steam.nix
./sway
./syncthing-client.nix
./syncthing-server.nix
./teeworlds.nix
./terminal.nix
./tetris.nix
./theming.nix
./tmux.nix
./ugent
./xdg.nix
./zeroad.nix
./zfs.nix
./zotero.nix
./zsh.nix
./base
./development
./games
./graphical
./programs
./services
./work
];
options.chvp = {
stateVersion = lib.mkOption {
example = "20.09";
};
dataPrefix = lib.mkOption {
default = "";
example = "/data";
};
cachePrefix = lib.mkOption {
default = "";
example = "/cache";
};
hasContainers = lib.mkOption {
default = false;
example = true;
};
};
config = {
home-manager.useGlobalPkgs = true;
system.stateVersion = config.chvp.stateVersion;
home-manager.users = {
charlotte = { ... }: {
home.stateVersion = config.chvp.stateVersion;
};
root = { ... }: {
home.stateVersion = config.chvp.stateVersion;
};
};
environment.systemPackages = with pkgs; [ htop moreutils ncdu ripgrep sshfs unzip ];
console = {
colors = [
"f8f8f8"
"a60000"
"005e00"
"813e00"
"0031a9"
"721045"
"00538b"
"282828"
"ffffff"
"972500"
"315b00"
"70480f"
"2544bb"
"8f0075"
"30517f"
"000000"
];
font = "Lat2-Terminus16";
keyMap = "us";
};
i18n = {
defaultLocale = "en_IE.UTF-8";
extraLocaleSettings = {
LC_TIME = "en_GB.UTF-8";
};
};
networking.nat = lib.mkIf config.chvp.hasContainers {
enable = true;
enableIPv6 = true;
internalInterfaces = [ "ve-+" ];
externalInterface = "eno3";
};
security.sudo.enable = false;
security.doas = {
enable = true;
extraRules = [
{
users = [ "charlotte" ];
noPass = true;
cmd = "nix-collect-garbage";
runAs = "root";
}
];
};
services.fwupd.enable = true;
users = {
mutableUsers = false;
defaultUserShell = pkgs.zsh;
users = {
charlotte = {
isNormalUser = true;
home = "/home/charlotte";
description = "Charlotte Van Petegem";
extraGroups = [ "systemd-journal" ];
passwordFile = config.age.secrets."passwords/users/charlotte".path;
};
root.passwordFile = config.age.secrets."passwords/users/root".path;
};
};
age.secrets = {
"passwords/users/charlotte".file = ../secrets/passwords/users/charlotte.age;
"passwords/users/root".file = ../secrets/passwords/users/root.age;
};
};
}

View file

@ -0,0 +1,27 @@
{ config, lib, ... }:
{
options.chvp.development.android.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.development.android.enable {
chvp.base = {
emacs.extraConfig = [
''
;; Groovy (gradle) language support
(use-package groovy-mode
:mode "\\.gradle\\'")
;; Kotlin language support
(use-package kotlin-mode
:mode "\\.kt\\'")
''
];
zfs.homeLinks = [{ path = ".android"; type = "cache"; }];
};
programs.adb.enable = true;
users.users.charlotte.extraGroups = [ "adbusers" ];
};
}

View file

@ -0,0 +1,79 @@
{ config, lib, ... }:
{
imports = [
./android
./docker
./git
];
options.chvp.development.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.development.enable {
chvp = {
base.emacs.extraConfig = [
''
;; Editorconfig
(use-package editorconfig
:diminish (editorconfig-mode)
:custom (editorconfig-get-properties-function 'editorconfig-get-properties)
:config (editorconfig-mode 1)
)
;; Language server support
(use-package lsp-mode :commands (lsp))
;; Markdown syntax support
(use-package markdown-mode
:commands (markdown-mode gfm-mode)
:mode ("README\\.md\\'" . gfm-mode)
:mode ("\\.md\\'" . markdown-mode)
:mode ("\\.markdown\\'" . markdown-mode)
)
;; YAML syntax support
(use-package yaml-mode
:mode "\\.yml\\'"
:mode "\\.yaml\\'"
)
;; R language support
(use-package ess)
;; Haskell language support
(use-package haskell-mode
:mode "\\.hs\\'")
;; Python syntax support
(use-package python-mode :mode "\\.py\\'")
;; Ruby language support
(use-package ruby-mode
:ensure nil ;; Included with emacs
:custom
(ruby-insert-encoding-magic-comment nil "Don't insert encoding magic comment")
)
;; TypeScript language support
(use-package typescript-mode
:mode "\\.ts\\'")
;; HTML (and HTML template) support
(use-package web-mode
:mode "\\.html\\'"
:mode "\\.html\\.erb\\'"
)
''
];
development = {
docker.enable = lib.mkDefault true;
git.enable = lib.mkDefault true;
};
};
boot.kernel.sysctl."fs.inotify.max_user_watches" = 524288;
};
}

View file

@ -1,16 +1,16 @@
{ config, lib, pkgs, ... }:
{
options.chvp.docker.enable = lib.mkOption {
options.chvp.development.docker.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.docker.enable {
config = lib.mkIf config.chvp.development.docker.enable {
virtualisation.docker = {
enable = true;
extraOptions = "--data-root ${config.chvp.dataPrefix}/var/lib/docker";
storageDriver = lib.mkIf config.chvp.zfs.enable "zfs";
storageDriver = "zfs";
};
environment.systemPackages = [ pkgs.docker-compose ];

View file

@ -0,0 +1,92 @@
{ config, lib, pkgs, ... }:
{
options.chvp.development.git = {
enable = lib.mkOption {
default = false;
example = true;
};
email = lib.mkOption {
type = lib.types.str;
default = "charlotte@vanpetegem.me";
example = "charlotte@vanpetegem.me";
description = ''
Default email set in global git config.
'';
};
};
config =
let
base = {
home.packages = with pkgs; [
gitAndTools.gitflow
git-crypt
];
programs.git = {
enable = true;
extraConfig = {
branch.autosetuprebase = "always";
pull.rebase = true;
github.user = "chvp";
};
ignores = [
".direnv"
".envrc"
"shell.nix"
# Ruby dependencies in source tree
"/vendor/bundle"
];
signing = {
key = "charlotte@vanpetegem.me";
signByDefault = config.chvp.graphical.enable;
};
userEmail = config.chvp.development.git.email;
userName = "Charlotte Van Petegem";
};
};
in
lib.mkIf config.chvp.development.git.enable {
chvp.base.emacs.extraConfig = [
''
;; Magit GitHub/GitLab integration
(use-package forge
:after magit)
;; Git integration
(use-package magit
:demand t
:general
(lmap
"g" '(:ignore t :which-key "git")
"gs" '(magit-status :which-key "status")
)
)
;; Project management
(use-package projectile
:after (ripgrep selectrum)
:demand t
:diminish (projectile-mode)
:config (projectile-mode 1)
:general
(lmap
"p" '(:ignore t :which-key "project")
"pf" '(projectile-find-file :which-key "find")
"pp" '(projectile-switch-project :which-key "switch")
"pr" '(projectile-replace :which-key "replace")
"ps" '(consult-ripgrep :search "incsearch")
"pS" '(projectile-ripgrep :which-key "search")
"p!" '(projectile-run-shell-command-in-root :which-key "command")
"p&" '(projectile-run-async-shell-command-in-root :which-key "task")
)
)
;; Ripgrep support (needed for `projectile-ripgrep')
(use-package ripgrep)
''
];
home-manager.users.charlotte = { ... }: base;
home-manager.users.root = { ... }: base;
};
}

View file

@ -1,66 +0,0 @@
{ config, lib, pkgs, ... }:
let
emacsConfigText = builtins.readFile ./emacs/init.el + (if config.chvp.mail-client.enable then config.chvp.mail-client.mu4eConfig else "") + ''
(provide 'init)
;;; init.el ends here
'';
emacsPkg = pkgs.emacsWithPackagesFromUsePackage {
config = emacsConfigText;
package = pkgs.emacsPgtk;
alwaysEnsure = true;
# mu4e is included in the mu package and should be used from there
extraEmacsPackages = epkgs: lib.optional config.chvp.mail-client.enable pkgs.mu;
};
in
{
options.chvp.emacs = {
enable = lib.mkOption {
default = true;
example = false;
};
package = lib.mkOption { };
};
config = lib.mkIf config.chvp.emacs.enable {
nixpkgs.overlays = [
(self: super: {
mu = super.mu.overrideAttrs (old: {
version = "1.5.13";
src = self.fetchFromGitHub {
owner = "djcb";
repo = "mu";
rev = "6d67e146fecb5aa512a7eff4b8044225af0dc5ce";
sha256 = "0ip7nd7z2l60a3dc1aic34hpab4alb0rmxlk9778nz3v88735iik";
};
});
})
];
chvp = {
emacs.package = emacsPkg;
zfs.homeLinks = [
{ path = ".emacs.d"; type = "cache"; }
];
};
home-manager.users.charlotte = { ... }: {
services.emacs = {
enable = true;
client.enable = true;
socketActivation.enable = true;
package = emacsPkg;
};
home = {
file = {
".emacs.d/early-init.el".source = ./emacs/early-init.el;
".emacs.d/init.el".text = emacsConfigText;
};
packages = [
(pkgs.writeShellScriptBin "emacs" ''${emacsPkg}/bin/emacsclient -c "$@"'')
(pkgs.writeShellScriptBin "emacsclient" ''${emacsPkg}/bin/emacsclient "$@"'')
];
sessionVariables = { EDITOR = "emacs"; };
};
};
};
}

26
modules/games/default.nix Normal file
View file

@ -0,0 +1,26 @@
{ config, lib, ... }:
{
imports = [
./minecraft
./mumble
./steam
./teeworlds
./tetris
./zeroad
];
options.chvp.games.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.games.enable {
chvp.games = {
minecraft.client = lib.mkDefault true;
mumble.enable = lib.mkDefault true;
steam.enable = lib.mkDefault true;
zeroad.client = lib.mkDefault true;
};
};
}

View file

@ -0,0 +1,32 @@
{ config, lib, pkgs, ... }:
{
options.chvp.games.minecraft = {
client = lib.mkOption {
default = false;
example = true;
};
server = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf (config.chvp.games.minecraft.client || config.chvp.games.minecraft.server) {
home-manager.users.charlotte = lib.mkIf config.chvp.games.minecraft.client ({ ... }: {
home.packages = [ pkgs.minecraft ];
});
chvp.base = {
zfs.homeLinks = lib.optional config.chvp.games.minecraft.client { path = ".minecraft"; type = "cache"; };
nix.unfreePackages =
(lib.optional config.chvp.games.minecraft.client "minecraft-launcher") ++
(lib.optional config.chvp.games.minecraft.server "minecraft-server");
};
services.minecraft-server = lib.mkIf config.chvp.games.minecraft.server {
enable = true;
dataDir = "${config.chvp.dataPrefix}/var/lib/minecraft-server";
eula = true;
openFirewall = true;
};
};
}

View file

@ -1,13 +1,13 @@
{ config, lib, pkgs, ... }:
{
options.chvp.mumble.enable = lib.mkOption {
options.chvp.games.mumble.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.mumble.enable {
chvp.zfs.homeLinks = [
config = lib.mkIf config.chvp.games.mumble.enable {
chvp.base.zfs.homeLinks = [
{ path = ".config/Mumble"; type = "data"; }
{ path = ".local/share/Mumble"; type = "data"; }
];

View file

@ -1,18 +1,18 @@
{ config, lib, pkgs, ... }:
{
options.chvp.steam.enable = lib.mkOption {
options.chvp.games.steam.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.steam.enable {
config = lib.mkIf config.chvp.games.steam.enable {
hardware.opengl = {
driSupport32Bit = true;
extraPackages = with pkgs.pkgsi686Linux; [ libva ];
};
services.pipewire.alsa.support32Bit = true;
chvp = {
chvp.base = {
nix.unfreePackages = [ "steam" "steam-original" "steam-runtime" ];
zfs.homeLinks = [
{ path = ".paradoxlauncher"; type = "cache"; }

View file

@ -2,13 +2,13 @@
{
options = {
chvp.teeworlds.enable = lib.mkOption {
chvp.games.teeworlds.server = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf config.chvp.teeworlds.enable {
config = lib.mkIf config.chvp.games.teeworlds.server {
services.teeworlds = {
enable = true;
openPorts = true;

View file

@ -10,7 +10,9 @@ let
rev = "a3ff63bb8aecd42241a40ac8f7bdb6acacef7038";
sha256 = "0nlj268kwbv45gsmsp2rc2bfdmbiks21pr8zsa22nfkpbm6m4c03";
};
yarnNix = ./tetris/yarn.nix;
packageJSON = ./package.json;
yarnLock = ./yarn.lock;
yarnNix = ./yarn.nix;
buildPhase = "yarn run build";
installPhase = ''
cp -r deps/tetris/dist $out
@ -20,13 +22,13 @@ let
};
in
{
options.chvp.tetris.enable = lib.mkOption {
options.chvp.games.tetris.server = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.tetris.enable {
chvp.nginx.hosts = [{
config = lib.mkIf config.chvp.games.tetris.server {
chvp.services.nginx.hosts = [{
fqdn = "tetris.vanpetegem.me";
options = {
root = "${tetris}";

View file

@ -0,0 +1,21 @@
{
"name": "tetris",
"version": "1.0.0",
"main": "src/index.ts",
"scripts": {
"dev": "parcel src/index.html",
"build": "parcel build src/index.html"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.4.0",
"@typescript-eslint/parser": "^4.4.0",
"eslint": "^7.11.0",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"parcel-bundler": "^1.12.4",
"typescript": "^4.0.3"
}
}

View file

@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell
#!nix-shell -p curl yarn2nix -i bash
curl -L -O https://github.com/chvp/tetris/raw/master/package.json
curl -L -O https://github.com/chvp/tetris/raw/master/yarn.lock
yarn2nix --lockfile yarn.lock --no-patch > yarn.nix
rm yarn.lock

File diff suppressed because it is too large Load diff

View file

@ -2,34 +2,34 @@
{
options = {
chvp.zeroad = {
enable = lib.mkOption {
chvp.games.zeroad = {
client = lib.mkOption {
default = false;
example = true;
};
asServer = lib.mkOption {
server = lib.mkOption {
default = false;
example = true;
};
};
};
config = lib.mkIf config.chvp.zeroad.enable {
chvp.zfs.homeLinks = [
config = lib.mkIf (config.chvp.games.zeroad.server || config.chvp.games.zeroad.client) {
chvp.base.zfs.homeLinks = [
{ path = ".config/0ad"; type = "cache"; }
];
# Needs to be here, since the headless server probably doesn't have this enabled yet.
# Needs to be here, since a headless server probably doesn't have this enabled yet.
hardware.opengl.enable = true;
home-manager.users.charlotte = { pkgs, ... }: {
home.packages = [ pkgs.zeroad ];
};
networking.firewall = lib.mkIf config.chvp.zeroad.asServer {
networking.firewall = lib.mkIf config.chvp.games.zeroad.server {
allowedTCPPorts = [ 20595 ];
allowedUDPPorts = [ 20595 ];
};
services.xrdp = lib.mkIf config.chvp.zeroad.asServer {
services.xrdp = lib.mkIf config.chvp.games.zeroad.server {
enable = true;
defaultWindowManager = "${pkgs.icewm}/bin/icewm";
};

View file

@ -1,60 +0,0 @@
{ config, lib, pkgs, ... }:
{
options.chvp.git = {
enable = lib.mkOption {
default = true;
example = false;
};
email = lib.mkOption {
type = lib.types.str;
default = "charlotte@vanpetegem.me";
example = "charlotte@vanpetegem.me";
description = ''
Default email set in global git config.
'';
};
};
config =
let
base = {
home.packages = with pkgs; [
gitAndTools.gitflow
git-crypt
];
programs.git = {
enable = true;
extraConfig = {
branch = {
autosetuprebase = "always";
};
pull = {
rebase = true;
};
github = {
user = "chvp";
};
};
ignores = [
".direnv"
".envrc"
"shell.nix"
# Ruby dependencies in source tree
"/vendor/bundle"
"**/*.patch"
];
signing = {
key = "charlotte@vanpetegem.me";
signByDefault = config.chvp.graphical;
};
userEmail = config.chvp.git.email;
userName = "Charlotte Van Petegem";
};
};
in
lib.mkIf config.chvp.git.enable {
home-manager.users.charlotte = { ... }: base;
home-manager.users.root = { ... }: base;
};
}

View file

@ -1,23 +0,0 @@
{ config, lib, pkgs, ... }:
{
options.chvp.globalMailer.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.globalMailer.enable {
services.ssmtp = {
enable = true;
authUser = "webmaster@vanpetegem.me";
authPassFile = config.age.secrets."passwords/services/ssmtp-pass".path;
domain = "${config.networking.hostName}.vanpetegem.me";
hostName = "mail.vanpetegem.me:465";
root = "webmaster@vanpetegem.me";
setSendmail = true;
useTLS = true;
};
age.secrets."passwords/services/ssmtp-pass".file = ../secrets/passwords/services/ssmtp-pass.age;
};
}

View file

@ -1,54 +0,0 @@
{ config, lib, pkgs, ... }:
{
options.chvp.graphical = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.graphical {
users.users.charlotte.extraGroups = [ "input" "video" ];
chvp = {
calibre.enable = lib.mkDefault true;
deluge-client.enable = lib.mkDefault true;
docker.enable = lib.mkDefault true;
eid.enable = lib.mkDefault true;
firefox.enable = lib.mkDefault true;
mail-client.enable = lib.mkDefault true;
gnupg = {
enable = lib.mkDefault true;
pinentryFlavor = lib.mkDefault "qt";
};
hledger.enable = lib.mkDefault true;
networkmanager.enable = lib.mkDefault true;
nix.unfreePackages = [ "google-chrome" ];
pass.enable = lib.mkDefault true;
sound.enable = lib.mkDefault true;
syncthing-client.enable = lib.mkDefault true;
sway.enable = lib.mkDefault true;
terminal.enable = lib.mkDefault true;
theming.enable = lib.mkDefault true;
ugent.enable = lib.mkDefault true;
xdg.enable = lib.mkDefault true;
zotero.enable = lib.mkDefault true;
};
home-manager.users.charlotte = { ... }: {
home.packages = with pkgs; [
google-chrome
jdtls
kotlin-language-server
libreoffice-fresh
mpv
okular
pandoc
ranger
texlive.combined.scheme-small
ungoogled-chromium
youtube-dl
];
};
boot.kernel.sysctl."fs.inotify.max_user_watches" = 524288;
};
}

View file

@ -0,0 +1,64 @@
{ config, lib, pkgs, ... }:
{
imports = [
./firefox
./gnupg
./mail
./pass
./sound
./sway
./syncthing
./terminal
./theme
./xdg
];
options.chvp.graphical.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.graphical.enable {
users.users.charlotte.extraGroups = [ "input" "video" ];
chvp = {
base = {
emacs.extraConfig = [
''
;; Ligatures in GUI mode
;; Should probably switch to ligature.el, but it isn't on MELPA (yet).
(use-package fira-code-mode :config (when window-system (global-fira-code-mode)))
''
];
nix.unfreePackages = [ "google-chrome" ];
};
graphical = {
firefox.enable = lib.mkDefault true;
gnupg = {
enable = lib.mkDefault true;
pinentryFlavor = "qt";
};
mail.enable = lib.mkDefault true;
pass.enable = lib.mkDefault true;
sound.enable = lib.mkDefault true;
sway.enable = lib.mkDefault true;
syncthing.enable = lib.mkDefault true;
terminal.enable = lib.mkDefault true;
theme.enable = lib.mkDefault true;
xdg.enable = lib.mkDefault true;
};
};
home-manager.users.charlotte = { ... }: {
home.packages = with pkgs; [
google-chrome
mpv
okular
ranger
ungoogled-chromium
youtube-dl
];
};
};
}

View file

@ -1,13 +1,13 @@
{ config, lib, pkgs, ... }:
{
options.chvp.firefox.enable = lib.mkOption {
options.chvp.graphical.firefox.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.firefox.enable {
chvp.zfs.homeLinks = [
config = lib.mkIf config.chvp.graphical.firefox.enable {
chvp.base.zfs.homeLinks = [
{ path = ".cache/mozilla"; type = "cache"; }
{ path = ".mozilla"; type = "data"; }
];

View file

@ -1,7 +1,7 @@
{ config, lib, ... }:
{
options.chvp.gnupg = {
options.chvp.graphical.gnupg = {
enable = lib.mkOption {
default = false;
example = true;
@ -16,13 +16,13 @@
};
};
config = lib.mkIf config.chvp.gnupg.enable {
chvp.zfs.homeLinks = [
config = lib.mkIf config.chvp.graphical.gnupg.enable {
chvp.base.zfs.homeLinks = [
{ path = ".gnupg"; type = "data"; }
];
programs.gnupg.agent = {
enable = true;
pinentryFlavor = config.chvp.gnupg.pinentryFlavor;
pinentryFlavor = config.chvp.graphical.gnupg.pinentryFlavor;
};
home-manager.users.charlotte = { lib, ... }: {
home.activation.fixPermissionsCommands = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
@ -34,7 +34,7 @@
enable = true;
defaultCacheTtl = 7200;
maxCacheTtl = 99999;
pinentryFlavor = config.chvp.gnupg.pinentryFlavor;
pinentryFlavor = config.chvp.graphical.gnupg.pinentryFlavor;
};
};
};

View file

@ -2,7 +2,7 @@
let
passwordScript = pkgs.writeShellScript "get_mail_password" ''${pkgs.pass}/bin/pass show "$@" | head -n1 | tr -d "\n"'';
notifyScript = name: pkgs.writeShellScript "notify_${name}_mail" (if config.chvp.graphical then ''
notifyScript = name: pkgs.writeShellScript "notify_${name}_mail" ''
unseen_count=$(${pkgs.mblaze}/bin/mlist -N ~/mail/*/INBOX | wc -l)
if [ "$unseen_count" = "1" ]
@ -12,7 +12,7 @@ let
then
${pkgs.libnotify}/bin/notify-send -t 5000 'New ${name} mail arrived' "$unseen_count unseen mails"
fi
'' else ''true'');
'';
makeAccount = { name, address, host ? "", imapHost ? host, smtpHost ? host, useStartTls ? false, passFile, extraConfig ? { } }: (lib.recursiveUpdate
{
inherit address;
@ -29,7 +29,7 @@ let
enable = true;
boxes = [ "INBOX" ];
onNotify = "${pkgs.isync}/bin/mbsync ${name}:INBOX";
onNotifyPost = "${config.chvp.emacs.package}/bin/emacsclient --eval \"(mu4e-update-index)\" && ${notifyScript name}";
onNotifyPost = "${config.chvp.base.emacs.package}/bin/emacsclient --eval \"(mu4e-update-index)\" && ${notifyScript name}";
};
mbsync = {
enable = true;
@ -76,139 +76,134 @@ let
toRecursiveINIBase 1;
in
{
options.chvp.mail-client = {
enable = lib.mkOption {
default = false;
example = true;
};
mu4eConfig =
let
mkAccountConfig = account: ''
(make-mu4e-context
:name "${account.name}"
:match-func (lambda (msg) (when msg (string-prefix-p "/${account.maildir.path}/" (mu4e-message-field msg :maildir))))
:vars '(
(user-mail-address . "${account.address}")
(user-full-name . "${account.realName}")
(mu4e-drafts-folder . "/${account.maildir.path}/${account.folders.drafts}")
(mu4e-sent-folder . "/${account.maildir.path}/${account.folders.sent}")
(mu4e-refile-folder . "/${account.maildir.path}/${account.folders.trash}")
(mu4e-trash-folder . "/${account.maildir.path}/${account.folders.trash}")
(message-sendmail-extra-arguments . ("--read-envelope-from" "--account" "${account.name}"))
)
)
'';
hmConfig = config.home-manager.users.charlotte;
in
lib.mkOption {
type = lib.types.str;
readOnly = true;
default = ''
(use-package mu4e
;; Use mu4e included in the mu package, see emacs.nix
:ensure nil
:demand t
:after (selectrum)
:hook
(mu4e-view-mode . display-line-numbers-mode)
(mu4e-compose-mode . mail/auto-dodona-cc-reply-to)
:custom
(mu4e-change-filenames-when-moving t "Avoid sync issues with mbsync")
(mu4e-maildir "${hmConfig.accounts.email.maildirBasePath}" "Root of the maildir hierarchy")
(mu4e-context-policy 'pick-first "Use the first mail context in the list")
(mu4e-attachment-dir "/home/charlotte/downloads/" "Save attachments to downloads folder")
(mu4e-compose-dont-reply-to-self t "Don't reply to myself on reply to all")
(mu4e-confirm-quit nil "Don't confirm when quitting")
(mu4e-completing-read-function 'completing-read "Use default completing read function")
(mu4e-headers-include-related nil "Don't show related messages by default")
(mu4e-headers-skip-duplicates nil "Show duplicate emails")
(message-kill-buffer-on-exit t "Close buffer when finished with email")
(mm-verify-option 'known "Always verify PGP signatures (known protocols)")
(mm-discouraged-alternatives '("text/html" "text/richtext") "Discourage showing HTML views")
(gnus-buttonized-mime-types '("multipart/signed") "Make sure signature verification is always shown")
(sendmail-program "msmtp" "Use msmtp to send email")
(message-sendmail-f-is-evil t "Remove username from the emacs message")
(message-send-mail-function 'message-send-mail-with-sendmail "Use sendmail to send mail instead internal smtp")
(message-cite-reply-position 'below "Bottom posting is the correct way to reply to email")
:config
(setq mu4e-contexts
(list
${lib.concatStringsSep "\n" (map mkAccountConfig (lib.attrValues hmConfig.accounts.email.accounts))}
)
)
(add-to-list
'mu4e-bookmarks
'(:name "Combined inbox" :query "maildir:/personal/INBOX or maildir:/work/INBOX or maildir:/posteo/INBOX or maildir:/jonggroen/INBOX" :key ?i)
)
(define-advice mu4e~context-ask-user
(:around (orig-fun &rest args) mu4e~context-ask-user-completing-read)
"Replace `mu4e-read-option` by general-purpose completing-read"
(cl-letf (((symbol-function 'mu4e-read-option)
(lambda (prompt options)
(let* ((prompt (mu4e-format "%s" prompt))
(choice (completing-read prompt (cl-mapcar #'car options) nil t))
(chosen-el (cl-find-if (lambda (option) (equal choice (car option))) options)))
(if chosen-el
(cdr chosen-el)
(mu4e-warn "Unknown option: '%s'" choice))))))
(apply orig-fun args)))
(define-skeleton mail/dodona-teacher-reply-skeleton
"Inserts a typical reply when someone uses the general form for a Dodona teacher request."
"Naam leerkracht: "
"Dag " str ",\n"
"\n"
_
"\n"
"Welkom op Dodona! Zou je het volgende formulier kunnen invullen?\n"
"\n"
"https://dodona.ugent.be/rights_requests/new/\n"
"\n"
"Zo hebben we meteen alle info die we nodig hebben om je "
"lesgeversrechten te geven op Dodona.\n"
"\n"
"Met vriendelijke groeten,\n"
"Charlotte Van Petegem"
)
(defun mail/dodona-cc-reply-to ()
"Add dodona@ugent.be in cc and reply-to headers."
(interactive)
(save-excursion (message-add-header "Cc: dodona@ugent.be\nReply-To: dodona@ugent.be\n"))
)
(defun mail/auto-dodona-cc-reply-to ()
"Set dodona@ugent.be in CC and Reply-To headers when message was directed to dodona@ugent.be"
(let ((msg mu4e-compose-parent-message))
(when (and msg (mu4e-message-contact-field-matches msg :to "dodona@ugent.be")) (mail/dodona-cc-reply-to))
)
)
:general
(lmap "m" '(mu4e :which-key "mail"))
;; Unmap SPC in the mail view so we can still use the leader.
(lmap mu4e-view-mode-map "" nil)
(lmap mu4e-compose-mode-map
"SPC s" '(mml-secure-message-sign-pgpmime :which-key "Sign")
"SPC c" '(mml-secure-message-encrypt-pgpmime :which-key "Encrypt")
"SPC t" '(mail/dodona-teacher-reply-skeleton :which-key "Teacher rights reply")
"SPC d" '(mail/dodona-cc-reply-to :which-key "Dodona support headers")
)
)
'';
description = "mu4e config for inclusion in init.el";
};
options.chvp.graphical.mail.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.mail-client.enable {
config = lib.mkIf config.chvp.graphical.mail.enable {
nixpkgs.overlays = [
(self: super: {
khal = super.khal.overrideAttrs (old: { doInstallCheck = false; });
})
];
chvp.zfs.homeLinks = [
{ path = "mail"; type = "data"; }
{ path = ".cache/mu"; type = "cache"; }
{ path = ".local/share/contacts"; type = "cache"; }
{ path = ".local/share/calendars"; type = "cache"; }
{ path = ".local/share/vdirsyncer"; type = "cache"; }
];
chvp = {
base = {
emacs.extraConfig =
let
mkAccountConfig = account: ''
(make-mu4e-context
:name "${account.name}"
:match-func (lambda (msg) (when msg (string-prefix-p "/${account.maildir.path}/" (mu4e-message-field msg :maildir))))
:vars '(
(user-mail-address . "${account.address}")
(user-full-name . "${account.realName}")
(mu4e-drafts-folder . "/${account.maildir.path}/${account.folders.drafts}")
(mu4e-sent-folder . "/${account.maildir.path}/${account.folders.sent}")
(mu4e-refile-folder . "/${account.maildir.path}/${account.folders.trash}")
(mu4e-trash-folder . "/${account.maildir.path}/${account.folders.trash}")
(message-sendmail-extra-arguments . ("--read-envelope-from" "--account" "${account.name}"))
)
)
'';
hmConfig = config.home-manager.users.charlotte;
in
[
''
(use-package mu4e
;; Use mu4e included in the mu package, see emacs.nix
:ensure nil
:demand t
:after (selectrum)
:hook
(mu4e-view-mode . display-line-numbers-mode)
(mu4e-compose-mode . mail/auto-dodona-cc-reply-to)
:custom
(mu4e-change-filenames-when-moving t "Avoid sync issues with mbsync")
(mu4e-maildir "${hmConfig.accounts.email.maildirBasePath}" "Root of the maildir hierarchy")
(mu4e-context-policy 'pick-first "Use the first mail context in the list")
(mu4e-attachment-dir "/home/charlotte/downloads/" "Save attachments to downloads folder")
(mu4e-compose-dont-reply-to-self t "Don't reply to myself on reply to all")
(mu4e-confirm-quit nil "Don't confirm when quitting")
(mu4e-completing-read-function 'completing-read "Use default completing read function")
(mu4e-headers-include-related nil "Don't show related messages by default")
(mu4e-headers-skip-duplicates nil "Show duplicate emails")
(message-kill-buffer-on-exit t "Close buffer when finished with email")
(mm-verify-option 'known "Always verify PGP signatures (known protocols)")
(mm-discouraged-alternatives '("text/html" "text/richtext") "Discourage showing HTML views")
(gnus-buttonized-mime-types '("multipart/signed") "Make sure signature verification is always shown")
(sendmail-program "msmtp" "Use msmtp to send email")
(message-sendmail-f-is-evil t "Remove username from the emacs message")
(message-send-mail-function 'message-send-mail-with-sendmail "Use sendmail to send mail instead internal smtp")
(message-cite-reply-position 'below "Bottom posting is the correct way to reply to email")
:config
(setq mu4e-contexts (list ${lib.concatStringsSep "\n" (map mkAccountConfig (lib.attrValues hmConfig.accounts.email.accounts))}))
(add-to-list
'mu4e-bookmarks
'(:name "Combined inbox" :query "maildir:/personal/INBOX or maildir:/work/INBOX or maildir:/posteo/INBOX or maildir:/jonggroen/INBOX" :key ?i)
)
(define-advice mu4e~context-ask-user
(:around (orig-fun &rest args) mu4e~context-ask-user-completing-read)
"Replace `mu4e-read-option` by general-purpose completing-read"
(cl-letf (((symbol-function 'mu4e-read-option)
(lambda (prompt options)
(let* ((prompt (mu4e-format "%s" prompt))
(choice (completing-read prompt (cl-mapcar #'car options) nil t))
(chosen-el (cl-find-if (lambda (option) (equal choice (car option))) options)))
(if chosen-el
(cdr chosen-el)
(mu4e-warn "Unknown option: '%s'" choice))))))
(apply orig-fun args)))
(define-skeleton mail/dodona-teacher-reply-skeleton
"Inserts a typical reply when someone uses the general form for a Dodona teacher request."
"Naam leerkracht: "
"Dag " str ",\n"
"\n"
_
"\n"
"Welkom op Dodona! Zou je het volgende formulier kunnen invullen?\n"
"\n"
"https://dodona.ugent.be/rights_requests/new/\n"
"\n"
"Zo hebben we meteen alle info die we nodig hebben om je "
"lesgeversrechten te geven op Dodona.\n"
"\n"
"Met vriendelijke groeten,\n"
"Charlotte Van Petegem"
)
(defun mail/dodona-cc-reply-to ()
"Add dodona@ugent.be in cc and reply-to headers."
(interactive)
(save-excursion (message-add-header "Cc: dodona@ugent.be\nReply-To: dodona@ugent.be\n"))
)
(defun mail/auto-dodona-cc-reply-to ()
"Set dodona@ugent.be in CC and Reply-To headers when message was directed to dodona@ugent.be"
(let ((msg mu4e-compose-parent-message))
(when (and msg (mu4e-message-contact-field-matches msg :to "dodona@ugent.be")) (mail/dodona-cc-reply-to))
)
)
:general
(lmap "m" '(mu4e :which-key "mail"))
;; Unmap SPC in the mail view so we can still use the leader.
(lmap mu4e-view-mode-map "" nil)
(lmap mu4e-compose-mode-map
"SPC s" '(mml-secure-message-sign-pgpmime :which-key "Sign")
"SPC c" '(mml-secure-message-encrypt-pgpmime :which-key "Encrypt")
"SPC t" '(mail/dodona-teacher-reply-skeleton :which-key "Teacher rights reply")
"SPC d" '(mail/dodona-cc-reply-to :which-key "Dodona support headers")
)
)
''
];
zfs.homeLinks = [
{ path = "mail"; type = "data"; }
{ path = ".cache/mu"; type = "cache"; }
{ path = ".local/share/contacts"; type = "cache"; }
{ path = ".local/share/calendars"; type = "cache"; }
{ path = ".local/share/vdirsyncer"; type = "cache"; }
];
};
};
home-manager.users.charlotte = { ... }: {
accounts.email = {
maildirBasePath = "/data/home/charlotte/mail";
@ -404,7 +399,7 @@ in
};
Service = {
Type = "oneshot";
ExecStart = [ "${pkgs.isync}/bin/mbsync -a" "${config.chvp.emacs.package}/bin/emacsclient --eval \"(mu4e-update-index)\"" ];
ExecStart = [ "${pkgs.isync}/bin/mbsync -a" "${config.chvp.base.emacs.package}/bin/emacsclient --eval \"(mu4e-update-index)\"" ];
};
};
vdirsyncer = {

View file

@ -1,12 +1,12 @@
{ config, lib, ... }:
{
options.chvp.pass.enable = lib.mkOption {
options.chvp.graphical.pass.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.pass.enable {
config = lib.mkIf config.chvp.graphical.pass.enable {
nixpkgs.overlays = [
(self: super: {
firefox = super.firefox.override { extraNativeMessagingHosts = [ self.passff-host ]; };
@ -14,6 +14,17 @@
})
];
chvp.base.emacs.extraConfig = [
''
(use-package auth-source-pass
:ensure nil
:custom
(auth-sources '(password-store))
(auth-source-pass-filename "${config.home-manager.users.charlotte.programs.password-store.settings.PASSWORD_STORE_DIR}")
)
''
];
home-manager.users.charlotte = { ... }: {
programs.password-store = {
enable = true;

View file

@ -1,13 +1,13 @@
{ config, lib, pkgs, ... }:
{
options.chvp.sound.enable = lib.mkOption {
options.chvp.graphical.sound.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.sound.enable {
chvp.zfs.homeLinks = [
config = lib.mkIf config.chvp.graphical.sound.enable {
chvp.base.zfs.homeLinks = [
{ path = ".config/pipewire"; type = "cache"; }
];

View file

@ -7,12 +7,12 @@ let
status-configuration = import ./status-configuration.nix { inherit pkgs config; };
in
{
options.chvp.sway.enable = lib.mkOption {
options.chvp.graphical.sway.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.sway.enable {
config = lib.mkIf config.chvp.graphical.sway.enable {
services.dbus.packages = with pkgs; [ gnome3.dconf ];
security.pam.services.swaylock = { };
xdg.portal = {

View file

@ -85,7 +85,7 @@ pkgs.writeText "configuration.toml" ''
json = true
command = "${mail-status}"
interval = 1
on_click = "${pkgs.isync}/bin/mbsync -a && ${config.chvp.emacs.package}/bin/emacsclient --eval \"(mu4e-update-index)\""
on_click = "${pkgs.isync}/bin/mbsync -a && ${config.chvp.base.emacs.package}/bin/emacsclient --eval \"(mu4e-update-index)\""
[[block]]
block = "time"

View file

@ -1,13 +1,13 @@
{ config, lib, pkgs, ... }:
{
options.chvp.syncthing-client.enable = lib.mkOption {
options.chvp.graphical.syncthing.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.syncthing-client.enable {
chvp.zfs.homeLinks = [
config = lib.mkIf config.chvp.graphical.syncthing.enable {
chvp.base.zfs.homeLinks = [
{ path = ".config/syncthing"; type = "data"; }
{ path = "sync"; type = "cache"; }
];

View file

@ -1,12 +1,12 @@
{ config, lib, pkgs, ... }:
{
options.chvp.terminal.enable = lib.mkOption {
options.chvp.graphical.terminal.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.terminal.enable {
config = lib.mkIf config.chvp.graphical.terminal.enable {
home-manager.users.charlotte = { pkgs, ... }: {
programs.kitty = {
enable = true;

View file

@ -1,12 +1,12 @@
{ config, lib, pkgs, ... }:
{
options.chvp.theming.enable = lib.mkOption {
options.chvp.graphical.theme.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.theming.enable {
config = lib.mkIf config.chvp.graphical.theme.enable {
fonts = {
fontDir.enable = true;
fontconfig = {

View file

@ -1,13 +1,13 @@
{ config, lib, pkgs, ... }:
{
options.chvp.xdg.enable = lib.mkOption {
options.chvp.graphical.xdg.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.xdg.enable {
chvp.zfs.homeLinks = [
config = lib.mkIf config.chvp.graphical.xdg.enable {
chvp.base.zfs.homeLinks = [
{ path = "desktop"; type = "data"; }
{ path = "documents"; type = "data"; }
{ path = "downloads"; type = "cache"; }

View file

@ -1,32 +0,0 @@
{ config, lib, pkgs, ... }:
let
hledger-repo = pkgs.fetchFromGitHub {
owner = "chvp";
repo = "hledger";
rev = "feature/gain-reports";
sha256 = "07qsrq71pnkys11q6k2zc20xc9l3yp8dhzp1ar5bnkgcwbm69rcx";
};
in
{
options.chvp.hledger.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.hledger.enable {
nixpkgs.overlays = [
(self: super: {
haskellPackages = super.haskellPackages.override {
overrides = hself: hsuper: rec {
hledger = hsuper.callCabal2nixWithOptions "hledger" hledger-repo "--subpath hledger" { };
hledger-lib = hsuper.callCabal2nixWithOptions "hledger-lib" hledger-repo "--subpath hledger-lib" { };
};
};
})
];
home-manager.users.charlotte = { ... }: {
home.packages = [ pkgs.hledger ];
};
};
}

View file

@ -1,30 +0,0 @@
{ config, lib, pkgs, ... }:
{
options.chvp.minecraft = {
client = lib.mkOption {
default = false;
example = true;
};
server = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf (config.chvp.minecraft.client || config.chvp.minecraft.server) {
home-manager.users.charlotte = lib.mkIf config.chvp.minecraft.client ({ ... }: {
home.packages = [ pkgs.minecraft ];
});
chvp.zfs.homeLinks = lib.optional config.chvp.minecraft.client { path = ".minecraft"; type = "cache"; };
services.minecraft-server = lib.mkIf config.chvp.minecraft.server {
enable = true;
dataDir = "${config.chvp.dataPrefix}/var/lib/minecraft-server";
eula = true;
openFirewall = true;
};
chvp.nix.unfreePackages =
(lib.optional config.chvp.minecraft.client "minecraft-launcher") ++
(lib.optional config.chvp.minecraft.server "minecraft-server");
};
}

View file

@ -1,13 +1,13 @@
{ config, lib, pkgs, ... }:
{
options.chvp.calibre.enable = lib.mkOption {
options.chvp.programs.calibre.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.calibre.enable {
chvp.zfs.homeLinks = [
config = lib.mkIf config.chvp.programs.calibre.enable {
chvp.base.zfs.homeLinks = [
{ path = ".config/calibre"; type = "cache"; }
];
home-manager.users.charlotte = { ... }: {

View file

@ -0,0 +1,12 @@
{ ... }:
{
imports = [
./calibre
./deluge
./dropbox
./eid
./hledger
./obs
];
}

View file

@ -1,17 +1,17 @@
{ config, lib, pkgs, ... }:
{
options.chvp.deluge-client.enable = lib.mkOption {
options.chvp.programs.deluge.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.deluge-client.enable {
config = lib.mkIf config.chvp.programs.deluge.enable {
home-manager.users.charlotte = { pkgs, ... }: {
home.packages = with pkgs; [ deluge ];
};
chvp.zfs.homeLinks = [
chvp.base.zfs.homeLinks = [
{ path = ".config/deluge"; type = "data"; }
];
};

View file

@ -1,13 +1,13 @@
{ config, lib, pkgs, ... }:
{
options.chvp.dropbox.enable = lib.mkOption {
options.chvp.programs.dropbox.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.dropbox.enable {
chvp = {
config = lib.mkIf config.chvp.programs.dropbox.enable {
chvp.base = {
nix.unfreePackages = [ "dropbox" ];
zfs.homeLinks = [
{ path = ".dropbox"; type = "cache"; }

View file

@ -1,12 +1,12 @@
{ config, lib, pkgs, ... }:
{
options.chvp.eid.enable = lib.mkOption {
options.chvp.programs.eid.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.eid.enable {
config = lib.mkIf config.chvp.programs.eid.enable {
environment.systemPackages = [ pkgs.eid-mw ];
nixpkgs.overlays = [
(self: super: {

View file

@ -0,0 +1,50 @@
{ config, lib, pkgs, ... }:
let
hledger-repo = pkgs.fetchFromGitHub {
owner = "chvp";
repo = "hledger";
rev = "feature/gain-reports";
sha256 = "07qsrq71pnkys11q6k2zc20xc9l3yp8dhzp1ar5bnkgcwbm69rcx";
};
in
{
options.chvp.programs.hledger.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.programs.hledger.enable {
nixpkgs.overlays = [
(self: super: {
haskellPackages = super.haskellPackages.override {
overrides = hself: hsuper: rec {
hledger = hsuper.callCabal2nixWithOptions "hledger" hledger-repo "--subpath hledger" { };
hledger-lib = hsuper.callCabal2nixWithOptions "hledger-lib" hledger-repo "--subpath hledger-lib" { };
};
};
})
];
chvp.base.emacs.extraConfig = [
''
;; Ledger syntax support
(use-package ledger-mode
:mode "\\.journal\\'"
:custom
(ledger-binary-path "hledger" "Use hledger instead of ledger")
(ledger-highlight-xact-under-point nil "Remove distracting highlight")
(ledger-mode-should-check-version nil "Remove version check, since it doesn't work with hledger anyway")
(ledger-post-account-alignment-column 4 "Indent postings with 4 spaces")
(ledger-post-amount-alignment-at :decimal "Align on the decimal")
(ledger-post-amount-alignment-column 59 "Align on column 60")
(ledger-post-auto-align t "Align when moving to the next line")
)
''
];
home-manager.users.charlotte = { ... }: {
home.packages = [ pkgs.hledger ];
};
};
}

View file

@ -1,19 +1,19 @@
{ config, lib, pkgs, ... }:
{
options.chvp.obs.enable = lib.mkOption {
options.chvp.programs.obs.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.obs.enable {
config = lib.mkIf config.chvp.programs.obs.enable {
boot.kernelModules = [ "v4l2loopback" ];
boot.extraModulePackages = [ pkgs.linuxPackages.v4l2loopback ];
boot.extraModprobeConfig = ''
options v4l2loopback video_nr=9 card_label="obs"
'';
chvp.zfs.homeLinks = [
chvp.base.zfs.homeLinks = [
{ path = ".config/obs-studio"; type = "data"; }
];

View file

@ -9,7 +9,9 @@ let
rev = "develop";
sha256 = "0z5a3jwi93rriq5hvdqv53421jj9pg5651nam6h9krj6zhr93fs3";
};
yarnNix = ./accentor/yarn.nix;
packageJSON = ./package.json;
yarnLock = ./yarn.lock;
yarnNix = ./yarn.nix;
buildPhase = ''
cp deps/accentor/postcss.config.js .
yarn run build
@ -29,9 +31,9 @@ let
gems = pkgs.bundlerEnv {
name = "accentor-api-env";
ruby = pkgs.ruby_3_0;
gemfile = ./accentor/Gemfile;
lockfile = ./accentor/Gemfile.lock;
gemset = ./accentor/gemset.nix;
gemfile = ./Gemfile;
lockfile = ./Gemfile.lock;
gemset = ./gemset.nix;
groups = [ "default" "development" "test" "production" ];
};
env = {
@ -48,12 +50,12 @@ let
};
in
{
options.chvp.accentor.enable = lib.mkOption {
options.chvp.services.accentor.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.accentor.enable {
config = lib.mkIf config.chvp.services.accentor.enable {
environment.systemPackages = [
(pkgs.writeShellScriptBin "accentor-console" ''
set -ex
@ -141,7 +143,7 @@ in
}) 4));
age.secrets."passwords/services/accentor" = {
file = ../secrets/passwords/services/accentor.age;
file = ../../../secrets/passwords/services/accentor.age;
owner = "accentor";
};
@ -153,7 +155,7 @@ in
};
users.groups.accentor.gid = 314;
chvp.nginx.hosts = [{
chvp.services.nginx.hosts = [{
fqdn = "accentor.vanpetegem.me";
options = {
root = web;

View file

@ -0,0 +1,45 @@
{
"name": "accentor",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'"
},
"dependencies": {
"@mdi/font": "^5.9.55",
"@mdi/svg": "^5.9.55",
"fetch-retry": "^4.1.1",
"roboto-fontface": "^0.10.0",
"vue": "^2.6.14",
"vue-i18n": "^8.24.5",
"vue-meta": "^2.4.0",
"vue-router": "^3.5.2",
"vuedraggable": "^2.24.3",
"vuetify": "^2.5.6",
"vuex": "^3.6.2",
"vuex-persistedstate": "^3.2.0"
},
"devDependencies": {
"@intlify/vue-i18n-loader": "^1.1.0",
"@vue/cli-plugin-babel": "^4.5.13",
"@vue/cli-plugin-eslint": "^4.5.13",
"@vue/cli-service": "^4.5.13",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.8.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-vue": "^7.12.1",
"eslint-plugin-vuetify": "^1.0.1",
"prettier": "^2.3.2",
"sass": "^1.35.1",
"sass-loader": "^10.1.1",
"vue-cli-plugin-i18n": "^2.1.0",
"vue-cli-plugin-vuetify": "^2.4.1",
"vue-template-compiler": "^2.6.14",
"vuetify-loader": "^1.7.2",
"webpack": "^4.46.0"
}
}

View file

@ -2,7 +2,7 @@
#!nix-shell -p curl yarn2nix bundix -i bash
curl -L -O https://github.com/accentor/api/raw/develop/Gemfile
curl -L -O https://github.com/accentor/api/raw/develop/Gemfile.lock
curl -L -O https://github.com/accentor/web/raw/develop/package.json
curl -L -O https://github.com/accentor/web/raw/develop/yarn.lock
yarn2nix --lockfile yarn.lock --no-patch > yarn.nix
rm yarn.lock
bundix -l

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,21 @@
{ config, lib, pkgs, ... }:
{
options.chvp.services.containers = {
enable = lib.mkOption {
default = false;
example = true;
};
externalInterface = lib.mkOption {
example = "eno3";
};
};
config = {
networking.nat = lib.mkIf config.chvp.services.containers.enable {
enable = true;
enableIPv6 = true;
internalInterfaces = [ "ve-+" ];
externalInterface = config.chvp.services.containers.externalInterface;
};
};
}

View file

@ -1,9 +1,6 @@
{ pkgs, ... }: {
imports = [
./config.secret.nix
];
{ pkgs, ... }:
{
users.users.data = {
isNormalUser = true;
home = "/home/data";

Binary file not shown.

View file

@ -0,0 +1,67 @@
{ config, lib, ... }:
{
imports = [ ./secret.nix ];
options.chvp.services.data-access.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.services.data-access.enable {
chvp.services = {
containers.enable = true;
nginx.hosts = [
{
fqdn = "data.vanpetegem.me";
options = {
default = true;
basicAuthFile = config.age.secrets."passwords/services/data-basic-auth".path;
root = "/srv/data";
locations = {
"/".extraConfig = ''
autoindex on;
'';
"/public".extraConfig = ''
autoindex on;
auth_basic off;
'';
};
};
}
];
};
containers.data-access = {
ephemeral = true;
autoStart = true;
bindMounts = {
"/home/data/data" = {
hostPath = "/srv/data";
isReadOnly = false;
};
"/run/secrets" = {
hostPath = "/run/secrets/data-access";
isReadOnly = true;
};
};
privateNetwork = true;
hostAddress = "192.168.100.10";
hostAddress6 = "fc00::1";
localAddress = "192.168.100.11";
localAddress6 = "fc00::2";
config = { ... }: {
imports = [ ./config.nix ./config.secret.nix ];
};
};
age.secrets."data-access/ssh_host_rsa_key".file = ../../../secrets/data-access/ssh_host_rsa_key.age;
age.secrets."data-access/ssh_host_rsa_key.pub".file = ../../../secrets/data-access/ssh_host_rsa_key.pub.age;
age.secrets."data-access/ssh_host_ed25519_key".file = ../../../secrets/data-access/ssh_host_ed25519_key.age;
age.secrets."data-access/ssh_host_ed25519_key.pub".file = ../../../secrets/data-access/ssh_host_ed25519_key.pub.age;
age.secrets."passwords/services/data-basic-auth" = {
file = ../../../secrets/passwords/services/data-basic-auth.age;
owner = "nginx";
};
};
}

Binary file not shown.

View file

@ -0,0 +1,13 @@
{ ... }:
{
imports = [
./accentor
./containers
./data-access
./deluge
./nextcloud
./nginx
./syncthing
];
}

View file

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }:
{
options.chvp.deluge-server = {
options.chvp.services.deluge = {
enable = lib.mkOption {
default = false;
example = true;
@ -12,18 +12,18 @@
};
};
config = lib.mkIf config.chvp.deluge-server.enable {
chvp.nginx.hosts = builtins.genList
config = lib.mkIf config.chvp.services.deluge.enable {
chvp.services.nginx.hosts = builtins.genList
(n: {
fqdn = "del${toString (n + 1)}.vanpetegem.me";
basicProxy = "http://localhost:${toString (8112 + n)}";
})
config.chvp.deluge-server.count;
config.chvp.services.deluge.count;
networking.firewall = {
allowedTCPPortRanges = [
{ from = 60000; to = 60000 + config.chvp.deluge-server.count - 1; }
{ from = 58846; to = 58846 + config.chvp.deluge-server.count - 1; }
{ from = 60000; to = 60000 + config.chvp.services.deluge.count - 1; }
{ from = 58846; to = 58846 + config.chvp.services.deluge.count - 1; }
];
};
@ -32,7 +32,8 @@
let num = toString (n + 1); in
{
"del${num}" = {
after = [ "network.target" ];
after = [ "network-online.target" ];
requires = [ "network-online.target" ];
description = "Deluge daemon ${num}";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.deluge ];
@ -61,6 +62,6 @@
};
};
})
config.chvp.deluge-server.count);
config.chvp.services.deluge.count);
};
}

View file

@ -1,11 +1,11 @@
{ config, lib, pkgs, ... }:
{
options.chvp.nextcloud.enable = lib.mkOption {
options.chvp.services.nextcloud.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.nextcloud.enable {
config = lib.mkIf config.chvp.services.nextcloud.enable {
services = {
nextcloud = {
home = "${config.chvp.dataPrefix}/var/lib/nextcloud";
@ -38,7 +38,7 @@
};
};
age.secrets."passwords/services/nextcloud-admin" = {
file = ../secrets/passwords/services/nextcloud-admin.age;
file = ../../../secrets/passwords/services/nextcloud-admin.age;
owner = "nextcloud";
};
systemd.services."nextcloud-setup" = {

View file

@ -1,10 +1,10 @@
{ config, lib, ... }:
{
options.chvp.nginx = {
options.chvp.services.nginx = {
enable = lib.mkOption {
default = false;
example = true;
readOnly = true;
default = (builtins.length config.chvp.services.nginx.hosts) > 0;
};
hosts = lib.mkOption {
default = [ ];
@ -41,7 +41,7 @@
};
};
config = lib.mkIf config.chvp.nginx.enable {
config = lib.mkIf config.chvp.services.nginx.enable {
networking.firewall.allowedTCPPorts = [ 80 443 ];
security.acme = {
certs."vanpetegem.me" = {
@ -54,17 +54,17 @@
"chvp.be"
"*.chvp.be"
];
postRun = lib.concatStrings config.chvp.nginx.extraPostACMEScripts;
postRun = lib.concatStrings config.chvp.services.nginx.extraPostACMEScripts;
};
email = "webmaster@vanpetegem.me";
acceptTerms = true;
preliminarySelfsigned = false;
};
age.secrets."passwords/services/acme" = {
file = ../secrets/passwords/services/acme.age;
file = ../../../secrets/passwords/services/acme.age;
owner = "acme";
};
chvp.zfs.systemLinks = [
chvp.base.zfs.systemLinks = [
{ type = "data"; path = "/var/lib/acme"; }
];
services.nginx = {
@ -88,7 +88,7 @@
};
} // (elem.options or { });
})
config.chvp.nginx.hosts);
config.chvp.services.nginx.hosts);
};
users.users.nginx.extraGroups = [ "acme" ];
};

View file

@ -1,12 +1,12 @@
{ config, lib, ... }:
{
options.chvp.syncthing-server.enable = lib.mkOption {
options.chvp.services.syncthing.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.syncthing-server.enable {
config = lib.mkIf config.chvp.services.syncthing.enable {
services.syncthing = {
enable = true;
dataDir = "${config.chvp.dataPrefix}/var/lib/syncthing";
@ -15,17 +15,16 @@
guiAddress = "127.0.0.1:8384";
};
chvp.nginx.hosts = [
chvp.services.nginx.hosts = [
{
fqdn = "syncthing.vanpetegem.me";
basicProxy = "http://localhost:8384";
options = {
basicAuthFile = config.age.secrets."passwords/services/syncthing-basic-auth".path;
};
options.basicAuthFile = config.age.secrets."passwords/services/syncthing-basic-auth".path;
}
];
age.secrets."passwords/services/syncthing-basic-auth" = {
file = ../secrets/passwords/services/syncthing-basic-auth.age;
file = ../../../secrets/passwords/services/syncthing-basic-auth.age;
owner = "nginx";
};
};

View file

@ -1,25 +0,0 @@
{ config, lib, pkgs, ... }:
{
options.chvp.smartd.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.smartd.enable {
chvp.globalMailer.enable = true;
environment.systemPackages = [ pkgs.smartmontools ];
services.smartd = {
enable = true;
autodetect = true;
notifications = {
mail = {
enable = true;
sender = "${config.networking.hostName}@vanpetegem.me";
recipient = "webmaster@vanpetegem.me";
};
wall.enable = false;
};
};
};
}

View file

@ -1,27 +0,0 @@
{ config, lib, ... }:
{
options.chvp.sshd.enable = lib.mkOption {
default = true;
example = false;
};
config = lib.mkIf config.chvp.sshd.enable {
services.openssh = {
enable = true;
passwordAuthentication = false;
permitRootLogin = "prohibit-password";
hostKeys = [
{ bits = 4096; path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_rsa_key"; type = "rsa"; }
{ path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; }
];
authorizedKeysFiles = [ "/run/secrets/authorized_keys/%u" ];
};
age.secrets."authorized_keys/charlotte" = {
file = ../secrets/authorized_keys/charlotte.age;
owner = "charlotte";
};
age.secrets."authorized_keys/root".file = ../secrets/authorized_keys/root.age;
};
}

View file

@ -1,24 +0,0 @@
{ config, lib, ... }:
{
imports = [
./vpn.nix
./citrix.nix
./mounts.nix
./teams.nix
];
options.chvp.ugent.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.ugent.enable {
chvp.ugent = {
citrix.enable = lib.mkDefault true;
vpn.enable = lib.mkDefault true;
mounts.enable = lib.mkDefault true;
teams.enable = lib.mkDefault true;
};
};
}

Binary file not shown.

View file

@ -1,13 +1,13 @@
{ config, lib, ... }:
{
options.chvp.ugent.citrix.enable = lib.mkOption {
options.chvp.work.citrix.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.ugent.citrix.enable {
chvp = {
config = lib.mkIf config.chvp.work.citrix.enable {
chvp.base = {
nix.unfreePackages = [ "citrix-workspace" ];
zfs.homeLinks = [
{ path = ".ICAClient"; type = "data"; }

Some files were not shown because too many files have changed in this diff Show more