This is a fork! What comes below was only partially written by myself and it is super awesome. I followed this blog post to adapt the config-repo to my needs: https://gist.github.com/domenkozar/b3c945035af53fa816e0ac460f1df853
There are still a lot of manual steps involved:
- install basic nixos (see gist above)
- add flakes support, change to desired hostname, add moritz user
- install this nixos-config (pull moritzschaefer/nixos-config, run nixos-rebuild switch)
- Install spacemacs (clone git-spacemacs into ~/.emacs.d as described in the installation instructions of spacemacs README)
- connect syncthing
- sync wiki and .ssh keys (possibly via usb stick, what else?)
- get encrypted private key from secrets: https://snow-dev.com/posts/setup-pass-on-multiple-devices.html
- clone my passwords repo to have my pass-logins, transfer gpg-keys (https://www.hjdskes.nl/blog/pass/)
- clone my dotfiles and link them using homesick
—
Hi there! That’s my dotfiles. Most of config files are now generated by org-babel fromonfig files just in case I won’t have access to my Emacs. However, I recommend against looking at them—they’re just a generated mess; you’ll have much better time reading this doc instead—trust me.
Pieces not (yet) covered in this document are:
- emacs configuration at
.emacs.d/
; - vim configuration at
.vimrc
and.vim/
; - awesome wm configuration at
.config/awesome/
; - scripts at
bin/
; - irssi config at
.irssi
;
I’m a NixOS user. What’s cool about it is that I can describe all my system configuration in one file (almost). I can execute a single command and have a system with the same software, system settings, etc.
An outline of configuration looks like this:
{ name, config, pkgs, lib, inputs, ... }:
let
machine-config = lib.getAttr name {
moxps = [
<<machine-moxps>>
];
mobook = [
<<machine-mobook>>
];
mopad = [
<<machine-mopad>>
];
moair = [
<<machine-moair>>
];
};
# nur-no-pkgs = import (builtins.fetchTarball {
# url = "https://github.com/nix-community/NUR/archive/master.tar.gz";
# sha256 = "10dq8abmw30lrpwfg7yb1zn6fb5d2q94yhsvg6dwcknn46nilbxs";
# }) {
# nurpkgs = pkgs;
# inherit pkgs;
# repoOverrides = {
# moritzschaefer = import /home/moritz/Projects/nur-packages;
# };
# };
in
{
# disabledModules = [ "services/printing/cupsd.nix" ];
imports = [
# (import "${inputs.nixpkgs-local}/nixos/modules/services/printing/cupsd.nix")
{
}
<<nixos-section>>
] ++ machine-config;
}
This <<nixos-section>>
is replaced by other parts of this doc.
Enable experimental Flakes support.
{
nix = {
package = pkgs.nixVersions.stable;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
}
Make this repository flake-compatible:
{
description = "Moritz's NixOS";
# edition = 201909;
inputs = {
nixpkgs = {
type = "github";
owner = "NixOS";
repo = "nixpkgs";
ref = "nixos-24.11";
};
nixpkgs-unstable = {
type = "github";
owner = "NixOS";
repo = "nixpkgs";
ref = "master";
};
nixpkgs-moritz = {
type = "github";
# owner = "rasendubi";
# repo = "nixpkgs";
# ref = "melpa-2020-04-27";
owner = "moritzschaefer";
# repo = "nixpkgs-channels";
repo = "nixpkgs";
# rev = "246294708d4b4d0f7a9b63fb3b6866860ed78704";
# ref = "nixpkgs-unstable";
ref = "fix-libnvidia-container";
};
# nixpkgs-local = {
# url = "/home/moritz/Projects/nixpkgs/";
# };
nixos-hardware = {
type = "github";
owner = "NixOS";
repo = "nixos-hardware";
};
nur = {
url = github:nix-community/NUR;
};
agenix.url = "github:ryantm/agenix";
apple-silicon = {
url = "github:tpwrules/nixos-apple-silicon";
# this line prevents fetching two versions of nixpkgs:
inputs.nixpkgs.follows = "nixpkgs";
};
};
# nixpkgs-local
outputs = { self, nixpkgs, nixpkgs-moritz, nixpkgs-unstable, nixos-hardware, nur, agenix, apple-silicon }@inputs:
let
system-wrapper = name: if name == "moair" then "aarch64-linux" else "x86_64-linux";
pkgs-wrapper = name: import nixpkgs {
system = system-wrapper name;
overlays = self.overlays;
config = { allowUnfree = true;
allowBroken = true;
nvidia.acceptLicense = true;
permittedInsecurePackages = [
"adobe-reader-9.5.5"
"python3.11-youtube-dl-2021.12.17"
"qtwebkit-5.212.0-alpha4"
"openjdk-18+36"
"python-2.7.18.6"
];
};
};
in {
nixosConfigurations =
let
hosts = ["moxps" "mobook" "mopad" "moair"];
mkHost = name:
nixpkgs.lib.nixosSystem {
system = system-wrapper name;
modules = [
{ nixpkgs = { pkgs = (pkgs-wrapper name); }; }
(import ./nixos-config.nix)
{ nixpkgs.overlays = [ nur.overlay ]; }
agenix.nixosModules.default
{
environment.systemPackages = [ agenix.packages.${system-wrapper name}.default ];
age.identityPaths = [ "/home/moritz/.ssh/id_ed25519_agenix" ];
}
];
specialArgs = { inherit name inputs; };
};
in nixpkgs.lib.genAttrs hosts mkHost;
# redundant
packages.x86_64-linux =
let
mergePackages = nixpkgs.lib.foldr nixpkgs.lib.mergeAttrs {};
in
mergePackages [
<<flake-packages>>
];
# redundant
packages.aarch64-linux =
let
mergePackages = nixpkgs.lib.foldr nixpkgs.lib.mergeAttrs {};
in
mergePackages [
<<flake-packages>>
];
overlays = [
# (_self: _super: builtins.getAttr _super.system self.packages) # this led to "infinite recursion" but it was actually not needed (weird!)
<<flake-overlays>>
];
# in nixpkgs.lib.genAttrs hosts mkHost;
};
}
(final: prev: {
unstable = import inputs.nixpkgs-unstable {
system = prev.system;
overlays = self.overlays; # .${system};
config = { allowUnfree = true; allowBroken = true; nvidia.acceptLicense = true; };
};
# mkNvidiaContainerPkg = { name, containerRuntimePath, configTemplate, additionalPaths ? [] }:
# let
# nvidia-container-runtime = pkgs.callPackage "${inputs.nixpkgs}/pkgs/applications/virtualization/nvidia-container-runtime" {
# inherit containerRuntimePath configTemplate;
# };
# in pkgs.symlinkJoin {
# inherit name;
# paths = [
# # (callPackage ../applications/virtualization/libnvidia-container { })
# (pkgs.callPackage "${inputs.nixpkgs-moritz}/pkgs/applications/virtualization/libnvidia-container" { inherit (pkgs.linuxPackages) nvidia_x11; })
# nvidia-container-runtime
# (pkgs.callPackage "${inputs.nixpkgs}/pkgs/applications/virtualization/nvidia-container-toolkit" {
# inherit nvidia-container-runtime;
# })
# ] ++ additionalPaths;
# };
# nvidia-docker = pkgs.mkNvidiaContainerPkg {
# name = "nvidia-docker";
# containerRuntimePath = "${pkgs.docker}/libexec/docker/runc";
# # configTemplate = "${inputs.nixpkgs}/pkgs/applications/virtualization/nvidia-docker/config.toml";
# configTemplate = builtins.toFile "config.toml" ''
# disable-require = false
# #swarm-resource = "DOCKER_RESOURCE_GPU"
# [nvidia-container-cli]
# #root = "/run/nvidia/driver"
# #path = "/usr/bin/nvidia-container-cli"
# environment = []
# debug = "/var/log/nvidia-container-runtime-hook.log"
# ldcache = "/tmp/ld.so.cache"
# load-kmods = true
# #no-cgroups = false
# #user = "root:video"
# ldconfig = "@@glibcbin@/bin/ldconfig"
# '';
# additionalPaths = [ (pkgs.callPackage "${inputs.nixpkgs}/pkgs/applications/virtualization/nvidia-docker" { }) ];
# };
# mesa-pin = import inputs.mesa-pin {
# inherit system;
# overlays = self.overlays; # .${system};
# config = { allowUnfree = true; };
# };
})
{
environment.systemPackages = [ pkgs.nixos-option ];
}
{
nix = {
settings = {
substituters = [
"https://nix-community.cachix.org"
"https://cache.nixos.org/"
];
trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
};
}
{
nix.nixPath = [
"nixpkgs=${inputs.nixpkgs}"
];
}
I’m the only user of the system:
{
users.users.moritz = {
isNormalUser = true;
uid = 1000;
extraGroups = [ "users" "wheel" "input" ];
initialPassword = "HelloWorld";
};
}
initialPassword
is used only first time when user is created. It must be changed as soon as possible with passwd
.
I currently have only one machine.
This is my Dell XPS 15. Only use Intel OR Nvidia
{
imports = [
(import "${inputs.nixos-hardware}/common/cpu/intel")
(import "${inputs.nixos-hardware}/common/cpu/intel/kaby-lake")
(import "${inputs.nixos-hardware}/common/pc/laptop") # tlp.enable = true
(import "${inputs.nixos-hardware}/common/pc/laptop/acpi_call.nix") # tlp.enable = true
(import "${inputs.nixos-hardware}/common/pc/laptop/ssd")
inputs.nixpkgs.nixosModules.notDetected
];
# from nixos-hardware
boot.loader.systemd-boot.enable = true;
boot.loader.systemd-boot.configurationLimit = 10;
boot.loader.efi.canTouchEfiVariables = false; # disabled after a boot or two to prevent usage on that kind of ram
services.thermald.enable = true;
# from initial config and other webresources
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.kernelModules = [ "kvm-intel" ];
boot.kernelParams = [ "acpi_rev_override=5" "i915.enable_guc=2" "pcie_aspm=off" ]; # "nouveau.modeset=0" ]; # 5,6,1 doesn't seem to make a difference. pcie_aspm=off might be required to avoid freezes
# OpenGL accelerateion
# nixpkgs.config.packageOverrides = pkgs: {
# vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
# };
# hardware.opengl = {
# enable = true;
# driSupport = true;
# extraPackages = with pkgs; [
# intel-media-driver # LIBVA_DRIVER_NAME=iHD <- works for VLC
# vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
# vaapiVdpau
# libvdpau-va-gl
# ];
# };
nix.settings.max-jobs = lib.mkDefault 8;
services.undervolt = {
enable = false; # disabled because it doesn't work anymore after BIOS upgrade
# coreOffset = 0;
# gpuOffset = 0;
coreOffset = -125;
gpuOffset = -75;
};
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
powerManagement.enable = true;
# The NixOS release to be compatible with for stateful data such as databases.
system.stateVersion = "24.05";
}
{
system.nixos.tags = [ "with-intel" ];
services.xserver.videoDrivers = [ "intel" ]; # modesetting didn't help
hardware.nvidiaOptimus.disable = true;
boot.blacklistedKernelModules = [ "nouveau" "nvidia" ]; # bbswitch
# https://github.com/NixOS/nixpkgs/issues/94315 <- from here. bugfix for this: https://discourse.nixos.org/t/update-to-21-05-breaks-opengl-because-of-dependency-on-glibc-2-31/14218 note, that there are multiple occurences of this
# hardware.opengl.package = pkgs.nixpkgs-2009.mesa_drivers;
services.xserver = {
enable = false;
displayManager = {
lightdm.enable = false;
gdm.enable = false;
};
};
}
{
system.nixos.tags = [ "with-nvidia" ];
# environment.systemPackages = let
# nvidia-offload = pkgs.writeShellScriptBin "nvidia-offload" ''
# export __NV_PRIME_RENDER_OFFLOAD=1
# export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0
# export __GLX_VENDOR_LIBRARY_NAME=nvidia
# export __VK_LAYER_NV_optimus=NVIDIA_only
# exec -a "$0" "$@"
# '';
# in [ nvidia-offload ];
# boot.extraModulePackages = [ pkgs.linuxPackages.nvidia_x11 ];
# Nvidia stuff (https://discourse.nixos.org/t/how-to-use-nvidia-prime-offload-to-run-the-x-server-on-the-integrated-board/9091/13)
boot.extraModprobeConfig = "options nvidia \"NVreg_DynamicPowerManagement=0x02\"\n";
services.hardware.bolt.enable = true;
services.udev.extraRules = ''
# Remove NVIDIA USB xHCI Host Controller devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{remove}="1"
# Remove NVIDIA USB Type-C UCSI devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{remove}="1"
# Remove NVIDIA Audio devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{remove}="1"
# Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"
# Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on"
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"
'';
services.xserver.videoDrivers = [ "nvidia" ];
hardware.nvidia.modesetting.enable = lib.mkDefault true;
hardware.nvidia.optimus_prime.enable = lib.mkDefault true; # warning: The option `hardware.nvidia.optimus_prime.enable' defined in `<unknown-file>' has been renamed to `hardware.nvidia.prime.sync.enable'.
hardware.nvidia.prime.nvidiaBusId = lib.mkDefault "PCI:1:0:0";
hardware.nvidia.prime.intelBusId = lib.mkDefault "PCI:0:2:0";
# hardware.bumblebee.enable = false;
# hardware.bumblebee.pmMethod = "none";
services.xserver = {
displayManager = {
lightdm.enable = true;
gdm.enable = false;
};
};
}
This strongly mimics /home/moritz/Projects/nixpkgs/nixos/modules/hardware/video/nvidia.nix
TODO try with xserver (nvidia displayer driver) and with datacenter. both with open driver. I need to get a working version before I go “wild”
{
services.xserver.videoDrivers = [ "nvidia" ];
hardware.nvidia.prime.nvidiaBusId = lib.mkDefault "PCI:1:0:0";
hardware.nvidia.prime.intelBusId = lib.mkDefault "PCI:0:2:0";
hardware.nvidia.prime.offload.enable = true;
services.xserver.enable = true;
services.hardware.bolt.enable = true;
hardware.nvidia.open = true; # required for eGPU maybe?
# config.boot.kernelPackages.nvidiaPackages
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.production;
# "pkgs.os-specific.linux.nvidia_x11.production"; # alternative: stable
boot.blacklistedKernelModules = [ "nouveau" ]; # bbswitch
hardware.nvidia.nvidiaPersistenced = true; # powerdown crashes the eGPU
hardware.opengl.enable = true; # needed for nvidia-docker
services.getty.autologinUser = "moritz";
hardware.nvidia.powerManagement.enable = false;
services.udev.extraRules = ''
# Remove NVIDIA USB xHCI Host Controller devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{remove}="1"
# Remove NVIDIA USB Type-C UCSI devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{remove}="1"
# Remove NVIDIA Audio devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{remove}="1"
# Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"
# Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on"
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"
'';
}
{
system.nixos.tags = [ "no-xserver-datacenter" ];
boot.extraModulePackages = with config.boot.kernelPackages; [ acpi_call bbswitch ];
# https://github.com/NixOS/nixpkgs/issues/94315 <- from here. bugfix for this: https://discourse.nixos.org/t/update-to-21-05-breaks-opengl-because-of-dependency-on-glibc-2-31/14218 note, that there are multiple occurences of this
# hardware.opengl.package = pkgs.nixpkgs-2009.mesa_drivers;
services.xserver.enable = false;
hardware.nvidia.datacenter.enable = true;
services.hardware.bolt.enable = true;
hardware.nvidia.open = true; # required for eGPU
hardware.nvidia.package = (pkgs.unstable.linuxPackagesFor config.boot.kernelPackages.kernel).nvidiaPackages.dc_535;
# "pkgs.os-specific.linux.nvidia_x11.production"; # alternative: stable
boot.blacklistedKernelModules = [ "nouveau" ]; # bbswitch
hardware.nvidia.nvidiaPersistenced = true; # disconnect crashes
hardware.opengl.enable = true; # needed for nvidia-docker
services.getty.autologinUser = "moritz";
hardware.nvidia.powerManagement.enable = false;
}
{
system.nixos.tags = [ "with-nvidia-egpu" ];
# environment.systemPackages = let
# nvidia-offload = pkgs.writeShellScriptBin "nvidia-offload" ''
# export __NV_PRIME_RENDER_OFFLOAD=1
# export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0
# export __GLX_VENDOR_LIBRARY_NAME=nvidia
# export __VK_LAYER_NV_optimus=NVIDIA_only
# exec -a "$0" "$@"
# '';
# in [ nvidia-offload ];
# Nvidia stuff (https://discourse.nixos.org/t/how-to-use-nvidia-prime-offload-to-run-the-x-server-on-the-integrated-board/9091/13)
# boot.extraModprobeConfig = "options nvidia \"NVreg_DynamicPowerManagement=0x02\"\n";
services.hardware.bolt.enable = true;
# systemd.tmpfiles.rules =
# lib.optional config.virtualisation.docker.enableNvidia
# "L+ /run/nvidia-docker/bin - - - - ${nvidia_x11.bin}/origBin";
services.udev.extraRules = ''
# Remove NVIDIA USB xHCI Host Controller devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{remove}="1"
# Remove NVIDIA USB Type-C UCSI devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{remove}="1"
# Remove NVIDIA Audio devices, if present
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{remove}="1"
# Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"
# Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on"
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"
# Create /dev/nvidia-uvm when the nvidia-uvm module is loaded.
KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidiactl c 195 255'"
KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'for i in $$(cat /proc/driver/nvidia/gpus/*/information | grep Minor | cut -d \ -f 4); do mknod -m 666 /dev/nvidia$${i} c 195 $${i}; done'"
KERNEL=="nvidia_modeset", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-modeset c 195 254'"
KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm c $$(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 0'"
KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm-tools c $$(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 1'"
'';
# hardware.opengl.package = pkgs.nixpkgs-2009.mesa_drivers;
services.xserver.videoDrivers = [ "intel" ];
boot.extraModulePackages = [ pkgs.linuxPackages.nvidia_x11.open ]; # .open added
boot.blacklistedKernelModules = [ "nouveau" "nvidia_drm" "nvidia_modeset" "nvidia" "nvidiafb" ];
boot.extraModprobeConfig = ''
softdep nvidia post: nvidia-uvm
'';
environment.systemPackages = [ pkgs.linuxPackages.nvidia_x11.bin ]; # packages # .bin added
hardware.firmware = [ pkgs.linuxPackages.nvidia_x11.firmware ];
boot.kernelParams = [ "nvidia.NVreg_OpenRmEnableUnsupportedGpus=1" ];
# hardware.nvidia.package = pkgs.os-specific.linux.nvidia_x11.production; # alternative: stable
# /home/moritz/Projects/nixpkgs/pkgs/os-specific/linux/nvidia-x11/default.nix <- add version 450
hardware.nvidia.open = true;
# hardware.nvidia.datacenter.enable = true;
hardware.opengl = {
enable = true;
driSupport = true;
extraPackages = with pkgs; [
# intel-media-driver # LIBVA_DRIVER_NAME=iHD
# vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
# vaapiVdpau
# libvdpau-va-gl
pkgs.linuxPackages.nvidia_x11.out # required for nvidia-docker
];
extraPackages32 = [ pkgs.linuxPackages.nvidia_x11.lib32 ];
};
services.xserver = {
displayManager = {
lightdm.enable = false;
gdm.enable = true;
};
};
}
{
fileSystems."/" =
{ device = "/dev/disk/by-uuid/8f0a4152-e9f1-4315-8c34-0402ff7efff4";
fsType = "btrfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/A227-1A0D";
fsType = "vfat";
};
swapDevices =
[
{ device = "/dev/disk/by-uuid/9eca5b06-730e-439f-997b-512a614ccce0"; }
{ device = "/swapfile"; } # size = 48 * 1024 (48G)
];
boot.initrd.kernelModules = [ "mmc_core" ]; # TODO try with USB stick first! https://medium.com/@geis/using-a-raw-usb-device-to-unlock-a-luks-volume-on-nixos-193406ee7474
boot.initrd.systemd.enable = true;
boot.initrd.luks.devices = {
cryptkey.device = "/dev/disk/by-uuid/ccd19ab7-0e4d-4df4-8912-b87139de56af";
anopassphrasekey = {
device = "/dev/disk/by-id/mmc-SD02G_0x6035b72d"; # TODO try without
allowDiscards = true;
keyFileSize = 4096;
keyFile = "/dev/mmcblk0";
};
cryptroot = {
device="/dev/disk/by-uuid/88242cfe-48a1-44d2-a29b-b55e6f05d3d3";
keyFile="/dev/mapper/cryptkey";
};
cryptswap = {
device="/dev/disk/by-uuid/f6fa3573-44a9-41cc-bab7-da60d21e27b3";
keyFile="/dev/mapper/cryptkey";
};
};
}
{
# 3.5" HDD in fast-swappable case
fileSystems."/mnt/hdd3tb" =
{ device = "/dev/disk/by-uuid/f6037d88-f54a-4632-bd9f-a296486fc9bc";
fsType = "ext4";
options = [ "nofail" ];
};
# 2.5" SSD ugreen
fileSystems."/mnt/ssd2tb" =
{ device = "/dev/disk/by-uuid/44d8f482-0ab4-4184-8941-1cf3969c298c";
fsType = "ext4";
options = [ "nofail" ];
};
}
{
services.libinput = {
enable = true;
touchpad.accelSpeed = "0.7";
};
services.xserver.displayManager.lightdm.greeters.gtk.cursorTheme = {
name = "Vanilla-DMZ";
package = pkgs.vanilla-dmz;
size = 128; # was 64
};
environment.variables.XCURSOR_SIZE = "64";
}
{
services.upower.ignoreLid = true;
services.logind = {
lidSwitchExternalPower = "ignore";
};
}
TODO switch off/on display on lid close
{
boot.kernelModules = [ "acpi_call" "bbswitch" ];
systemd.services.server_init = {
description = "";
wantedBy = [ "multi-user.target" ];
after = [ "docker.service" ]; # Ensure server_init starts after Docker
requires = [ "docker.service" ]; # Require Docker service to start successfully
script = ''
echo -n "0000:01:00.0" | tee /sys/bus/pci/drivers/nvidia/unbind || true
echo OFF | tee /proc/acpi/bbswitch
/run/current-system/sw/bin/nvidia-smi -pm 1
cd /home/moritz/Projects/cellwhisperer/hosting/home
echo 1 | tee /sys/class/backlight/intel_backlight/brightness
'';
serviceConfig.Type = "oneshot";
};
}
Thinkpad X1 Extreme gen 4
{
imports = [
(import "${inputs.nixos-hardware}/lenovo/thinkpad/p1/3th-gen")
(import "${inputs.nixos-hardware}/lenovo/thinkpad/p1/3th-gen/nvidia.nix")
(import "${inputs.nixos-hardware}/lenovo/thinkpad/x1-extreme/gen4/default.nix") # implies cpu/inel and laptop/ssd
(import "${inputs.nixos-hardware}/common/pc/laptop") # tlp.enable = true
(import "${inputs.nixos-hardware}/common/gpu/nvidia/prime.nix") # default: offload
inputs.nixpkgs.nixosModules.notDetected
];
# hardware.nvidia.modesetting.enable = true;
# hardware.opengl.driSupport32Bit = true;
# hardware.opengl.enable = true;
# services.xserver.videoDrivers = [ "nvidia" ];
# hardware.bumblebee.enable = false;
services.hardware.bolt.enable = true;
hardware.nvidia.powerManagement.enable = true; # might be buggy (https://github.com/NVIDIA/open-gpu-kernel-modules/issues/472)
hardware.nvidia.powerManagement.finegrained = false; # TODO is this good or bad?
hardware.nvidia.prime = {
# Bus ID of the Intel GPU.
intelBusId = lib.mkDefault "PCI:0:2:0";
# Bus ID of the NVIDIA GPU.
nvidiaBusId = lib.mkDefault "PCI:1:0:0";
};
hardware.nvidia.open = true;
specialisation = {
sync-gpu.configuration = {
system.nixos.tags = [ "sync-gpu" ];
hardware.nvidia.prime.offload.enable = lib.mkForce false;
hardware.nvidia.prime.sync.enable = lib.mkForce true;
hardware.nvidia.powerManagement.finegrained = lib.mkForce false;
hardware.nvidia.powerManagement.enable = lib.mkForce false;
};
};
environment.systemPackages = [ pkgs.linuxPackages.nvidia_x11 ];
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" "sdhci_pci" ];
# boot.blacklistedKernelModules = [ "nouveau" "nvidia_drm" "nvidia_modeset" "nvidia" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/aed145a9-e93a-428b-be62-d3220fb1ab0f";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/F1D8-DA4A";
fsType = "vfat";
};
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
swapDevices =
[ { device = "/dev/disk/by-uuid/a048e8ec-3daa-4430-86ad-3a7f5e9acd91"; }
];
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# high-resolution display
services.xserver = {
enable = true;
displayManager = {
lightdm.enable = true;
# gdm.enable = true;
};
};
services.libinput = {
enable = true;
touchpad.accelSpeed = "0.7";
# disabling mouse acceleration
# mouse = {
# accelProfile = "flat";
# };
# # disabling touchpad acceleration
# touchpad = {
# accelProfile = "flat";
# };
};
# The NixOS release to be compatible with for stateful data such as databases.
system.stateVersion = "20.03";
}
Keyboard:
https://nixos.wiki/wiki/Keyboard_Layout_Customization#Using_xmodmap
{
# TODO the keyboard is not fixed in the right manner (in browsers, alt and enter lead to the original keypresses...)
services.xserver.displayManager.sessionCommands = let
myCustomLayout = pkgs.writeText "xkb-layout" ''
keycode 36 = ISO_Level3_Shift
'';
in
''
${pkgs.xorg.xmodmap}/bin/xmodmap ${myCustomLayout}"
xsetroot -cursor_name left_ptr
'';
}
Cursor related: https://discourse.nixos.org/t/how-to-fix-cursor-size/2938
{
services.xserver.displayManager.lightdm.greeters.gtk.cursorTheme = {
name = "Vanilla-DMZ";
package = pkgs.vanilla-dmz;
size = 64; # was 64
};
xsession.pointerCursor = {
package = pkgs.vanilla-dmz; # pkgs.gnome.adwaita-icon-theme;
name = "Vanilla-DMZ";
size = 64;
};
environment.variables.XCURSOR_SIZE = "64";
}
as described in https://nixos.wiki/wiki/Keyboard_Layout_Customization I could also add the following xkb code, but how?
partial modifier_keys xkb_symbols “enter_switch” { key <RTRN> { type[Group1]=”ONE_LEVEL”, symbols[Group1] = [ ISO_Level3_Shift ] }; include “level3(modifier_mapping)” };
Of note, rasendubi somehow did this quite elegantly. Have a look here: home/moritz/nixos-config.config/xkb/my
This is my late 2013 MBP.
{
imports = [
# (import "${inputs.nixos-hardware}/apple/macbook-pro") # messes up the keyboard...
(import "${inputs.nixos-hardware}/common/pc/laptop/ssd")
(import "${inputs.nixos-hardware}/common/pc/laptop") # tlp.enable = true
(import "${inputs.nixos-hardware}/common/cpu/intel")
#inputs.nixpkgs.modules.hardware.network.broadcom-43xx # <- using import vs not using import?
# <nixpkgs/nixos/modules/hardware/network/broadcom-43xx.nix> <- this is when using channels instead of flakes?
inputs.nixpkgs.nixosModules.notDetected
];
hardware.facetimehd.enable = true;
# from https://wiki.archlinux.org/index.php/MacBookPro11,x#Powersave
services.udev.extraRules = let
# remove_script = pkgs.requireFile {
# name = "remove_ignore_usb_devices.sh";
# url = "https://gist.githubusercontent.com/anonymous/9c9d45c4818e3086ceca/raw/2aa42b5b7d564868ff089dc72445f24586b6c55e/gistfile1.sh";
# sha256 = "b2e1d250b1722ec7d3a381790175b1fdd3344e638882ac00f83913e2f9d27603";
# };
remove_script = ''
# from https://gist.github.com/anonymous/9c9d45c4818e3086ceca
logger -p info "$0 executed."
if [ "$#" -eq 2 ];then
removevendorid=$1
removeproductid=$2
usbpath="/sys/bus/usb/devices/"
devicerootdirs=`ls -1 $usbpath`
for devicedir in $devicerootdirs; do
if [ -f "$usbpath$devicedir/product" ]; then
product=`cat "$usbpath$devicedir/product"`
productid=`cat "$usbpath$devicedir/idProduct"`
vendorid=`cat "$usbpath$devicedir/idVendor"`
if [ "$removevendorid" == "$vendorid" ] && [ "$removeproductid" == "$productid" ]; then
if [ -f "$usbpath$devicedir/remove" ]; then
logger -p info "$0 removing $product ($vendorid:$productid)"
echo 1 > "$usbpath$devicedir/remove"
exit 0
else
logger -p info "$0 already removed $product ($vendorid:$productid)"
exit 0
fi
fi
fi
done
else
logger -p err "$0 needs 2 args vendorid and productid"
exit 1
fi'';
remove_script_local = pkgs.writeShellScript "remove_ignore_usb-devices_local.sh" remove_script; #(import ./remove_ignore_usb_devices.sh.nix); # (builtins.readFile remove_script)
in
''
# /etc/udev/rules.d/99-apple_cardreader.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="05ac", ATTRS{idProduct}=="8406", RUN+="${remove_script_local} 05ac 8406"
# /etc/udev/rules.d/99-apple_broadcom_bcm2046_bluetooth.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="05ac", ATTRS{idProduct}=="8289", RUN+="${remove_script_local} 05ac 8289"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0a5c", ATTRS{idProduct}=="4500", RUN+="${remove_script_local} 0a5c 4500"
# Disable XHC1 wakeup signal to avoid resume getting triggered some time
# after suspend. Reboot required for this to take effect.
SUBSYSTEM=="pci", KERNEL=="0000:00:14.0", ATTR{power/wakeup}="disabled"
'';
systemd.services.disable-gpe06 = {
description = "Disable GPE06 interrupt leading to high kworker";
wantedBy = [ "multi-user.target" ];
script = ''
/run/current-system/sw/bin/bash -c 'echo "disable" > /sys/firmware/acpi/interrupts/gpe06'
'';
serviceConfig.Type = "oneshot";
};
boot.loader.systemd-boot.enable = true;
boot.loader.systemd-boot.configurationLimit = 10;
# boot.loader.efi.canTouchEfiVariables = true;
# accelerateion
# nixpkgs.config.packageOverrides = pkgs: {
# vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
# };
# hardware.opengl = {
# enable = true;
# extraPackages = with pkgs; [
# intel-media-driver # LIBVA_DRIVER_NAME=iHD
# vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
# vaapiVdpau
# libvdpau-va-gl
# ];
# };
boot.kernelModules = [ "kvm-intel" "wl" ];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "sd_mod" "usbhid" ];
boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
powerManagement.enable = true;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
services.mbpfan = {
enable = true;
lowTemp = 60;
highTemp = 67;
maxTemp = 84;
};
# The NixOS release to be compatible with for stateful data such as databases.
system.stateVersion = "20.03";
}
LVM on LUKS setup for disk encryption.
{
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/E64F-3226";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/912c5850-5f71-4d15-8b69-1e0dad5718b0"; }
];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/73edc386-3f1a-46ff-9ae1-76a4fd6c0ea4";
fsType = "btrfs";
};
boot.initrd.luks.devices = {
cryptkey = {
device = "/dev/disk/by-uuid/179ecdea-edd4-4dc5-b8c3-5ed760bc2a0d";
};
cryptroot = {
device = "/dev/disk/by-uuid/623db0a5-d0e0-405a-88ae-b83a3d321656";
keyFile = "/dev/mapper/cryptkey";
};
cryptswap = {
device = "/dev/disk/by-uuid/da63991e-8edd-48db-bc4b-66fbc96917eb";
keyFile = "/dev/mapper/cryptkey";
};
};
}
Clickpad and DPI:
{
services.libinput = {
enable = true;
touchpad.accelSpeed = "0.7";
};
# displayManager.lightdm.greeters.gtk.cursorTheme = { # TODO if home manager cursor doesnt work
# name = "Vanilla-DMZ";
# package = pkgs.vanilla-dmz;
# size = 64;
# };
}
{
imports = [
# apple-silicon hardware support
inputs.apple-silicon.nixosModules.apple-silicon-support
# (import "${inputs.apple-silicon}/")
inputs.nixpkgs.nixosModules.notDetected
];
nixpkgs.overlays = [ inputs.apple-silicon.overlays.apple-silicon-overlay ];
boot.kernelParams = [ "apple_dcp.show_notch=1" ];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = false; # modified
boot.initrd.availableKernelModules = [ "usb_storage" ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/e24c4ea5-1dd7-4b80-ac54-d6f87e72b3a6";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/0747-1012";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
fileSystems."/mnt/data" =
{ device = "/dev/disk/by-uuid/66EC-4934";
fsType = "exfat";
options = [ "nofail" "uid=1000" "gid=100" "umask=0022" ];
};
swapDevices = [ ];
# # backlight control
# programs.light.enable = true;
# services.actkbd = {
# enable = true;
# bindings = [
# { keys = [ 225 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/light -A 10"; }
# { keys = [ 224 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/light -U 10"; }
# ];
# };
# Reference Asahi/Apple data path (required for flake)
hardware.asahi.peripheralFirmwareDirectory = ./firmware;
# Optionally disable their extraction
# hardware.asahi.extractPeripheralFirmware = false;
# hardware.asahi = { # TODO this might improve graphics stuff
# withRust = true;
# useExperimentalGPUDriver = true;
# experimentalGPUInstallMode = "replace";
# setupAsahiSound = true;
# };
# 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
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.wlan0.useDHCP = lib.mkDefault true;
networking.hostName = "moair"; # Define your hostname.
# Pick only one of the below networking options.
networking.wireless.iwd = {
enable = true;
settings.General.EnableNetworkConfiguration = true;
};
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
services.xserver = {
enable = true;
displayManager = {
lightdm.enable = true;
};
};
services.libinput = {
enable = true;
touchpad.accelSpeed = "0.7";
# mouse.disableWhileTyping = true;
touchpad.disableWhileTyping = true;
touchpad.tapping = false;
# disabling mouse acceleration
# mouse = {
# accelProfile = "flat";
# };
# # disabling touchpad acceleration
# touchpad = {
# accelProfile = "flat";
# };
};
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
system.stateVersion = "24.11"; # Do not change!
}
Cursor
{
services.xserver.displayManager.sessionCommands = ''
xsetroot -cursor_name left_ptr
'';
}
related: https://discourse.nixos.org/t/how-to-fix-cursor-size/2938
{
services.xserver.displayManager.lightdm.greeters.gtk.cursorTheme = {
name = "Vanilla-DMZ";
package = pkgs.vanilla-dmz;
size = 64; # was 64
};
xsession.pointerCursor = {
package = pkgs.vanilla-dmz; # pkgs.gnome.adwaita-icon-theme;
name = "Vanilla-DMZ";
size = 64;
};
environment.variables.XCURSOR_SIZE = "64";
}
Battery limitation (to save battery live)
{
services.udev.extraRules = ''
KERNEL=="macsmc-battery", SUBSYSTEM=="power_supply", ATTR{charge_control_end_threshold}="95"
'';
# , ATTR{charge_control_start_threshold}="70" only charge below 70 <- nope :)
}
As a responsible NixOS user, I refuse to install software blindly with sudo make install
. That’s why I must write my own nix-expressions.
I like the following settings more than defaults. I also need a custom four-style family because Emacs confuses regular/medium weight otherwise. Use link specified in requireFile
to download the font.
{
# note it's a new attribute and does not override old one
input-mono = (pkgs.input-fonts.overrideAttrs (old: {
src = pkgs.requireFile {
name = "Input-Font.zip";
url = "https://input.fontbureau.com/build/?fontSelection=fourStyleFamily®ular=InputMonoNarrow-Regular&italic=InputMonoNarrow-Italic&bold=InputMonoNarrow-Bold&boldItalic=InputMonoNarrow-BoldItalic&a=0&g=0&i=topserif&l=serifs_round&zero=0&asterisk=height&braces=straight&preset=default&line-height=1.2&accept=I+do&email=";
sha256 = "888bbeafe4aa6e708f5c37b42fdbab526bc1d125de5192475e7a4bb3040fc45a";
};
outputHash = "1w2i660dg04nyc6fc6r6sd3pw53h8dh8yx4iy6ccpii9gwjl9val";
}));
}
I have a bluetooth headset, so this enables bluetooth audio in NixOS.
{
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = false;
services.blueman.enable = true;
hardware.bluetooth.settings.General.Enable = "Source,Sink,Media,Socket";
}
Install ntfs-3g to mount ntfs volumes in read-write mode.
{
environment.systemPackages = [
pkgs.ntfs3g
pkgs.exfatprogs
];
}
For background, see this thread: https://discourse.nixos.org/t/seeking-assistance-with-old-exwm-emacs-version-after-23-11-update/36607/4
{
environment.systemPackages = [
pkgs.sshfs
];
age.secrets.muwhpc.file = "/home/moritz/nixos-config/secrets/muwhpc.age";
fileSystems."/mnt/muwhpc" = {
device = "//msc-smb.hpc.meduniwien.ac.at/mschae83";
fsType = "cifs";
options = [
"username=mschae83"
"credentials=${config.age.secrets.muwhpc.path}"
"domain=smb"
"x-systemd.automount"
"noauto"
"uid=1000"
"x-systemd.idle-timeout=60"
"x-systemd.device-timeout=5s"
"x-systemd.mount-timeout=5s"
];
};
# mount command fails unfortunately. Use Thunar instead
# age.secrets.cemm.file = /home/moritz/nixos-config/secrets/cemm.age;
# fileSystems."/mnt/cemm" = {
# device = "//int.cemm.at/files";
# fsType = "cifs";
# options = [
# "username=mschaefer"
# "credentials=${config.age.secrets.cemm.path}"
# # "domain=int.cemm.at" # CEMMINT
# "x-systemd.automount"
# "noauto"
# "uid=1000"
# "x-systemd.idle-timeout=60"
# "x-systemd.device-timeout=5s"
# "x-systemd.mount-timeout=5s"
# ];
# };
}
“vers=1.0” “nounix”
“vers=3” “sec=ntlmssp” “cache=strict” “noserverino” “nodev” “noexec”
{
systemd.services.gdrive_mount = let mountdir = "/mnt/gdrive"; in {
description = "mount gdrive dirs";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStartPre = "/run/current-system/sw/bin/mkdir -p ${mountdir}";
ExecStart = ''
${pkgs.rclone}/bin/rclone mount gdrive: ${mountdir} \
--dir-cache-time 48h \
--vfs-cache-max-age 48h \
--vfs-read-chunk-size 10M \
--vfs-read-chunk-size-limit 512M \
--buffer-size 512M
'';
ExecStop = "/run/wrappers/bin/fusermount -u ${mountdir}";
Type = "notify";
Restart = "always";
RestartSec = "10s";
Environment = [ "PATH=/run/wrappers/bin:$PATH" ];
User = "moritz";
};
};
}
{
system.autoUpgrade.enable = true;
}
{
environment.systemPackages = with pkgs; [ libnotify ];
systemd.timers.hibernate-on-low-battery = {
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnUnitActiveSec = "120";
OnBootSec= "120";
};
};
systemd.services.hibernate-on-low-battery =
let
battery-level-sufficient = pkgs.writeShellScriptBin
"battery-level-sufficient" ''
#!/bin/bash
# set environment to allow notify-send to work
export XAUTHORITY="/home/moritz/.Xauthority"
export DISPLAY=":0"
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
export PATH="${pkgs.dbus}/bin:$PATH"
capacity=$(cat /sys/class/power_supply/BAT0/capacity)
status=$(cat /sys/class/power_supply/BAT0/status)
if [ "$capacity" -le 20 ] && [ "$status" = "Discharging" ]; then
${pkgs.sudo}/bin/sudo -E -u moritz ${pkgs.libnotify}/bin/notify-send -t 4000 "Low Battery" "Your battery is below 20%, please plug in your charger."
fi
test "$(cat /sys/class/power_supply/BAT0/status)" != Discharging \
|| test "$(cat /sys/class/power_supply/BAT0/capacity)" -ge 10
'';
in
{
serviceConfig = { Type = "oneshot"; };
onFailure = [ "hibernate.target" ];
script = "${battery-level-sufficient}/bin/battery-level-sufficient";
};
}
{
nix.optimise.automatic = true;
nix.gc.automatic = true;
nix.gc.options = "--delete-generations +12";
}
{
security.pam.loginLimits = [{ # http://www.linux-pam.org/Linux-PAM-html/sag-pam_limits.html
"domain" = "moritz"; # or group @users
"type" = "-";
"item" = "nice";
"value" = "-18";
}
# { # disabled for testing. check if everything works fine after reboot...
# "domain" = "moritz"; # or group @users
# "type" = "-";
# "item" = "priority";
# "value" = "-10";
# }
];
}
{
networking = {
hostName = name;
firewall.checkReversePath = false; # required for wireguard (potential security risk. see https://nixos.wiki/wiki/WireGuard#Setting_up_WireGuard_with_NetworkManager for details)
networkmanager = {
enable = true;
plugins = [
pkgs.networkmanager-openconnect
pkgs.networkmanager-vpnc
];
};
# disable wpa_supplicant
wireless.enable = false;
};
users.users.moritz.extraGroups = [ "networkmanager" ];
environment.systemPackages = [
pkgs.openconnect
pkgs.networkmanagerapplet
pkgs.vpnc
pkgs.vpnc-scripts
];
}
Wireguard: (note: mopad was configured via NetworkManager)
{
networking.firewall = {
allowedUDPPorts = [ 51820 ]; # Clients and peers can use the same port, see listenport
};
age.secrets.client_wireguard_private.file = "/home/moritz/nixos-config/secrets/wireguard_client_private_key.age";
# Enable WireGuard
networking.wireguard.enable = true;
networking.wireguard.interfaces = {
# "wg0" is the network interface name. You can name the interface arbitrarily.
wg0 = {
# Determines the IP address and subnet of the client's end of the tunnel interface.
ips = [ "10.100.0.3/24" ];
listenPort = 51820; # to match firewall allowedUDPPorts (without this wg uses random port numbers)
# Path to the private key file.
#
# Note: The private key can also be included inline via the privateKey option,
# but this makes the private key world-readable; thus, using privateKeyFile is
# recommended.
privateKeyFile = config.age.secrets.client_wireguard_private.path;
peers = [
# For this client configuration, one peer entry for the server will suffice.
{
# Public key of the server (not a file path).
publicKey = "KYF+BBuoY7dNYswft+vhlNrAKjAkMIMYnkhBbHcH7Dw=";
# Forward all the traffic via VPN.
# allowedIPs = [ "0.0.0.0/0" ];
# Or forward only particular subnets
allowedIPs = [ "10.100.0.1" "192.168.0.0/24" ];
# Set this to the server IP and port.
endpoint = "moritzs.duckdns.org:51820";
# Send keepalives every 25 seconds. Important to keep NAT tables alive.
persistentKeepalive = 25;
}
];
};
};
}
{
services.avahi = {
enable = true;
allowInterfaces = [ "wlp9s0" "wlan" "tun0" "wg0" ]; # TODO how to add "all"?
openFirewall = true;
publish = {
addresses = true;
workstation = true;
enable = true;
};
nssmdns4 = true;
};
}
Use pulseaudio (multiple sound sinks, skype calls). pavucontrol
is PulseAudio Volume Control—a nice utility for controlling pulseaudio settings.
Also, Pulseaudio is a requirement for Firefox Quantum.
{
# TODO enable instead of pulseaudio
# security.rtkit.enable = true;
services.pipewire = {
enable = true;
pulse.enable = true;
# alsa.enable = true;
# alsa.support32Bit = true;
# pulse.enable = true;
# # If you want to use JACK applications, uncomment this
# jack.enable = true;
};
environment.systemPackages = with pkgs; [
pavucontrol
# libjack2 jack2 qjackctl jack2 jack_capture
gst_all_1.gstreamer
gst_all_1.gst-plugins-good
gst_all_1.gst-plugins-base
# gst_all_1.gst-plugins-ugly gst_all_1.gst-plugins-bad
ffmpeg
];
# services.jack = {
# jackd.enable = true;
# # support ALSA only programs via ALSA JACK PCM plugin
# alsa.enable = false;
# # support ALSA only programs via loopback device (supports programs like Steam)
# loopback = {
# enable = true;
# # buffering parameters for dmix device to work with ALSA only semi-professional sound programs
# #dmixConfig = ''
# # period_size 2048
# #'';
# };
# };
# boot.kernelModules = [ "snd-seq" "snd-rawmidi" ];
users.users.moritz.extraGroups = [ "audio" ]; # "jackaudio"
# from https://github.com/JeffreyBenjaminBrown/nixos-experiments/blob/6c4be545e2ec18c6d9b32ec9b66d37c59d9ebc1f/audio.nix
security.sudo.extraConfig = ''
moritz ALL=(ALL) NOPASSWD: ${pkgs.systemd}/bin/systemctl
'';
}
{
boot.extraModprobeConfig ='' # https://github.com/NixOS/nixpkgs/issues/330685#issuecomment-2279718903
options snd-hda-intel dmic_detect=0
'';
}
https://nixos.wiki/wiki/Printing
{
services.printing.enable = true;
services.printing.browsedConf = ''
CreateIPPPrinterQueues All
'';
services.printing.drivers = with pkgs; [
gutenprint
# gutenprintBin # not aarch64
samsung-unified-linux-driver
splix
canon-cups-ufr2
carps-cups
];
services.system-config-printer.enable = true;
environment.systemPackages = [
pkgs.gtklp
];
}
Update locate database daily.
{
services.locate = {
enable = true;
localuser = "moritz";
};
}
Needs to be enabled so we have the public key (for agenix).
{
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
};
users.users.moritz.openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMc+scl71X7g21XFygTNB3onyGuION89iHSUw0eYcN2H [email protected]" ];
}
Mosh (mobile shell) is a cool addition to ssh.
{
programs.mosh.enable = true;
}
Use dnsmasq as a DNS cache.
{
services.dnsmasq = {
enable = false;
# These are used in addition to resolv.conf
settings = {
servers = [
"8.8.8.8"
"8.8.4.4"
];
listenAddress = "127.0.0.1";
cacheSize = 1000;
noNegcache = true;
};
};
}
I use Syncthing to sync my org-mode files to my phone.
{
services.syncthing = {
enable = true;
package = pkgs.unstable.syncthing;
user = "moritz";
dataDir = "/home/moritz/.config/syncthing";
configDir = "/home/moritz/.config/syncthing";
openDefaultPorts = true;
};
}
I use OneDrive from my job
{
# services.onedrive = {
# enable = true;
# };
environment.systemPackages = [
pkgs.unstable.onedrivegui
];
}
Enable firewall. This blocks all ports (for ingress traffic) and pings.
{
networking.firewall = {
enable = true;
allowPing = true; # needed for samba
connectionTrackingModules = [];
autoLoadConntrackHelpers = false;
};
}
{
virtualisation.virtualbox.host.enable = false; # slow compile times
virtualisation.docker.enable = true;
# virtualisation.docker.enableNvidia = true; # TODO
# hardware.opengl.driSupport32Bit = true;
environment.systemPackages = [
pkgs.docker-compose
pkgs.qemu_kvm
pkgs.qemu
# pkgs.nvtop # for nvidia
pkgs.usbtop
pkgs.xorg.xhost
];
users.users.moritz.extraGroups = ["libvirtd" "docker"]; # the former is required for qemu I think
}
I use borg for backups.
{
environment.systemPackages =
let mount_external = pkgs.writeScriptBin "mount-external" ''
#!${pkgs.stdenv.shell}
sudo ${pkgs.cryptsetup}/bin/cryptsetup luksOpen /dev/disk/by-uuid/aeebfb90-65b5-4515-bf6e-001d0cfc8a40 encrypted-2tb
sudo mount /dev/mapper/encrypted-2tb /mnt/encrypted
'';
umount_external = pkgs.writeScriptBin "umount-external" ''
#!${pkgs.stdenv.shell}
sudo umount /mnt/encrypted
sudo ${pkgs.cryptsetup}/bin/cryptsetup luksClose encrypted-2tb
'';
in
[ mount_external umount_external pkgs.borgbackup ];
}
I need to access my Android device.
{
services.udev.packages = [ pkgs.android-udev-rules ];
programs.adb.enable = true;
users.users.moritz.extraGroups = ["adbusers"];
}
fwupd is a service that allows applications to update firmware.
{
services.fwupd.enable = true;
}
{
environment.systemPackages = [
pkgs.direnv
];
programs.fish.shellInit = ''
eval (direnv hook fish)
'';
services.lorri.enable = true;
}
Automatic USB stick mounting
{
# services.udisks2.enable = true;
services.devmon.enable = true;
}
{
services.logind.extraConfig = ''
HandlePowerKey=suspend
'';
}
{
networking.firewall.extraCommands = ''iptables -t raw -A OUTPUT -p udp -m udp --dport 137 -j CT --helper netbios-ns'';
services.gvfs = { # https://nixos.wiki/wiki/Samba#Browsing_samba_shares_with_GVFS
enable = true;
package = lib.mkForce pkgs.gnome.gvfs;
};
services.samba = {
enable = true;
securityType = "user";
openFirewall = true;
settings = {
global = {
workgroup = "WORKGROUP";
"wins support" = "no";
"wins server" = "192.168.1.10";
"server string" = "smbnix";
"netbios name" = "smbnix";
security = "user";
"hosts allow" = "192.168. localhost";
"hosts deny" = "0.0.0.0/0";
"guest account" = "nobody";
"map to guest" = "bad user";
};
};
shares = {
# public = {
# path = "/mnt/Shares/Public";
# browseable = "yes";
# "read only" = "no";
# "guest ok" = "yes";
# "create mask" = "0644";
# "directory mask" = "0755";
# "force user" = "username";
# "force group" = "groupname";
# };
moritz = {
path = "/home/moritz/";
browseable = "yes";
"read only" = "no";
"guest ok" = "no";
"create mask" = "0644";
"directory mask" = "0755";
"force user" = "moritz";
"force group" = "users";
};
};
};
}
TODO: this one could/should use agenix credentials
{
# docs: https://nixos.wiki/wiki/Samba#CIFS_mount_configuration
# could be mounted as user as well (default is root)
environment.systemPackages = [ pkgs.cifs-utils ];
fileSystems."/mnt/moxps_ssd2tb" = {
device = "//192.168.0.52/ssd2tb";
fsType = "cifs";
options = let
# this line prevents hanging on network split
automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";
in ["${automount_opts},credentials=/etc/nixos/smb-secrets"];
};
}
{
systemd.services."weekly-git-commit" = {
script = ''
set -ev
cd /home/moritz/wiki/
export PATH=$PATH:${pkgs.git-lfs}/bin
${pkgs.git}/bin/git add .
${pkgs.git}/bin/git commit -m "Weekly checkpoint"
'';
serviceConfig = {
Type = "oneshot";
User = "moritz";
};
};
systemd.timers."weekly-git-commit" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "Sun 10:00";
Persistent = true;
Unit = "weekly-git-commit.service";
};
};
systemd.services."download-paperpile" = {
script = ''
set -ev
cd /home/moritz/wiki/papers
${pkgs.wget}/bin/wget --content-disposition -N https://paperpile.com/eb/ghEynTRTJb
'';
serviceConfig = {
Type = "oneshot";
User = "moritz";
};
};
systemd.timers."download-paperpile" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*:0/1";
Persistent = true;
Unit = "download-paperpile.service";
};
};
}
I use mbsync to sync my accounts and make them available offline.
{
environment.systemPackages = [
pkgs.isync
];
}
Config file is .mbsyncrc
.
MaildirStore local
Path ~/Mail/
Inbox ~/Mail/INBOX
SubFolders Verbatim
<<mbsync-gmail(name="gmail", email="[email protected]", path="Personal")>>
I have multiple Gmail accounts, so here is a general template.
(defmacro rasen/interpolate-string (text)
"Expand text like \"Hello <<name>>\" to (format \"Hello %s\" name)."
(let ((pattern "<<\\(.*?\\)>>"))
;; The regexp matches anything between delimiters, non-greedily
(with-temp-buffer
(save-excursion (insert text))
(let ((matches '()))
(while (re-search-forward pattern nil t)
(push (match-string 1) matches)
(replace-match "%s" t t))
`(format ,(buffer-string) ,@(reverse (mapcar 'read matches)))))))
(rasen/interpolate-string "
IMAPAccount <<name>>
Host imap.gmail.com
User <<email>>
PassCmd \"pass imap.gmail.com/<<email>>\"
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt
IMAPStore <<name>>-remote
Account <<name>>
Channel sync-<<name>>-all
Master :<<name>>-remote:\"[Gmail]/All Mail\"
Slave :local:<<path>>/all
Create Both
SyncState *
Channel sync-<<name>>-spam
Master :<<name>>-remote:\"[Gmail]/Spam\"
Slave :local:<<path>>/spam
Create Both
SyncState *
Channel sync-<<name>>-sent
Master :<<name>>-remote:\"[Gmail]/Sent Mail\"
Slave :local:<<path>>/sent
Create Both
SyncState *
Group sync-<<name>>
Channel sync-<<name>>-all
Channel sync-<<name>>-spam
Channel sync-<<name>>-sent
")
Msmtp is used to send mail.
{
environment.systemPackages = [
pkgs.msmtp
];
}
Config file is .msmtprc
.
defaults
auth on
tls on
tls_starttls off
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile ~/.msmtp.log
<<msmtp-gmail(name="gmail", email="[email protected]")>>
Again, general template for gmail accounts.
(rasen/interpolate-string "
# <<name>>
account <<name>>
host smtp.gmail.com
port 465
from <<email>>
user <<email>>
passwordeval \"pass imap.gmail.com/<<email>>\"
")
Notmuch is used for tagging.
{
environment.systemPackages = [
pkgs.notmuch
];
}
Config file is .notmuch-config
.
[user]
name=Moritz Schaefer
[email protected]
[email protected],[email protected],[email protected],[email protected]
[database]
path=/home/moritz/Mail
[new]
tags=inbox;
ignore=.mbsyncstate;.mbsyncstate.lock;.mbsyncstate.new;.mbsyncstate.journal;.uidvalidity;dovecot-uidlist;dovecot-keywords;dovecot.index;dovecot.index.log;dovecot.index.log.2;dovecot.index.cache;/^archive/
[search]
exclude_tags=deleted;spam;muted;
[crypto]
gpg_path=gpg2
Here’s a basic NixOS configuration that should do what you’re asking for. This configuration assumes that you have wget
and gawk
installed on your system. If not, you should add them to your environment.systemPackages
.
# TODO also the awk script is for google calendar, maybe I should try to find an office365-specific script.
# TODO I modified that script such that it does not adjust the time zone (because it was broken: the ical file indicates the wrong timezone but the correct time!). ( return 0 in parse_timezone_offset
# TODO also, filter either ical or org for events older than last month (otherwise org-agenda has to work so much more...)
# TODO note: I disabled syncthing wiki syncing o the `calendar-sync` folder (ignore/exception)
{
environment.systemPackages = with pkgs; [ wget gawk gnugrep ];
age.secrets.mcUrl.file = "/home/moritz/nixos-config/secrets/mcUrl.age";
age.secrets.gcUrl.file = "/home/moritz/nixos-config/secrets/gcUrl.age";
systemd.services.ics2org = let
scriptPath = "/home/moritz/wiki/calendar-sync/ical2org.awk";
mcIcsPath = "/home/moritz/wiki/calendar-sync/mc_office365.ics";
gcIcsPath = "/home/moritz/wiki/calendar-sync/gc_office365.ics";
orgPath = "/home/moritz/wiki/calendar-sync/calendars.org";
# mcUrlFile = config.age.secrets.mcUrl.path;
# gcUrlFile = config.age.secrets.gcUrl.path;
in {
description = "Convert .ics to .org";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
};
script = ''
# not redownloading the script, because the time-zone adaptation is broken (see TODO above)
# ${pkgs.wget}/bin/wget https://raw.githubusercontent.com/msherry/ical2org/master/ical2org.awk -O ${scriptPath}
${pkgs.wget}/bin/wget `cat ${config.age.secrets.mcUrl.path}` -O ${mcIcsPath}
${pkgs.wget}/bin/wget `cat ${config.age.secrets.gcUrl.path}` -O ${gcIcsPath}
${pkgs.gawk}/bin/gawk -f ${scriptPath} ${mcIcsPath} | ${pkgs.gnugrep}/bin/grep -v 'CLOCK:' > ${orgPath}
${pkgs.gawk}/bin/gawk -f ${scriptPath} ${gcIcsPath} | ${pkgs.gnugrep}/bin/grep -v 'CLOCK:' >> ${orgPath}
'';
};
systemd.timers.ics2org = {
description = "Run ics2org every 5 minutes";
wantedBy = [ "timers.target" ];
timerConfig = {
OnUnitActiveSec = "5m";
};
};
}
Also, please note that this configuration is for a user service and timer. If you want to run this as a system service and timer, you should remove .user
from systemd.user.services.ics2org
and systemd.user.timers.ics2org
, and add wantedBy = [ "multi-user.target" ];
to the service configuration.
Use English as my only supported locale:
{
i18n.supportedLocales = [ "en_US.UTF-8/UTF-8" ];
}
Setup timezone:
{
time.timeZone = "Europe/Berlin";
}
Increase sudo timeout
{
security.sudo.extraConfig = ''
Defaults timestamp_timeout=120
'';
}
I needed to hack this to emacs29, because emacs28 failed with my org-mode config. The overlay and code block below can be trashed with version 23.11 (when emacs 29 is default)
{
boot.crashDump.enable = true;
services.displayManager = {
autoLogin = {
user = "moritz";
enable = true;
};
defaultSession = "none+exwm"; # Firefox works more fluently with plasma5+exwm instead of "none+exwm". or does it??
};
services.xserver = {
displayManager.startx.enable = false;
windowManager = {
exwm = {
enable = true;
extraPackages = epkgs: with epkgs; [ emacsql-sqlite pkgs.imagemagick pkgs.escrotum epkgs.vterm ]; # unfortunately, adding zmq and jupyter here, didn't work so I had to install them manually (i.e. compiling emacs-zmq)
# I only managed to compile emacs-zmq once (~/emacs.d/elpa/27.1/develop/zmq-.../emacs-zmq.so). I just copied it from there to mobook
# careful, 'loadScript option' was merged from Vizaxo into my personal nixpkgs repo.
loadScript = ''
(require 'exwm)
;; most of it is now in .spacemacs.d/lisp/exwm.el
(setq exwm-workspace-number 8)
(require 'exwm-systemtray)
(require 'exwm-randr)
;; (setq exwm-randr-workspace-monitor-plist '(0 "eDP1" 1 "HDMI1" 2 "DP2" 3 "eDP1" 4 "HDMI1" 5 "DP2"))
;; (setq exwm-randr-workspace-monitor-plist '(0 "eDP1" 1 "eDP1" 2 "HDMI1" 3 "eDP1" 4 "eDP1" 5 "eDP1"))
(exwm-randr-enable) ;; for the old EXWM 0.28 version
(exwm-systemtray-enable)
(exwm-enable)
;; (exwm-randr-mode) ;; I think this would be for the new version
'';
};
stumpwm.enable = false;
};
desktopManager = {
xterm.enable = false;
plasma5.enable = true;
xfce = {
enable = true;
noDesktop= true;
enableXfwm = true;
};
};
};
services.picom.enable = false; # required for KDE connect but does not work anyways... might be responsible for weird/slow behaviour a couple of minutes after boot
}
These packages are used by my desktop setup
{
environment.systemPackages = [
pkgs.wmname
pkgs.xclip
pkgs.clipit
pkgs.escrotum
pkgs.graphviz
];
}
https://github.com/bsag/nixos-config/blob/330e34c40aba37664bbc20550bf4dd427f0e4788/configuration.nix
{
environment.systemPackages = with pkgs; [
dunst
];
systemd.user.services."dunst" = {
enable = true;
description = "";
wantedBy = [ "default.target" ];
serviceConfig.Restart = "always";
serviceConfig.RestartSec = 2;
serviceConfig.ExecStart = "${pkgs.dunst}/bin/dunst";
};
}
{
systemd.services.fix-enter-iso3 = {
script = ''
/run/current-system/sw/bin/setkeycodes 0x1c 58 # enter
/run/current-system/sw/bin/setkeycodes 0x2b 28 # enter
/run/current-system/sw/bin/setkeycodes e038 86 # map alt gr to less than/greater than international key. should fix some issues in browser-based excel etc.
'';
wantedBy = [ "multi-user.target" ];
};
services.xserver.xkb.options= "lv5:rwin_switch_lock,terminate:ctrl_alt_bksp,altwin:swap_lalt_lwin";
}
{
services.xserver.xkb.layout = "de,de,us";
services.xserver.xkb.variant = "bone,,";
environment.systemPackages = [ pkgs.xorg.xmodmap ];
# Use same config for linux console
console.useXkbConfig = true;
}
{
services.xserver.xkb.options= "lv5:rwin_switch_lock,terminate:ctrl_alt_bksp,altwin:swap_lalt_lwin";
}
{
services.xserver.xkb.options= "lv5:rwin_switch_lock,terminate:ctrl_alt_bksp";
}
https://askubuntu.com/questions/41213/what-does-key-to-choose-5th-level-in-gnome-keyboard-properties-do nixos-section <- continue here i created the a folder in nixos-config https://nixos.wiki/wiki/Keyboard_Layout_Customization
{
services.xserver.autoRepeatDelay = 150;
services.xserver.autoRepeatInterval = 35;
# Use same config for linux console
console.useXkbConfig = true;
}
{
# services.xserver.synaptics.enable = true;
# services.xserver.synaptics.dev = "/dev/input/event7";
# services.xserver.synaptics.tapButtons = false;
# services.xserver.synaptics.buttonsMap = [ 1 3 2 ];
# services.xserver.synaptics.twoFingerScroll = true;
# services.xserver.synaptics.palmDetect = false;
# services.xserver.synaptics.accelFactor = "0.001";
# services.xserver.synaptics.additionalOptions = ''
# Option "SHMConfig" "on"
# Option "VertScrollDelta" "-100"
# Option "HorizScrollDelta" "-100"
# Option "Resolution" "370"
# '';
services.unclutter = {
enable = true;
};
}
{
hardware.logitech.wireless.enable = true;
hardware.logitech.wireless.enableGraphical = true;
}
Redshift adjusts the color temperature of the screen according to the position of the sun.
Blue light blocks melatonin (sleep harmone) secretion, so you feel less sleepy when you stare at computer screen. `Redshift` blocks some blue light (making screen more red), which should improve melatonin secretion and sleepiness (which is a good thing).
NOTE: I disabled it because it doesn’t allow time control. seasons (sunrise, sunset) shouldn’t matter actually
{
services.redshift = {
enable = true;
brightness.night = "1";
temperature.night = 2800;
extraOptions = [
"-l manual"
"-l 0.0:0.0"
];
};
location.provider = "geoclue2";
systemd.services.resume-redshift-restart = {
description = "Restart redshift after resume to workaround bug not reacting after suspend/resume";
wantedBy = [ "sleep.target" ];
after = [ "systemd-suspend.service" "systemd-hybrid-sleep.service" "systemd-hibernate.service" ];
script = ''
/run/current-system/sw/bin/systemctl restart [email protected] --user redshift
'';
serviceConfig.Type = "oneshot";
};
}
xbacklight
stopped working recently. acpilight
is a drop-in replacement.
{
hardware.acpilight.enable = true;
environment.systemPackages = [
pkgs.acpilight
pkgs.brightnessctl
];
users.users.moritz.extraGroups = [ "video" ];
}
I’m not a font guru, so I just stuffed a bunch of random fonts in here.
{
fonts = {
# fontDir.enable = true; # 21.03 rename
fontDir.enable = true;
enableGhostscriptFonts = false;
packages = with pkgs; [
corefonts
inconsolata
dejavu_fonts
source-code-pro
ubuntu_font_family
unifont
# Used by Emacs
# input-mono
libertine
];
};
}
Also see https://wiki.archlinux.org/title/HiDPI (e.g. for GDK_SCALE)
Be careful: ~/.spacemacs.d/.spacemacs.env does not update and overwrites env-variables…
xserver-dpi is also controlled in ~/.Xresources <- this influences URXVT and emacs/EXWM itself!
{
console.packages = [
pkgs.terminus_font
];
environment.variables = {
GDK_SCALE = "1"; # this one impacts inkscape and only takes integers (1.3 would be ideal..., 2 is too much..)
GDK_DPI_SCALE = "1.2"; # this only scales text and can take floats
QT_SCALE_FACTOR = "1.2"; # this one impacts qutebrowser
QT_AUTO_SCREEN_SCALE_FACTOR = "1.4";
};
console.font = "ter-132n";
}
{
services.xserver.dpi = 220;
}
This one seems to determine chrome
{
services.xserver.dpi = 140; # was 130,
services.xserver.upscaleDefaultCursor = true;
}
{
services.xserver.dpi = 200;
}
Here go applications (almost) every normal user needs.
{
programs.ssh = {
startAgent = true;
};
programs.gnupg.agent = {
enable = true;
enableSSHSupport = false;
pinentryPackage = pkgs.pinentry-qt;
};
# is it no longer needed?
# systemd.user.sockets.gpg-agent-ssh = {
# wantedBy = [ "sockets.target" ];
# listenStreams = [ "%t/gnupg/S.gpg-agent.ssh" ];
# socketConfig = {
# FileDescriptorName = "ssh";
# Service = "gpg-agent.service";
# SocketMode = "0600";
# DirectoryMode = "0700";
# };
# };
services.pcscd.enable = true;
}
{
environment.systemPackages = with pkgs; [
filezilla
];
}
{
programs.kdeconnect.enable = false; # segfaulted unfortunately. probably because it was also enabled in home.nix (https://discourse.nixos.org/t/kernel-panic-how-to-retrieve-logs/49983)
}
{
services.minidlna = {
enable = true;
openFirewall = true;
settings.media_dir= [ "/mnt/ssd2tb/Media/Filme" ];
};
}
{
environment.systemPackages = with pkgs; [
element-desktop
];
}
Install password-store along with one-time password extension.
{
environment.systemPackages = with pkgs; [
(pass.withExtensions (exts: [ exts.pass-otp ]))
pinentry-curses
pinentry-qt
pinentry-emacs
expect
];
# services.keepassx.enable = true;
}
I don’t use full KDE but some apps are definitely nice.
{
environment.systemPackages = [
pkgs.gwenview
pkgs.filelight
pkgs.shared-mime-info
];
}
KDE apps might have issues with mime types without this:
{
environment.pathsToLink = [ "/share" ];
}
Google Chrome used to be my default browser and I still use it from time to time.
{
programs.browserpass.enable = true;
environment.systemPackages = [
# pkgs.google-chrome # not available for aarch64
pkgs.chromium
];
}
I use Firefox Quantum as my default browser now.
{
environment.systemPackages = [
(pkgs.firefox.override { nativeMessagingHosts = [ pkgs.passff-host ]; })
];
}
{
environment.systemPackages =
let wrapper = pkgs.writeScriptBin "qutebrowser-niced" ''
#!${pkgs.stdenv.shell}
exec nice --adjustment="-6" ${pkgs.qutebrowser}/bin/qutebrowser
'';
in
[ pkgs.qutebrowser wrapper ];
environment.variables.QUTE_BIB_FILEPATH = "/home/moritz/wiki/papers/references.bib";
}
Zathura is a cool document viewer with Vim-like bindings.
{
environment.systemPackages = [
pkgs.zathura
];
}
Enable incremental search (Zathura’s config goes to ~/.config/zathura/zathurarc
).
set incremental-search true
These are my rebinding for Workman layout (swap j/k):
map j scroll up
map k scroll down
{
# environment.systemPackages = with pkgs; [ xournalpp masterpdfeditor qpdfview sioyek evince adobe-reader pdftk scribus ]; # unstable.sioyek fails tzz
}
{
environment.systemPackages = [
pkgs.weylus
];
networking.firewall.allowedTCPPorts = [ 1701 9001 ]; # syncthing as well, and FTP; and 5000 for vispr
users.groups.uinput = {};
users.users.moritz.extraGroups = [ "uinput" ];
services.udev.extraRules = ''
KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput"
'';
}
Slock is a simple X display locker and should probably not crash as xscreensaver does.
Slock tries to disable OOM killer (so the locker is not killed when memory is low) and this requires a suid flag for executable. Otherwise, you get the following message:
slock: unable to disable OOM killer. Make sure to suid or sgid slock.
{
programs.slock.enable = true;
}
xss-lock is a small utility to plug a screen locker into screen saver extension for X. This automatically activates selected screensaver after a period of user inactivity, or when system goes to sleep.
{
environment.systemPackages = [
pkgs.xss-lock
];
}
{
environment.systemPackages = with pkgs; [
igv
];
}
{
environment.systemPackages =
let wrapper = pkgs.writeScriptBin "spotify-highres" ''
#!${pkgs.stdenv.shell}
exec ${pkgs.spotify}/bin/spotify --force-device-scale-factor=2
'';
in
[ pkgs.spotify wrapper pkgs.playerctl ];
}
{
services.tor.enable = false;
services.tor.client.enable = false;
# environment.systemPackages = [ pkgs.tor-browser-bundle-bin ]; # aarch64 not supported
}
{
environment.systemPackages = [ pkgs.steam-run pkgs.steam ];
hardware.opengl.driSupport32Bit = true;
hardware.opengl.extraPackages32 = with pkgs.pkgsi686Linux; [ libva vaapiIntel];
hardware.pulseaudio.support32Bit = true;
programs.steam.package = pkgs.steam.override {
extraLibraries = pkgs: (with config.hardware.opengl;
if pkgs.hostPlatform.is64bit
then [ package ] ++ extraPackages
else [ package32 ] ++ extraPackages32)
++ [ pkgs.libxcrypt ];
};
}
{
environment.systemPackages = [ pkgs.steam pkgs.steam-run ];
hardware.opengl.driSupport32Bit = true;
hardware.opengl.extraPackages32 = with pkgs.pkgsi686Linux; [ libva vaapiIntel];
hardware.pulseaudio.support32Bit = true;
}
{
environment.systemPackages = with pkgs; [
#haskellPackages.pandoc
# jabref
pandoc
haskellPackages.pandoc-crossref
# haskellPackages.pandoc-citeproc # broken...
texlive.combined.scheme-full
perl538Packages.LaTeXML
];
}
{
environment.systemPackages = [ pkgs.supercollider ];
}
{
# virtualisation.virtualbox.host.enable = true;
users.extraGroups.vboxusers.members = [ "moritz" ];
virtualisation.virtualbox.host.enableExtensionPack = true;
}
{
environment.systemPackages = with pkgs; [
# qt5Full
aria
fd
wmctrl
unstable.nodejs_20
unstable.nodePackages_latest.npm
unstable.nodePackages_latest.eslint # required for cellxgene
mupdf
];
environment.variables.QT_QPA_PLATFORM_PLUGIN_PATH = "${pkgs.qt5.qtbase.bin.outPath}/lib/qt-${pkgs.qt5.qtbase.version}/plugins"; # need to rerun 'spacemacs/force-init-spacemacs-env' after QT updates...
}
{
environment.systemPackages = [
pkgs.davinci-resolve
];
}
{
programs.thunar.enable = true;
# discussed here: https://github.com/NixOS/nixpkgs/issues/61539
security.pam.services.emacs.enableGnomeKeyring = true;
services.gnome.gnome-keyring.enable = true;
}
Don’t require additional setup.
{
environment.systemPackages =
with pkgs;
[
# betaflight-configurator # TODO nwjs not supported for aarch64 -.-
# spotdl
homesick
miraclecast
xcolor
xorg.xgamma
vlc
aria
# jetbrains.pycharm-community # takes a lot of memeory
obs-studio
jmtpfs
qbittorrent
# unstable.blender
rclone
# teams
# discord # no aarch64
inkscape
arandr
dmenu
# # soulseekqt
gnome.cheese
gnome.gnome-screenshot
# sparkleshare_fixed
gnome.gpaste
autorandr
libnotify
feh
# kdenlive # fails in current unstable
audacity
# tdesktop # Telegram
signal-cli # Signal
signal-desktop # Signal
# unstable.zoom-us
libreoffice
# wineWowPackages.stable
# # winetricks # requires p7zip (which is unsafe...)
# gimp-with-plugins # TODO
mplayer
mpv
smplayer
lm_sensors
tcl
pymol
ruby
vscode
tesseract
dotool
lsof
];
}
- State “CANCELLED” from [2021-07-14 Wed 12:52]
this is done by home.nix
{
xdg.mime.defaultApplications = {
"inode/directory" = [ "org.xfce.Thunar.desktop" ];
"application/pdf" = [ "emacsclient.desktop" ];
"x-scheme-handler/org-protocol" = [ "org-protocol.desktop" ];
"x-scheme-handler/msteams" = [ "teams.desktop" ];
"image/png" = [ "feh.desktop" "org.inkscape.Inkscape.desktop" ];
"image/svg+xml" = [ "org.inkscape.Inkscape.desktop" ];
"x-scheme-handler/http" = [ "chromium.desktop" ];
"x-scheme-handler/https" = [ "chromium.desktop" ];
"x-scheme-handler/about" = [ "chromium.desktop" ]; # Added
"x-scheme-handler/unknown" = [ "chromium.desktop" ]; # Added
"image/jpeg" = [ "feh.desktop" "gimp.desktop" ]; # Added
"video/mp4" = [ "vlc.desktop" ]; # Added
};
}
{
environment.systemPackages = [ pkgs.niv ];
}
{
environment.systemPackages = [ pkgs.hugo ];
}
{
services.flatpak.enable = true;
}
I’m a seasoned Vim user, but I’ve switched to emacs.
{
environment.variables.EDITOR = "vim";
environment.systemPackages = [
pkgs.vim_configurable # .override { python3 = true; })
pkgs.neovim
];
}
TODO: I think this one is not called/used since I am using exwm Start emacs as a daemon:
{
services.emacs =
let emacsConfig = import .config/nixpkgs/emacs.nix { inherit pkgs; };
in {
enable = false; # TODO
defaultEditor = true;
package = emacsConfig.finalEmacs;
};
environment.systemPackages = [
pkgs.ripgrep
(pkgs.aspellWithDicts (dicts: with dicts; [en en-computers en-science ru uk]))
# pkgs.rustup
# pkgs.rustracer
# pkgs.clojure
# pkgs.leiningen
];
# environment.variables.RUST_SRC_PATH = "${pkgs.rustPlatform.rustcSrc}";
}
{
environment.systemPackages = [
pkgs.cudaPackages.cuda_nvcc
];
}
{
# leads to trouble only..
systemd.services.modem-manager.enable = false;
systemd.services."dbus-org.freedesktop.ModemManager1".enable = false;
services.udev.extraRules = ''
# Atmel DFU
### ATmega16U2
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2fef", TAG+="uaccess"
### ATmega32U2
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff0", TAG+="uaccess"
### ATmega16U4
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff3", TAG+="uaccess"
### ATmega32U4
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff4", TAG+="uaccess"
### AT90USB64
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff9", TAG+="uaccess"
### AT90USB128
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ffb", TAG+="uaccess"
### Pro Micro 5V/16MHz
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1b4f", ATTRS{idProduct}=="9205", TAG+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
## dog hunter AG
### Leonardo
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2a03", ATTRS{idProduct}=="0036", TAG+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
### Micro
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2a03", ATTRS{idProduct}=="0037", TAG+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
'';
environment.systemPackages = [ pkgs.qmk ]; # TODO might need unstable
}
{
environment.systemPackages = with pkgs; [
(pkgs.buildFHSUserEnv {
name = "micromamba-fhs";
targetPkgs = pkgs: [
pkgs.micromamba
# Add other packages if needed
(pkgs.stdenv.mkDerivation { # for fish conda initialization
name = "conda-config-files";
buildCommand = ''
mkdir -p $out/etc/fish
mkdir -p $out/etc/conda
cp $fishrc $out/etc/fish/config.fish
cp $basecondaenv $out/etc/conda/base.yaml
cp $bashrc $out/etc/bashrc.local # bashrc.local is automatically called by /etc/bashrc
'';
bashrc = pkgs.writeTextFile {
name = "bashrc-file";
text = ''
eval "$(micromamba shell hook --shell=posix)"
micromamba activate # needed, because in the `profile` script the env does not propagate :|
'';
};
fishrc = pkgs.writeTextFile {
name = "fishrc-file";
text = ''
eval "$(micromamba shell hook --shell=fish)"
micromamba activate # needed, because in the `profile` script the env does not propagate :|
'';
};
basecondaenv = pkgs.writeTextFile {
name = "base-conda-env";
text = ''
name: base
channels:
- conda-forge
- bioconda
- nodefaults
dependencies:
- conda
- python=3.12
- mamba
- virtualenv
- ca-certificates
- certifi
- openssl
- openh264
- argcomplete
- snakemake
- openpyxl
- samtools
- pyreadstat
- conda-libmamba-solver
- ipdb
- nb_conda_kernels
- libmamba
- notebook
- ipywidgets
- seaborn
- matplotlib
- ipython
prefix: /home/moritz/.mamba
'';
};
})
];
profile = ''
set -e
eval "$(micromamba shell hook --shell=posix)"
export MAMBA_ROOT_PREFIX=/home/moritz/.mamba # alternative: ${builtins.getEnv "PWD"}/.mamba
if ! test -d $MAMBA_ROOT_PREFIX; then
micromamba create --yes -q -n base
micromamba activate base
micromamba install --yes -f /etc/conda/base.yaml
fi
set +e
'';
runScript = "fish";
})
];
}
{
environment.systemPackages =
let mamba_shell_kernel_commands = pkgs.writeScript "mamba_environment" ''
#!${pkgs.stdenv.shell}
micromamba activate base
set LOG /tmp/mamba_environ_kernel_output
set SYMLINK /tmp/mamba_kernel.json
if [ -L $SYMLINK ]; then
echo "Warning: Removing symlink to old kernel."
rm $SYMLINK
fi
# Redirect the output of the first command to the named pipe and run it in the background
jupyter kernel --kernel=python 2> $LOG &
set PATTERN '/[.a-z0-9/\-]\+.json'
while ! grep -q "$PATTERN" $LOG; do sleep 0.2; done
target=$(grep -o $PATTERN $LOG)
echo $target
ln -s $target $SYMLINK
wait
rm $SYMLINK
'';
mamba_command = pkgs.writeScript "mamba_environment" ''
#!${pkgs.stdenv.shell}
micromamba "$argv"
'';
mamba_shell_cmd = pkgs.writeScript "mamba_environment" ''
#!${pkgs.stdenv.shell}
micromamba activate base
$argv
'';
kernel_wrapper = pkgs.writeShellScriptBin "mamba_kernel" ''
/run/current-system/sw/bin/micromamba-fhs ${mamba_shell_kernel_commands}
''; # TODO mamba-shell should be provided via a nix variable
mamba_wrapper = pkgs.writeShellScriptBin "mamba" ''
/run/current-system/sw/bin/micromamba-fhs ${mamba_command} "$@"
''; # TODO mamba-shell should be provided via a nix variable
repl_wrapper = pkgs.writeShellScriptBin "mamba_repl" ''
/run/current-system/sw/bin/micromamba-fhs ${mamba_shell_cmd} "python" "$@"
''; # TODO mamba-shell should be provided via a nix variable
cmd_wrapper = pkgs.writeShellScriptBin "mamba_cmd" ''
/run/current-system/sw/bin/micromamba-fhs ${mamba_shell_cmd} "$@"
''; # TODO mamba-shell should be provided via a nix variable
in [
pkgs.mamba kernel_wrapper repl_wrapper cmd_wrapper mamba_wrapper
];
}
(_self: _super: { conda = _super.conda.override { extraPkgs = [ _super.libffi_3_3 _super.libffi _super.which _super.libxcrypt ]; }; }) # this is an overlay
I use urxvt as my terminal emulator:
{
environment.systemPackages = [
pkgs.rxvt-unicode-unwrapped
];
}
Urxvt gets its setting from .Xresources
file. If you ever want to reload it on-the-fly, type the following (or press C-c C-c
if you’re reading this document in emacs now):
xrdb ~/.Xresources
See rxvt-unicode documentation for the full reference.
urxvt.loginShell: true
urxvt.saveLines: 65535
urxvt.urgentOnBell: true
urxvt.scrollBar: false
urxvt.scrollTtyOutput: false
urxvt.scrollTtyKeypress: true
urxvt.secondaryScroll: true
The next piece disables annoying message when pressing Ctrl+Shift:
urxvt.iso14755: False
Copy-paste with Ctrl+Shift+C, Ctrl+Shift+V:
From urxvt-perls:
Since version 9.20 rxvt-unicode natively supports copying to and pasting from the CLIPBOARD buffer with the Ctrl-Meta-c and Ctrl-Meta-v key bindings. The clipboard.autocopy setting is provided by the selection_to_clipboard extension shipped with rxvt-unicode.
That means, I don’t need perl extensions at all.
I use Terminus font.
{
fonts = {
packages = with pkgs; [
powerline-fonts
terminus_font
];
};
}
URxvt.font: -*-terminus-medium-r-normal-*-32-*-*-*-*-*-iso10646-1
I like Molokai color theme.
URxvt*background: #101010
URxvt*foreground: #d0d0d0
URxvt*color0: #101010
URxvt*color1: #960050
URxvt*color2: #66aa11
URxvt*color3: #c47f2c
URxvt*color4: #30309b
URxvt*color5: #7e40a5
URxvt*color6: #3579a8
URxvt*color7: #9999aa
URxvt*color8: #303030
URxvt*color9: #ff0090
URxvt*color10: #80ff00
URxvt*color11: #ffba68
URxvt*color12: #5f5fee
URxvt*color13: #bb88dd
URxvt*color14: #4eb4fa
URxvt*color15: #d0d0d0
fish is a cool shell, I use it as my default for day-to-day work.
{
programs.fish.enable = true;
users.defaultUserShell = pkgs.fish;
environment.systemPackages = [
pkgs.any-nix-shell
pkgs.mcfly
];
programs.fish.promptInit = ''
any-nix-shell fish --info-right | source
'';
# a lot more is configured in /home/moritz/.homesick/repos/dotfiles/home/.config/fish/config.fish (tracked with homesick)
}
Tangle to .config/fish/functions/fish_user_key_bindings.fish
.
function fish_user_key_bindings
fish_vi_key_bindings
bind -s j up-or-search
bind -s k down-or-search
bind -s -M visual j up-line
bind -s -M visual k down-line
bind -s '.' repeat-jump
end
{
environment.systemPackages = [
pkgs.gitFull
pkgs.gitg
pkgs.git-lfs
pkgs.git-filter-repo
];
}
Basic info: my name, email, ui, editor, rerere.
[user]
name = Moritz Schaefer
email = [email protected]
[sendemail]
smtpencryption = ssl
smtpserver = smtp.gmail.com
smtpuser = [email protected]
smtpserverport = 465
[color]
ui = true
[core]
editor = vim
[push]
default = simple
[pull]
rebase = true
[rebase]
autostash = true
[rerere]
enabled = true
[advice]
detachedHead = false
Configure signing with gpg.
[user]
signingkey = EB3066C3
[gpg]
program = gpg2
[push]
gpgSign = if-asked
I have LOTS of aliases:
[alias]
cl = clone
gh-cl = gh-clone
cr = cr-fix
p = push
pl = pull
f = fetch
fa = fetch --all
a = add
ap = add -p
d = diff
dl = diff HEAD~ HEAD
ds = diff --staged
l = log --show-signature
l1 = log -1
lp = log -p
c = commit
ca = commit --amend
co = checkout
cb = checkout -b
cm = checkout origin/master
de = checkout --detach
fco = fetch-checkout
br = branch
s = status
re = reset --hard
r = rebase
rc = rebase --continue
ri = rebase -i
m = merge
t = tag
su = submodule update --init --recursive
bi = bisect
Always push to github with ssh keys instead of login/password.
[url "[email protected]:"]
pushInsteadOf = https://github.com/
Adapted from https://github.com/srid/nixos-config/blob/master/home/tmux.nix
{
environment.systemPackages = [
pkgs.powerline
pkgs.python311Packages.powerline
];
programs.tmux = {
enable = true;
shortcut = if name == "moair" then "n" else "b";
clock24 = true;
# aggressiveResize = true; -- Disabled to be iTerm-friendly
baseIndex = 1;
newSession = true;
# Force tmux to use /tmp for sockets (WSL2 compat)
secureSocket = false;
terminal = "xterm-256color"; # seems to be the same as screen-256color
plugins = with pkgs; [
tmuxPlugins.better-mouse-mode
tmuxPlugins.jump
tmuxPlugins.sensible
];
extraConfig = ''
set -ga terminal-overrides ",*256col*:Tc"
set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q'
set-environment -g COLORTERM "truecolor"
# Mouse works as expected
set-option -g mouse on
# easy-to-remember split pane commands
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind c new-window
# copied from old tmux
set -g bell-action none
# resize
bind-key -r C-j resize-pane -D 7
bind-key -r C-k resize-pane -U 7
bind-key -r C-l resize-pane -R 7
bind-key -r C-h resize-pane -L 7
# copy like vim
bind-key C-u copy-mode \; send -X halfpage-up
bind-key v copy-mode
bind-key -T copy-mode-vi 'v' send -X begin-selection
bind-key -T copy-mode-vi 'y' send -X copy-selection
bind-key -T copy-mode-vi 'C-d' send -X halfpage-down
bind-key -T copy-mode-vi 'C-u' send -X halfpage-up
# Vim style
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xsel -i -p && xsel -o -p | xsel -i -b"
bind-key -n C-v run "xsel -ob | tmux load-buffer - ; tmux paste-buffer"
# act like vim
setw -g mode-keys vi
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
# bind-key -n Left if-shell "$is_vim" "send-keys C-h" "select-pane -L"
# bind-key -n Down if-shell "$is_vim" "send-keys C-j" "select-pane -D"
# bind-key -n Up if-shell "$is_vim" "send-keys C-k" "select-pane -U"
# bind-key -n Right if-shell "$is_vim" "send-keys C-l" "select-pane -R"
# bind-key -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L"
# bind-key -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D"
# bind-key -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U"
# bind-key -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R"
# bind-key -n C-\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"
# start window numbers at 1 to match keyboard order with tmux window order
set -g base-index 1
set-window-option -g pane-base-index 1
# renumber windows sequentially after closing any of them
set -g renumber-windows on
# soften status bar color from harsh green to light gray
set -g status-bg '#666666'
set -g status-fg '#aaaaaa'
# remove administrative debris (session name, hostname, time) in status bar
set -g status-left ""
set -g status-right ""
# TODO what are these doing?
set -g prefix2 none
# prefix -> back-one-character
bind-key C-b send-prefix
# prefix-2 -> forward-incremental-history-search
bind-key C-s send-prefix -2
# don't suspend-client
unbind-key C-z
# don't kill tab on d
unbind-key C-d
# need to redefine next
bind n next-window
set-option -g default-shell $SHELL
# reload config
bind-key r source-file ~/.tmux.conf \; \
display-message "source-file done"
# Local config
if-shell "[ -f ~/.tmux.conf.local ]" 'source ~/.tmux.conf.local'
## set the default TERM
## update the TERM variable of terminal emulator when creating a new session or attaching a existing session
set -g update-environment 'DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY TERM'
source-file /run/current-system/sw/lib/python3.11/site-packages/powerline/bindings/tmux/powerline.conf
'';
};
}
# TODO override R package (openssl)
{
environment.systemPackages = let my-r-packages = with pkgs.rPackages; [ ggplot2 eulerr gridExtra INSPEcT XVector S4Vectors MAGeCKFlute openxlsx tidyverse enrichR];
R-with-my-packages = pkgs.rWrapper.override{ packages = my-r-packages; };
RStudio-with-my-packages = pkgs.rstudioWrapper.override{ packages = my-r-packages; };
in [ R-with-my-packages RStudio-with-my-packages ];
}
{
environment.systemPackages =
let python = (with pkgs; python3.withPackages (python-packages: with python-packages;
let opencvGtk = opencv4.override (old : { enableGtk2 = true; enableGStreamer = true; });
eaf-deps = [
# pyqt5 sip
# pyqtwebengine
epc lxml
# eaf-file-browser
qrcode
# eaf-browser
pysocks
# eaf-pdf-viewer
pymupdf
# eaf-file-manager
pypinyin
# eaf-system-monitor
psutil
# eaf-markdown-previewer
retry
markdown
];
orger-pkgs = [
orger
hpi
pdfannots # required for pdfs
datasets # for twint (twitter)
twint
];
# orger-pkgs ++ # temporarily disabled because of github installation issue
in eaf-deps ++ [
# gseapy
pymol
umap-learn
icecream
plotly
pytorch
# ignite
# pytorch-lightning
# pytorch-geometric
python3
black
pandas
XlsxWriter
# opencvGtk
openpyxl
biopython
scikitlearn
wandb
imageio
matplotlib
pyproj
seaborn
requests
pillow
ipdb
isort
tox
tqdm
xlrd
pyyaml
# matplotlib-venn
networkx
statsmodels
# up-set-plot
# jedi
# json-rpc
# service-factory
debugpy
# faster-whisper # fails on moair!
# private-gpt # fails on moair!
fritzconnection
# jupyter
# jupyter_core
powerline
adjust-text
# up-set-plot
# moritzsphd
tabulate
# swifter
# gffutils
# pyensembl # fails due to serializable
# pybedtools
pybigwig
xdg
# importmagic epc # disabled because it runs ages during startup of emacs
jupyterlab
jupyter_console
ipykernel
pyperclip
# scikit-plot
# scikit-bio
powerline
python-lsp-server
smogn
docker
absl-py
hjson
pygments
# ptvsd
])); in with pkgs.python3Packages; [
python # let is stronger than with, which is why this installs the correct python (the one defined above)
pkgs.rPackages.orca # required for plotly
pkgs.pipenv
pip
pkgs.pyright
python-lsp-server
selenium
# pkgs.zlib
#pkgs.zlib.dev
# nur-no-pkgs.repos.moritzschaefer.python3Packages.cytoflow
];
# Adding libstdc++ to LD_LIB_PATH to fix some python imports (https://nixos.wiki/wiki/Packaging/Quirks_and_Caveats) # TODO might not work anymore because of libgl?
# environment.variables.LD_LIBRARY_PATH = with pkgs; "$LD_LIBRARY_PATH:${stdenv.cc.cc.lib}/lib"; # for file libstdc++.so.6 # TODO disabled after 23.11 because it was buggy
}
( let
myOverride = rec {
packageOverrides = _self: _super: {
# python-socks = _super.buildPythonPackage rec { # overwrite because too old
# pname = "python-socks";
# version = "2.0.3";
# src = _super.fetchPypi {
# inherit pname version;
# # sha256 = "e3a9ca8e554733862ce4d8ce1d10efb480fd3a3acdafd03393943ec00c98ba8a"; 2.0.3
# };
# propagatedBuildInputs = with _super; [ trio curio async-timeout anyio ];
# };
# aiohttp-socks-new = _super.buildPythonPackage rec { # if >=0.7 is needed
# pname = "aiohttp-socks";
# version = "0.7.1";
# propagatedBuildInputs = [ _super.aiohttp _super.attrs _self.python-socks];
# doCheck = false;
# src = _super.fetchPypi {
# inherit version;
# pname = "aiohttp_socks";
# sha256 = "2215cac4891ef3fa14b7d600ed343ed0f0a670c23b10e4142aa862b3db20341a";
# };
# };
googletransx = _super.buildPythonPackage rec {
pname = "googletransx";
version = "2.4.2";
propagatedBuildInputs = [ _super.requests ];
doCheck = false;
src = _super.fetchPypi {
inherit pname version;
sha256 = "c46567e3365c2abbe8af1004121b6303f530bf72025d1c3045ed14861902d6da";
};
};
twint = _super.buildPythonPackage rec {
pname = "twint";
version = "2.1.22";
propagatedBuildInputs = with _super; [ aiohttp aiodns beautifulsoup4 cchardet elasticsearch pysocks pandas aiohttp-socks schedule geopy fake-useragent _self.googletransx ];
postPatch = ''
substituteInPlace setup.py --replace "dataclasses" ""
'';
doCheck = false;
src = builtins.fetchGit {
url = "https://github.com/twintproject/twint/";
rev = "e7c8a0c764f6879188e5c21e25fb6f1f856a7221";
};
};
pdfannots = _super.buildPythonPackage rec {
pname = "pdfannots";
version = "0.3";
propagatedBuildInputs = [ _super.pdfminer ];
nativeBuildInputes = [ _super.setuptools-scm ];
doCheck = false;
src = _super.fetchPypi {
inherit pname version;
sha256 = "5931fdab0f06283536b58782bec16109a6c193816d6df0ab737924513ea7ed0a";
};
};
cachew = _super.buildPythonPackage rec {
pname = "cachew";
version = "0.9.0";
propagatedBuildInputs = [ _super.setuptools-scm _super.appdirs _super.sqlalchemy ];
nativeBuildInputes = [ _super.setuptools-scm ];
doCheck = false;
src = _super.fetchPypi {
inherit pname version;
sha256 = "8d2b82260e35c48e9c27efc8054c46ff3fe2c0a767e7534f1be2719541b5d8a7";
};
};
hpi =_super.buildPythonPackage rec {
pname = "HPI";
version = "0.3.20211031";
propagatedBuildInputs = [ _super.pytz _super.appdirs _super.more-itertools _super.decorator _super.click _super.setuptools-scm _super.logzero _self.cachew _super.mypy ]; # orjson
nativeBuildInputes = [ _super.setuptools-scm ];
SETUPTOOLS_SCM_PRETEND_VERSION = version;
doCheck = false;
src = builtins.fetchGit {
url = "git://github.com/karlicoss/HPI";
rev = "a1f03f9c028df9d1898de2cc14f1df4fa6d8c471";
};
};
orger =_super.buildPythonPackage rec {
pname = "orger";
version = "0.3.20210220";
propagatedBuildInputs = [ _super.appdirs _super.atomicwrites _super.setuptools-scm ];
nativeBuildInputes = [ _super.setuptools-scm ];
doCheck = false;
src = _super.fetchPypi {
inherit pname version;
sha256 = "cb6191e685c91f3bb760b2997c386e0f5e94562d13ab0dc69230c60ddbf52cf0";
};
};
service-factory =_super.buildPythonPackage rec {
pname = "service_factory";
version = "0.1.6";
propagatedBuildInputs = [ _super.pytest ];
doCheck = false;
src = _super.fetchPypi {
inherit pname version;
sha256 = "abd8e715e2d32ee83ea4bbe365d34e0f94e3068ec03683f09f4512f657e1cd64";
};
};
json-rpc =_super.buildPythonPackage rec {
pname = "json-rpc";
version = "1.13.0";
buildInputs = [ _super.pytest ];
propagatedBuildInputs = [ _super.pytest ];
doCheck = false;
src = _super.fetchPypi {
inherit pname version;
sha256 = "def0dbcf5b7084fc31d677f2f5990d988d06497f2f47f13024274cfb2d5d7589";
};
};
up-set-plot = _super.buildPythonPackage rec {
pname = "UpSetPlot";
version = "0.4.1";
buildInputs = [ _super.pytestrunner ];
propagatedBuildInputs = [ _super.matplotlib _super.pandas ];
doCheck = false;
src = _super.fetchPypi {
inherit pname version;
sha256 = "c1e23af4d90ca88d024cdea45dc3a84591cd97a80a6a3dfc18b5e7ad2b93944f";
};
};
adjust-text = _super.buildPythonPackage rec {
pname = "adjustText";
version = "0.7.3";
propagatedBuildInputs = [ _super.matplotlib _super.numpy ];
doCheck = false;
src = _super.fetchPypi {
inherit pname version;
sha256 = "b90e275a95b4d980cbbac7967914b8d66477c09bc346a0b3c9e2125bba664b06";
};
};
matplotlib-venn = _super.buildPythonPackage rec {
version = "0.11.5";
pname = "matplotlib-venn";
src = builtins.fetchGit {
url = "git://github.com/konstantint/matplotlib-venn";
rev = "c26796c9925bdac512edf48387452fbd1848c791";
};
checkInputs = [ _super.pytest ];
propagatedBuildInputs = [ _super.matplotlib _super.numpy _super.scipy ];
checkPhase = ''
pytest
'';
# Tests require extra dependencies
doCheck = false;
# meta = with stdenv.lib; {
# homepage = "https://github.com/konstantint/matplotlib-venn";
# description = "Area-weighted venn-diagrams for Python/matplotlib";
# license = licenses.mit;
# };
};
swifter = _super.buildPythonPackage rec {
version = "0.304";
pname = "swifter";
src = _super.fetchPypi {
inherit pname version;
sha256 = "5fe99d18e8716e82bce5a76322437d180c25ef1e29f1e4c5d5dd007928a316e9";
};
checkInputs = [ _super.nose ];
propagatedBuildInputs = [ _super.pandas _super.psutil _super.dask _super.tqdm
_super.ipywidgets _super.numba _super.bleach
_super.parso _super.distributed ];
disabled = _super.pythonOlder "3.7";
pythonImportsCheck = [ "swifter" ];
checkPhase = ''
nosetests
'';
# Tests require extra dependencies
doCheck = true;
# meta = with stdenv.lib; {
# homepage = "https://github.com/jmcarpenter2/swifter";
# description = "A package which efficiently applies any function to a pandas dataframe or series in the fastest available manner";
# license = licenses.mit;
# maintainers = [ maintainers.moritzs ];
# };
};
# pyensembl = _super. buildPythonPackage rec {
# version = "1.8.5";
# pname = "pyensembl";
# src = _super.fetchPypi {
# inherit pname version;
# sha256 = "13dd05aba296e4acadb14de5a974e6f73834452851a36b9237917ae85b3e060f";
# };
# propagatedBuildInputs = [ _super.numpy _super.pandas _self.datacache _super.six _self.memoized-property
# _self.gtfparse _self.tinytimer _self.serializable ];
# # pythonImportsCheck = [ "pyensembl" ];
# doCheck = false; # import fails (only) in build environment because pyensembl creates a file in root directory
# # meta = with stdenv.lib; {
# # homepage = "https://github.com/openvax/pyensembl";
# # description = " Python interface to access reference genome features (such as genes, transcripts, and exons) from Ensembl ";
# # license = licenses.asl20;
# # maintainers = [ maintainers.moritzs ];
# # };
# };
gffutils = _super.buildPythonPackage rec {
version = "0.10.1";
pname = "gffutils";
src = _super.fetchPypi {
inherit pname version;
sha256 = "a8fc39006d7aa353147238160640e2210b168f7849cb99896be3fc9441e351cb";
};
checkInputs = [ _super.nose _super.wget ];
propagatedBuildInputs = [ _super.pyfaidx _super.six _super.argh _super.argcomplete _super.simplejson ];
doCheck = false;
# checkPhase = '' # unfortunately fails
# # sh gffutils/test/data/download-large-annotation-files.sh
# # nosetests
# '';
pythonImportsCheck = [ "gffutils" ];
# meta = with stdenv.lib; {
# homepage = "https://github.com/daler/gffutils";
# description = "GFF and GTF file manipulation and interconversion http://daler.github.io/gffutils";
# license = licenses.mit;
# maintainers = [ maintainers.moritzs ];
# };
};
gtfparse = _super.buildPythonPackage rec {
version = "1.2.0";
pname = "gtfparse";
src = _super.fetchPypi {
inherit pname version;
sha256 = "2f27aa2b87eb43d613edabf27f9c11147dc595c8683b440ac1d88e9acdb85873";
};
checkInputs = [ _super.nose _super.six ];
propagatedBuildInputs = [ _super.numpy _super.pandas ];
doCheck = false;
pythonImportsCheck = [ "gtfparse" ];
# checkPhase = ''
# # PYTHONPATH='test' nosetests # fails because six is not found
# '';
# meta = with stdenv.lib; {
# homepage = "https://github.com/openvax/gtfparse";
# description = " Parsing tools for GTF (gene transfer format) files ";
# license = licenses.asl20;
# maintainers = [ maintainers.moritzs ];
# };
};
memoized-property = _super.buildPythonPackage rec {
version = "1.0.3";
pname = "memoized-property";
src = _super.fetchPypi {
inherit pname version;
sha256 = "4be4d0209944b9b9b678dae9d7e312249fe2e6fb8bdc9bdaa1da4de324f0fcf5";
};
pythonImportsCheck = [ "memoized_property" ];
doCheck = false;
# meta = with stdenv.lib; {
# homepage = "https://github.com/estebistec/python-memoized-property";
# description = "A simple python decorator for defining properties that only run their fget function once ";
# license = licenses.bsd3;
# maintainers = [ maintainers.moritzs ];
# };
};
# pybedtools = _super.buildPythonPackage rec {
# version = "0.8.1";
# pname = "pybedtools";
# src = _super.fetchPypi {
# inherit pname version;
# sha256 = "c035e078617f94720eb627e20c91f2377a7bd9158a137872a6ac88f800898593";
# };
# checkInputs = [ _super.pytest _super.numpydoc _super.psutil _super.pyyaml _super.sphinx ];
# propagatedBuildInputs = [ _super.numpy _super.pandas _super.pysam _super.six pkgs.zlib pkgs.bash pkgs.bedtools ]; # Is it OK to use pkgs here?
# checkPhase = ''
# # pytest -v --doctest-modules
# # ${_super.python.interpreter} -c 'import pybedtools' # test and import do not work in checkPhase, because the built pyx file cannot be included
# '';
# # Tests require extra dependencies
# doCheck = false;
# # meta = with stdenv.lib; {
# # homepage = "https://github.com/daler/pybedtools";
# # description = "Python wrapper -- and more -- for Aaron Quinlan's BEDTools (bioinformatics tools) http://daler.github.io/pybedtools";
# # license = licenses.gpl2;
# # };
# };
scikit-plot = _super.buildPythonPackage rec {
version = "0.3.7";
pname = "scikit-plot";
src = builtins.fetchGit {
url = "https://github.com/moritzschaefer/scikit-plot";
ref = "feature/label-dots";
rev = "70ea50616366c87ef730f53efb192217b725a9f0";
};
# src = _super.fetchPypi {
# inherit pname version;
# sha256 = "2c7948817fd2dc06879cfe3c1fdde56a8e71fa5ac626ffbe79f043650baa6242";
# };
checkInputs = [ _super.nose ];
propagatedBuildInputs = [ _super.matplotlib _self.scikitlearn _super.scipy _super.joblib ];
checkPhase = ''
nosetests
'';
};
datacache = _super.buildPythonPackage rec {
version = "1.1.5";
pname = "datacache";
src = _super.fetchPypi {
inherit pname version;
sha256 = "b2ca31b2b9d3803a49645ab4f5b30fdd0820e833a81a6952b4ec3a68c8ee24a7";
};
propagatedBuildInputs = [ _super.pandas _super.appdirs _super.progressbar33 _super.requests _self.typechecks _super.mock ];
pythonImportsCheck = [ "datacache" ];
};
# serializable = _super.buildPythonPackage rec {
# version = "0.2.1";
# pname = "serializable";
# src = _super.fetchPypi {
# inherit pname version;
# sha256 = "ec604e5df0c1236c06d190043a407495c4412dd6b6fd3b45a8514518173ed961";
# };
# checkInputs = [ _super.nose ];
# propagatedBuildInputs = [ _self.typechecks _super.six _super.simplejson ];
# checkPhase = ''
# nosetests
# '';
# # meta = with stdenv.lib; {
# # homepage = "https://github.com/iskandr/serializable";
# # description = "Base class with serialization methods for user-defined Python objects";
# # license = licenses.asl20;
# # maintainers = [ maintainers.moritzs ];
# # };
# };
tinytimer = _super.buildPythonPackage rec {
version = "0.0.0";
pname = "tinytimer";
src = _super.fetchPypi {
inherit pname version;
sha256 = "6ad13c8f01ab6094e58081a5367ffc4c5831f2d6b29034d2434d8ae106308fa5";
};
pythonImportsCheck = [ "tinytimer" ];
# meta = with stdenv.lib; {
# homepage = "https://github.com/iskandr/tinytimer";
# description = "Tiny Python benchmarking library";
# license = licenses.asl20;
# maintainers = [ maintainers.moritzs ];
# };
};
typechecks = _super.buildPythonPackage rec {
version = "0.1.0";
pname = "typechecks";
src = _super.fetchPypi {
inherit pname version;
sha256 = "7d801a6018f60d2a10aa3debc3af65f590c96c455de67159f39b9b183107c83b";
};
pythonImportsCheck = [ "typechecks" ];
# meta = with stdenv.lib; {
# homepage = "https://github.com/openvax/typechecks";
# description = "Helper functions for runtime type checking";
# license = licenses.asl20;
# maintainers = [ maintainers.moritzs ];
# };
};
easydev = _super.buildPythonPackage rec {
version = "0.12.0";
pname = "easydev";
propagatedBuildInputs = [
_super.colorama
_super.pexpect
_super.colorlog
];
src = _super.fetchPypi {
inherit pname version;
sha256 = "f4a340c5ffe193654c387d271bcd466d1fe56bf9850f2704122d3b52b1e6090d";
};
checkPhase = ''
'';
};
# attrs = _super.buildPythonPackage rec {
# pname = "attrs";
# version = "21.2.0";
# src = _super.fetchPypi {
# inherit pname version;
# sha256 = "ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb";
# };
# # macOS needs clang for testing
# checkInputs = [
# _super.pytest _super.hypothesis _super.zope_interface _super.pympler _super.coverage _super.six
# ];
# checkPhase = ''
# py.test
# '';
# # To prevent infinite recursion with pytest
# doCheck = false;
# };
requests-cache = _super.buildPythonPackage rec {
version = "0.8.0";
pname = "requests-cache";
propagatedBuildInputs = [
_super.requests
_super.appdirs
_super.attrs
_super.cattrs
_super.url-normalize
];
src = _super.fetchPypi {
inherit pname version;
sha256 = "2f80b2a43d6bb886558181133d9b74db12f1eed42c190b53d8e98ab62a0d2231";
};
checkPhase = ''
'';
};
bioservices = _super.buildPythonPackage rec {
version = "1.8.0";
pname = "bioservices";
propagatedBuildInputs = [
_super.grequests
_super.requests
_self.requests-cache
_self.easydev
_super.beautifulsoup4
_super.xmltodict
_super.lxml
_super.suds-jurko
_super.appdirs
_super.wrapt
_super.pandas
_super.colorlog
];
src = _super.fetchPypi {
inherit pname version;
sha256 = "e581f7096b0083afa1e9d5b075c46b5a8e042767ca0fedb617daa50d1e1a739f";
};
checkPhase = ''
'';
# pythonImportsCheck = [ "smogn" ];
};
gseapy = _super.buildPythonPackage rec {
version = "0.10.4";
pname = "gseapy";
propagatedBuildInputs = [
_super.scipy
_super.matplotlib
_super.requests
_super.joblib
_self.bioservices
_self.numpy
_super.pandas ];
src = _super.fetchPypi {
inherit pname version;
sha256 = "6404b79a3b5dc07ed39f6a4f67b3c662df5bd8b0d50829c2819d8921a768dffb";
};
checkPhase = ''
'';
};
smogn = _super.buildPythonPackage rec {
version = "0.1.2";
pname = "smogn";
propagatedBuildInputs = [ _self.numpy _super.pandas _super.tqdm ];
src = _super.fetchPypi {
inherit pname version;
sha256 = "6555b907f2c9df223eae8813abd09054ad6491fc8509a23fccc9d578b3e76d89";
};
checkPhase = ''
'';
# pythonImportsCheck = [ "smogn" ];
};
# I don't know how to overwrite seaborn from unstable. That's why I overwrite it manually..
# seaborn = _super.buildPythonPackage rec {
# pname = "seaborn";
# version = "0.11.1";
# disabled = _super.pythonOlder "3.6";
# doCheck = false;
# src = _super.fetchPypi {
# inherit pname version;
# sha256 = "44e78eaed937c5a87fc7a892c329a7cc091060b67ebd1d0d306b446a74ba01ad";
# };
# checkInputs = [ _super.nose ];
# propagatedBuildInputs = [ _super.pandas _super.matplotlib ];
# };
# scikitlearn_0241 = _super.buildPythonPackage rec {
# pname = "scikit-learn";
# version = "0.24.1";
# doCheck = false;
# src = _super.fetchPypi {
# inherit pname version;
# sha256 = "oDNKGALmTWVgIsO/q1anP71r9LEpg0PzaIryFRgQu98=";
# };
# buildInputs = [
# _super.pillow
# pkgs.gfortran
# pkgs.glibcLocales
# ] ++ pkgs.lib.optionals pkgs.stdenv.cc.isClang [
# pkgs.llvmPackages.openmp
# ];
# nativeBuildInputs = [
# _super.cython
# ];
# propagatedBuildInputs = [
# _super.numpy
# _super.scipy
# _super.numpy.blas
# _super.joblib
# _super.threadpoolctl
# ];
# LC_ALL="en_US.UTF-8";
# };
};
};
in _self: _super: rec {
# Add an override for each required python version.
# There’s currently no way to add a package that’s automatically picked up by
# all python versions, besides editing python-packages.nix
python2 = _super.python2.override myOverride;
python3 = _super.python3.override myOverride;
python38 = _super.python38.override myOverride;
python2Packages = python2.pkgs;
python3Packages = python3.pkgs;
# python37Packages = python37.pkgs;
python38Packages = python38.pkgs;
} )
{
environment.systemPackages = with pkgs; [ clojure leiningen ];
}
{
environment.systemPackages = with pkgs; [
libGL
zlib
zstd
gcc
pkg-config
autoconf
clang-tools
automake
autoconf-archive
libtool
zeromq
];
}
{
environment.systemPackages = with pkgs; [
bedtools
];
}
{
environment.systemPackages = [ pkgs.unstable.esphome ]; # 1.15.0 fixes bug
# from https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules
# QinHeng Electronics HL-340 USB-Serial adapter
services.udev.extraRules = ''
# CP210X USB UART
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
# FT231XS USB UART
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
# Prolific Technology, Inc. PL2303 Serial Port
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
# QinHeng Electronics HL-340 USB-Serial adapter
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
# Arduino boards
ATTRS{idVendor}=="2341", ATTRS{idProduct}=="[08][02]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
ATTRS{idVendor}=="2a03", ATTRS{idProduct}=="[08][02]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
# Arduino SAM-BA
ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="6124", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{MTP_NO_PROBE}="1"
# Digistump boards
ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0753", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
# Maple with DFU
ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="000[34]", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
# USBtiny
ATTRS{idProduct}=="0c9f", ATTRS{idVendor}=="1781", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
# USBasp V2.0
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
# Teensy boards
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666"
#TI Stellaris Launchpad
ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
#TI MSP430 Launchpad
ATTRS{idVendor}=="0451", ATTRS{idProduct}=="f432", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
#GD32V DFU Bootloader
ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
'';
}
{
environment.systemPackages = [ pkgs.arduino ];
users.users.moritz.extraGroups = [ "dialout" ];
}
{
environment.systemPackages = with pkgs; [
cookiecutter
nix-index
# gpu-burn
gdrive
tldr
nmap
sqlite
gitAndTools.hub
yt-dlp
sshfs
bash
wget
htop
glances
psmisc
zip
p7zip
unzip
unrar
bind
file
which
# utillinuxCurses
powerstat
pciutils
silver-searcher
ispell
usbutils
libv4l
v4l-utils
gparted
# etcher
powerline-fonts
xsel
tree
gitAndTools.diff-so-fancy
gitAndTools.git-hub
# pypi2nix
lsyncd
gnupg
imagemagick
gdb
ncdu
mesa-demos
patchelf
cmake
gnumake
jq
];
environment.variables.SNAKEMAKE_CONDA_PREFIX = "/home/moritz/.conda";
environment.variables.SNAKEMAKE_PROFILE = "default";
# environment.variables.NPM_CONFIG_PREFIX = "$HOME/.npm-global";
# environment.variables.PATH = "$HOME/.npm-global/bin:$PATH";
}
This install a number of default man pages for the linux/posix system.
{
documentation = {
man.enable = true;
dev.enable = true;
};
environment.systemPackages = [
pkgs.man-pages
pkgs.stdman
pkgs.posix_man_pages
pkgs.stdmanpages
];
}
{
networking = {
hostName = "moxps";
useDHCP = false;
interfaces.eth0.useDHCP = true;
interfaces.wlp2s0.useDHCP = true;
wireless.enable = false;
networkmanager.enable = true;
nat = { # NAT for wireguard
enable = true;
externalInterface = "wlp2s0";
internalInterfaces = [ "wg0" ];
};
firewall.allowedUDPPorts = [ 51820 ];
firewall.allowedTCPPorts = [ 51821 8384 21 5000 8086 ]; # syncthing as well, and FTP; and 5000 for vispr; and influxdb2
};
services.nscd.enable = true;
systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ];
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "yes";
PasswordAuthentication = false;
};
};
}
{
age.secrets.server_wireguard_private.file = "/home/moritz/nixos-config/secrets/wireguard_server_private_key.age";
networking.wireguard.interfaces = {
# "wg0" is the network interface name. You can name the interface arbitrarily.
wg0 = {
# Determines the IP address and subnet of the server's end of the tunnel interface.
ips = [ "10.100.0.1/24" ];
# The port that WireGuard listens to. Must be accessible by the client.
listenPort = 51820;
# This allows the wireguard server to route your traffic to the internet and hence be like a VPN
# For this to work you have to set the dnsserver IP of your router (or dnsserver of choice) in your clients
postSetup = ''
${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o wlp2s0 -j MASQUERADE
'';
# This undoes the above command
postShutdown = ''
${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o wlp2s0 -j MASQUERADE
'';
# Path to the private key file.
#
# Note: The private key can also be included inline via the privateKey option,
# but this makes the private key world-readable; thus, using privateKeyFile is
# recommended.
privateKeyFile = config.age.secrets.server_wireguard_private.path;
# server public key is KYF+BBuoY7dNYswft+vhlNrAKjAkMIMYnkhBbHcH7Dw=
peers = [
# List of allowed peers.
{ # Phone
# Public key of the peer (not a file path).
publicKey = "iHSpBC8syb+vybBX02aDuIL16uyWfoMbljInRtvuEzU=";
# List of IPs assigned to this peer within the tunnel subnet. Used to configure routing.
allowedIPs = [ "10.100.0.2/32" ];
}
{ # Mopad & Moair
publicKey = "zdDbsCZd65as6OwRlT/PgfgDju9LwpjRhpCRIrfMhWU=";
# List of IPs assigned to this peer within the tunnel subnet. Used to configure routing.
allowedIPs = [ "10.100.0.3/32" ];
}
];
};
};
}
{
age.secrets.duckdns_password.file = "/home/moritz/nixos-config/secrets/duckdns_password.age";
services.ddclient = {
enable = true;
domains = [ "moritzs.duckdns.org" ];
protocol = "duckdns";
server = "www.duckdns.org";
username = "nouser";
passwordFile = config.age.secrets.duckdns_password.path;
};
# TODO I might need nginx to setup letsencrypt (see monix)
}
{
# FTP server
services.vsftpd = {
enable = false;
# cannot chroot && write
# chrootlocalUser = true;
writeEnable = true;
localUsers = true;
userlist = [ "moritz" ];
anonymousUserHome = "/mnt/hdd3tb/ftp_anon/";
userlistEnable = true;
anonymousUser = true;
anonymousUploadEnable = true;
anonymousMkdirEnable = true;
};
# networking.firewall.allowedTCPPorts = [ 21 ]; # defined elsewhere
services.vsftpd.extraConfig = ''
pasv_enable=Yes
pasv_min_port=51000
pasv_max_port=51800
'';
networking.firewall.allowedTCPPortRanges = [ { from = 51000; to = 51800; } ];
}
{
services.node-red = {
enable = true;
openFirewall = true;
withNpmAndGcc = true;
};
}
{
config.virtualisation.oci-containers.containers.pihole = let serverIP = "192.168.0.10"; in {
image = "pihole/pihole:latest";
ports = [
"${serverIP}:53:53/tcp"
"${serverIP}:53:53/udp"
"3080:80"
"30443:443"
];
volumes = [
"/var/lib/pihole/:/etc/pihole/"
"/var/lib/dnsmasq.d:/etc/dnsmasq.d/"
];
environment = {
ServerIP = serverIP;
};
extraOptions = [
"--cap-add=NET_ADMIN"
"--dns=127.0.0.1"
"--dns=1.1.1.1"
];
workdir = "/var/lib/pihole/";
};
}
{
config.virtualisation.oci-containers.containers = {
rhasspy = {
image = "rhasspy/rhasspy";
ports = [ "0.0.0.0:12101:12101" "11111:11111/udp" ];
extraOptions = ["--device=/dev/snd:/dev/snd"];
cmd = [ "--user-profiles" "/profiles" "--profile" "en"];
volumes = [
"/home/moritz/.config/rhasspy/profiles:/profiles"
"/etc/localtime:/etc/localtime:ro"
"/etc/asound.conf:/etc/asound.conf:ro"
];
};
};
}
influxdb2 was initialized manually: username: moritz, password: moritzsch Organization: HomeAssistant Bucket Home Assistant
{
environment.systemPackages = with pkgs; [ alsa-utils ];
virtualisation.oci-containers = {
# backend = "podman";
containers = {
homeassistant = {
volumes = [ "/var/lib/hass:/config" ];
environment.TZ = "Europe/Berlin";
ports = [ "0.0.0.0:8123:8123" ];
hostname = "homeassistant";
image = "ghcr.io/home-assistant/home-assistant:stable"; # Warning: if the tag does not change, the image will not be updated
extraOptions = [
"--network=hass"
# "--device=/dev/ttyACM0:/dev/ttyACM0" # Example, change this to match your own hardware
# "--device=/dev/ttyUSB0:/dev/ttyUSB0" # Example, change this to match your own hardware
];
};
deconz = {
image = "deconzcommunity/deconz";
ports = [ "0.0.0.0:8124:80" "0.0.0.0:8125:443" ];
extraOptions = [ "--device=/dev/ttyUSB0:/dev/ttyUSB0:rwm" "--expose" "5900" "--expose" "6080" "--network=hass" ]; # I think the exposes can be deleted
volumes = [
"/var/lib/deconz:/opt/deCONZ"
"/etc/localtime:/etc/localtime:ro"
];
};
wyoming-whisper = {
image = "rhasspy/wyoming-whisper";
ports = [ "0.0.0.0:10300:10300" ];
extraOptions = ["--network=hass"];
hostname = "wyoming-whisper";
volumes = [
"/var/lib/wyoming-whisper:/data"
];
cmd = [ "--model" "base" ]; # tiny-int8, timy, base-int8, base, and small-int8
};
wyoming-piper = {
image = "rhasspy/wyoming-piper";
ports = [ "0.0.0.0:10200:10200" ];
extraOptions = ["--network=hass"];
hostname = "wyoming-piper";
volumes = [
"/var/lib/wyoming-piper:/data"
];
cmd = [ "--voice" "en_US-lessac-medium" ];
};
openwakeword = {
image = "rhasspy/wyoming-openwakeword";
extraOptions = ["--network=hass"];
hostname = "openwakeword";
volumes = [
"/var/lib/openwakeword:/data"
# "./wakeword:/custom"
# "/etc/timezone:/etc/timezone:ro" # nonexistent on our system
"/etc/localtime:/etc/localtime:ro"
];
environment.TZ = "Europe/Vienna";
cmd = [ "--preload-model" "ok_nabu"]; # "--custom-model-dir" "/custom"
};
# TODO improve by adding configs here: https://github.com/rhasspy/wyoming-satellite (e.g. audio enhancements)
wyoming-satellite = {
image = "satellite"; # TODO reference the dockerfile here /home/moritz/wyoming-satellite/Dockerfile
ports = [ "0.0.0.0:10700:10700" ];
hostname = "wyoming-satellite";
extraOptions = [
"--network=hass"
"--device=/dev/snd:/dev/snd"
"--group-add=audio"
];
cmd = [
"--name" "living_room"
"--mic-command" "arecord -D plughw:1,0 -r 16000 -c 1 -f S16_LE -t raw"
"--snd-command" "aplay -D plughw:0,0 -r 22050 -c 1 -f S16_LE -t raw"
# "--debug"
];
};
};
};
}
}; }; services.influxdb2 = { enable = true; };
}
TODO 1: make sure that sdd2b is accessible (i.e. mounted) TODO 2: make sure to remount the two things if they drop out!
{
services.borgbackup.jobs =
let common-excludes = [
# Largest cache dirs
"*/venv"
"*/.venv"
"*/.conda"
];
borg-dirs = {
wiki="/home/moritz/wiki";
wiki_git="/home/moritz/wiki_git";
media="/mnt/ssd2tb/Media";
# moxps-home="/home/moritz";
var-lib="/var/lib";
var-backup="/var/backup"; # maybe postgresql
};
basicBorgJob = name: {
encryption.mode = "none";
# environment.BORG_RSH = "ssh -o 'StrictHostKeyChecking=no' -i /home/moritz/.ssh/id_ed25519";
environment.BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK = "yes";
extraCreateArgs = "--verbose --stats --checkpoint-interval 600";
repo = "/mnt/hdd3tb/borg/${name}";
compression = "zstd,1";
startAt = "daily"; # this means "*-*-* 00:00:00"
user = if builtins.match "^/var" name != null then "root" else "moritz";
prune.keep = {
within = "1d"; # Keep all archives from the last day
daily = 7;
weekly = 4;
monthly = 6; # half a year monthly
yearly = -1; # every year one backup forever (maybe I should change this at some point?)
};
};
in builtins.mapAttrs (name: value:
basicBorgJob name // rec {
paths = value;
exclude = map (x: paths + "/" + x) common-excludes;
}) borg-dirs;
}
{
services.nature_filter = {
enable = true; # feedly fucks
};
}
{
services.samba = {
enable = true;
securityType = "user";
openFirewall = true;
extraConfig = ''
workgroup = WORKGROUP
wins support = yes
server string = smbnix
netbios name = smbnix
security = user
#use sendfile = yes
#max protocol = smb2
hosts allow = 192.168.0.1/24 10.100.0.1/24 localhost
hosts deny = 0.0.0.0/0
guest account = nobody
map to guest = bad user
'';
shares = {
ssd2tb = {
"path" = "/mnt/ssd2tb";
"guest ok" = "yes";
"read only" = "no";
"browseable" = "yes";
"create mask" = "0644";
"directory mask" = "0755";
"force user" = "moritz";
"force group" = "users";
};
moritz = {
path = "/home/moritz/";
browseable = "yes";
"read only" = "no";
"guest ok" = "no";
"create mask" = "0644";
"directory mask" = "0755";
"force user" = "moritz";
"force group" = "users";
};
};
};
services.samba-wsdd = {
enable = true;
openFirewall = true;
};
}
{
environment.systemPackages = with pkgs; [
openai-whisper
openai-whisper-cpp
whisper-ctranslate2
];
systemd.services.smart-glass-parsing = {
description = "Smart Glass MP4 Parsing";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
# unitConfig = {
# StartLimitBurst = "0"; # set to 0 to avoid failure. Note
# };
serviceConfig = {
Type = "simple";
ExecStart = let
script = pkgs.writeShellScript "smart-glass-parsing" ''
#!/bin/sh
set -e
VIDEO_DIRECTORY="$HOME/Smart Glasses"
TARGET_DIRECTORY="$HOME/wiki/video_notes"
ORG_MODE_FILE="$HOME/wiki/gtd/video_notes.org"
for file in "$VIDEO_DIRECTORY"/*.mp4; do
[ -e "$file" ] || continue
base_name=$(basename "$file" .mp4) # this is something like 20240407_202217_959eea70.txt
txt_file="$TARGET_DIRECTORY/$base_name.txt"
if [ ! -f "$txt_file" ]; then
${pkgs.whisper-ctranslate2}/bin/whisper-ctranslate2 --model base.en -f txt --compute_type int8 --threads 4 --logprob_threshold 0.2 --no_speech_threshold 0.3 -f txt -o $TARGET_DIRECTORY "$file"
# append to the org mode file
echo "* TODO [[file:$file][$base_name]]" >> "$ORG_MODE_FILE"
echo "#+created_at: $(date +"[%Y-%m-%d %a %H:%M]")" >> "$ORG_MODE_FILE"
echo ":PROPERTIES:" >> "$ORG_MODE_FILE"
echo ":VIDEO_CREATED: $(echo $base_name | sed -E 's/([0-9]{4})([0-9]{2})([0-9]{2})_([0-9]{2})([0-9]{2})([0-9]{2})_.*/[\1-\2-\3 \4:\5:\6]/')" >> "$ORG_MODE_FILE"
echo ":VIDEO_FILE: $file" >> "$ORG_MODE_FILE"
echo ":END:" >> "$ORG_MODE_FILE"
cat "$txt_file" >> "$ORG_MODE_FILE"
echo "" >> "$ORG_MODE_FILE"
fi
done
'';
in "${script}";
User = "moritz";
Restart = "no";
};
};
systemd.timers."smart-glass-parsing-timer" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "10min";
OnUnitInactiveSec = "10min";
# OnCalendar = "*:0/10"; # alternative (ever 10 mins)
Unit = "smart-glass-parsing.service";
};
};
# This led to unit-start-limit-hit'.
# systemd.paths.smart-glass-watcher = {
# description = "Watch Smart Glasses Video Directory for New Files";
# pathConfig = {
# PathExistsGlob = "/home/moritz/Smart Glasses/*.mp4"; # TODO better watch the directory (how cares if it is triggered for mp4s)?
# Unit = "smart-glass-parsing.service";
# # TriggerLimitIntervalSec= "10"; # 2 is the default
# TriggerLimitBurst= "0"; # 200 is default. 0 is "no triggering"
# };
# wantedBy = [ "multi-user.target" ];
# };
}
Need to run docker compose run –rm certbot renew docker compose exec nginx nginx -s reload
within /home/moritz/Projects/cellwhisperer/hosting/home/docker-compose.yml