Compare commits

...

6 Commits

Author SHA1 Message Date
7499a21cbd feat: nb add wim-api project 2025-10-22 12:31:53 +02:00
5758b3a320 fix(nvim): enable yaml syntax highlighting for sops files
Add BufReadPre autocmd to set filetype=yaml before buffer is loaded,
ensuring syntax highlighting works immediately when opening encrypted
sops files. Also updated BufReadPost to unconditionally set yaml
filetype after decryption.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 12:29:10 +02:00
7d2f818fca feat: nb add env variable for sops 2025-10-22 11:58:58 +02:00
19d0946e06 feat: add sops to vim 2025-10-22 09:52:40 +02:00
7d5294e7b9 fix: hibernate resume for nb 2025-10-19 18:14:40 +02:00
28ed3fcf74 fix(nb): resolve keyboard/touchpad and btrfs read-only issues after suspend
This commit addresses two critical suspend/resume issues on the nb host:

1. Keyboard and touchpad not working after suspend
   - Added i2c_hid_acpi kernel module
   - Created systemd service to reload the module after resume
   - Excluded input devices from TLP USB autosuspend

2. /nix/persist becoming read-only after suspend
   - Moved swap from /nix/persist to dedicated @swap subvolume
   - Added systemd service to remount /nix/persist if needed
   - Separated swap from persistent data to prevent btrfs corruption

Changes:
- Created hosts/nb/modules/suspend-fixes.nix with resume hooks
- Updated swap path from /nix/persist/swapfile to /swap/swapfile
- Added /swap filesystem mount for @swap btrfs subvolume
- Added USB_EXCLUDE_INPUT=1 to TLP configuration

Note: Manual step required before deployment - create @swap subvolume.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-19 16:43:02 +02:00
8 changed files with 204 additions and 6 deletions

View File

@@ -30,6 +30,7 @@ in {
./modules/ollama.nix
./modules/qdrant.nix
./modules/battery-brightness.nix
./modules/suspend-fixes.nix
./cachix.nix
./users
@@ -71,6 +72,14 @@ in {
theme = "steeef"; # Set theme
plugins = [ "git" ]; # Add plugins
};
interactiveShellInit = ''
# Bind Shift+Return to insert newline (foot terminal sends \e[27;2;13~)
insert-newline() {
LBUFFER="''${LBUFFER}"$'\n'
}
zle -N insert-newline
bindkey '^[[27;2;13~' insert-newline
'';
};
users.defaultUserShell = pkgs.zsh;
@@ -79,7 +88,7 @@ in {
services.irqbalance.enable = false;
swapDevices = [ {
device = "/nix/persist/swapfile";
device = "/swap/swapfile";
size = 96 * 1024; # Size is in megabytes (96GB for full hibernation with 92GB RAM)
} ];
@@ -92,8 +101,8 @@ in {
# Battery optimization - increase dirty writeback time to batch writes
"vm.dirty_writeback_centisecs" = 3000; # 30 seconds (default: 500 = 5s)
"vm.dirty_expire_centisecs" = 3000; # 30 seconds (default: 3000)
# Enable laptop mode for aggressive disk power management
"vm.laptop_mode" = 5;
# Enable laptop mode for disk power management (2 = balanced, less aggressive than 5)
"vm.laptop_mode" = 2;
};
# nixos cross building qemu

View File

@@ -28,7 +28,6 @@
"snd_hda_intel.power_save=1"
"transparent_hugepage=madvise"
"pcie_aspm=force"
"nvme.noacpi=1"
];
fileSystems."/" = {
@@ -92,6 +91,16 @@
];
};
fileSystems."/swap" = {
device = "/dev/mapper/root";
fsType = "btrfs";
neededForBoot = true;
options = [
"subvol=@swap"
"noatime"
];
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking

View File

@@ -159,6 +159,7 @@ in {
USB_EXCLUDE_PHONE = 0;
USB_EXCLUDE_PRINTER = 1;
USB_EXCLUDE_WWAN = 0;
USB_EXCLUDE_INPUT = 1; # Exclude keyboard/touchpad to prevent suspend issues
# Audio power saving
SOUND_POWER_SAVE_ON_AC = 0;

View File

@@ -0,0 +1,152 @@
-- SOPS integration for automatic encryption/decryption of secrets files
-- This module sets up autocmds to handle .secrets.yaml files transparently
local sops_group = vim.api.nvim_create_augroup("SopsEncryption", { clear = true })
-- Pattern matching for secrets files
local secrets_patterns = {
"*/secrets.yaml",
"*secrets*.yaml",
}
-- Helper function to check if file matches secrets pattern
local function is_secrets_file(filepath)
for _, pattern in ipairs(secrets_patterns) do
if vim.fn.match(filepath, vim.fn.glob2regpat(pattern)) ~= -1 then
return true
end
end
return false
end
-- Set filetype before reading to enable syntax highlighting
vim.api.nvim_create_autocmd("BufReadPre", {
group = sops_group,
pattern = secrets_patterns,
callback = function(args)
-- Set filetype to yaml before the file is read so syntax highlighting works
vim.bo.filetype = "yaml"
end,
})
-- Decrypt file after reading
vim.api.nvim_create_autocmd("BufReadPost", {
group = sops_group,
pattern = secrets_patterns,
callback = function(args)
local filepath = vim.fn.expand("%:p")
-- Only decrypt if file exists and has content
if vim.fn.filereadable(filepath) == 1 and vim.fn.getfsize(filepath) > 0 then
-- Save cursor position
local cursor_pos = vim.api.nvim_win_get_cursor(0)
-- Decrypt file content
local result = vim.fn.system("sops --decrypt " .. vim.fn.shellescape(filepath))
if vim.v.shell_error == 0 then
-- Replace buffer content with decrypted content
vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.split(result, "\n"))
-- Mark buffer as not modified (since we just loaded it)
vim.bo.modified = false
-- Restore cursor position
pcall(vim.api.nvim_win_set_cursor, 0, cursor_pos)
-- Disable swap, backup, and undo files for security
vim.bo.swapfile = false
vim.bo.backup = false
vim.bo.writebackup = false
vim.bo.undofile = false
-- Ensure filetype is set to yaml for syntax highlighting
vim.bo.filetype = "yaml"
vim.notify("SOPS: File decrypted successfully", vim.log.levels.INFO)
else
vim.notify("SOPS: Failed to decrypt file: " .. result, vim.log.levels.ERROR)
end
end
end,
})
-- Encrypt file before writing
vim.api.nvim_create_autocmd("BufWritePre", {
group = sops_group,
pattern = secrets_patterns,
callback = function(args)
local filepath = vim.fn.expand("%:p")
if is_secrets_file(filepath) then
-- Get current buffer content
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
local content = table.concat(lines, "\n")
-- Encrypt content using SOPS
local encrypted = vim.fn.system("sops --encrypt /dev/stdin", content)
if vim.v.shell_error == 0 then
-- Write encrypted content directly to file
local file = io.open(filepath, "w")
if file then
file:write(encrypted)
file:close()
-- Mark buffer as saved (prevent Vim from writing again)
vim.bo.modified = false
vim.notify("SOPS: File encrypted and saved successfully", vim.log.levels.INFO)
else
vim.notify("SOPS: Failed to write encrypted file", vim.log.levels.ERROR)
end
else
vim.notify("SOPS: Failed to encrypt file: " .. encrypted, vim.log.levels.ERROR)
-- Prevent write on encryption failure
return true
end
-- Prevent default write behavior since we handled it
return true
end
end,
})
-- Re-decrypt after writing to show plaintext in buffer
vim.api.nvim_create_autocmd("BufWritePost", {
group = sops_group,
pattern = secrets_patterns,
callback = function(args)
local filepath = vim.fn.expand("%:p")
if is_secrets_file(filepath) and vim.fn.filereadable(filepath) == 1 then
-- Decrypt and reload buffer content
local result = vim.fn.system("sops --decrypt " .. vim.fn.shellescape(filepath))
if vim.v.shell_error == 0 then
-- Save cursor position
local cursor_pos = vim.api.nvim_win_get_cursor(0)
-- Replace buffer with decrypted content
vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.split(result, "\n"))
-- Mark as not modified
vim.bo.modified = false
-- Restore cursor position
pcall(vim.api.nvim_win_set_cursor, 0, cursor_pos)
end
end
end,
})
-- Warn when leaving a secrets buffer with unsaved changes
vim.api.nvim_create_autocmd("BufLeave", {
group = sops_group,
pattern = secrets_patterns,
callback = function(args)
if vim.bo.modified then
vim.notify("Warning: Unsaved changes in secrets file!", vim.log.levels.WARN)
end
end,
})

View File

@@ -102,6 +102,7 @@ in
"utils"
"bufferline"
"which-key"
"sops"
]);
in ''
lua << EOF

View File

@@ -0,0 +1,24 @@
{ config, pkgs, lib, ... }:
{
# Add i2c_hid_acpi kernel module for proper input device support
boot.kernelModules = [ "i2c_hid_acpi" ];
# Commands to run after resume from suspend/hibernate
# This is the NixOS-native way to ensure proper execution timing
powerManagement.resumeCommands = ''
# Reload i2c_hid_acpi module to fix keyboard/touchpad after suspend
${pkgs.kmod}/bin/rmmod i2c_hid_acpi || true
${pkgs.kmod}/bin/modprobe i2c_hid_acpi
# Sync filesystem to ensure all pending writes are committed
${pkgs.util-linux}/bin/sync
# Remount all btrfs subvolumes read-write if they became read-only
# This fixes the issue where LUKS + btrfs can remount read-only after suspend
${pkgs.util-linux}/bin/mount -o remount,rw /nix || true
${pkgs.util-linux}/bin/mount -o remount,rw /nix/store || true
${pkgs.util-linux}/bin/mount -o remount,rw /nix/persist || true
${pkgs.util-linux}/bin/mount -o remount,rw /swap || true
'';
}

View File

@@ -46,7 +46,7 @@
/home/dominik/projects/epicenter.works/epicenter.works-website
/home/dominik/projects/epicenter.works/epicenter-nixos
/home/dominik/projects/epicenter.works/spenden.akvorrat.at
/home/dominik/projects/epicenter.works/eidas.monitor
/home/dominik/projects/epicenter.works/whoidentifies.me/wim-api
/home/dominik/projects/cloonar/lena-schilling-website
/home/dominik/projects/cloonar/dialog-relations-website

View File

@@ -165,6 +165,7 @@ in
programs.zsh = {
shellInit = ''
export OPENAI_API_KEY=$(cat ${config.sops.secrets.openai_api_key.path})
export SOPS_AGE_KEY_FILE="$HOME/.config/sops/age/key.age"
'';
};
@@ -175,6 +176,7 @@ in
home.enableNixpkgsReleaseCheck = false;
home.sessionVariables = {
MOZ_ENABLE_WAYLAND = "1";
SOPS_AGE_KEY_FILE = "$HOME/.config/sops/age/key.age";
};
nixpkgs.config.allowUnfree = true;
@@ -625,7 +627,7 @@ in
git clone git@github.com:AKVorrat/epicenter.works-website.git ${persistHome}/projects/epicenter.works/epicenter.works-website 2>/dev/null
git clone git@github.com:AKVorrat/spenden.akvorrat.at.git ${persistHome}/projects/epicenter.works/spenden.akvorrat.at 2>/dev/null
git clone git@github.com:AKVorrat/dearmep-website.git ${persistHome}/projects/epicenter.works/dearmep-website 2>/dev/null
git clone gitea@git.cloonar.com:Cloonar/eidas.monitor.git ${persistHome}/projects/epicenter.works/eidas.monitor 2>/dev/null
git clone git@github.com:whoidentifies-me/api.git ${persistHome}/projects/epicenter.works/whoidentifies.me/wim-api 2>/dev/null
set -eu
'';