Compare commits
2 commits
d67d75eda3
...
50c182d827
Author | SHA1 | Date | |
---|---|---|---|
b12f | 50c182d827 | ||
b12f | a1670dcb3d |
|
@ -6,7 +6,8 @@ end_of_line = lf
|
|||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
charset = utf-8
|
||||
indent_style = tab
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# Ignore diffs/patches
|
||||
[*.{diff,patch}]
|
||||
|
@ -19,8 +20,8 @@ indent_style = unset
|
|||
indent_size = unset
|
||||
|
||||
[{.*,secrets}/**]
|
||||
end_of_line = unset
|
||||
insert_final_newline = unset
|
||||
end_of_line = false
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = unset
|
||||
charset = unset
|
||||
indent_style = unset
|
||||
|
|
15
flake.nix
15
flake.nix
|
@ -48,8 +48,8 @@
|
|||
invoiceplane-template.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = inputs@{ self, ... }:
|
||||
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
outputs = inputs @ {self, ...}:
|
||||
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
|
@ -65,7 +65,13 @@
|
|||
./overlays
|
||||
];
|
||||
|
||||
perSystem = args@{ system, pkgs, lib, config, ... }: {
|
||||
perSystem = args @ {
|
||||
system,
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
_module.args = {
|
||||
inherit inputs;
|
||||
pkgs = import inputs.nixpkgs {
|
||||
|
@ -98,12 +104,11 @@
|
|||
|
||||
deploy-rs
|
||||
|
||||
terraform-ls
|
||||
terraform-ls
|
||||
opentofu
|
||||
terraform-backend-git
|
||||
|
||||
deno
|
||||
denols
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ ... }: {
|
||||
{...}: {
|
||||
imports = [
|
||||
./configuration.nix
|
||||
./hardware-configuration.nix
|
||||
|
|
|
@ -39,6 +39,6 @@ in {
|
|||
];
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 34197 ];
|
||||
networking.firewall.allowedTCPPorts = [ 34197 ];
|
||||
networking.firewall.allowedUDPPorts = [34197];
|
||||
networking.firewall.allowedTCPPorts = [34197];
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
{ withSystem, self, inputs, ...}:
|
||||
{
|
||||
withSystem,
|
||||
self,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
flake = {
|
||||
nixosConfigurations = {
|
||||
stroopwafel = self.nixos-flake.lib.mkLinuxSystem {
|
||||
|
@ -137,7 +141,7 @@
|
|||
self.nixosModules.graphical
|
||||
self.nixosModules.audio
|
||||
self.nixosModules.bluetooth
|
||||
({ ... }: { pub-solar.graphical.wayland.software-renderer.enable = true; })
|
||||
({...}: {pub-solar.graphical.wayland.software-renderer.enable = true;})
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@ in {
|
|||
# Hack so that network is considered up by boot.initrd.network and postCommands gets executed.
|
||||
"ip=127.0.0.1:::::lo:none"
|
||||
];
|
||||
boot.initrd.availableKernelModules = [ "tg3" ];
|
||||
boot.initrd.availableKernelModules = ["tg3"];
|
||||
boot.initrd.network = {
|
||||
enable = true;
|
||||
ssh = {
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "ehci_pci" "usbhid" "usb_storage" "uas" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ "dm-snapshot" "amdgpu" ];
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "ehci_pci" "usbhid" "usb_storage" "uas" "sd_mod"];
|
||||
boot.initrd.kernelModules = ["dm-snapshot" "amdgpu"];
|
||||
boot.kernelModules = ["kvm-amd"];
|
||||
boot.extraModulePackages = [];
|
||||
|
||||
boot.initrd.luks.devices = {
|
||||
"cryptroot" = {
|
||||
|
@ -21,42 +25,42 @@
|
|||
"cryptdata".device = "/dev/sda1";
|
||||
};
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "none";
|
||||
fsType = "tmpfs";
|
||||
};
|
||||
fileSystems."/" = {
|
||||
device = "none";
|
||||
fsType = "tmpfs";
|
||||
};
|
||||
|
||||
fileSystems."/nix" =
|
||||
{ device = "/dev/disk/by-uuid/837cc93f-6d9a-4bfd-b089-29ac6d68127c";
|
||||
fsType = "ext4";
|
||||
neededForBoot = true;
|
||||
};
|
||||
fileSystems."/nix" = {
|
||||
device = "/dev/disk/by-uuid/837cc93f-6d9a-4bfd-b089-29ac6d68127c";
|
||||
fsType = "ext4";
|
||||
neededForBoot = true;
|
||||
};
|
||||
|
||||
fileSystems."/persist" =
|
||||
{ device = "/dev/disk/by-uuid/a7711118-51b0-4d84-8f18-ef2e06084e05";
|
||||
fsType = "ext4";
|
||||
neededForBoot = true;
|
||||
};
|
||||
fileSystems."/persist" = {
|
||||
device = "/dev/disk/by-uuid/a7711118-51b0-4d84-8f18-ef2e06084e05";
|
||||
fsType = "ext4";
|
||||
neededForBoot = true;
|
||||
};
|
||||
|
||||
fileSystems."/home" =
|
||||
{ device = "/dev/disk/by-uuid/0965d496-ffad-4a8d-9de7-28af903baf16";
|
||||
fsType = "ext4";
|
||||
};
|
||||
fileSystems."/home" = {
|
||||
device = "/dev/disk/by-uuid/0965d496-ffad-4a8d-9de7-28af903baf16";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/991E-79C1";
|
||||
fsType = "vfat";
|
||||
neededForBoot = true;
|
||||
};
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/991E-79C1";
|
||||
fsType = "vfat";
|
||||
neededForBoot = true;
|
||||
};
|
||||
|
||||
fileSystems."/data" =
|
||||
{ device = "/dev/disk/by-uuid/5fc34ef4-207b-45fb-b846-dbb01080d9fe";
|
||||
fsType = "ext4";
|
||||
};
|
||||
fileSystems."/data" = {
|
||||
device = "/dev/disk/by-uuid/5fc34ef4-207b-45fb-b846-dbb01080d9fe";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/0ef8dbbd-2832-4fb2-8a52-86682822f769"; }
|
||||
];
|
||||
swapDevices = [
|
||||
{device = "/dev/disk/by-uuid/0ef8dbbd-2832-4fb2-8a52-86682822f769";}
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
};
|
||||
|
||||
# from https://jellyfin.org/docs/general/networking/index.html
|
||||
networking.firewall.allowedUDPPorts = [ 1900 7359 ];
|
||||
networking.firewall.allowedUDPPorts = [1900 7359];
|
||||
|
||||
security.acme.certs = {
|
||||
"media.b12f.io" = {};
|
||||
|
|
|
@ -10,7 +10,12 @@
|
|||
networking.interfaces.enp2s0f1.useDHCP = true;
|
||||
|
||||
networking.interfaces.enp2s0f0 = {
|
||||
ipv6.addresses = [ { address = "2a02:908:5b1:e3c0:3::"; prefixLength = 64; } ];
|
||||
ipv6.addresses = [
|
||||
{
|
||||
address = "2a02:908:5b1:e3c0:3::";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
# Allow pub.solar restic backups
|
||||
|
|
|
@ -9,7 +9,6 @@ with lib; let
|
|||
psCfg = config.pub-solar;
|
||||
xdg = config.home-manager.users."${psCfg.user.name}".xdg;
|
||||
in {
|
||||
|
||||
# Use the systemd-boot EFI boot loader.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
@ -20,13 +19,13 @@ in {
|
|||
"ip=127.0.0.1:::::lo:none"
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_net" ];
|
||||
boot.initrd.availableKernelModules = ["virtio_pci" "virtio_net"];
|
||||
boot.initrd.network = {
|
||||
enable = true;
|
||||
ssh = {
|
||||
enable = true;
|
||||
port = 2222;
|
||||
hostKeys = [ /boot/initrd-ssh-key ];
|
||||
hostKeys = [/boot/initrd-ssh-key];
|
||||
authorizedKeys = flake.self.publicKeys;
|
||||
shell = "/bin/cryptsetup-askpass";
|
||||
};
|
||||
|
@ -44,7 +43,7 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
boot.supportedFilesystems = [ "zfs" ];
|
||||
boot.supportedFilesystems = ["zfs"];
|
||||
|
||||
# Copy the NixOS configuration file and link it from the resulting system
|
||||
# (/run/current-system/configuration.nix). This is useful in case you
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
lib,
|
||||
...
|
||||
}: let
|
||||
hzDomain = lib.concatStrings [ "hw" "dz" "z." "net" ];
|
||||
hzDomain = lib.concatStrings ["hw" "dz" "z." "net"];
|
||||
dkimDNSb12fio = ''
|
||||
default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyla9hW3TvoXvZQxwzaJ4SZ9ict1HU3E6+FWlwNIgE6tIpTCyRJtiSIUDqB8TLTIBoxIs+QQBXZi+QUi3Agu6OSY2RiV0EwO8+oOOqOD9pERftc/aqe51cXuv4kPqwvpXEBwrXFWVM+VxivEubUJ7eKkFyXJpelv0LslXv/MmYbUyed6dF+reOGZCsvnbiRv74qdxbAL/25j62E8WrnxzJwhUtx/JhdBOjsHBvuw9hy6rZsVJL9eXayWyGRV6qmsLRzsRSBs+mDrgmKk4dugADd11+A03ics3i8hplRoWDkqnNKz1qy4f5TsV6v9283IANrAzRfHwX8EvNiFsBz+ZCQIDAQAB" ) ;
|
||||
default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyla9hW3TvoXvZQxwzaJ4SZ9ict1HU3E6+FWlwNIgE6tIpTCyRJtiSIUDqB8TLTIBoxIs+QQBXZi+QUi3Agu6OSY2RiV0EwO8+oOOqOD9pERftc/aqe51cXuv4kPqwvpXEBwrXFWVM+VxivEubUJ7eKkFyXJpelv0LslXv/MmYbUyed6dF+reOGZCsvnbiRv74qdxbAL/25j62E8WrnxzJwhUtx/JhdBOjsHBvuw9hy6rZsVJL9eXayWyGRV6qmsLRzsRSBs+mDrgmKk4dugADd11+A03ics3i8hplRoWDkqnNKz1qy4f5TsV6v9283IANrAzRfHwX8EvNiFsBz+ZCQIDAQAB" ) ;
|
||||
'';
|
||||
dkimDNSmezzabiz = ''
|
||||
default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDG8iuDq0eon2k7QlBJWGxwDiEv53iJQu2uqxOjr7Ul/nfQjuR6kVKs6oOVopnyFTGRpffrpSHHW1YUN5nF76p0fJphk4l+QmJP36/xweajsNU27PAkb88xG6yRKl28MCfPdMR96+Jobpei8S0UhqcskYs1aZybm7ci9ZuAMidziwIDAQAB" ) ;
|
||||
default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDG8iuDq0eon2k7QlBJWGxwDiEv53iJQu2uqxOjr7Ul/nfQjuR6kVKs6oOVopnyFTGRpffrpSHHW1YUN5nF76p0fJphk4l+QmJP36/xweajsNU27PAkb88xG6yRKl28MCfPdMR96+Jobpei8S0UhqcskYs1aZybm7ci9ZuAMidziwIDAQAB" ) ;
|
||||
'';
|
||||
dkimDNShzDomain = ''
|
||||
default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvVA2XZno6g6qBdmxoLgX2Qmd883M6yV4YkE/VaNH6xcR0AcTo4hEYoAOPryfKn4FE/TYvyk/k2cyBKpMBn2qbVhwUavYQh/e9bweS2FKQvdzCUUoqXk04o2MqSXb2ZFwkUCtfrPcckBgpF754PDL4HMZGPnkMSdDX7bmYe37CWQIDAQAB") ;
|
||||
default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvVA2XZno6g6qBdmxoLgX2Qmd883M6yV4YkE/VaNH6xcR0AcTo4hEYoAOPryfKn4FE/TYvyk/k2cyBKpMBn2qbVhwUavYQh/e9bweS2FKQvdzCUUoqXk04o2MqSXb2ZFwkUCtfrPcckBgpF754PDL4HMZGPnkMSdDX7bmYe37CWQIDAQAB") ;
|
||||
'';
|
||||
in {
|
||||
age.secrets."b12f.io-dkim-private-rsa" = {
|
||||
|
@ -55,21 +55,23 @@ in {
|
|||
owner = "maddy";
|
||||
};
|
||||
|
||||
users.users.maddy.extraGroups = [ "nginx" ];
|
||||
users.users.maddy.extraGroups = ["nginx"];
|
||||
|
||||
security.acme.certs = {
|
||||
"mail.b12f.io".reloadServices = [ "maddy" ];
|
||||
"b12f.io".reloadServices = [ "maddy" ];
|
||||
"mail.b12f.io".reloadServices = ["maddy"];
|
||||
"b12f.io".reloadServices = ["maddy"];
|
||||
"mta-sts.b12f.io" = {};
|
||||
"mail.mezza.biz".reloadServices = [ "maddy" ];
|
||||
"mezza.biz".reloadServices = [ "maddy" ];
|
||||
"mail.mezza.biz".reloadServices = ["maddy"];
|
||||
"mezza.biz".reloadServices = ["maddy"];
|
||||
"mta-sts.mezza.biz" = {};
|
||||
"mail.${hzDomain}".reloadServices = [ "maddy" ];
|
||||
"${hzDomain}".reloadServices = [ "maddy" ];
|
||||
"mail.${hzDomain}".reloadServices = ["maddy"];
|
||||
"${hzDomain}".reloadServices = ["maddy"];
|
||||
"mta-sts.${hzDomain}" = {};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts = builtins.foldl' (hosts: hostName: hosts // {
|
||||
services.nginx.virtualHosts = builtins.foldl' (hosts: hostName:
|
||||
hosts
|
||||
// {
|
||||
"mta-sts.${hostName}" = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "mta-sts.${hostName}";
|
||||
|
@ -86,13 +88,13 @@ in {
|
|||
tryFiles = "$uri $uri/ =404";
|
||||
};
|
||||
};
|
||||
}) {} [ "b12f.io" "mezza.biz" hzDomain ];
|
||||
}) {} ["b12f.io" "mezza.biz" hzDomain];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '/run/maddy' 0750 maddy maddy - -"
|
||||
];
|
||||
|
||||
system.activationScripts.makeMaddyDKIMDNS = lib.stringAfter [ "var" ] ''
|
||||
system.activationScripts.makeMaddyDKIMDNS = lib.stringAfter ["var"] ''
|
||||
mkdir -p /var/lib/maddy/dkim_keys
|
||||
|
||||
echo '${dkimDNSb12fio}' >> /var/lib/maddy/dkim_keys/b12f.io_default.dns
|
||||
|
@ -101,8 +103,8 @@ in {
|
|||
chown -R maddy:maddy /var/lib/maddy
|
||||
'';
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 25 ];
|
||||
networking.firewall.interfaces.wg-private.allowedTCPPorts = [ 465 587 993 ];
|
||||
networking.firewall.allowedTCPPorts = [25];
|
||||
networking.firewall.interfaces.wg-private.allowedTCPPorts = [465 587 993];
|
||||
|
||||
services.maddy = {
|
||||
enable = true;
|
||||
|
@ -311,7 +313,7 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
systemd.services.rspamd.serviceConfig.SupplementaryGroups = [ "maddy" ];
|
||||
systemd.services.rspamd.serviceConfig.SupplementaryGroups = ["maddy"];
|
||||
|
||||
age.secrets."rclone-pubsolar.conf" = {
|
||||
file = "${flake.self}/secrets/rclone-pubsolar.conf.age";
|
||||
|
@ -325,7 +327,7 @@ in {
|
|||
|
||||
services.restic.backups = {
|
||||
maddy = {
|
||||
paths = [ "/var/lib/maddy" ];
|
||||
paths = ["/var/lib/maddy"];
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-password".path;
|
||||
# See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
boot.initrd.availableKernelModules = ["ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];
|
||||
boot.initrd.kernelModules = [];
|
||||
boot.kernelModules = [];
|
||||
boot.extraModulePackages = [];
|
||||
|
||||
boot.initrd.luks.devices = {
|
||||
cryptroot = {
|
||||
|
@ -19,19 +24,19 @@
|
|||
};
|
||||
};
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "zroot/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
fileSystems."/" = {
|
||||
device = "zroot/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/684A-5884";
|
||||
fsType = "vfat";
|
||||
};
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/684A-5884";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/a7d1cbb8-7c9e-4c3d-841a-add867f47389"; }
|
||||
];
|
||||
swapDevices = [
|
||||
{device = "/dev/disk/by-uuid/a7d1cbb8-7c9e-4c3d-841a-add867f47389";}
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
|
|
|
@ -17,8 +17,18 @@
|
|||
# Network configuration (Hetzner uses static IP assignments, and we don't use DHCP here)
|
||||
networking.useDHCP = false;
|
||||
networking.interfaces.enp1s0 = {
|
||||
ipv4.addresses = [{ address = "128.140.109.213"; prefixLength = 32; }];
|
||||
ipv6.addresses = [{ address = "2a01:4f8:c2c:b60::"; prefixLength = 64; }];
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "128.140.109.213";
|
||||
prefixLength = 32;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = [
|
||||
{
|
||||
address = "2a01:4f8:c2c:b60::";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
networking.defaultGateway = {
|
||||
address = "172.31.1.1";
|
||||
|
@ -29,5 +39,5 @@
|
|||
interface = "enp1s0";
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
owner = "unbound";
|
||||
};
|
||||
|
||||
networking.firewall.interfaces.wg-private.allowedUDPPorts = [ 53 ];
|
||||
networking.firewall.interfaces.wg-private.allowedTCPPorts = [ 53 ];
|
||||
networking.firewall.interfaces.wg-private.allowedUDPPorts = [53];
|
||||
networking.firewall.interfaces.wg-private.allowedTCPPorts = [53];
|
||||
services.resolved.enable = false;
|
||||
|
||||
services.unbound = {
|
||||
|
@ -102,10 +102,10 @@
|
|||
"\"mail.mezza.biz. 10800 IN A 10.13.12.7\""
|
||||
"\"mail.mezza.biz. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\""
|
||||
|
||||
"\"h${"w"+"dz"+"z.n"}et. 10800 IN A 10.13.12.7\""
|
||||
"\"h${"w"+"dz"+"z.n"}et. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\""
|
||||
"\"mail.h${"w"+"dz"+"z.n"}et. 10800 IN A 10.13.12.7\""
|
||||
"\"mail.h${"w"+"dz"+"z.n"}et. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\""
|
||||
"\"h${"w" + "dz" + "z.n"}et. 10800 IN A 10.13.12.7\""
|
||||
"\"h${"w" + "dz" + "z.n"}et. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\""
|
||||
"\"mail.h${"w" + "dz" + "z.n"}et. 10800 IN A 10.13.12.7\""
|
||||
"\"mail.h${"w" + "dz" + "z.n"}et. 10800 IN AAAA fd00:b12f:acab:1312:acab:7::\""
|
||||
];
|
||||
|
||||
tls-cert-bundle = "/etc/ssl/certs/ca-certificates.crt";
|
||||
|
@ -133,5 +133,4 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: with lib; {
|
||||
}:
|
||||
with lib; {
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv4.ip_forward" = 1;
|
||||
"net.ipv6.conf.wg-private.forwarding" = 1;
|
||||
|
@ -16,10 +17,10 @@
|
|||
enable = true;
|
||||
enableIPv6 = true;
|
||||
externalInterface = "enp1s0";
|
||||
internalInterfaces = [ "wg-private" ];
|
||||
internalInterfaces = ["wg-private"];
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 51899 ];
|
||||
networking.firewall.allowedUDPPorts = [51899];
|
||||
|
||||
networking.firewall.extraForwardRules = [
|
||||
"iifname { != wg-private } reject"
|
||||
|
@ -57,7 +58,8 @@
|
|||
];
|
||||
privateKeyFile = config.age.secrets.wg-private-key.path;
|
||||
peers = [
|
||||
{ # pie
|
||||
{
|
||||
# pie
|
||||
publicKey = "hPTXEqQ2GYEywdPNdZBacwB9KKcoFZ/heClxnqmizyw=";
|
||||
allowedIPs = [
|
||||
"10.13.12.2/32"
|
||||
|
@ -66,7 +68,8 @@
|
|||
persistentKeepalive = 30;
|
||||
dynamicEndpointRefreshSeconds = 30;
|
||||
}
|
||||
{ # droppie
|
||||
{
|
||||
# droppie
|
||||
publicKey = "qsnBMoj9Z16D8PJ5ummRtIfT5AiMpoF3SoOCo4sbyiw=";
|
||||
allowedIPs = [
|
||||
"10.13.12.3/32"
|
||||
|
@ -75,7 +78,8 @@
|
|||
persistentKeepalive = 30;
|
||||
dynamicEndpointRefreshSeconds = 30;
|
||||
}
|
||||
{ # chocolatebar
|
||||
{
|
||||
# chocolatebar
|
||||
publicKey = "nk8EtGE/QsnSEm1lhLS3/w83nOBD2OGYhODIf92G91A=";
|
||||
allowedIPs = [
|
||||
"10.13.12.5/32"
|
||||
|
@ -84,7 +88,8 @@
|
|||
persistentKeepalive = 30;
|
||||
dynamicEndpointRefreshSeconds = 30;
|
||||
}
|
||||
{ # biolimo
|
||||
{
|
||||
# biolimo
|
||||
publicKey = "4ymN7wwBuhF+h+5fFN0TqXmVyOe1AsWiTqRL0jJ3CDc=";
|
||||
allowedIPs = [
|
||||
"10.13.12.6/32"
|
||||
|
@ -93,7 +98,8 @@
|
|||
persistentKeepalive = 30;
|
||||
dynamicEndpointRefreshSeconds = 30;
|
||||
}
|
||||
{ # stroopwafel
|
||||
{
|
||||
# stroopwafel
|
||||
publicKey = "5iNRg13utOJ30pX2Z8SjwPNUFwfH2zonlbeYW2mKFkU=";
|
||||
allowedIPs = [
|
||||
"10.13.12.8/32"
|
||||
|
@ -102,7 +108,8 @@
|
|||
persistentKeepalive = 30;
|
||||
dynamicEndpointRefreshSeconds = 30;
|
||||
}
|
||||
{ # fp3
|
||||
{
|
||||
# fp3
|
||||
publicKey = "wQJXFibxhWkyUbRPrPt5y/YfDnH3gDQ5a/PWoyxDfDI=";
|
||||
allowedIPs = [
|
||||
"10.13.12.9/32"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
...
|
||||
}: {
|
||||
isoImage.squashfsCompression = "gzip -Xcompression-level 1";
|
||||
systemd.services.sshd.wantedBy = lib.mkForce [ "multi-user.target" ];
|
||||
systemd.services.sshd.wantedBy = lib.mkForce ["multi-user.target"];
|
||||
networking.networkmanager.enable = false;
|
||||
services.openssh.openFirewall = lib.mkForce true;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
{ flake, pkgs, ... }: {
|
||||
{
|
||||
flake,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./configuration.nix
|
||||
./hardware-configuration.nix
|
||||
((import "${flake.inputs.mobile-nixos}/lib/configuration.nix") { device = "pine64-pinephone"; })
|
||||
((import "${flake.inputs.mobile-nixos}/lib/configuration.nix") {device = "pine64-pinephone";})
|
||||
"${flake.inputs.mobile-nixos}/examples/phosh/phosh.nix"
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
# NOTE: this file was generated by the Mobile NixOS installer.
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/51a668b8-fa2e-4d3e-ac3f-73ca002d0004";
|
||||
|
|
|
@ -81,7 +81,7 @@ in {
|
|||
};
|
||||
authentication_backend = {
|
||||
refresh_interval = "disable";
|
||||
password_reset = { disable = true; };
|
||||
password_reset = {disable = true;};
|
||||
file = {
|
||||
path = config.age.secrets."authelia-users-file".path;
|
||||
watch = false;
|
||||
|
@ -93,7 +93,10 @@ in {
|
|||
storage.local.path = "/var/lib/authelia-b12f/db.sqlite3";
|
||||
access_control.default_policy = "two_factor";
|
||||
session.cookies = [
|
||||
{ domain = "b12f.io"; authelia_url = "https://auth.b12f.io"; }
|
||||
{
|
||||
domain = "b12f.io";
|
||||
authelia_url = "https://auth.b12f.io";
|
||||
}
|
||||
];
|
||||
notifier.smtp = {
|
||||
host = "mail.b12f.io";
|
||||
|
@ -110,7 +113,7 @@ in {
|
|||
|
||||
services.restic.backups = {
|
||||
authelia = {
|
||||
paths = [ "/var/lib/authelia-b12f" ];
|
||||
paths = ["/var/lib/authelia-b12f"];
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-password".path;
|
||||
# See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/
|
||||
|
|
|
@ -20,7 +20,7 @@ in {
|
|||
boot.loader.systemd-boot.enable = false;
|
||||
boot.loader.generic-extlinux-compatible.enable = false;
|
||||
|
||||
boot.supportedFilesystems = [ "zfs" ];
|
||||
boot.supportedFilesystems = ["zfs"];
|
||||
|
||||
boot.kernelParams = [
|
||||
"boot.shell_on_fail=1"
|
||||
|
@ -28,7 +28,7 @@ in {
|
|||
"ip=127.0.0.1:::::lo:none"
|
||||
];
|
||||
# See https://discourse.nixos.org/t/ssh-and-network-in-initrd-on-raspberry-pi-4/6289/3
|
||||
boot.initrd.availableKernelModules = [ "genet" ];
|
||||
boot.initrd.availableKernelModules = ["genet"];
|
||||
boot.initrd.network = {
|
||||
enable = true;
|
||||
ssh = {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
{ pkgs, adblock-unbound, ... }:
|
||||
{
|
||||
networking.firewall.allowedUDPPorts = [ 67 547 ];
|
||||
pkgs,
|
||||
adblock-unbound,
|
||||
...
|
||||
}: {
|
||||
networking.firewall.allowedUDPPorts = [67 547];
|
||||
networking.firewall.extraInputRules = ''
|
||||
ip6 daddr ff02::1:2/128 udp dport 547 accept comment "DHCPv6 server"
|
||||
'';
|
||||
|
@ -30,7 +33,7 @@
|
|||
{
|
||||
subnet = "192.168.178.0/24";
|
||||
pools = [
|
||||
{ pool = "192.168.178.2 - 192.168.178.255"; }
|
||||
{pool = "192.168.178.2 - 192.168.178.255";}
|
||||
];
|
||||
|
||||
option-data = [
|
||||
|
@ -100,19 +103,19 @@
|
|||
subnet = "2a02:908:5b1:e3c0::/64";
|
||||
|
||||
pools = [
|
||||
{ pool = "2a02:908:5b1:e3c0::/72"; }
|
||||
{pool = "2a02:908:5b1:e3c0::/72";}
|
||||
];
|
||||
|
||||
ddns-qualifying-suffix = "local.";
|
||||
|
||||
option-data = [
|
||||
{
|
||||
name = "dns-servers";
|
||||
data = "2a02:908:5b1:e3c0:2::";
|
||||
name = "dns-servers";
|
||||
data = "2a02:908:5b1:e3c0:2::";
|
||||
}
|
||||
{
|
||||
name = "domain-search";
|
||||
data = "local";
|
||||
name = "domain-search";
|
||||
data = "local";
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -80,14 +80,14 @@ in {
|
|||
volumes = [
|
||||
"/var/lib/firefly/upload:/var/www/html/storage/upload"
|
||||
];
|
||||
extraOptions = [ "--network=firefly" ];
|
||||
extraOptions = ["--network=firefly"];
|
||||
environmentFiles = [
|
||||
./.env.firefly
|
||||
config.age.secrets."firefly-secrets.env".path
|
||||
config.age.secrets."firefly-cron-secrets.env".path
|
||||
];
|
||||
ports = [ "127.0.0.1:8080:8080" ];
|
||||
dependsOn = [ "firefly-db" ];
|
||||
ports = ["127.0.0.1:8080:8080"];
|
||||
dependsOn = ["firefly-db"];
|
||||
};
|
||||
|
||||
containers."firefly-db" = {
|
||||
|
@ -96,7 +96,7 @@ in {
|
|||
volumes = [
|
||||
"/var/lib/firefly/db:/var/lib/postgresql/data"
|
||||
];
|
||||
extraOptions = [ "--network=firefly" ];
|
||||
extraOptions = ["--network=firefly"];
|
||||
environmentFiles = [
|
||||
config.age.secrets."firefly-db-secrets.env".path
|
||||
];
|
||||
|
@ -105,8 +105,8 @@ in {
|
|||
containers."firefly-importer" = {
|
||||
image = "fireflyiii/data-importer:latest";
|
||||
autoStart = true;
|
||||
extraOptions = [ "--network=firefly" ];
|
||||
ports = [ "127.0.0.1:8081:8080" ];
|
||||
extraOptions = ["--network=firefly"];
|
||||
ports = ["127.0.0.1:8081:8080"];
|
||||
environment = {
|
||||
FIREFLY_III_URL = "https://firefly.b12f.io";
|
||||
};
|
||||
|
@ -114,7 +114,7 @@ in {
|
|||
./.env.firefly-importer
|
||||
config.age.secrets."firefly-importer-secrets.env".path
|
||||
];
|
||||
dependsOn = [ "firefly" ];
|
||||
dependsOn = ["firefly"];
|
||||
};
|
||||
|
||||
containers."firefly-cron" = {
|
||||
|
@ -128,7 +128,7 @@ in {
|
|||
environmentFiles = [
|
||||
config.age.secrets."firefly-cron-secrets.env".path
|
||||
];
|
||||
extraOptions = [ "--network=firefly" ];
|
||||
extraOptions = ["--network=firefly"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "usbhid" "uas" "usb_storage" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
boot.supportedFilesystems = [ "zfs" ];
|
||||
boot.initrd.availableKernelModules = ["xhci_pci" "usbhid" "uas" "usb_storage"];
|
||||
boot.initrd.kernelModules = [];
|
||||
boot.kernelModules = [];
|
||||
boot.extraModulePackages = [];
|
||||
boot.supportedFilesystems = ["zfs"];
|
||||
|
||||
boot.initrd.luks.devices = {
|
||||
cryptroot = {
|
||||
|
@ -21,20 +25,19 @@
|
|||
};
|
||||
};
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "zroot/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
fileSystems."/" = {
|
||||
device = "zroot/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/0D5D-B809";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/af71e930-42ce-4174-a098-4ea5753b1ea9"; }
|
||||
];
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/0D5D-B809";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices = [
|
||||
{device = "/dev/disk/by-uuid/af71e930-42ce-4174-a098-4ea5753b1ea9";}
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
|
||||
|
|
|
@ -44,7 +44,7 @@ in {
|
|||
createLocally = false;
|
||||
};
|
||||
|
||||
invoiceTemplates = [ pkgs.invoiceplane-template ];
|
||||
invoiceTemplates = [pkgs.invoiceplane-template];
|
||||
|
||||
extraConfig = ''
|
||||
SETUP_COMPLETED=true
|
||||
|
@ -72,7 +72,7 @@ in {
|
|||
containers."invoiceplane-db" = {
|
||||
image = "mariadb:11";
|
||||
autoStart = true;
|
||||
ports = [ "127.0.0.1:3306:3306" ];
|
||||
ports = ["127.0.0.1:3306:3306"];
|
||||
volumes = [
|
||||
"/var/lib/invoiceplane/db:/var/lib/mysql"
|
||||
];
|
||||
|
|
|
@ -15,16 +15,25 @@
|
|||
|
||||
networking.interfaces.enabcm6e4ei0 = {
|
||||
ipv4.addresses = [
|
||||
{ address = "192.168.178.2"; prefixLength = 32; }
|
||||
{
|
||||
address = "192.168.178.2";
|
||||
prefixLength = 32;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = [
|
||||
{ address = "2a02:908:5b1:e3c0:2::"; prefixLength = 128; }
|
||||
{ address = "fe80:b12f:acab:1312:acab:2::"; prefixLength = 128; }
|
||||
{
|
||||
address = "2a02:908:5b1:e3c0:2::";
|
||||
prefixLength = 128;
|
||||
}
|
||||
{
|
||||
address = "fe80:b12f:acab:1312:acab:2::";
|
||||
prefixLength = 128;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
networking.hosts = {
|
||||
"192.168.178.3" = [ "droppie-initrd.b12f.io" ];
|
||||
"192.168.178.3" = ["droppie-initrd.b12f.io"];
|
||||
};
|
||||
|
||||
services.openssh.allowSFTP = true;
|
||||
|
|
|
@ -13,33 +13,34 @@ with lib; let
|
|||
backupDir = "/var/lib/PaperlessBackup";
|
||||
consumptionDir = "/var/lib/scandir";
|
||||
|
||||
scan2paperless = with pkgs; writeShellScriptBin "scan2paperless" ''
|
||||
DEVICE=$1
|
||||
NUM_PAGES=$2
|
||||
NAME=$3
|
||||
scan2paperless = with pkgs;
|
||||
writeShellScriptBin "scan2paperless" ''
|
||||
DEVICE=$1
|
||||
NUM_PAGES=$2
|
||||
NAME=$3
|
||||
|
||||
if [ -z "''${DEVICE}" ] || [ -z "''${NUM_PAGES}" ] || [ -z "''${NAME}" ]; then
|
||||
echo "Usage: scan2paperless <device> <num_pages> <name>"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "''${DEVICE}" ] || [ -z "''${NUM_PAGES}" ] || [ -z "''${NAME}" ]; then
|
||||
echo "Usage: scan2paperless <device> <num_pages> <name>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmpDir=$(${coreutils}/bin/mktemp -d)
|
||||
files=()
|
||||
tmpDir=$(${coreutils}/bin/mktemp -d)
|
||||
files=()
|
||||
|
||||
for i in $(seq 1 $NUM_PAGES); do
|
||||
fileName=$(${openssl}/bin/openssl rand -hex 12)
|
||||
file="$tmpDir/$fileName.jpg"
|
||||
echo "Start scanning page $i/$NUM_PAGES";
|
||||
${sane-backends}/bin/scanimage -d $DEVICE --format=jpeg --resolution 300 --progress -o $file
|
||||
echo "Finished scanning page $i";
|
||||
files+=($file)
|
||||
done
|
||||
for i in $(seq 1 $NUM_PAGES); do
|
||||
fileName=$(${openssl}/bin/openssl rand -hex 12)
|
||||
file="$tmpDir/$fileName.jpg"
|
||||
echo "Start scanning page $i/$NUM_PAGES";
|
||||
${sane-backends}/bin/scanimage -d $DEVICE --format=jpeg --resolution 300 --progress -o $file
|
||||
echo "Finished scanning page $i";
|
||||
files+=($file)
|
||||
done
|
||||
|
||||
pdf="${consumptionDir}/$NAME.pdf"
|
||||
${python3Packages.img2pdf}/bin/img2pdf --output $pdf ''${files[@]}
|
||||
pdf="${consumptionDir}/$NAME.pdf"
|
||||
${python3Packages.img2pdf}/bin/img2pdf --output $pdf ''${files[@]}
|
||||
|
||||
echo "PDF written to $pdf"
|
||||
'';
|
||||
echo "PDF written to $pdf"
|
||||
'';
|
||||
in {
|
||||
age.secrets."paperless.env" = {
|
||||
file = "${flake.self}/secrets/paperless.env.age";
|
||||
|
@ -82,7 +83,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
systemd.services.paperless-web.serviceConfig.EnvironmentFile = [ config.age.secrets."paperless.env".path ];
|
||||
systemd.services.paperless-web.serviceConfig.EnvironmentFile = [config.age.secrets."paperless.env".path];
|
||||
|
||||
#################################
|
||||
# Scanning
|
||||
|
@ -147,7 +148,7 @@ in {
|
|||
|
||||
services.restic.backups = {
|
||||
paperless = {
|
||||
paths = [ backupDir ];
|
||||
paths = [backupDir];
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-password".path;
|
||||
# See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
owner = "unbound";
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||
networking.firewall.allowedTCPPorts = [ 53 ];
|
||||
networking.firewall.allowedUDPPorts = [53];
|
||||
networking.firewall.allowedTCPPorts = [53];
|
||||
services.resolved.enable = false;
|
||||
|
||||
services.unbound = {
|
||||
|
@ -94,5 +94,4 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
{pkgs, ...}: {
|
||||
services.cron = {
|
||||
enable = true;
|
||||
systemCronJobs = [
|
||||
|
|
|
@ -17,9 +17,9 @@ in {
|
|||
boot.initrd.preLVMCommands = "udevadm trigger --settle";
|
||||
boot.swraid.enable = true;
|
||||
boot.swraid.mdadmConf = ''
|
||||
DEVICE /dev/nvme0n1p2 /dev/nvme1n1p2
|
||||
ARRAY /dev/md/nixos:root metadata=1.2 name=nixos:root UUID=67d1aa81:1b348887:c17a75e8:f2edf2bd
|
||||
MAILADDR ${psCfg.user.email}
|
||||
DEVICE /dev/nvme0n1p2 /dev/nvme1n1p2
|
||||
ARRAY /dev/md/nixos:root metadata=1.2 name=nixos:root UUID=67d1aa81:1b348887:c17a75e8:f2edf2bd
|
||||
MAILADDR ${psCfg.user.email}
|
||||
'';
|
||||
|
||||
pub-solar.core.hibernation.enable = true;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ ... }: {
|
||||
{...}: {
|
||||
imports = [
|
||||
./configuration.nix
|
||||
./hardware-configuration.nix
|
||||
|
|
|
@ -1,55 +1,59 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod"];
|
||||
boot.initrd.kernelModules = ["dm-snapshot"];
|
||||
boot.kernelModules = ["kvm-amd"];
|
||||
boot.extraModulePackages = [];
|
||||
|
||||
boot.initrd.luks.devices."cryptroot" = {
|
||||
device = "/dev/disk/by-id/md-name-nixos:root";
|
||||
allowDiscards = true;
|
||||
};
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "none";
|
||||
fsType = "tmpfs";
|
||||
};
|
||||
fileSystems."/" = {
|
||||
device = "none";
|
||||
fsType = "tmpfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/EC82-67F4";
|
||||
fsType = "vfat";
|
||||
};
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/EC82-67F4";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
fileSystems."/home" =
|
||||
{ device = "/dev/disk/by-uuid/0cc568f0-402d-4535-980a-ed3a1dc697b9";
|
||||
fsType = "ext4";
|
||||
# https://github.com/ryantm/agenix/issues/45#issuecomment-957865406
|
||||
neededForBoot = true;
|
||||
};
|
||||
fileSystems."/home" = {
|
||||
device = "/dev/disk/by-uuid/0cc568f0-402d-4535-980a-ed3a1dc697b9";
|
||||
fsType = "ext4";
|
||||
# https://github.com/ryantm/agenix/issues/45#issuecomment-957865406
|
||||
neededForBoot = true;
|
||||
};
|
||||
|
||||
fileSystems."/nix" =
|
||||
{ device = "/dev/disk/by-uuid/e203d629-4d34-4147-bee6-919f0bfa25de";
|
||||
fsType = "ext4";
|
||||
};
|
||||
fileSystems."/nix" = {
|
||||
device = "/dev/disk/by-uuid/e203d629-4d34-4147-bee6-919f0bfa25de";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/persist" =
|
||||
{ device = "/dev/disk/by-uuid/a0855aaa-76bf-445e-b0d1-ab1552e5496f";
|
||||
fsType = "ext4";
|
||||
# https://github.com/ryantm/agenix/issues/45#issuecomment-957865406
|
||||
neededForBoot = true;
|
||||
};
|
||||
fileSystems."/persist" = {
|
||||
device = "/dev/disk/by-uuid/a0855aaa-76bf-445e-b0d1-ab1552e5496f";
|
||||
fsType = "ext4";
|
||||
# https://github.com/ryantm/agenix/issues/45#issuecomment-957865406
|
||||
neededForBoot = true;
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/761507ab-479d-414b-ac3e-2149564ca470"; }
|
||||
];
|
||||
swapDevices = [
|
||||
{device = "/dev/disk/by-uuid/761507ab-479d-414b-ac3e-2149564ca470";}
|
||||
];
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
pub-solar.wireguard.ehex = {
|
||||
ownIPs = [
|
||||
"10.42.0.135/22"
|
||||
"10.42.0.135/22"
|
||||
];
|
||||
privateKeyFile = config.age.secrets.wg-ehex-key.path;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{ lib }:
|
||||
hostnames: {
|
||||
{lib}: hostnames: {
|
||||
"127.0.0.1" = hostnames;
|
||||
"::1" = hostnames;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
{ lib, inputs, ... }: {
|
||||
{
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
# Configuration common to all Linux systems
|
||||
flake = {
|
||||
lib = let
|
||||
|
@ -10,7 +14,7 @@
|
|||
#foo = callLibs ./foo.nix;
|
||||
## In configs, they can be used under "lib.our"
|
||||
|
||||
deploy = import ./deploy.nix { inherit inputs lib; };
|
||||
deploy = import ./deploy.nix {inherit inputs lib;};
|
||||
addLocalHostname = callLibs ./add-local-hostname.nix;
|
||||
recursiveMerge = callLibs ./recursive-merge.nix;
|
||||
mkEmailAddress = account: domain: account + "@" + domain;
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/*
|
||||
* The contents of this file are adapted from digga
|
||||
* https://github.com/divnix/digga
|
||||
*
|
||||
* Licensed under the MIT license
|
||||
*/
|
||||
|
||||
{ lib, inputs }: let
|
||||
* The contents of this file are adapted from digga
|
||||
* https://github.com/divnix/digga
|
||||
*
|
||||
* Licensed under the MIT license
|
||||
*/
|
||||
{
|
||||
lib,
|
||||
inputs,
|
||||
}: let
|
||||
getFqdn = c: let
|
||||
net = c.config.networking;
|
||||
fqdn =
|
||||
|
@ -17,48 +19,53 @@
|
|||
in {
|
||||
mkDeployNodes = systemConfigurations: extraConfig:
|
||||
/*
|
||||
*
|
||||
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
|
||||
*
|
||||
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
|
||||
|
||||
Generate the `nodes` attribute expected by deploy-rs
|
||||
where _systemConfigurations_ are `nodes`.
|
||||
Generate the `nodes` attribute expected by deploy-rs
|
||||
where _systemConfigurations_ are `nodes`.
|
||||
|
||||
_systemConfigurations_ should take the form of a flake's
|
||||
_nixosConfigurations_. Note that deploy-rs does not currently support
|
||||
deploying to darwin hosts.
|
||||
_systemConfigurations_ should take the form of a flake's
|
||||
_nixosConfigurations_. Note that deploy-rs does not currently support
|
||||
deploying to darwin hosts.
|
||||
|
||||
_extraConfig_, if specified, will be merged into each of the
|
||||
nodes' configurations.
|
||||
_extraConfig_, if specified, will be merged into each of the
|
||||
nodes' configurations.
|
||||
|
||||
Example _systemConfigurations_ input:
|
||||
Example _systemConfigurations_ input:
|
||||
|
||||
```
|
||||
{
|
||||
hostname-1 = {
|
||||
fastConnection = true;
|
||||
sshOpts = [ "-p" "25" ];
|
||||
};
|
||||
hostname-2 = {
|
||||
sshOpts = [ "-p" "19999" ];
|
||||
sshUser = "root";
|
||||
};
|
||||
}
|
||||
```
|
||||
*
|
||||
*/
|
||||
```
|
||||
{
|
||||
hostname-1 = {
|
||||
fastConnection = true;
|
||||
sshOpts = [ "-p" "25" ];
|
||||
};
|
||||
hostname-2 = {
|
||||
sshOpts = [ "-p" "19999" ];
|
||||
sshUser = "root";
|
||||
};
|
||||
}
|
||||
```
|
||||
*
|
||||
*/
|
||||
lib.recursiveUpdate
|
||||
(lib.mapAttrs
|
||||
(
|
||||
_: c: let
|
||||
system = c.pkgs.stdenv.hostPlatform.system;
|
||||
# Unmodified nixpkgs
|
||||
pkgs = import inputs.nixpkgs { inherit system; };
|
||||
pkgs = import inputs.nixpkgs {inherit system;};
|
||||
# nixpkgs with deploy-rs overlay but force the nixpkgs package
|
||||
deployPkgs = import inputs.nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
inputs.deploy-rs.overlay # or deploy-rs.overlays.default
|
||||
(self: super: { deploy-rs = { inherit (pkgs) deploy-rs; lib = super.deploy-rs.lib; }; })
|
||||
(self: super: {
|
||||
deploy-rs = {
|
||||
inherit (pkgs) deploy-rs;
|
||||
lib = super.deploy-rs.lib;
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
in {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
{ lib }:
|
||||
attrList:
|
||||
let
|
||||
{lib}: attrList: let
|
||||
f = attrPath:
|
||||
zipAttrsWith (
|
||||
n: values:
|
||||
|
@ -13,4 +11,4 @@ let
|
|||
else last values
|
||||
);
|
||||
in
|
||||
f [] attrList;
|
||||
f [] attrList
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
systemd.services.systemd-networkd-wait-online.enable = lib.mkDefault false;
|
||||
|
||||
networking.hosts = {
|
||||
"128.140.109.213" = [ "vpn.b12f.io" ];
|
||||
"2a01:4f8:c2c:b60::" = [ "vpn.b12f.io" ];
|
||||
"128.140.109.213" = ["vpn.b12f.io"];
|
||||
"2a01:4f8:c2c:b60::" = ["vpn.b12f.io"];
|
||||
};
|
||||
|
||||
networking.networkmanager = {
|
||||
|
@ -38,7 +38,7 @@
|
|||
};
|
||||
|
||||
# Don't expose SSH via public interfaces
|
||||
networking.firewall.interfaces.wg-private.allowedTCPPorts = [ 22 ];
|
||||
networking.firewall.interfaces.wg-private.allowedTCPPorts = [22];
|
||||
|
||||
# For rage encryption, all hosts need a ssh key pair
|
||||
services.openssh = {
|
||||
|
|
|
@ -159,8 +159,8 @@
|
|||
# Base16 Burn 256 - alacritty color config
|
||||
# Benjamin Bädorf
|
||||
colors = {
|
||||
# When true, bold text is drawn using the bright variant of colors.
|
||||
draw_bold_text_with_bright_colors = true;
|
||||
# When true, bold text is drawn using the bright variant of colors.
|
||||
draw_bold_text_with_bright_colors = true;
|
||||
|
||||
# Default colors
|
||||
primary = {
|
||||
|
|
|
@ -105,7 +105,7 @@ in {
|
|||
toggle-kbd-layout
|
||||
vlc
|
||||
wcwd
|
||||
wl-mirror
|
||||
wl-mirror
|
||||
];
|
||||
|
||||
home-manager.users."${psCfg.user.name}" = {
|
||||
|
|
|
@ -2,39 +2,40 @@
|
|||
pkgs,
|
||||
psCfg,
|
||||
...
|
||||
}: with pkgs;
|
||||
''
|
||||
# Set shut down, restart and locking features
|
||||
''
|
||||
+ (
|
||||
if psCfg.core.hibernation.enable
|
||||
then ''
|
||||
set $mode_system (e)xit, (l)ock, (h)ibernate, (r)eboot, (Shift+s)hutdown
|
||||
}:
|
||||
with pkgs;
|
||||
''
|
||||
else ''
|
||||
set $mode_system (e)xit, (l)ock, (r)eboot, (Shift+s)hutdown
|
||||
# Set shut down, restart and locking features
|
||||
''
|
||||
)
|
||||
+ ''
|
||||
bindsym $mod+0 mode "$mode_system"
|
||||
+ (
|
||||
if psCfg.core.hibernation.enable
|
||||
then ''
|
||||
set $mode_system (e)xit, (l)ock, (h)ibernate, (r)eboot, (Shift+s)hutdown
|
||||
''
|
||||
else ''
|
||||
set $mode_system (e)xit, (l)ock, (r)eboot, (Shift+s)hutdown
|
||||
''
|
||||
)
|
||||
+ ''
|
||||
bindsym $mod+0 mode "$mode_system"
|
||||
|
||||
mode "$mode_system" {
|
||||
bindsym e exec ${sway}/bin/swaymsg exit, mode "default"
|
||||
bindsym l exec ${swaylock-bg}/bin/swaylock-bg, mode "default"
|
||||
''
|
||||
+ (
|
||||
if psCfg.core.hibernation.enable
|
||||
then ''
|
||||
bindsym h exec ${systemd}/bin/systemctl hibernate, mode "default"
|
||||
mode "$mode_system" {
|
||||
bindsym e exec ${sway}/bin/swaymsg exit, mode "default"
|
||||
bindsym l exec ${swaylock-bg}/bin/swaylock-bg, mode "default"
|
||||
''
|
||||
else ""
|
||||
)
|
||||
+ ''
|
||||
bindsym r exec ${systemd}/bin/systemctl reboot, mode "default"
|
||||
bindsym Shift+s exec ${systemd}/bin/systemctl poweroff, mode "default"
|
||||
+ (
|
||||
if psCfg.core.hibernation.enable
|
||||
then ''
|
||||
bindsym h exec ${systemd}/bin/systemctl hibernate, mode "default"
|
||||
''
|
||||
else ""
|
||||
)
|
||||
+ ''
|
||||
bindsym r exec ${systemd}/bin/systemctl reboot, mode "default"
|
||||
bindsym Shift+s exec ${systemd}/bin/systemctl poweroff, mode "default"
|
||||
|
||||
# exit system mode: "Enter" or "Escape"
|
||||
bindsym Return mode "default"
|
||||
bindsym Escape mode "default"
|
||||
}
|
||||
''
|
||||
# exit system mode: "Enter" or "Escape"
|
||||
bindsym Return mode "default"
|
||||
bindsym Escape mode "default"
|
||||
}
|
||||
''
|
||||
|
|
|
@ -46,10 +46,10 @@ in {
|
|||
on-scroll = "-1";
|
||||
on-click-right = "mode";
|
||||
format = {
|
||||
months = "<span color='#ffead3'><b>{}</b></span>";
|
||||
days = "<span color='#ecc6d9'><b>{}</b></span>";
|
||||
weekdays = "<span color='#ffcc66'><b>{}</b></span>";
|
||||
today = "<span color='#ff6699'><b><u>{}</u></b></span>";
|
||||
months = "<span color='#ffead3'><b>{}</b></span>";
|
||||
days = "<span color='#ecc6d9'><b>{}</b></span>";
|
||||
weekdays = "<span color='#ffcc66'><b>{}</b></span>";
|
||||
today = "<span color='#ff6699'><b><u>{}</u></b></span>";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,215 +1,221 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.services.invoiceplane;
|
||||
eachSite = cfg.sites;
|
||||
user = "invoiceplane";
|
||||
webserver = config.services.${cfg.webserver};
|
||||
|
||||
invoiceplane-config = hostName: cfg: pkgs.writeText "ipconfig.php" ''
|
||||
IP_URL=http://${hostName}
|
||||
ENABLE_DEBUG=false
|
||||
DISABLE_SETUP=false
|
||||
REMOVE_INDEXPHP=false
|
||||
DB_HOSTNAME=${cfg.database.host}
|
||||
DB_USERNAME=${cfg.database.user}
|
||||
# NOTE: file_get_contents adds newline at the end of returned string
|
||||
DB_PASSWORD=${if cfg.database.passwordFile == null then "" else "trim(file_get_contents('${cfg.database.passwordFile}'),\"\\r\\n\")"}
|
||||
DB_DATABASE=${cfg.database.name}
|
||||
DB_PORT=${toString cfg.database.port}
|
||||
SESS_EXPIRATION=864000
|
||||
ENABLE_INVOICE_DELETION=false
|
||||
DISABLE_READ_ONLY=false
|
||||
ENCRYPTION_KEY=
|
||||
ENCRYPTION_CIPHER=AES-256
|
||||
SETUP_COMPLETED=false
|
||||
REMOVE_INDEXPHP=true
|
||||
'';
|
||||
|
||||
extraConfig = hostName: cfg: pkgs.writeText "extraConfig.php" ''
|
||||
${toString cfg.extraConfig}
|
||||
'';
|
||||
|
||||
pkg = hostName: cfg: pkgs.stdenv.mkDerivation rec {
|
||||
pname = "invoiceplane-${hostName}";
|
||||
version = src.version;
|
||||
src = pkgs.invoiceplane;
|
||||
|
||||
postPhase = ''
|
||||
# Patch index.php file to load additional config file
|
||||
substituteInPlace index.php \
|
||||
--replace "require('vendor/autoload.php');" "require('vendor/autoload.php'); \$dotenv = Dotenv\Dotenv::createImmutable(__DIR__, 'extraConfig.php'); \$dotenv->load();";
|
||||
invoiceplane-config = hostName: cfg:
|
||||
pkgs.writeText "ipconfig.php" ''
|
||||
IP_URL=http://${hostName}
|
||||
ENABLE_DEBUG=false
|
||||
DISABLE_SETUP=false
|
||||
REMOVE_INDEXPHP=false
|
||||
DB_HOSTNAME=${cfg.database.host}
|
||||
DB_USERNAME=${cfg.database.user}
|
||||
# NOTE: file_get_contents adds newline at the end of returned string
|
||||
DB_PASSWORD=${
|
||||
if cfg.database.passwordFile == null
|
||||
then ""
|
||||
else "trim(file_get_contents('${cfg.database.passwordFile}'),\"\\r\\n\")"
|
||||
}
|
||||
DB_DATABASE=${cfg.database.name}
|
||||
DB_PORT=${toString cfg.database.port}
|
||||
SESS_EXPIRATION=864000
|
||||
ENABLE_INVOICE_DELETION=false
|
||||
DISABLE_READ_ONLY=false
|
||||
ENCRYPTION_KEY=
|
||||
ENCRYPTION_CIPHER=AES-256
|
||||
SETUP_COMPLETED=false
|
||||
REMOVE_INDEXPHP=true
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -r * $out/
|
||||
|
||||
# symlink uploads and log directories
|
||||
rm -r $out/uploads $out/application/logs $out/vendor/mpdf/mpdf/tmp
|
||||
ln -sf ${cfg.stateDir}/uploads $out/
|
||||
ln -sf ${cfg.stateDir}/logs $out/application/
|
||||
ln -sf ${cfg.stateDir}/tmp $out/vendor/mpdf/mpdf/
|
||||
|
||||
# symlink the InvoicePlane config
|
||||
ln -s ${cfg.stateDir}/ipconfig.php $out/ipconfig.php
|
||||
|
||||
# symlink the extraConfig file
|
||||
ln -s ${extraConfig hostName cfg} $out/extraConfig.php
|
||||
|
||||
# symlink additional templates
|
||||
${concatMapStringsSep "\n" (template: "cp -r ${template}/. $out/application/views/invoice_templates/pdf/") cfg.invoiceTemplates}
|
||||
extraConfig = hostName: cfg:
|
||||
pkgs.writeText "extraConfig.php" ''
|
||||
${toString cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
siteOpts = { lib, name, ... }:
|
||||
{
|
||||
options = {
|
||||
pkg = hostName: cfg:
|
||||
pkgs.stdenv.mkDerivation rec {
|
||||
pname = "invoiceplane-${hostName}";
|
||||
version = src.version;
|
||||
src = pkgs.invoiceplane;
|
||||
|
||||
enable = mkEnableOption (lib.mdDoc "InvoicePlane web application");
|
||||
postPhase = ''
|
||||
# Patch index.php file to load additional config file
|
||||
substituteInPlace index.php \
|
||||
--replace "require('vendor/autoload.php');" "require('vendor/autoload.php'); \$dotenv = Dotenv\Dotenv::createImmutable(__DIR__, 'extraConfig.php'); \$dotenv->load();";
|
||||
'';
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/invoiceplane/${name}";
|
||||
description = lib.mdDoc ''
|
||||
This directory is used for uploads of attachments and cache.
|
||||
The directory passed here is automatically created and permissions
|
||||
adjusted as required.
|
||||
'';
|
||||
};
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -r * $out/
|
||||
|
||||
database = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = lib.mdDoc "Database host address.";
|
||||
};
|
||||
# symlink uploads and log directories
|
||||
rm -r $out/uploads $out/application/logs $out/vendor/mpdf/mpdf/tmp
|
||||
ln -sf ${cfg.stateDir}/uploads $out/
|
||||
ln -sf ${cfg.stateDir}/logs $out/application/
|
||||
ln -sf ${cfg.stateDir}/tmp $out/vendor/mpdf/mpdf/
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3306;
|
||||
description = lib.mdDoc "Database host port.";
|
||||
};
|
||||
# symlink the InvoicePlane config
|
||||
ln -s ${cfg.stateDir}/ipconfig.php $out/ipconfig.php
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "invoiceplane";
|
||||
description = lib.mdDoc "Database name.";
|
||||
};
|
||||
# symlink the extraConfig file
|
||||
ln -s ${extraConfig hostName cfg} $out/extraConfig.php
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "invoiceplane";
|
||||
description = lib.mdDoc "Database user.";
|
||||
};
|
||||
# symlink additional templates
|
||||
${concatMapStringsSep "\n" (template: "cp -r ${template}/. $out/application/views/invoice_templates/pdf/") cfg.invoiceTemplates}
|
||||
'';
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/run/keys/invoiceplane-dbpassword";
|
||||
description = lib.mdDoc ''
|
||||
A file containing the password corresponding to
|
||||
{option}`database.user`.
|
||||
'';
|
||||
};
|
||||
|
||||
createLocally = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = lib.mdDoc "Create the database and database user locally.";
|
||||
};
|
||||
};
|
||||
|
||||
invoiceTemplates = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
List of path(s) to respective template(s) which are copied from the 'invoice_templates/pdf' directory.
|
||||
|
||||
::: {.note}
|
||||
These templates need to be packaged before use, see example.
|
||||
:::
|
||||
'';
|
||||
example = literalExpression ''
|
||||
let
|
||||
# Let's package an example template
|
||||
template-vtdirektmarketing = pkgs.stdenv.mkDerivation {
|
||||
name = "vtdirektmarketing";
|
||||
# Download the template from a public repository
|
||||
src = pkgs.fetchgit {
|
||||
url = "https://git.project-insanity.org/onny/invoiceplane-vtdirektmarketing.git";
|
||||
sha256 = "1hh0q7wzsh8v8x03i82p6qrgbxr4v5fb05xylyrpp975l8axyg2z";
|
||||
};
|
||||
sourceRoot = ".";
|
||||
# Installing simply means copying template php file to the output directory
|
||||
installPhase = ""
|
||||
mkdir -p $out
|
||||
cp invoiceplane-vtdirektmarketing/vtdirektmarketing.php $out/
|
||||
"";
|
||||
};
|
||||
# And then pass this package to the template list like this:
|
||||
in [ template-vtdirektmarketing ]
|
||||
'';
|
||||
};
|
||||
|
||||
poolConfig = mkOption {
|
||||
type = with types; attrsOf (oneOf [ str int bool ]);
|
||||
default = {
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 4;
|
||||
"pm.max_requests" = 500;
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Options for the InvoicePlane PHP pool. See the documentation on `php-fpm.conf`
|
||||
for details on configuration directives.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
example = ''
|
||||
SETUP_COMPLETED=true
|
||||
DISABLE_SETUP=true
|
||||
IP_URL=https://invoice.example.com
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
InvoicePlane configuration. Refer to
|
||||
<https://github.com/InvoicePlane/InvoicePlane/blob/master/ipconfig.php.example>
|
||||
for details on supported values.
|
||||
'';
|
||||
};
|
||||
|
||||
cron = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Enable cron service which periodically runs Invoiceplane tasks.
|
||||
Requires key taken from the administration page. Refer to
|
||||
<https://wiki.invoiceplane.com/en/1.0/modules/recurring-invoices>
|
||||
on how to configure it.
|
||||
'';
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = types.str;
|
||||
description = lib.mdDoc "Cron key taken from the administration page.";
|
||||
};
|
||||
|
||||
};
|
||||
siteOpts = {
|
||||
lib,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
enable = mkEnableOption (lib.mdDoc "InvoicePlane web application");
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/invoiceplane/${name}";
|
||||
description = lib.mdDoc ''
|
||||
This directory is used for uploads of attachments and cache.
|
||||
The directory passed here is automatically created and permissions
|
||||
adjusted as required.
|
||||
'';
|
||||
};
|
||||
|
||||
database = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = lib.mdDoc "Database host address.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3306;
|
||||
description = lib.mdDoc "Database host port.";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "invoiceplane";
|
||||
description = lib.mdDoc "Database name.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "invoiceplane";
|
||||
description = lib.mdDoc "Database user.";
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/run/keys/invoiceplane-dbpassword";
|
||||
description = lib.mdDoc ''
|
||||
A file containing the password corresponding to
|
||||
{option}`database.user`.
|
||||
'';
|
||||
};
|
||||
|
||||
createLocally = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = lib.mdDoc "Create the database and database user locally.";
|
||||
};
|
||||
};
|
||||
|
||||
invoiceTemplates = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
List of path(s) to respective template(s) which are copied from the 'invoice_templates/pdf' directory.
|
||||
|
||||
::: {.note}
|
||||
These templates need to be packaged before use, see example.
|
||||
:::
|
||||
'';
|
||||
example = literalExpression ''
|
||||
let
|
||||
# Let's package an example template
|
||||
template-vtdirektmarketing = pkgs.stdenv.mkDerivation {
|
||||
name = "vtdirektmarketing";
|
||||
# Download the template from a public repository
|
||||
src = pkgs.fetchgit {
|
||||
url = "https://git.project-insanity.org/onny/invoiceplane-vtdirektmarketing.git";
|
||||
sha256 = "1hh0q7wzsh8v8x03i82p6qrgbxr4v5fb05xylyrpp975l8axyg2z";
|
||||
};
|
||||
sourceRoot = ".";
|
||||
# Installing simply means copying template php file to the output directory
|
||||
installPhase = ""
|
||||
mkdir -p $out
|
||||
cp invoiceplane-vtdirektmarketing/vtdirektmarketing.php $out/
|
||||
"";
|
||||
};
|
||||
# And then pass this package to the template list like this:
|
||||
in [ template-vtdirektmarketing ]
|
||||
'';
|
||||
};
|
||||
|
||||
poolConfig = mkOption {
|
||||
type = with types; attrsOf (oneOf [str int bool]);
|
||||
default = {
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 4;
|
||||
"pm.max_requests" = 500;
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Options for the InvoicePlane PHP pool. See the documentation on `php-fpm.conf`
|
||||
for details on configuration directives.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
example = ''
|
||||
SETUP_COMPLETED=true
|
||||
DISABLE_SETUP=true
|
||||
IP_URL=https://invoice.example.com
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
InvoicePlane configuration. Refer to
|
||||
<https://github.com/InvoicePlane/InvoicePlane/blob/master/ipconfig.php.example>
|
||||
for details on supported values.
|
||||
'';
|
||||
};
|
||||
|
||||
cron = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Enable cron service which periodically runs Invoiceplane tasks.
|
||||
Requires key taken from the administration page. Refer to
|
||||
<https://wiki.invoiceplane.com/en/1.0/modules/recurring-invoices>
|
||||
on how to configure it.
|
||||
'';
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = types.str;
|
||||
description = lib.mdDoc "Cron key taken from the administration page.";
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
};
|
||||
in {
|
||||
disabledModules = [
|
||||
"services/web-apps/invoiceplane.nix"
|
||||
];
|
||||
|
@ -218,7 +224,6 @@ in
|
|||
options = {
|
||||
services.invoiceplane = mkOption {
|
||||
type = types.submodule {
|
||||
|
||||
options.sites = mkOption {
|
||||
type = types.attrsOf (types.submodule siteOpts);
|
||||
default = {};
|
||||
|
@ -226,7 +231,7 @@ in
|
|||
};
|
||||
|
||||
options.webserver = mkOption {
|
||||
type = types.enum [ "caddy" "nginx" ];
|
||||
type = types.enum ["caddy" "nginx"];
|
||||
default = "caddy";
|
||||
description = lib.mdDoc ''
|
||||
Which webserver to use for virtual host management. Currently only
|
||||
|
@ -237,160 +242,172 @@ in
|
|||
default = {};
|
||||
description = lib.mdDoc "InvoicePlane configuration.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
# implementation
|
||||
config = mkIf (eachSite != {}) (mkMerge [{
|
||||
config = mkIf (eachSite != {}) (mkMerge [
|
||||
{
|
||||
assertions = flatten (mapAttrsToList (hostName: cfg: [
|
||||
{
|
||||
assertion = cfg.database.createLocally -> cfg.database.user == user;
|
||||
message = ''services.invoiceplane.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned'';
|
||||
}
|
||||
{
|
||||
assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
|
||||
message = ''services.invoiceplane.sites."${hostName}".database.passwordFile cannot be specified if services.invoiceplane.sites."${hostName}".database.createLocally is set to true.'';
|
||||
}
|
||||
{
|
||||
assertion = cfg.cron.enable -> cfg.cron.key != null;
|
||||
message = ''services.invoiceplane.sites."${hostName}".cron.key must be set in order to use cron service.'';
|
||||
}
|
||||
])
|
||||
eachSite);
|
||||
|
||||
assertions = flatten (mapAttrsToList (hostName: cfg:
|
||||
[{ assertion = cfg.database.createLocally -> cfg.database.user == user;
|
||||
message = ''services.invoiceplane.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned'';
|
||||
}
|
||||
{ assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
|
||||
message = ''services.invoiceplane.sites."${hostName}".database.passwordFile cannot be specified if services.invoiceplane.sites."${hostName}".database.createLocally is set to true.'';
|
||||
}
|
||||
{ assertion = cfg.cron.enable -> cfg.cron.key != null;
|
||||
message = ''services.invoiceplane.sites."${hostName}".cron.key must be set in order to use cron service.'';
|
||||
}
|
||||
]) eachSite);
|
||||
|
||||
services.mysql = mkIf (any (v: v.database.createLocally) (attrValues eachSite)) {
|
||||
enable = true;
|
||||
package = mkDefault pkgs.mariadb;
|
||||
ensureDatabases = mapAttrsToList (hostName: cfg: cfg.database.name) eachSite;
|
||||
ensureUsers = mapAttrsToList (hostName: cfg:
|
||||
{ name = cfg.database.user;
|
||||
ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
|
||||
}
|
||||
) eachSite;
|
||||
};
|
||||
|
||||
services.phpfpm = {
|
||||
phpPackage = pkgs.php81;
|
||||
pools = mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "invoiceplane-${hostName}" {
|
||||
inherit user;
|
||||
group = webserver.group;
|
||||
settings = {
|
||||
"listen.owner" = webserver.user;
|
||||
"listen.group" = webserver.group;
|
||||
} // cfg.poolConfig;
|
||||
}
|
||||
)) eachSite;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
systemd.tmpfiles.rules = flatten (mapAttrsToList (hostName: cfg: [
|
||||
"d ${cfg.stateDir} 0750 ${user} ${webserver.group} - -"
|
||||
"f ${cfg.stateDir}/ipconfig.php 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/logs 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads/archive 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads/customer_files 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads/temp 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads/temp/mpdf 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/tmp 0750 ${user} ${webserver.group} - -"
|
||||
]) eachSite);
|
||||
|
||||
systemd.services.invoiceplane-config = {
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = concatStrings (mapAttrsToList (hostName: cfg:
|
||||
''
|
||||
mkdir -p ${cfg.stateDir}/logs \
|
||||
${cfg.stateDir}/uploads
|
||||
if ! grep -q IP_URL "${cfg.stateDir}/ipconfig.php"; then
|
||||
cp "${invoiceplane-config hostName cfg}" "${cfg.stateDir}/ipconfig.php"
|
||||
fi
|
||||
'') eachSite);
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
users.users.${user} = {
|
||||
group = webserver.group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
}
|
||||
{
|
||||
|
||||
# Cron service implementation
|
||||
|
||||
systemd.timers = mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "invoiceplane-cron-${hostName}" (mkIf cfg.cron.enable {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnBootSec = "5m";
|
||||
OnUnitActiveSec = "5m";
|
||||
Unit = "invoiceplane-cron-${hostName}.service";
|
||||
};
|
||||
})
|
||||
)) eachSite;
|
||||
|
||||
systemd.services =
|
||||
mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "invoiceplane-cron-${hostName}" (mkIf cfg.cron.enable {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = user;
|
||||
ExecStart = "${pkgs.curl}/bin/curl --header 'Host: ${hostName}' http://localhost/invoices/cron/recur/${cfg.cron.key}";
|
||||
};
|
||||
})
|
||||
)) eachSite;
|
||||
|
||||
}
|
||||
|
||||
(mkIf (cfg.webserver == "caddy") {
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
virtualHosts = mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "http://${hostName}" {
|
||||
extraConfig = ''
|
||||
root * ${pkg hostName cfg}
|
||||
file_server
|
||||
php_fastcgi unix/${config.services.phpfpm.pools."invoiceplane-${hostName}".socket}
|
||||
'';
|
||||
}
|
||||
)) eachSite;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.webserver == "nginx") {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "${hostName}" {
|
||||
root = "${pkg hostName cfg}";
|
||||
extraConfig = ''
|
||||
index index.php index.html index.htm;
|
||||
|
||||
if (!-e $request_filename){
|
||||
rewrite ^(.*)$ /index.php break;
|
||||
services.mysql = mkIf (any (v: v.database.createLocally) (attrValues eachSite)) {
|
||||
enable = true;
|
||||
package = mkDefault pkgs.mariadb;
|
||||
ensureDatabases = mapAttrsToList (hostName: cfg: cfg.database.name) eachSite;
|
||||
ensureUsers =
|
||||
mapAttrsToList (
|
||||
hostName: cfg: {
|
||||
name = cfg.database.user;
|
||||
ensurePermissions = {"${cfg.database.name}.*" = "ALL PRIVILEGES";};
|
||||
}
|
||||
'';
|
||||
)
|
||||
eachSite;
|
||||
};
|
||||
|
||||
locations = {
|
||||
"/setup".extraConfig = ''
|
||||
rewrite ^(.*)$ http://${hostName}/ redirect;
|
||||
'';
|
||||
services.phpfpm = {
|
||||
phpPackage = pkgs.php81;
|
||||
pools =
|
||||
mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "invoiceplane-${hostName}" {
|
||||
inherit user;
|
||||
group = webserver.group;
|
||||
settings =
|
||||
{
|
||||
"listen.owner" = webserver.user;
|
||||
"listen.group" = webserver.group;
|
||||
}
|
||||
// cfg.poolConfig;
|
||||
}
|
||||
))
|
||||
eachSite;
|
||||
};
|
||||
}
|
||||
|
||||
"~ .php$" = {
|
||||
extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools."invoiceplane-${hostName}".socket};
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
'';
|
||||
{
|
||||
systemd.tmpfiles.rules = flatten (mapAttrsToList (hostName: cfg: [
|
||||
"d ${cfg.stateDir} 0750 ${user} ${webserver.group} - -"
|
||||
"f ${cfg.stateDir}/ipconfig.php 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/logs 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads/archive 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads/customer_files 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads/temp 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/uploads/temp/mpdf 0750 ${user} ${webserver.group} - -"
|
||||
"d ${cfg.stateDir}/tmp 0750 ${user} ${webserver.group} - -"
|
||||
])
|
||||
eachSite);
|
||||
|
||||
systemd.services.invoiceplane-config = {
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = concatStrings (mapAttrsToList (hostName: cfg: ''
|
||||
mkdir -p ${cfg.stateDir}/logs \
|
||||
${cfg.stateDir}/uploads
|
||||
if ! grep -q IP_URL "${cfg.stateDir}/ipconfig.php"; then
|
||||
cp "${invoiceplane-config hostName cfg}" "${cfg.stateDir}/ipconfig.php"
|
||||
fi
|
||||
'')
|
||||
eachSite);
|
||||
wantedBy = ["multi-user.target"];
|
||||
};
|
||||
|
||||
users.users.${user} = {
|
||||
group = webserver.group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
# Cron service implementation
|
||||
|
||||
systemd.timers =
|
||||
mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "invoiceplane-cron-${hostName}" (mkIf cfg.cron.enable {
|
||||
wantedBy = ["timers.target"];
|
||||
timerConfig = {
|
||||
OnBootSec = "5m";
|
||||
OnUnitActiveSec = "5m";
|
||||
Unit = "invoiceplane-cron-${hostName}.service";
|
||||
};
|
||||
};
|
||||
}
|
||||
)) eachSite;
|
||||
};
|
||||
})
|
||||
})
|
||||
))
|
||||
eachSite;
|
||||
|
||||
systemd.services =
|
||||
mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "invoiceplane-cron-${hostName}" (mkIf cfg.cron.enable {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = user;
|
||||
ExecStart = "${pkgs.curl}/bin/curl --header 'Host: ${hostName}' http://localhost/invoices/cron/recur/${cfg.cron.key}";
|
||||
};
|
||||
})
|
||||
))
|
||||
eachSite;
|
||||
}
|
||||
|
||||
(mkIf (cfg.webserver == "caddy") {
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
virtualHosts =
|
||||
mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "http://${hostName}" {
|
||||
extraConfig = ''
|
||||
root * ${pkg hostName cfg}
|
||||
file_server
|
||||
php_fastcgi unix/${config.services.phpfpm.pools."invoiceplane-${hostName}".socket}
|
||||
'';
|
||||
}
|
||||
))
|
||||
eachSite;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.webserver == "nginx") {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts =
|
||||
mapAttrs' (hostName: cfg: (
|
||||
nameValuePair "${hostName}" {
|
||||
root = "${pkg hostName cfg}";
|
||||
extraConfig = ''
|
||||
index index.php index.html index.htm;
|
||||
|
||||
if (!-e $request_filename){
|
||||
rewrite ^(.*)$ /index.php break;
|
||||
}
|
||||
'';
|
||||
|
||||
locations = {
|
||||
"/setup".extraConfig = ''
|
||||
rewrite ^(.*)$ http://${hostName}/ redirect;
|
||||
'';
|
||||
|
||||
"~ .php$" = {
|
||||
extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools."invoiceplane-${hostName}".socket};
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
))
|
||||
eachSite;
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -5,15 +5,16 @@
|
|||
flake,
|
||||
...
|
||||
}: {
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||
"steam"
|
||||
"steam-original"
|
||||
"steam-run"
|
||||
"hplip"
|
||||
"cups-brother-hl3140cw"
|
||||
"uhk-agent"
|
||||
"uhk-udev-rules"
|
||||
];
|
||||
nixpkgs.config.allowUnfreePredicate = pkg:
|
||||
builtins.elem (lib.getName pkg) [
|
||||
"steam"
|
||||
"steam-original"
|
||||
"steam-run"
|
||||
"hplip"
|
||||
"cups-brother-hl3140cw"
|
||||
"uhk-agent"
|
||||
"uhk-udev-rules"
|
||||
];
|
||||
|
||||
nix = {
|
||||
# Use default version alias for nix package
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
{ lib, config, ... }:
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
environment.persistence."/persist" = {
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
|
@ -17,7 +20,7 @@
|
|||
|
||||
fileSystems."/etc/nixos" = {
|
||||
device = "/home/${config.pub-solar.user.name}/Workspace/os";
|
||||
options = [ "bind" ];
|
||||
options = ["bind"];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
{pkgs, ...}: {
|
||||
services.cron = {
|
||||
enable = true;
|
||||
systemCronJobs = [
|
||||
|
|
|
@ -16,11 +16,15 @@
|
|||
services.printing.listenAddresses = ["localhost:631"];
|
||||
services.printing.defaultShared = lib.mkDefault false;
|
||||
|
||||
services.printing.drivers = [
|
||||
pkgs.gutenprint
|
||||
] ++ (if (pkgs.system == "x86_64-linux")
|
||||
then [ pkgs.cups-brother-hl3140cw ]
|
||||
else []);
|
||||
services.printing.drivers =
|
||||
[
|
||||
pkgs.gutenprint
|
||||
]
|
||||
++ (
|
||||
if (pkgs.system == "x86_64-linux")
|
||||
then [pkgs.cups-brother-hl3140cw]
|
||||
else []
|
||||
);
|
||||
|
||||
# environment.persistence."/persist" = {
|
||||
# directories = [
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
lib,
|
||||
...
|
||||
}: {
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
|
|
@ -6,27 +6,27 @@
|
|||
user = config.pub-solar.user;
|
||||
xdg = config.home-manager.users."${user.name}".xdg;
|
||||
in ''
|
||||
# What happened?
|
||||
#
|
||||
# fix feat build chore ci docs style refactor perf test
|
||||
#
|
||||
# type!(optional scope): <summary> --------------#
|
||||
#
|
||||
# What happened?
|
||||
#
|
||||
# fix feat build chore ci docs style refactor perf test
|
||||
#
|
||||
# type!(optional scope): <summary> --------------#
|
||||
#
|
||||
|
||||
|
||||
# ^\n
|
||||
# What exactly was done and why? --------------------------------------#
|
||||
#
|
||||
# ^\n
|
||||
# What exactly was done and why? --------------------------------------#
|
||||
#
|
||||
|
||||
|
||||
# ^\n
|
||||
#
|
||||
# Any issue numbers or links?
|
||||
#
|
||||
# Ref: #123
|
||||
# ^\n
|
||||
#
|
||||
# Any issue numbers or links?
|
||||
#
|
||||
# Ref: #123
|
||||
|
||||
|
||||
# ^\n
|
||||
#
|
||||
# Co-authored-by: Example Name <email@example.com>
|
||||
# ^\n
|
||||
#
|
||||
# Co-authored-by: Example Name <email@example.com>
|
||||
''
|
||||
|
|
|
@ -21,34 +21,40 @@ in {
|
|||
config = {
|
||||
programs.command-not-found.enable = false;
|
||||
|
||||
users.users."${psCfg.user.name}".packages = with pkgs; [
|
||||
asciinema
|
||||
bat
|
||||
blesh
|
||||
eza
|
||||
fd
|
||||
ripgrep
|
||||
(nnn.overrideAttrs (o: {
|
||||
patches =
|
||||
(o.patches or [])
|
||||
++ [
|
||||
./nnn/0001-feat-use-wasd-keybindings-for-jkli.patch
|
||||
];
|
||||
}))
|
||||
p
|
||||
powerline
|
||||
screen
|
||||
watson
|
||||
jump
|
||||
] ++ (if cfg.full then [
|
||||
# Nix specific utilities
|
||||
alejandra
|
||||
manix
|
||||
nix-index
|
||||
nix-tree
|
||||
nix-inspect
|
||||
nvd
|
||||
] else []);
|
||||
users.users."${psCfg.user.name}".packages = with pkgs;
|
||||
[
|
||||
asciinema
|
||||
bat
|
||||
blesh
|
||||
eza
|
||||
fd
|
||||
ripgrep
|
||||
(nnn.overrideAttrs (o: {
|
||||
patches =
|
||||
(o.patches or [])
|
||||
++ [
|
||||
./nnn/0001-feat-use-wasd-keybindings-for-jkli.patch
|
||||
];
|
||||
}))
|
||||
p
|
||||
powerline
|
||||
screen
|
||||
watson
|
||||
jump
|
||||
]
|
||||
++ (
|
||||
if cfg.full
|
||||
then [
|
||||
# Nix specific utilities
|
||||
alejandra
|
||||
manix
|
||||
nix-index
|
||||
nix-tree
|
||||
nix-inspect
|
||||
nvd
|
||||
]
|
||||
else []
|
||||
);
|
||||
|
||||
home-manager.users."${psCfg.user.name}" = {
|
||||
xdg.dataFile."scripts/base16.sh".source = .local/share/scripts/base16.sh;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{ ... }:
|
||||
{
|
||||
{...}: {
|
||||
enable = true;
|
||||
nix-direnv = {
|
||||
enable = true;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{ ... }:
|
||||
{
|
||||
{...}: {
|
||||
enable = true;
|
||||
|
||||
extraConfig = {
|
||||
|
|
|
@ -4,45 +4,45 @@ local luasnip = require 'luasnip'
|
|||
|
||||
local cmp = require 'cmp'
|
||||
cmp.setup {
|
||||
snippet = {
|
||||
expand = function(args)
|
||||
require('luasnip').lsp_expand(args.body)
|
||||
end,
|
||||
},
|
||||
mapping = {
|
||||
['<C-p>'] = cmp.mapping.select_prev_item(),
|
||||
['<C-n>'] = cmp.mapping.select_next_item(),
|
||||
['<C-d>'] = cmp.mapping.scroll_docs(-4),
|
||||
['<C-f>'] = cmp.mapping.scroll_docs(4),
|
||||
['<C-Space>'] = cmp.mapping.complete(),
|
||||
['<C-e>'] = cmp.mapping.close(),
|
||||
['<CR>'] = cmp.mapping.confirm {
|
||||
behavior = cmp.ConfirmBehavior.Replace,
|
||||
select = true,
|
||||
},
|
||||
['<Tab>'] = function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_next_item()
|
||||
elseif luasnip.expand_or_jumpable() then
|
||||
luasnip.expand_or_jump()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end,
|
||||
['<S-Tab>'] = function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_prev_item()
|
||||
elseif luasnip.jumpable(-1) then
|
||||
luasnip.jump(-1)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end,
|
||||
},
|
||||
sources = {
|
||||
{ name = 'nvim_lsp' },
|
||||
{ name = 'luasnip' },
|
||||
},
|
||||
snippet = {
|
||||
expand = function(args)
|
||||
require('luasnip').lsp_expand(args.body)
|
||||
end,
|
||||
},
|
||||
mapping = {
|
||||
['<C-p>'] = cmp.mapping.select_prev_item(),
|
||||
['<C-n>'] = cmp.mapping.select_next_item(),
|
||||
['<C-d>'] = cmp.mapping.scroll_docs(-4),
|
||||
['<C-f>'] = cmp.mapping.scroll_docs(4),
|
||||
['<C-Space>'] = cmp.mapping.complete(),
|
||||
['<C-e>'] = cmp.mapping.close(),
|
||||
['<CR>'] = cmp.mapping.confirm {
|
||||
behavior = cmp.ConfirmBehavior.Replace,
|
||||
select = true,
|
||||
},
|
||||
['<Tab>'] = function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_next_item()
|
||||
elseif luasnip.expand_or_jumpable() then
|
||||
luasnip.expand_or_jump()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end,
|
||||
['<S-Tab>'] = function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_prev_item()
|
||||
elseif luasnip.jumpable(-1) then
|
||||
luasnip.jump(-1)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end,
|
||||
},
|
||||
sources = {
|
||||
{ name = 'nvim_lsp' },
|
||||
{ name = 'luasnip' },
|
||||
},
|
||||
}
|
||||
|
||||
EOF
|
||||
|
|
|
@ -19,119 +19,130 @@ in {
|
|||
withPython3 = true;
|
||||
|
||||
extraPackages = with pkgs; [
|
||||
ripgrep
|
||||
nixd
|
||||
universal-ctags
|
||||
# ansible-language-server
|
||||
# clang-tools
|
||||
# gopls
|
||||
# nodePackages.bash-language-server
|
||||
# nodePackages.svelte-language-server
|
||||
# nodePackages.typescript
|
||||
# nodePackages.typescript-language-server
|
||||
# nodePackages.vue-language-server
|
||||
# nodePackages.vscode-langservers-extracted
|
||||
# nginx-language-server
|
||||
# lua-language-server
|
||||
# cmake-language-server
|
||||
# vim-language-server
|
||||
# yaml-language-server
|
||||
# python3Packages.python-lsp-server
|
||||
# nodePackages.dockerfile-language-server-nodejs
|
||||
# docker-compose-language-service
|
||||
# rust-analyzer
|
||||
# cargo
|
||||
# solargraph
|
||||
# terraform-ls
|
||||
# python3Full
|
||||
];
|
||||
ripgrep
|
||||
nixd
|
||||
universal-ctags
|
||||
# ansible-language-server
|
||||
# clang-tools
|
||||
# gopls
|
||||
# nodePackages.bash-language-server
|
||||
# nodePackages.svelte-language-server
|
||||
# nodePackages.typescript
|
||||
# nodePackages.typescript-language-server
|
||||
# nodePackages.vue-language-server
|
||||
# nodePackages.vscode-langservers-extracted
|
||||
# nginx-language-server
|
||||
# lua-language-server
|
||||
# cmake-language-server
|
||||
# vim-language-server
|
||||
# yaml-language-server
|
||||
# python3Packages.python-lsp-server
|
||||
# nodePackages.dockerfile-language-server-nodejs
|
||||
# docker-compose-language-service
|
||||
# rust-analyzer
|
||||
# cargo
|
||||
# solargraph
|
||||
# terraform-ls
|
||||
# python3Full
|
||||
];
|
||||
|
||||
plugins = with pkgs.vimPlugins; [
|
||||
# The status bar in the bottom of the screen with the mode indication and file location
|
||||
vim-airline
|
||||
plugins = with pkgs.vimPlugins;
|
||||
[
|
||||
# The status bar in the bottom of the screen with the mode indication and file location
|
||||
vim-airline
|
||||
|
||||
# Automatically load editorconfig files in repos to configure nvim settings
|
||||
editorconfig-vim
|
||||
# Automatically load editorconfig files in repos to configure nvim settings
|
||||
editorconfig-vim
|
||||
|
||||
# File browser. Use <leader>n to access
|
||||
nnn-vim
|
||||
# File browser. Use <leader>n to access
|
||||
nnn-vim
|
||||
|
||||
# Highlight characters when using f, F, t, and T
|
||||
quick-scope
|
||||
# Highlight characters when using f, F, t, and T
|
||||
quick-scope
|
||||
|
||||
# Undo history etc. per project
|
||||
vim-workspace-nvfetcher
|
||||
# Undo history etc. per project
|
||||
vim-workspace-nvfetcher
|
||||
|
||||
# Neovim colorschemes / themes
|
||||
sonokai
|
||||
vim-hybrid-material
|
||||
vim-airline-themes
|
||||
vim-apprentice-nvfetcher
|
||||
# Neovim colorschemes / themes
|
||||
sonokai
|
||||
vim-hybrid-material
|
||||
vim-airline-themes
|
||||
vim-apprentice-nvfetcher
|
||||
|
||||
# Git integrations
|
||||
# A Git wrapper so awesome, it should be illegal
|
||||
fugitive
|
||||
# Shows git diff markers in the sign column
|
||||
vim-gitgutter
|
||||
# GitHub extension for fugitive
|
||||
vim-rhubarb
|
||||
# Ease your git workflow within Vim
|
||||
vimagit-nvfetcher
|
||||
# Git integrations
|
||||
# A Git wrapper so awesome, it should be illegal
|
||||
fugitive
|
||||
# Shows git diff markers in the sign column
|
||||
vim-gitgutter
|
||||
# GitHub extension for fugitive
|
||||
vim-rhubarb
|
||||
# Ease your git workflow within Vim
|
||||
vimagit-nvfetcher
|
||||
|
||||
# Telescope fuzzy finder
|
||||
telescope-nvim
|
||||
telescope-fzf-native-nvim
|
||||
# Telescope fuzzy finder
|
||||
telescope-nvim
|
||||
telescope-fzf-native-nvim
|
||||
|
||||
# Make the yanked region apparent
|
||||
vim-highlightedyank
|
||||
# Make the yanked region apparent
|
||||
vim-highlightedyank
|
||||
|
||||
# :Beautify Code beautifier
|
||||
vim-beautify-nvfetcher
|
||||
# :Beautify Code beautifier
|
||||
vim-beautify-nvfetcher
|
||||
|
||||
# Unload, delete or wipe a buffer without closing the window
|
||||
vim-bufkill
|
||||
# Unload, delete or wipe a buffer without closing the window
|
||||
vim-bufkill
|
||||
|
||||
# Defaults everyone can agree on
|
||||
vim-sensible
|
||||
# Defaults everyone can agree on
|
||||
vim-sensible
|
||||
|
||||
# Work with tags files
|
||||
vim-gutentags
|
||||
] ++ (if cfg.full then [
|
||||
nvim-treesitter.withAllGrammars
|
||||
# Work with tags files
|
||||
vim-gutentags
|
||||
]
|
||||
++ (
|
||||
if cfg.full
|
||||
then [
|
||||
nvim-treesitter.withAllGrammars
|
||||
|
||||
# Dependencies for nvim-lspconfig
|
||||
nvim-cmp
|
||||
cmp-nvim-lsp
|
||||
cmp_luasnip
|
||||
luasnip
|
||||
# Dependencies for nvim-lspconfig
|
||||
nvim-cmp
|
||||
cmp-nvim-lsp
|
||||
cmp_luasnip
|
||||
luasnip
|
||||
|
||||
# Quickstart configs for neovim LSP
|
||||
lsp_extensions-nvim
|
||||
nvim-lspconfig
|
||||
# Quickstart configs for neovim LSP
|
||||
lsp_extensions-nvim
|
||||
nvim-lspconfig
|
||||
|
||||
# Collaborative editing in Neovim using built-in capabilities
|
||||
instant-nvim-nvfetcher
|
||||
# Collaborative editing in Neovim using built-in capabilities
|
||||
instant-nvim-nvfetcher
|
||||
|
||||
# JSON schemas
|
||||
SchemaStore-nvim
|
||||
] else []);
|
||||
# JSON schemas
|
||||
SchemaStore-nvim
|
||||
]
|
||||
else []
|
||||
);
|
||||
|
||||
extraConfig = builtins.concatStringsSep "\n" ([
|
||||
''
|
||||
" Persistent undo
|
||||
set undofile
|
||||
set undodir=${xdg.cacheHome}/nvim/undo
|
||||
''
|
||||
" Persistent undo
|
||||
set undofile
|
||||
set undodir=${xdg.cacheHome}/nvim/undo
|
||||
|
||||
set backupdir=${xdg.dataHome}/nvim/backup
|
||||
set directory=${xdg.dataHome}/nvim/swap/
|
||||
''
|
||||
(builtins.readFile ./init.vim)
|
||||
(builtins.readFile ./plugins.vim)
|
||||
(builtins.readFile ./clipboard.vim)
|
||||
(builtins.readFile ./ui.vim)
|
||||
(builtins.readFile ./filetypes.vim)
|
||||
] ++ (if cfg.full then [
|
||||
(builtins.readFile ./lsp.vim)
|
||||
(builtins.readFile ./cmp.vim)
|
||||
] else []));
|
||||
set backupdir=${xdg.dataHome}/nvim/backup
|
||||
set directory=${xdg.dataHome}/nvim/swap/
|
||||
''
|
||||
(builtins.readFile ./init.vim)
|
||||
(builtins.readFile ./plugins.vim)
|
||||
(builtins.readFile ./clipboard.vim)
|
||||
(builtins.readFile ./ui.vim)
|
||||
(builtins.readFile ./filetypes.vim)
|
||||
]
|
||||
++ (
|
||||
if cfg.full
|
||||
then [
|
||||
(builtins.readFile ./lsp.vim)
|
||||
(builtins.readFile ./cmp.vim)
|
||||
]
|
||||
else []
|
||||
));
|
||||
}
|
||||
|
|
|
@ -23,39 +23,39 @@ vim.api.nvim_set_keymap('n', '<leader>dq', '<cmd>lua vim.diagnostic.setloclist()
|
|||
vim.api.nvim_set_keymap('n', '<leader>f', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts)
|
||||
|
||||
local on_attach = function(client, bufnr)
|
||||
-- Enable completion triggered by <c-x><c-o>
|
||||
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
|
||||
-- Enable completion triggered by <c-x><c-o>
|
||||
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
|
||||
|
||||
-- Mappings (available if LSP is configured and attached to buffer)
|
||||
-- See `:help vim.lsp.*` for documentation on any of the below functions
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
|
||||
-- Mappings (available if LSP is configured and attached to buffer)
|
||||
-- See `:help vim.lsp.*` for documentation on any of the below functions
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
|
||||
|
||||
-- Show diagnostic popup on cursor hold
|
||||
vim.api.nvim_create_autocmd("CursorHold", {
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
local opts = {
|
||||
focusable = false,
|
||||
close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" },
|
||||
border = 'rounded',
|
||||
source = 'always',
|
||||
prefix = ' ',
|
||||
scope = 'cursor',
|
||||
}
|
||||
vim.diagnostic.open_float(nil, opts)
|
||||
end
|
||||
})
|
||||
-- Show diagnostic popup on cursor hold
|
||||
vim.api.nvim_create_autocmd("CursorHold", {
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
local opts = {
|
||||
focusable = false,
|
||||
close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" },
|
||||
border = 'rounded',
|
||||
source = 'always',
|
||||
prefix = ' ',
|
||||
scope = 'cursor',
|
||||
}
|
||||
vim.diagnostic.open_float(nil, opts)
|
||||
end
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
|
@ -65,23 +65,23 @@ local CAPABILITIES = require('cmp_nvim_lsp').default_capabilities()
|
|||
|
||||
--- Event handlers
|
||||
local HANDLERS = {
|
||||
-- TODO: replace with vim.lsp.protocol.Methods
|
||||
["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, FLOAT_CONFIG),
|
||||
["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, FLOAT_CONFIG),
|
||||
-- TODO: replace with vim.lsp.protocol.Methods
|
||||
["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, FLOAT_CONFIG),
|
||||
["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, FLOAT_CONFIG),
|
||||
}
|
||||
|
||||
-- vscode HTML lsp needs this https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#html
|
||||
CAPABILITIES.textDocument.completion.completionItem.snippetSupport = true
|
||||
|
||||
local function setup(lsp, config)
|
||||
if config == nil then
|
||||
config = {}
|
||||
end
|
||||
if config == nil then
|
||||
config = {}
|
||||
end
|
||||
|
||||
config.capabilities = CAPABILITIES
|
||||
config.handlers = HANDLERS
|
||||
config.on_attach = on_attach
|
||||
lspconfig[lsp].setup(config)
|
||||
config.capabilities = CAPABILITIES
|
||||
config.handlers = HANDLERS
|
||||
config.on_attach = on_attach
|
||||
lspconfig[lsp].setup(config)
|
||||
end
|
||||
|
||||
setup('nixd')
|
||||
|
@ -96,28 +96,28 @@ setup('svelte')
|
|||
setup('html')
|
||||
setup('yamlls')
|
||||
setup('jsonls', {
|
||||
json = {
|
||||
schemas = require('schemastore').json.schemas(),
|
||||
validate = {
|
||||
enable = true
|
||||
}
|
||||
}
|
||||
json = {
|
||||
schemas = require('schemastore').json.schemas(),
|
||||
validate = {
|
||||
enable = true
|
||||
}
|
||||
}
|
||||
})
|
||||
setup('gopls', {
|
||||
settings = {
|
||||
gopls = { semanticTokens = true }
|
||||
}
|
||||
settings = {
|
||||
gopls = { semanticTokens = true }
|
||||
}
|
||||
})
|
||||
setup('phpactor')
|
||||
setup('pylsp')
|
||||
setup('solargraph') -- ruby
|
||||
setup('rust_analyzer', {
|
||||
settings = {
|
||||
['rust-analyzer'] = {
|
||||
checkOnSave = { extraArgs = { "--target-dir", "/tmp/rust-analyzer-check" } },
|
||||
diagnostics = { disabled = { 'inactive-code' } },
|
||||
},
|
||||
}
|
||||
settings = {
|
||||
['rust-analyzer'] = {
|
||||
checkOnSave = { extraArgs = { "--target-dir", "/tmp/rust-analyzer-check" } },
|
||||
diagnostics = { disabled = { 'inactive-code' } },
|
||||
},
|
||||
}
|
||||
})
|
||||
setup('sqlls')
|
||||
setup('salt_ls')
|
||||
|
@ -128,22 +128,22 @@ setup('terraformls')
|
|||
|
||||
-- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#denols
|
||||
vim.g.markdown_fenced_languages = {
|
||||
"ts=typescript"
|
||||
"ts=typescript"
|
||||
}
|
||||
|
||||
-- Configure diagnostics
|
||||
vim.diagnostic.config({
|
||||
virtual_text = false,
|
||||
signs = true,
|
||||
underline = true,
|
||||
update_in_insert = false,
|
||||
severity_sort = false,
|
||||
virtual_text = false,
|
||||
signs = true,
|
||||
underline = true,
|
||||
update_in_insert = false,
|
||||
severity_sort = false,
|
||||
})
|
||||
|
||||
-- Change diagnostic symbols in the sign column (gutter)
|
||||
local signs = { Error = "x ", Warn = "! ", Hint = "? ", Info = "i " }
|
||||
for type, icon in pairs(signs) do
|
||||
local hl = "DiagnosticSign" .. type
|
||||
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
|
||||
local hl = "DiagnosticSign" .. type
|
||||
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
|
||||
end
|
||||
EOF
|
||||
|
|
|
@ -54,21 +54,26 @@ telescope.setup{
|
|||
defaults = {
|
||||
mappings = {
|
||||
n = {
|
||||
["k"] = actions.move_selection_next,
|
||||
["i"] = actions.move_selection_previous,
|
||||
["I"] = actions.move_to_top,
|
||||
["K"] = actions.move_to_bottom,
|
||||
["<C-c>"] = actions.close,
|
||||
["k"] = actions.move_selection_next,
|
||||
["i"] = actions.move_selection_previous,
|
||||
["I"] = actions.move_to_top,
|
||||
["K"] = actions.move_to_bottom,
|
||||
["<C-c>"] = actions.close,
|
||||
},
|
||||
},
|
||||
},
|
||||
pickers = {
|
||||
find_files = {
|
||||
-- `hidden = true` will still show the inside of `.git/` as it's not `.gitignore`d.
|
||||
find_command = { "rg", "--files", "--hidden", "--glob", "!**/.git/*" },
|
||||
},
|
||||
},
|
||||
extensions = {
|
||||
fzf = {
|
||||
fuzzy = true, -- false will only do exact matching
|
||||
override_generic_sorter = true, -- override the generic sorter
|
||||
override_file_sorter = true, -- override the file sorter
|
||||
case_mode = "smart_case", -- or "ignore_case" or "respect_case"
|
||||
-- the default case_mode is "smart_case"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +85,7 @@ vim.keymap.set('n', '<leader>ff', builtin.find_files, {})
|
|||
vim.keymap.set('n', '<leader>f/', builtin.live_grep, {})
|
||||
vim.keymap.set('n', '<leader>f?', builtin.builtin, {})
|
||||
vim.keymap.set('n', '<leader>fb', builtin.buffers, {})
|
||||
vim.keymap.set('n', '<leader>fr', builtin.command_history, {})
|
||||
vim.keymap.set('n', '<leader>fc', builtin.commands, {})
|
||||
vim.keymap.set('n', '<leader>ft', builtin.treesitter, {})
|
||||
EOF
|
||||
|
|
|
@ -7,98 +7,100 @@
|
|||
}: let
|
||||
psCfg = config.pub-solar;
|
||||
in
|
||||
with lib; {
|
||||
imports = [
|
||||
./home.nix
|
||||
];
|
||||
|
||||
options.pub-solar = {
|
||||
user = {
|
||||
name = mkOption {
|
||||
description = "User login name";
|
||||
type = types.nullOr types.str;
|
||||
default = "nixos";
|
||||
};
|
||||
description = mkOption {
|
||||
description = "User description";
|
||||
type = types.nullOr types.str;
|
||||
default = "The main PubSolarOS user";
|
||||
};
|
||||
password = mkOption {
|
||||
description = "User password";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
passwordlessSudo = mkOption {
|
||||
description = "Whether this user can use sudo without entering a password";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
publicKeys = mkOption {
|
||||
description = "User SSH public keys";
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
};
|
||||
fullName = mkOption {
|
||||
description = "User full name";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
email = mkOption {
|
||||
description = "User email address";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
gpgKeyId = mkOption {
|
||||
description = "GPG Key ID";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
users = {
|
||||
mutableUsers = false;
|
||||
|
||||
users."${psCfg.user.name}" = {
|
||||
# Indicates whether this is an account for a “real” user.
|
||||
# This automatically sets group to users, createHome to true,
|
||||
# home to /home/username, useDefaultShell to true, and isSystemUser to false.
|
||||
isNormalUser = true;
|
||||
description = psCfg.user.description;
|
||||
extraGroups = [
|
||||
"input"
|
||||
"lp"
|
||||
"networkmanager"
|
||||
"scanner"
|
||||
"video"
|
||||
"dialout"
|
||||
"wheel"
|
||||
];
|
||||
shell = pkgs.bash;
|
||||
initialHashedPassword =
|
||||
if psCfg.user.password != null
|
||||
then psCfg.user.password
|
||||
else "";
|
||||
openssh.authorizedKeys.keys =
|
||||
flake.self.publicKeys ++
|
||||
(if psCfg.user.publicKeys != null
|
||||
then psCfg.user.publicKeys
|
||||
else []);
|
||||
};
|
||||
};
|
||||
|
||||
security.sudo.extraRules = mkIf psCfg.user.passwordlessSudo [
|
||||
{
|
||||
users = ["${psCfg.user.name}"];
|
||||
commands = [
|
||||
{
|
||||
command = "ALL";
|
||||
options = ["NOPASSWD"];
|
||||
}
|
||||
];
|
||||
}
|
||||
with lib; {
|
||||
imports = [
|
||||
./home.nix
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
options.pub-solar = {
|
||||
user = {
|
||||
name = mkOption {
|
||||
description = "User login name";
|
||||
type = types.nullOr types.str;
|
||||
default = "nixos";
|
||||
};
|
||||
description = mkOption {
|
||||
description = "User description";
|
||||
type = types.nullOr types.str;
|
||||
default = "The main PubSolarOS user";
|
||||
};
|
||||
password = mkOption {
|
||||
description = "User password";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
passwordlessSudo = mkOption {
|
||||
description = "Whether this user can use sudo without entering a password";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
publicKeys = mkOption {
|
||||
description = "User SSH public keys";
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
};
|
||||
fullName = mkOption {
|
||||
description = "User full name";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
email = mkOption {
|
||||
description = "User email address";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
gpgKeyId = mkOption {
|
||||
description = "GPG Key ID";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
users = {
|
||||
mutableUsers = false;
|
||||
|
||||
users."${psCfg.user.name}" = {
|
||||
# Indicates whether this is an account for a “real” user.
|
||||
# This automatically sets group to users, createHome to true,
|
||||
# home to /home/username, useDefaultShell to true, and isSystemUser to false.
|
||||
isNormalUser = true;
|
||||
description = psCfg.user.description;
|
||||
extraGroups = [
|
||||
"input"
|
||||
"lp"
|
||||
"networkmanager"
|
||||
"scanner"
|
||||
"video"
|
||||
"dialout"
|
||||
"wheel"
|
||||
];
|
||||
shell = pkgs.bash;
|
||||
initialHashedPassword =
|
||||
if psCfg.user.password != null
|
||||
then psCfg.user.password
|
||||
else "";
|
||||
openssh.authorizedKeys.keys =
|
||||
flake.self.publicKeys
|
||||
++ (
|
||||
if psCfg.user.publicKeys != null
|
||||
then psCfg.user.publicKeys
|
||||
else []
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
security.sudo.extraRules = mkIf psCfg.user.passwordlessSudo [
|
||||
{
|
||||
users = ["${psCfg.user.name}"];
|
||||
commands = [
|
||||
{
|
||||
command = "ALL";
|
||||
options = ["NOPASSWD"];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ ... }: {
|
||||
{...}: {
|
||||
imports = [
|
||||
./private.nix
|
||||
./tunnel.nix
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
}: let
|
||||
cfg = config.pub-solar.wireguard.ehex;
|
||||
in {
|
||||
options.pub-solar.wireguard.ehex = {
|
||||
|
@ -19,10 +18,10 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (lib.length cfg.ownIPs != 0){
|
||||
config = lib.mkIf (lib.length cfg.ownIPs != 0) {
|
||||
networking.firewall.allowedUDPPorts = [51822];
|
||||
|
||||
systemd.network.wait-online.ignoredInterfaces = [ "wg-ehex" ];
|
||||
systemd.network.wait-online.ignoredInterfaces = ["wg-ehex"];
|
||||
|
||||
systemd.services.wireguard-wg-ehex = import ./service-override.nix lib;
|
||||
|
||||
|
@ -42,8 +41,8 @@ in {
|
|||
{
|
||||
endpoint = "vpn-gateway.ehex.de:4242";
|
||||
publicKey = "Fsg4KEyDEvQEt/1cVWU9xa/k9x/3UhONDj61aXZ7tys=";
|
||||
presharedKey = "tQy7B5R3wOgWwIKFDcEr4WZIqCrwG+9UgPRIQx/5xso=";
|
||||
allowedIPs = [ "10.42.0.0/22" "10.0.66.0/24" ];
|
||||
presharedKey = "tQy7B5R3wOgWwIKFDcEr4WZIqCrwG+9UgPRIQx/5xso=";
|
||||
allowedIPs = ["10.42.0.0/22" "10.0.66.0/24"];
|
||||
persistentKeepalive = 15;
|
||||
dynamicEndpointRefreshSeconds = 30;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
}: let
|
||||
cfg = config.pub-solar.wireguard.private;
|
||||
in {
|
||||
options.pub-solar.wireguard.private = {
|
||||
|
@ -43,7 +42,7 @@ in {
|
|||
config = lib.mkIf (builtins.length cfg.ownIPs != 0) {
|
||||
networking.firewall.allowedUDPPorts = [51899];
|
||||
|
||||
systemd.network.wait-online.ignoredInterfaces = [ "wg-private" ];
|
||||
systemd.network.wait-online.ignoredInterfaces = ["wg-private"];
|
||||
|
||||
systemd.services.wireguard-wg-private = import ./service-override.nix lib;
|
||||
|
||||
|
@ -53,21 +52,30 @@ in {
|
|||
mtu = 1300;
|
||||
ips = cfg.ownIPs;
|
||||
privateKeyFile = cfg.privateKeyFile;
|
||||
postSetup = ""
|
||||
+ (if cfg.useDNS then ''
|
||||
printf "nameserver 10.13.12.7\nnameserver fd00:b12f:acab:1312:acab:7::" | resolvconf -a wg-private -m 0 -x
|
||||
'' else "")
|
||||
+ (if cfg.fullTunnel then ''
|
||||
defaultRoute=$(${pkgs.iproute2}/bin/ip r | ${pkgs.gnugrep}/bin/grep "default via" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $3 " " $4 " " $5 }')
|
||||
ipv4=$(${pkgs.dnsutils}/bin/dig +short A vpn.b12f.io)
|
||||
${pkgs.iproute2}/bin/ip route add $ipv4 metric 256 via $defaultRoute
|
||||
ipv6=$(${pkgs.dnsutils}/bin/dig +short AAAA vpn.b12f.io)
|
||||
${pkgs.iproute2}/bin/ip route add $ipv6 metric 256 via $defaultRoute
|
||||
ip -4 route delete default dev wg-private || true
|
||||
ip -4 route replace default dev wg-private metric 512
|
||||
ip -6 route delete default dev wg-private || true
|
||||
ip -6 route replace default dev wg-private metric 512
|
||||
'' else "");
|
||||
postSetup =
|
||||
""
|
||||
+ (
|
||||
if cfg.useDNS
|
||||
then ''
|
||||
printf "nameserver 10.13.12.7\nnameserver fd00:b12f:acab:1312:acab:7::" | resolvconf -a wg-private -m 0 -x
|
||||
''
|
||||
else ""
|
||||
)
|
||||
+ (
|
||||
if cfg.fullTunnel
|
||||
then ''
|
||||
defaultRoute=$(${pkgs.iproute2}/bin/ip r | ${pkgs.gnugrep}/bin/grep "default via" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $3 " " $4 " " $5 }')
|
||||
ipv4=$(${pkgs.dnsutils}/bin/dig +short A vpn.b12f.io)
|
||||
${pkgs.iproute2}/bin/ip route add $ipv4 metric 256 via $defaultRoute
|
||||
ipv6=$(${pkgs.dnsutils}/bin/dig +short AAAA vpn.b12f.io)
|
||||
${pkgs.iproute2}/bin/ip route add $ipv6 metric 256 via $defaultRoute
|
||||
ip -4 route delete default dev wg-private || true
|
||||
ip -4 route replace default dev wg-private metric 512
|
||||
ip -6 route delete default dev wg-private || true
|
||||
ip -6 route replace default dev wg-private metric 512
|
||||
''
|
||||
else ""
|
||||
);
|
||||
postShutdown = lib.mkIf cfg.useDNS ''
|
||||
resolvconf -d wg-private -f
|
||||
'';
|
||||
|
@ -75,13 +83,19 @@ in {
|
|||
{
|
||||
# frikandel
|
||||
publicKey = "p6YKNYBlySKfhTN+wbSsKdoNjzko/XSAiTAlCJzP1jA=";
|
||||
allowedIPs = [
|
||||
"10.13.12.0/24"
|
||||
"fd00:b12f:acab:1312::/64"
|
||||
] ++ (if cfg.fullTunnel then [
|
||||
"0.0.0.0/0"
|
||||
"::/0"
|
||||
] else []);
|
||||
allowedIPs =
|
||||
[
|
||||
"10.13.12.0/24"
|
||||
"fd00:b12f:acab:1312::/64"
|
||||
]
|
||||
++ (
|
||||
if cfg.fullTunnel
|
||||
then [
|
||||
"0.0.0.0/0"
|
||||
"::/0"
|
||||
]
|
||||
else []
|
||||
);
|
||||
endpoint = "vpn.b12f.io:51899";
|
||||
dynamicEndpointRefreshSeconds = 30;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
}: let
|
||||
cfg = config.pub-solar.wireguard.pub-solar;
|
||||
in {
|
||||
options.pub-solar.wireguard.pub-solar = {
|
||||
|
@ -19,10 +18,10 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (lib.length cfg.ownIPs != 0){
|
||||
config = lib.mkIf (lib.length cfg.ownIPs != 0) {
|
||||
networking.firewall.allowedUDPPorts = [51821];
|
||||
|
||||
systemd.network.wait-online.ignoredInterfaces = [ "wg-pub-solar" ];
|
||||
systemd.network.wait-online.ignoredInterfaces = ["wg-pub-solar"];
|
||||
|
||||
systemd.services.wireguard-wg-pub-solar = import ./service-override.nix lib;
|
||||
|
||||
|
@ -36,14 +35,14 @@ in {
|
|||
{
|
||||
endpoint = "flora-6.pub.solar:51820";
|
||||
publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU=";
|
||||
allowedIPs = [ "10.7.6.2/32" "fd00:fae:fae:fae:fae:2::/96" ];
|
||||
allowedIPs = ["10.7.6.2/32" "fd00:fae:fae:fae:fae:2::/96"];
|
||||
persistentKeepalive = 15;
|
||||
dynamicEndpointRefreshSeconds = 30;
|
||||
}
|
||||
{
|
||||
endpoint = "nachtigall.pub.solar:51820";
|
||||
publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk=";
|
||||
allowedIPs = [ "10.7.6.1/32" "fd00:fae:fae:fae:fae:1::/96" ];
|
||||
allowedIPs = ["10.7.6.1/32" "fd00:fae:fae:fae:fae:1::/96"];
|
||||
persistentKeepalive = 15;
|
||||
dynamicEndpointRefreshSeconds = 30;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
lib: {
|
||||
wantedBy = [
|
||||
"network.target"
|
||||
"network-online.target"
|
||||
"nss-lookup.target"
|
||||
];
|
||||
wantedBy = [
|
||||
"network.target"
|
||||
"network-online.target"
|
||||
"nss-lookup.target"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
Type = lib.mkForce "simple";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "15";
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = lib.mkForce "simple";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "15";
|
||||
};
|
||||
|
||||
environment = {
|
||||
WG_ENDPOINT_RESOLUTION_RETRIES = "infinity";
|
||||
};
|
||||
environment = {
|
||||
WG_ENDPOINT_RESOLUTION_RETRIES = "infinity";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
}: let
|
||||
cfg = config.pub-solar.wireguard.tunnel;
|
||||
in {
|
||||
options.pub-solar.wireguard.tunnel = {
|
||||
|
@ -37,10 +36,10 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (lib.length cfg.ownIPs != 0){
|
||||
config = lib.mkIf (lib.length cfg.ownIPs != 0) {
|
||||
networking.firewall.allowedUDPPorts = [51820];
|
||||
|
||||
systemd.network.wait-online.ignoredInterfaces = [ "wg-tunnel" ];
|
||||
systemd.network.wait-online.ignoredInterfaces = ["wg-tunnel"];
|
||||
|
||||
systemd.targets.wireguard-wg-tunnel = {
|
||||
wantedBy = lib.mkForce [];
|
||||
|
@ -73,11 +72,22 @@ in {
|
|||
};
|
||||
|
||||
networking.wireguard.interfaces = let
|
||||
splitEndpoint = (lib.strings.splitString ":" cfg.peer.endpoint);
|
||||
joinIPV6 = p: ip: p + (if (lib.stringLength ip > 0) then ":" else "") + ip;
|
||||
splitEndpoint = lib.strings.splitString ":" cfg.peer.endpoint;
|
||||
joinIPV6 = p: ip:
|
||||
p
|
||||
+ (
|
||||
if (lib.stringLength ip > 0)
|
||||
then ":"
|
||||
else ""
|
||||
)
|
||||
+ ip;
|
||||
isIPV4 = lib.length splitEndpoint < 3;
|
||||
ipFlag = if isIPV4 then "-4" else "-6";
|
||||
endpointIP = (if isIPV4
|
||||
ipFlag =
|
||||
if isIPV4
|
||||
then "-4"
|
||||
else "-6";
|
||||
endpointIP = (
|
||||
if isIPV4
|
||||
then lib.elemAt splitEndpoint 0
|
||||
else lib.lists.fold joinIPV6 "" ((lib.lists.take ((lib.length splitEndpoint) - 1)) splitEndpoint)
|
||||
);
|
||||
|
@ -87,24 +97,36 @@ in {
|
|||
listenPort = 51820;
|
||||
ips = cfg.ownIPs;
|
||||
privateKeyFile = cfg.privateKeyFile;
|
||||
postSetup = ''
|
||||
defaultRoute=$(${pkgs.iproute2}/bin/ip ${ipFlag} r | ${pkgs.gnugrep}/bin/grep "default via" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $3 " " $4 " " $5 }')
|
||||
${pkgs.iproute2}/bin/ip ${ipFlag} route add "${endpointIPStripped}${if isIPV4 then "/32" else "/128"}" metric 256 via $defaultRoute
|
||||
ip -4 route delete default dev wg-tunnel || true
|
||||
ip -4 route add default dev wg-tunnel metric 512
|
||||
ip -6 route delete default dev wg-tunnel || true
|
||||
ip -6 route add default dev wg-tunnel metric 512
|
||||
'' + (if cfg.useDNS
|
||||
then ''printf "nameserver 10.64.0.1" | resolvconf -a wg-tunnel -m 0 -x''
|
||||
else "");
|
||||
postShutdown = ''
|
||||
addedRoute=$(${pkgs.iproute2}/bin/ip ${ipFlag} r | ${pkgs.gnugrep}/bin/grep "${endpointIPStripped}" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $1 " " $2 " " $3 " " $4 " " $5 }')
|
||||
if [ -n "$addedRoute" ]; then
|
||||
${pkgs.iproute2}/bin/ip ${ipFlag} route delete $addedRoute
|
||||
fi
|
||||
'' + (if cfg.useDNS
|
||||
then ''resolvconf -d wg-tunnel -f''
|
||||
else "");
|
||||
postSetup =
|
||||
''
|
||||
defaultRoute=$(${pkgs.iproute2}/bin/ip ${ipFlag} r | ${pkgs.gnugrep}/bin/grep "default via" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $3 " " $4 " " $5 }')
|
||||
${pkgs.iproute2}/bin/ip ${ipFlag} route add "${endpointIPStripped}${
|
||||
if isIPV4
|
||||
then "/32"
|
||||
else "/128"
|
||||
}" metric 256 via $defaultRoute
|
||||
ip -4 route delete default dev wg-tunnel || true
|
||||
ip -4 route add default dev wg-tunnel metric 512
|
||||
ip -6 route delete default dev wg-tunnel || true
|
||||
ip -6 route add default dev wg-tunnel metric 512
|
||||
''
|
||||
+ (
|
||||
if cfg.useDNS
|
||||
then ''printf "nameserver 10.64.0.1" | resolvconf -a wg-tunnel -m 0 -x''
|
||||
else ""
|
||||
);
|
||||
postShutdown =
|
||||
''
|
||||
addedRoute=$(${pkgs.iproute2}/bin/ip ${ipFlag} r | ${pkgs.gnugrep}/bin/grep "${endpointIPStripped}" | head -n 1 | ${pkgs.gawk}/bin/awk '{ print $1 " " $2 " " $3 " " $4 " " $5 }')
|
||||
if [ -n "$addedRoute" ]; then
|
||||
${pkgs.iproute2}/bin/ip ${ipFlag} route delete $addedRoute
|
||||
fi
|
||||
''
|
||||
+ (
|
||||
if cfg.useDNS
|
||||
then ''resolvconf -d wg-tunnel -f''
|
||||
else ""
|
||||
);
|
||||
peers = [
|
||||
{
|
||||
publicKey = cfg.peer.publicKey;
|
||||
|
|
|
@ -12,6 +12,6 @@ in {
|
|||
users.users."${psCfg.user.name}" = {
|
||||
extraGroups = ["wireshark"];
|
||||
|
||||
packages = [ pkgs.wireshark ];
|
||||
packages = [pkgs.wireshark];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
}: {
|
||||
flake = {
|
||||
nixosModules = rec {
|
||||
overlays = ({ ... }: {
|
||||
overlays = {...}: {
|
||||
nixpkgs.overlays = [
|
||||
inputs.deno2nix.overlays.default
|
||||
inputs.nixd.overlays.default
|
||||
inputs.invoiceplane-template.overlays.default
|
||||
|
||||
(final: prev: let
|
||||
unstable = import inputs.nixpkgs-unstable { system = prev.system; };
|
||||
master = import inputs.nixpkgs-master { system = prev.system; };
|
||||
authelia-438 = import inputs.authelia-438 { system = prev.system; };
|
||||
unstable = import inputs.nixpkgs-unstable {system = prev.system;};
|
||||
master = import inputs.nixpkgs-master {system = prev.system;};
|
||||
authelia-438 = import inputs.authelia-438 {system = prev.system;};
|
||||
in {
|
||||
factorio-headless = master.factorio-headless;
|
||||
paperless-ngx = unstable.paperless-ngx;
|
||||
|
@ -59,7 +59,7 @@
|
|||
};
|
||||
})
|
||||
];
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
final: prev: {
|
||||
element-desktop = prev.element-desktop.override { electron = prev.electron_28; };
|
||||
element-desktop = prev.element-desktop.override {electron = prev.electron_28;};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
# This file was generated by nvfetcher, please do not modify it manually.
|
||||
{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
|
||||
{
|
||||
fetchgit,
|
||||
fetchurl,
|
||||
fetchFromGitHub,
|
||||
dockerTools,
|
||||
}: {
|
||||
b12f-io-nvfetcher = {
|
||||
pname = "b12f-io-nvfetcher";
|
||||
version = "38adb94ce69d8807ea2e36f57abe08091192b31c";
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
self:
|
||||
with self; ''
|
||||
status=$(cat /sys/class/power_supply/BAT0/status)
|
||||
if [ $status != "Discharging" ]; then
|
||||
exit 0
|
||||
fi
|
||||
status=$(cat /sys/class/power_supply/BAT0/status)
|
||||
if [ $status != "Discharging" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
capacity=$(cat /sys/class/power_supply/BAT0/capacity)
|
||||
if [ $capacity -lt 20 ]; then
|
||||
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus
|
||||
${libnotify}/bin/notify-send -u critical "Battery ''${capacity}%"
|
||||
fi
|
||||
capacity=$(cat /sys/class/power_supply/BAT0/capacity)
|
||||
if [ $capacity -lt 20 ]; then
|
||||
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus
|
||||
${libnotify}/bin/notify-send -u critical "Battery ''${capacity}%"
|
||||
fi
|
||||
''
|
||||
|
|
|
@ -5,8 +5,14 @@ with prev; {
|
|||
# then, call packages with `final.callPackage`
|
||||
check-battery = writeShellScriptBin "check-battery" (import ./check-battery.nix final);
|
||||
concourse = import ./concourse.nix final;
|
||||
element-b12f = writeShellScriptBin "element-b12f" (import ./element-desktop.nix { inherit final; profile = "b12f"; });
|
||||
element-mezza = writeShellScriptBin "element-mezza" (import ./element-desktop.nix { inherit final; profile = "mezza"; });
|
||||
element-b12f = writeShellScriptBin "element-b12f" (import ./element-desktop.nix {
|
||||
inherit final;
|
||||
profile = "b12f";
|
||||
});
|
||||
element-mezza = writeShellScriptBin "element-mezza" (import ./element-desktop.nix {
|
||||
inherit final;
|
||||
profile = "mezza";
|
||||
});
|
||||
fetch-hostingde-invoices = import ./fetch-hostingde-invoices final;
|
||||
import-gtk-settings = writeShellScriptBin "import-gtk-settings" (import ./import-gtk-settings.nix final);
|
||||
lgcl = writeShellScriptBin "lgcl" (import ./lgcl.nix final);
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
{ final, profile }:
|
||||
{
|
||||
final,
|
||||
profile,
|
||||
}:
|
||||
with final; ''
|
||||
${element-desktop}/bin/element-desktop --profile=${profile}
|
||||
${element-desktop}/bin/element-desktop --profile=${profile}
|
||||
''
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
self: self.deno2nix.mkExecutable {
|
||||
self:
|
||||
self.deno2nix.mkExecutable {
|
||||
pname = "fetch-hostingde-invoices";
|
||||
version = "0.1.0";
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{ lib, ... }:
|
||||
{
|
||||
{lib, ...}: {
|
||||
flake = {
|
||||
publicKeys = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCmXpOU6vzQiVSSYCoxHYv7wDxC63Qg3dxlAMR6AOzwIABCU5PFFNcO0NWYms/YR7MOViorl+19LCLRABar9JgHU1n+uqxKV6eGph3OPeMp5sN8LAh7C9N+TZj8iJzBxQ3ch+Z/LdmLRwYNJ7KSUI+gwGK6xRS3+z1022Y4P0G0sx7IeCBl4lealQEIIF10ZOfjUdBcLQar7XTc5AxyGKnHCerXHRtccCoadLQujk0AvPXbv3Ma4JwX9X++AnCWRWakqS5UInu2tGuZ/6Hrjd2a9AKWjTaBVDcbYqCvY4XVuMj2/A2bCceFBaoi41apybSk26FSFTU4qiEUNQ6lxeOwG4+1NCXyHe2bGI4VyoxinDYa8vLLzXIRfTRA0qoGfCweXNeWPf0jMqASkUKaSOH5Ot7O5ps34r0j9pWzavDid8QeKJPyhxKuF1a5G4iBEZ0O9vuti60dPSjJPci9oTxbune2/jb7Sa0yO06DtLFJ2ncr5f70s/BDxKk4XIwQLy+KsvzlQEGdY8yA6xv28bOGxL3sQ0HE2pDTsvIbAisVOKzdJeolStL9MM5W8Hg0r/KkGj2bg0TfoRp1xHV9hjKkvJrsQ6okaPvNFeZq0HXzPhWMOVQ+/46z80uaQ1ByRLr3FTwuWJ7F/73ndfxiq6bDE4z2Ji0vOjeWJm6HCxTdGw== id_bbcom"
|
||||
|
|
|
@ -12,59 +12,71 @@ with lib; let
|
|||
cacheHome = xdg.cacheHome;
|
||||
maildirBasePath = "/home/${psCfg.user.name}/Mail";
|
||||
|
||||
generateMailAccount = args@{ address, ... }: rec {
|
||||
inherit address;
|
||||
realName = if (args ? "fullName") then args.fullName else psCfg.user.fullName;
|
||||
signature = {
|
||||
showSignature = "append";
|
||||
text = if (args ? "emptysignature") then "" else builtins.readFile (./.config/neomutt + "/${builtins.replaceStrings ["@"] ["_"] address}.signature");
|
||||
};
|
||||
generateMailAccount = args @ {address, ...}:
|
||||
rec {
|
||||
inherit address;
|
||||
realName =
|
||||
if (args ? "fullName")
|
||||
then args.fullName
|
||||
else psCfg.user.fullName;
|
||||
signature = {
|
||||
showSignature = "append";
|
||||
text =
|
||||
if (args ? "emptysignature")
|
||||
then ""
|
||||
else builtins.readFile (./.config/neomutt + "/${builtins.replaceStrings ["@"] ["_"] address}.signature");
|
||||
};
|
||||
|
||||
folders = {
|
||||
inbox = "INBOX";
|
||||
drafts = "Drafts";
|
||||
sent = "Sent";
|
||||
trash = "Trash";
|
||||
};
|
||||
folders = {
|
||||
inbox = "INBOX";
|
||||
drafts = "Drafts";
|
||||
sent = "Sent";
|
||||
trash = "Trash";
|
||||
};
|
||||
|
||||
gpg.key = psCfg.user.gpgKeyId;
|
||||
gpg.key = psCfg.user.gpgKeyId;
|
||||
|
||||
userName = address;
|
||||
passwordCommand = "secret-tool lookup email ${address}";
|
||||
imap = {
|
||||
host = mkIf (args ? "host") args.host;
|
||||
port = 993;
|
||||
};
|
||||
smtp = {
|
||||
host = mkIf (args ? "host") args.host;
|
||||
port = 587;
|
||||
tls.useStartTls = true;
|
||||
};
|
||||
userName = address;
|
||||
passwordCommand = "secret-tool lookup email ${address}";
|
||||
imap = {
|
||||
host = mkIf (args ? "host") args.host;
|
||||
port = 993;
|
||||
};
|
||||
smtp = {
|
||||
host = mkIf (args ? "host") args.host;
|
||||
port = 587;
|
||||
tls.useStartTls = true;
|
||||
};
|
||||
|
||||
offlineimap.enable = true;
|
||||
imapnotify = {
|
||||
enable = true;
|
||||
boxes = [ "INBOX" ];
|
||||
onNotify = "${pkgs.offlineimap}/bin/offlineimap -a ${address}";
|
||||
onNotifyPost = "${pkgs.libnotify}/bin/notify-send '${address} has new mail'";
|
||||
};
|
||||
msmtp.enable = true;
|
||||
neomutt = {
|
||||
enable = true;
|
||||
sendMailCommand = "msmtp -a ${address}";
|
||||
extraConfig = ''
|
||||
set pgp_default_key="${gpg.key}"
|
||||
offlineimap.enable = true;
|
||||
imapnotify = {
|
||||
enable = true;
|
||||
boxes = ["INBOX"];
|
||||
onNotify = "${pkgs.offlineimap}/bin/offlineimap -a ${address}";
|
||||
onNotifyPost = "${pkgs.libnotify}/bin/notify-send '${address} has new mail'";
|
||||
};
|
||||
msmtp.enable = true;
|
||||
neomutt = {
|
||||
enable = true;
|
||||
sendMailCommand = "msmtp -a ${address}";
|
||||
extraConfig = ''
|
||||
set pgp_default_key="${gpg.key}"
|
||||
|
||||
unmailboxes *
|
||||
unmailboxes *
|
||||
|
||||
mailboxes +INBOX \
|
||||
+Drafts \
|
||||
+Sent \
|
||||
+Archive \
|
||||
+Trash
|
||||
'';
|
||||
};
|
||||
} // (if args ? "config" then args.config else {});
|
||||
mailboxes +INBOX \
|
||||
+Drafts \
|
||||
+Sent \
|
||||
+Archive \
|
||||
+Trash
|
||||
'';
|
||||
};
|
||||
}
|
||||
// (
|
||||
if args ? "config"
|
||||
then args.config
|
||||
else {}
|
||||
);
|
||||
in {
|
||||
users.users."${psCfg.user.name}".packages = with pkgs; [
|
||||
w3m
|
||||
|
@ -86,65 +98,66 @@ in {
|
|||
accounts.email = {
|
||||
inherit maildirBasePath;
|
||||
|
||||
accounts = with flake.self.lib; lib.lists.foldr (item: set: (set // { "${item.address}" = generateMailAccount item; })) {} [
|
||||
{
|
||||
address = mkEmailAddress "hello" "benjaminbaedorf.eu";
|
||||
host = "mail.hosting.de";
|
||||
config.primary = true;
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "mail" "b12f.io";
|
||||
host = "mail.b12f.io";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "benjamin.baedorf" "rwth-aachen.de";
|
||||
host = "mail.rwth-aachen.de";
|
||||
config.userName = mkEmailAddress "bb564306" "rwth-aachen.de";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "byb" "miom.space";
|
||||
host = "mail.hosting.de";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "contact" "miom.space";
|
||||
host = "mail.hosting.de";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "admins" "pub.solar";
|
||||
host = "mail.pub.solar";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "crew" "pub.solar";
|
||||
host = "mail.pub.solar";
|
||||
}
|
||||
# {
|
||||
# address = mkEmailAddress "benjamin.yule.baedorf" "verkstedt.com";
|
||||
# flavor = "gmail";
|
||||
# config = {
|
||||
# smtp.host = "smtp.gmail.com";
|
||||
# imap.host = "imap.gmail.com";
|
||||
# };
|
||||
# }
|
||||
{
|
||||
address = mkEmailAddress "benjamin-yule.baedorf" "ext.ehealthexperts.de";
|
||||
config = {
|
||||
smtp.host = "smtp.mailbox.org";
|
||||
imap.host = "imap.mailbox.org";
|
||||
};
|
||||
}
|
||||
{
|
||||
fullName = "mezza";
|
||||
address = mkEmailAddress "mail" "mezza.biz";
|
||||
host = "mail.mezza.biz";
|
||||
emptysignature = true;
|
||||
}
|
||||
{
|
||||
fullname = "hwd"+ "zz";
|
||||
address = mkEmailAddress "mail" "h" + "w" + "dz" + "z.net";
|
||||
host = "mail.h" + "w" + "dz" + "z.net";
|
||||
emptysignature = true;
|
||||
}
|
||||
];
|
||||
accounts = with flake.self.lib;
|
||||
lib.lists.foldr (item: set: (set // {"${item.address}" = generateMailAccount item;})) {} [
|
||||
{
|
||||
address = mkEmailAddress "hello" "benjaminbaedorf.eu";
|
||||
host = "mail.hosting.de";
|
||||
config.primary = true;
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "mail" "b12f.io";
|
||||
host = "mail.b12f.io";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "benjamin.baedorf" "rwth-aachen.de";
|
||||
host = "mail.rwth-aachen.de";
|
||||
config.userName = mkEmailAddress "bb564306" "rwth-aachen.de";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "byb" "miom.space";
|
||||
host = "mail.hosting.de";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "contact" "miom.space";
|
||||
host = "mail.hosting.de";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "admins" "pub.solar";
|
||||
host = "mail.pub.solar";
|
||||
}
|
||||
{
|
||||
address = mkEmailAddress "crew" "pub.solar";
|
||||
host = "mail.pub.solar";
|
||||
}
|
||||
# {
|
||||
# address = mkEmailAddress "benjamin.yule.baedorf" "verkstedt.com";
|
||||
# flavor = "gmail";
|
||||
# config = {
|
||||
# smtp.host = "smtp.gmail.com";
|
||||
# imap.host = "imap.gmail.com";
|
||||
# };
|
||||
# }
|
||||
{
|
||||
address = mkEmailAddress "benjamin-yule.baedorf" "ext.ehealthexperts.de";
|
||||
config = {
|
||||
smtp.host = "smtp.mailbox.org";
|
||||
imap.host = "imap.mailbox.org";
|
||||
};
|
||||
}
|
||||
{
|
||||
fullName = "mezza";
|
||||
address = mkEmailAddress "mail" "mezza.biz";
|
||||
host = "mail.mezza.biz";
|
||||
emptysignature = true;
|
||||
}
|
||||
{
|
||||
fullname = "hwd" + "zz";
|
||||
address = mkEmailAddress "mail" "h" + "w" + "dz" + "z.net";
|
||||
host = "mail.h" + "w" + "dz" + "z.net";
|
||||
emptysignature = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.imapnotify.enable = true;
|
||||
|
@ -154,69 +167,167 @@ in {
|
|||
enable = true;
|
||||
binds = [
|
||||
# Moving around
|
||||
{ map = ["generic"]; key = "g"; action = "noop"; }
|
||||
{ map = ["generic"]; key = "gg"; action = "first-entry"; }
|
||||
{ map = ["generic" "index"]; key = "G"; action = "last-entry"; }
|
||||
{ map = ["generic" "index"]; key = "i"; action = "previous-entry"; }
|
||||
{ map = ["generic" "index"]; key = "k"; action = "next-entry"; }
|
||||
{ map = ["pager" "index"]; key = "d"; action = "noop"; }
|
||||
{ map = ["pager" "index"]; key = "dd"; action = "delete-message"; }
|
||||
{ map = ["pager"]; key = "i"; action = "previous-line"; }
|
||||
{ map = ["pager"]; key = "k"; action = "next-line"; }
|
||||
{ map = ["pager"]; key = "I"; action = "previous-entry"; }
|
||||
{ map = ["pager"]; key = "K"; action = "next-entry"; }
|
||||
{
|
||||
map = ["generic"];
|
||||
key = "g";
|
||||
action = "noop";
|
||||
}
|
||||
{
|
||||
map = ["generic"];
|
||||
key = "gg";
|
||||
action = "first-entry";
|
||||
}
|
||||
{
|
||||
map = ["generic" "index"];
|
||||
key = "G";
|
||||
action = "last-entry";
|
||||
}
|
||||
{
|
||||
map = ["generic" "index"];
|
||||
key = "i";
|
||||
action = "previous-entry";
|
||||
}
|
||||
{
|
||||
map = ["generic" "index"];
|
||||
key = "k";
|
||||
action = "next-entry";
|
||||
}
|
||||
{
|
||||
map = ["pager" "index"];
|
||||
key = "d";
|
||||
action = "noop";
|
||||
}
|
||||
{
|
||||
map = ["pager" "index"];
|
||||
key = "dd";
|
||||
action = "delete-message";
|
||||
}
|
||||
{
|
||||
map = ["pager"];
|
||||
key = "i";
|
||||
action = "previous-line";
|
||||
}
|
||||
{
|
||||
map = ["pager"];
|
||||
key = "k";
|
||||
action = "next-line";
|
||||
}
|
||||
{
|
||||
map = ["pager"];
|
||||
key = "I";
|
||||
action = "previous-entry";
|
||||
}
|
||||
{
|
||||
map = ["pager"];
|
||||
key = "K";
|
||||
action = "next-entry";
|
||||
}
|
||||
|
||||
{ map = ["pager"]; key = "r"; action = "noop"; }
|
||||
{ map = ["pager"]; key = "rr"; action = "reply"; }
|
||||
{ map = ["pager"]; key = "ra"; action = "group-reply"; }
|
||||
{ map = ["pager"]; key = "rn"; action = "group-chat-reply"; }
|
||||
{ map = ["pager"]; key = "rl"; action = "list-reply"; }
|
||||
{
|
||||
map = ["pager"];
|
||||
key = "r";
|
||||
action = "noop";
|
||||
}
|
||||
{
|
||||
map = ["pager"];
|
||||
key = "rr";
|
||||
action = "reply";
|
||||
}
|
||||
{
|
||||
map = ["pager"];
|
||||
key = "ra";
|
||||
action = "group-reply";
|
||||
}
|
||||
{
|
||||
map = ["pager"];
|
||||
key = "rn";
|
||||
action = "group-chat-reply";
|
||||
}
|
||||
{
|
||||
map = ["pager"];
|
||||
key = "rl";
|
||||
action = "list-reply";
|
||||
}
|
||||
|
||||
# Threads
|
||||
{ map = ["browser" "pager" "index"]; key = "N"; action = "search-opposite"; }
|
||||
{ map = ["pager" "index"]; key = "dT"; action = "delete-thread"; }
|
||||
{ map = ["pager" "index"]; key = "dt"; action = "delete-subthread"; }
|
||||
{ map = ["pager" "index"]; key = "g"; action = "noop"; }
|
||||
{ map = ["pager" "index"]; key = "gt"; action = "next-thread"; }
|
||||
{ map = ["pager" "index"]; key = "gT"; action = "previous-thread"; }
|
||||
{ map = ["index"]; key = "za"; action = "collapse-thread"; }
|
||||
{ map = ["index"]; key = "zA"; action = "collapse-all"; }
|
||||
];
|
||||
|
||||
macros = [
|
||||
# Enable URL opening
|
||||
{
|
||||
map = ["index" "pager"];
|
||||
key = "\\Cb";
|
||||
action = ''<pipe-message> ${pkgs.urlscan}/bin/urlscan<Enter>" "call urlscan to extract URLs out of a message'';
|
||||
map = ["browser" "pager" "index"];
|
||||
key = "N";
|
||||
action = "search-opposite";
|
||||
}
|
||||
{
|
||||
map = ["attach" "compose"];
|
||||
key = "\\Cb";
|
||||
action = ''<pipe-entry> ${pkgs.urlscan}/bin/urlscan<Enter>" "call urlscan to extract URLs out of a message'';
|
||||
map = ["pager" "index"];
|
||||
key = "dT";
|
||||
action = "delete-thread";
|
||||
}
|
||||
# Translate markdown to html
|
||||
{
|
||||
map = ["compose"];
|
||||
key = "\\Cm";
|
||||
action = ''F ${pkgs.pandoc}/bin/pandoc -s -f markdown -t html \ny^T^Utext/html; charset=utf-8\n" "Convert to HTML'';
|
||||
map = ["pager" "index"];
|
||||
key = "dt";
|
||||
action = "delete-subthread";
|
||||
}
|
||||
# Save to ~/Downloads by default
|
||||
{
|
||||
map = ["attach"];
|
||||
key = "S";
|
||||
action = ''<save-entry><bol>~/Downloads/<eol>" "Save to Downloads'';
|
||||
map = ["pager" "index"];
|
||||
key = "g";
|
||||
action = "noop";
|
||||
}
|
||||
{
|
||||
map = ["pager" "index"];
|
||||
key = "gt";
|
||||
action = "next-thread";
|
||||
}
|
||||
{
|
||||
map = ["pager" "index"];
|
||||
key = "gT";
|
||||
action = "previous-thread";
|
||||
}
|
||||
{
|
||||
map = ["index"];
|
||||
key = "\\Ca";
|
||||
action = ''<tag-pattern>~N<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "Mark all as read'';
|
||||
key = "za";
|
||||
action = "collapse-thread";
|
||||
}
|
||||
] ++ lib.lists.imap1 (i: address: {
|
||||
map = ["index" "pager"];
|
||||
key = "<F${builtins.toString i}>";
|
||||
action = ''<sync-mailbox><enter-command>source ${configHome}/neomutt/${address}<enter><change-folder>!<enter>'';
|
||||
}) (builtins.attrNames accounts.email.accounts);
|
||||
{
|
||||
map = ["index"];
|
||||
key = "zA";
|
||||
action = "collapse-all";
|
||||
}
|
||||
];
|
||||
|
||||
macros =
|
||||
[
|
||||
# Enable URL opening
|
||||
{
|
||||
map = ["index" "pager"];
|
||||
key = "\\Cb";
|
||||
action = ''<pipe-message> ${pkgs.urlscan}/bin/urlscan<Enter>" "call urlscan to extract URLs out of a message'';
|
||||
}
|
||||
{
|
||||
map = ["attach" "compose"];
|
||||
key = "\\Cb";
|
||||
action = ''<pipe-entry> ${pkgs.urlscan}/bin/urlscan<Enter>" "call urlscan to extract URLs out of a message'';
|
||||
}
|
||||
# Translate markdown to html
|
||||
{
|
||||
map = ["compose"];
|
||||
key = "\\Cm";
|
||||
action = ''F ${pkgs.pandoc}/bin/pandoc -s -f markdown -t html \ny^T^Utext/html; charset=utf-8\n" "Convert to HTML'';
|
||||
}
|
||||
# Save to ~/Downloads by default
|
||||
{
|
||||
map = ["attach"];
|
||||
key = "S";
|
||||
action = ''<save-entry><bol>~/Downloads/<eol>" "Save to Downloads'';
|
||||
}
|
||||
{
|
||||
map = ["index"];
|
||||
key = "\\Ca";
|
||||
action = ''<tag-pattern>~N<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "Mark all as read'';
|
||||
}
|
||||
]
|
||||
++ lib.lists.imap1 (i: address: {
|
||||
map = ["index" "pager"];
|
||||
key = "<F${builtins.toString i}>";
|
||||
action = ''<sync-mailbox><enter-command>source ${configHome}/neomutt/${address}<enter><change-folder>!<enter>'';
|
||||
}) (builtins.attrNames accounts.email.accounts);
|
||||
|
||||
# unmailboxes = true;
|
||||
extraConfig = ''
|
||||
|
@ -234,7 +345,7 @@ in {
|
|||
imap_check_subscribed = "yes";
|
||||
date_format = ''"!%d.%m.%Y %H:%M"'';
|
||||
index_format = ''"%4C %Z %D %4c %20.20L %s"'';
|
||||
mailcap_path = "${configHome}/neomutt/mailcap";
|
||||
mailcap_path = "${configHome}/neomutt/mailcap";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -251,7 +362,7 @@ in {
|
|||
|
||||
services.restic.backups = {
|
||||
email = {
|
||||
paths = [ maildirBasePath ];
|
||||
paths = [maildirBasePath];
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-password".path;
|
||||
# See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{ self, ... }:
|
||||
{
|
||||
{self, ...}: {
|
||||
flake = {
|
||||
nixosModules = rec {
|
||||
root = import ./root;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
{...}:
|
||||
{
|
||||
{...}: {
|
||||
users.users.root.hashedPassword = "$y$j9T$HihsChALx5fotahvDVhdC/$iQCGUr35quGDDEFg0SGjDBxWzU/kokgOVDX.weRvL80";
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue