Compare commits
1 Commits
main
...
e98ac9bb85
| Author | SHA1 | Date | |
|---|---|---|---|
|
e98ac9bb85
|
@@ -1,8 +1,6 @@
|
|||||||
# nix fmt & statix
|
# nix fmt & statix
|
||||||
f011c8d71ba09bd94ab04b8d771858b90a03fbf9
|
f011c8d71ba09bd94ab04b8d771858b90a03fbf9
|
||||||
3aff25b4486a143cd6282f8845c16216598e1c7e
|
3aff25b4486a143cd6282f8845c16216598e1c7e
|
||||||
2204b12fadf27886058e6945806ce93a547f5278
|
|
||||||
77236af5896524218605badcd3cdfc2267b213da
|
|
||||||
|
|
||||||
# host rename
|
# host rename
|
||||||
cfe4c43887a41e52be4e6472474c0fc3788f86e8
|
cfe4c43887a41e52be4e6472474c0fc3788f86e8
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
{
|
|
||||||
nixos =
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.bootloader;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [ inputs.lanzaboote.nixosModules.lanzaboote ];
|
|
||||||
|
|
||||||
options.features.bootloader = {
|
|
||||||
enable = lib.mkEnableOption "bootloader";
|
|
||||||
|
|
||||||
mode = lib.mkOption {
|
|
||||||
type = lib.types.enum [
|
|
||||||
"systemd-boot"
|
|
||||||
"lanzaboote"
|
|
||||||
];
|
|
||||||
default = "systemd-boot";
|
|
||||||
};
|
|
||||||
|
|
||||||
plymouth.enable = lib.mkEnableOption "plymouth boot splash";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
|
||||||
lib.mkMerge [
|
|
||||||
{
|
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
|
||||||
# request the largest framebuffer uefi offers; plymouth inherits it
|
|
||||||
boot.loader.systemd-boot.consoleMode = "max";
|
|
||||||
}
|
|
||||||
|
|
||||||
(lib.mkIf (cfg.mode == "systemd-boot") {
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf (cfg.mode == "lanzaboote") {
|
|
||||||
boot.loader.systemd-boot.enable = lib.mkForce false;
|
|
||||||
boot.lanzaboote = {
|
|
||||||
enable = true;
|
|
||||||
pkiBundle = "/var/lib/sbctl";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf cfg.plymouth.enable {
|
|
||||||
# plymouth needs systemd-initrd to render the luks prompt cleanly
|
|
||||||
boot.initrd.systemd.enable = true;
|
|
||||||
|
|
||||||
# host is responsible for early-KMS so plymouth lands on the gpu driver,
|
|
||||||
# not simpledrm (e.g. hardware.amdgpu.initrd.enable on amd hosts)
|
|
||||||
boot.plymouth.enable = true;
|
|
||||||
stylix.targets.plymouth.logoAnimated = false;
|
|
||||||
|
|
||||||
boot.kernelParams = [
|
|
||||||
"quiet"
|
|
||||||
"splash"
|
|
||||||
"loglevel=3"
|
|
||||||
"rd.systemd.show_status=false"
|
|
||||||
"rd.udev.log_level=3"
|
|
||||||
"udev.log_priority=3"
|
|
||||||
"plymouth.force-scale=1"
|
|
||||||
];
|
|
||||||
boot.consoleLogLevel = 0;
|
|
||||||
boot.initrd.verbose = false;
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
22
features/calibre.nix
Normal file
22
features/calibre.nix
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
nixos =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
environment.systemPackages = [ pkgs.calibre ];
|
||||||
|
|
||||||
|
# udev rules for kindle and mtp device access
|
||||||
|
# NOTE:(@janezicmatej) uses services.udev.packages instead of extraRules
|
||||||
|
# because extraRules writes to 99-local.rules which is too late for uaccess
|
||||||
|
# see https://github.com/NixOS/nixpkgs/issues/308681
|
||||||
|
services.udev.packages = [
|
||||||
|
pkgs.libmtp
|
||||||
|
(pkgs.writeTextFile {
|
||||||
|
name = "kindle-udev-rules";
|
||||||
|
text = ''
|
||||||
|
ACTION!="remove", SUBSYSTEM=="usb", ATTRS{idVendor}=="1949", TAG+="uaccess"
|
||||||
|
'';
|
||||||
|
destination = "/etc/udev/rules.d/70-kindle.rules";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,28 +1,10 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
options.features.claude.enable = lib.mkEnableOption "claude";
|
|
||||||
};
|
|
||||||
|
|
||||||
home =
|
home =
|
||||||
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
inputs,
|
|
||||||
osConfig,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = osConfig.features.claude;
|
|
||||||
packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
home.packages = [
|
home.packages = [
|
||||||
packages.claude-code
|
pkgs.claude-code
|
||||||
pkgs.mcp-nixos
|
pkgs.mcp-nixos
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
45
features/desktop-minimal.nix
Normal file
45
features/desktop-minimal.nix
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
nixos =
|
||||||
|
{ pkgs, inputs, ... }:
|
||||||
|
{
|
||||||
|
imports = [ inputs.stylix.nixosModules.stylix ];
|
||||||
|
|
||||||
|
# audio
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
security.polkit.enable = true;
|
||||||
|
services.dbus.enable = true;
|
||||||
|
services.playerctld.enable = true;
|
||||||
|
|
||||||
|
xdg.portal = {
|
||||||
|
enable = true;
|
||||||
|
xdgOpenUsePortal = true;
|
||||||
|
extraPortals = [
|
||||||
|
pkgs.xdg-desktop-portal-wlr
|
||||||
|
pkgs.xdg-desktop-portal-gtk
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fonts.packages = with pkgs; [
|
||||||
|
font-awesome
|
||||||
|
nerd-fonts.jetbrains-mono
|
||||||
|
];
|
||||||
|
|
||||||
|
# theming
|
||||||
|
stylix = {
|
||||||
|
enable = true;
|
||||||
|
polarity = "dark";
|
||||||
|
image = "${inputs.assets}/wallpaper.png";
|
||||||
|
base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-material-dark-medium.yaml";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home =
|
||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
home.file.".assets".source = inputs.assets;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,126 +1,59 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
|
{ pkgs, inputs, ... }:
|
||||||
{
|
{
|
||||||
config,
|
imports = [ inputs.stylix.nixosModules.stylix ];
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.desktop;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.desktop = {
|
|
||||||
enable = lib.mkEnableOption "desktop environment";
|
|
||||||
|
|
||||||
audio.enable = lib.mkOption {
|
# audio
|
||||||
type = lib.types.bool;
|
services.pipewire = {
|
||||||
default = true;
|
enable = true;
|
||||||
|
pulse.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
bluetooth.enable = lib.mkOption {
|
# bluetooth
|
||||||
type = lib.types.bool;
|
hardware.bluetooth.enable = true;
|
||||||
default = false;
|
services.blueman.enable = true;
|
||||||
};
|
|
||||||
|
|
||||||
apps.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
theme = {
|
|
||||||
wallpaper = lib.mkOption {
|
|
||||||
type = lib.types.path;
|
|
||||||
default = "${inputs.assets}/wallpaper.png";
|
|
||||||
};
|
|
||||||
|
|
||||||
scheme = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "gruvbox-material-dark-medium";
|
|
||||||
};
|
|
||||||
|
|
||||||
polarity = lib.mkOption {
|
|
||||||
type = lib.types.enum [
|
|
||||||
"dark"
|
|
||||||
"light"
|
|
||||||
];
|
|
||||||
default = "dark";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
internalCA.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
|
||||||
lib.mkMerge [
|
|
||||||
# base desktop
|
|
||||||
{
|
|
||||||
security.polkit.enable = true;
|
security.polkit.enable = true;
|
||||||
services.dbus.enable = true;
|
services.dbus.enable = true;
|
||||||
services.playerctld.enable = true;
|
services.playerctld.enable = true;
|
||||||
|
|
||||||
xdg.portal = {
|
xdg.portal = {
|
||||||
enable = true;
|
enable = true;
|
||||||
extraPortals = with pkgs; [
|
xdgOpenUsePortal = true;
|
||||||
xdg-desktop-portal-wlr
|
extraPortals = [
|
||||||
xdg-desktop-portal-gtk
|
pkgs.xdg-desktop-portal-wlr
|
||||||
|
pkgs.xdg-desktop-portal-gtk
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# honor persist_mode so electron apps don't re-prompt for screencast every login
|
|
||||||
systemd.user.services.xdg-desktop-portal-wlr.environment.XDPW_PERSIST_MODE = "permanent";
|
|
||||||
|
|
||||||
# enable ozone/wayland for electron apps so idle detection works
|
|
||||||
environment.sessionVariables.NIXOS_OZONE_WL = "1";
|
|
||||||
|
|
||||||
fonts.packages = with pkgs; [
|
fonts.packages = with pkgs; [
|
||||||
font-awesome
|
font-awesome
|
||||||
nerd-fonts.jetbrains-mono
|
nerd-fonts.jetbrains-mono
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# theming
|
||||||
stylix = {
|
stylix = {
|
||||||
enable = true;
|
enable = true;
|
||||||
inherit (cfg.theme) polarity;
|
polarity = "dark";
|
||||||
image = cfg.theme.wallpaper;
|
image = "${inputs.assets}/wallpaper.png";
|
||||||
base16Scheme = "${pkgs.base16-schemes}/share/themes/${cfg.theme.scheme}.yaml";
|
base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-material-dark-medium.yaml";
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
# audio
|
|
||||||
(lib.mkIf cfg.audio.enable {
|
|
||||||
services.pipewire = {
|
|
||||||
enable = true;
|
|
||||||
pulse.enable = true;
|
|
||||||
};
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
pavucontrol
|
|
||||||
easyeffects
|
|
||||||
];
|
|
||||||
})
|
|
||||||
|
|
||||||
# bluetooth
|
|
||||||
(lib.mkIf cfg.bluetooth.enable {
|
|
||||||
hardware.bluetooth.enable = true;
|
|
||||||
services.blueman.enable = true;
|
|
||||||
})
|
|
||||||
|
|
||||||
# apps
|
|
||||||
(lib.mkIf cfg.apps.enable {
|
|
||||||
programs.thunderbird.enable = true;
|
programs.thunderbird.enable = true;
|
||||||
|
programs._1password.enable = true;
|
||||||
|
programs._1password-gui.enable = true;
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
|
easyeffects
|
||||||
ghostty
|
ghostty
|
||||||
google-chrome
|
google-chrome
|
||||||
zathura
|
zathura
|
||||||
calibre
|
pavucontrol
|
||||||
bolt-launcher
|
bolt-launcher
|
||||||
libnotify
|
libnotify
|
||||||
bibata-cursors
|
bibata-cursors
|
||||||
discord
|
vesktop
|
||||||
rocketchat-desktop
|
rocketchat-desktop
|
||||||
telegram-desktop
|
telegram-desktop
|
||||||
slack
|
slack
|
||||||
@@ -132,142 +65,21 @@
|
|||||||
wl-mirror
|
wl-mirror
|
||||||
protonmail-bridge
|
protonmail-bridge
|
||||||
ledger-live-desktop
|
ledger-live-desktop
|
||||||
imv
|
|
||||||
yazi
|
|
||||||
nemo
|
|
||||||
file-roller
|
|
||||||
libreoffice-still
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# kindle udev rules for calibre
|
|
||||||
features.udev.kindle.enable = lib.mkDefault true;
|
|
||||||
})
|
|
||||||
|
|
||||||
# internal CA
|
# internal CA
|
||||||
(lib.mkIf cfg.internalCA.enable {
|
|
||||||
security.pki.certificateFiles = [
|
security.pki.certificateFiles = [
|
||||||
inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system}.ca-matheo-si
|
inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system}.ca-matheo-si
|
||||||
];
|
];
|
||||||
})
|
|
||||||
]
|
xdg.mime.defaultApplications = {
|
||||||
);
|
"application/pdf" = "org.pwmt.zathura.desktop";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
home =
|
home =
|
||||||
{
|
{ inputs, ... }:
|
||||||
lib,
|
|
||||||
inputs,
|
|
||||||
osConfig,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = osConfig.features.desktop;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = lib.mkIf cfg.enable (
|
|
||||||
lib.mkMerge [
|
|
||||||
{
|
{
|
||||||
home.file.".assets".source = inputs.assets;
|
home.file.".assets".source = inputs.assets;
|
||||||
}
|
|
||||||
|
|
||||||
(lib.mkIf cfg.apps.enable {
|
|
||||||
# TODO:(@janezicmatej) consider moving nvim desktop entry to neovim feature
|
|
||||||
xdg.desktopEntries.nvim = {
|
|
||||||
name = "Neovim";
|
|
||||||
exec = "ghostty -e nvim %F";
|
|
||||||
terminal = false;
|
|
||||||
mimeType = [
|
|
||||||
"text/plain"
|
|
||||||
"application/json"
|
|
||||||
"text/markdown"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
xdg.mimeApps = {
|
|
||||||
enable = true;
|
|
||||||
defaultApplications = {
|
|
||||||
# text
|
|
||||||
"text/plain" = "nvim.desktop";
|
|
||||||
"application/json" = "nvim.desktop";
|
|
||||||
"text/markdown" = "nvim.desktop";
|
|
||||||
|
|
||||||
# web
|
|
||||||
"text/html" = "google-chrome.desktop";
|
|
||||||
"application/xhtml+xml" = "google-chrome.desktop";
|
|
||||||
"x-scheme-handler/http" = "google-chrome.desktop";
|
|
||||||
"x-scheme-handler/https" = "google-chrome.desktop";
|
|
||||||
"x-scheme-handler/ftp" = "google-chrome.desktop";
|
|
||||||
"x-scheme-handler/about" = "google-chrome.desktop";
|
|
||||||
"x-scheme-handler/unknown" = "google-chrome.desktop";
|
|
||||||
|
|
||||||
# mail and calendar
|
|
||||||
"x-scheme-handler/mailto" = "thunderbird.desktop";
|
|
||||||
"message/rfc822" = "thunderbird.desktop";
|
|
||||||
"text/calendar" = "thunderbird.desktop";
|
|
||||||
|
|
||||||
# documents
|
|
||||||
"application/pdf" = "org.pwmt.zathura.desktop";
|
|
||||||
"application/postscript" = "org.pwmt.zathura.desktop";
|
|
||||||
"image/vnd.djvu" = "org.pwmt.zathura.desktop";
|
|
||||||
"application/epub+zip" = "org.pwmt.zathura.desktop";
|
|
||||||
|
|
||||||
# office
|
|
||||||
"application/msword" = "libreoffice-writer.desktop";
|
|
||||||
"application/vnd.ms-excel" = "libreoffice-calc.desktop";
|
|
||||||
"application/vnd.ms-powerpoint" = "libreoffice-impress.desktop";
|
|
||||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" =
|
|
||||||
"libreoffice-writer.desktop";
|
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" = "libreoffice-calc.desktop";
|
|
||||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation" =
|
|
||||||
"libreoffice-impress.desktop";
|
|
||||||
"application/vnd.oasis.opendocument.text" = "libreoffice-writer.desktop";
|
|
||||||
"application/vnd.oasis.opendocument.spreadsheet" = "libreoffice-calc.desktop";
|
|
||||||
"application/vnd.oasis.opendocument.presentation" = "libreoffice-impress.desktop";
|
|
||||||
"text/csv" = "libreoffice-calc.desktop";
|
|
||||||
|
|
||||||
# images
|
|
||||||
"image/png" = "imv-dir.desktop";
|
|
||||||
"image/jpeg" = "imv-dir.desktop";
|
|
||||||
"image/gif" = "imv-dir.desktop";
|
|
||||||
"image/webp" = "imv-dir.desktop";
|
|
||||||
"image/tiff" = "imv-dir.desktop";
|
|
||||||
"image/bmp" = "imv-dir.desktop";
|
|
||||||
"image/svg+xml" = "google-chrome.desktop";
|
|
||||||
|
|
||||||
# video
|
|
||||||
"video/mp4" = "mpv.desktop";
|
|
||||||
"video/x-matroska" = "mpv.desktop";
|
|
||||||
"video/webm" = "mpv.desktop";
|
|
||||||
"video/quicktime" = "mpv.desktop";
|
|
||||||
"video/x-msvideo" = "mpv.desktop";
|
|
||||||
|
|
||||||
# audio
|
|
||||||
"audio/mpeg" = "mpv.desktop";
|
|
||||||
"audio/flac" = "mpv.desktop";
|
|
||||||
"audio/ogg" = "mpv.desktop";
|
|
||||||
"audio/wav" = "mpv.desktop";
|
|
||||||
"audio/aac" = "mpv.desktop";
|
|
||||||
|
|
||||||
# archives
|
|
||||||
"application/zip" = "org.gnome.FileRoller.desktop";
|
|
||||||
"application/x-tar" = "org.gnome.FileRoller.desktop";
|
|
||||||
"application/gzip" = "org.gnome.FileRoller.desktop";
|
|
||||||
"application/x-rar-compressed" = "org.gnome.FileRoller.desktop";
|
|
||||||
"application/x-7z-compressed" = "org.gnome.FileRoller.desktop";
|
|
||||||
"application/x-bzip2" = "org.gnome.FileRoller.desktop";
|
|
||||||
"application/x-xz" = "org.gnome.FileRoller.desktop";
|
|
||||||
|
|
||||||
# file manager
|
|
||||||
"inode/directory" = "nemo.desktop";
|
|
||||||
|
|
||||||
# app deep links
|
|
||||||
"x-scheme-handler/tg" = "org.telegram.desktop.desktop";
|
|
||||||
"x-scheme-handler/discord" = "discord.desktop";
|
|
||||||
"x-scheme-handler/slack" = "slack.desktop";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,15 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
options.features.dev.enable = lib.mkEnableOption "development tools";
|
|
||||||
};
|
|
||||||
|
|
||||||
home =
|
home =
|
||||||
{
|
{ pkgs, inputs, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
inputs,
|
|
||||||
osConfig,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
cfg = osConfig.features.dev;
|
|
||||||
packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system};
|
packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
home.packages = [
|
home.packages = [
|
||||||
|
pkgs.git
|
||||||
|
packages.git-linearize
|
||||||
|
packages.ggman
|
||||||
|
|
||||||
pkgs.python3
|
pkgs.python3
|
||||||
pkgs.osc
|
pkgs.osc
|
||||||
|
|
||||||
@@ -29,8 +19,7 @@
|
|||||||
packages.ahab
|
packages.ahab
|
||||||
pkgs.just
|
pkgs.just
|
||||||
pkgs.presenterm
|
pkgs.presenterm
|
||||||
pkgs.qemu
|
|
||||||
];
|
];
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,7 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
|
{ inputs, ... }:
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.direnv;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.direnv.enable = lib.mkEnableOption "direnv";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
nix.registry.dev = {
|
nix.registry.dev = {
|
||||||
from = {
|
from = {
|
||||||
type = "indirect";
|
type = "indirect";
|
||||||
@@ -24,15 +13,8 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
home =
|
home = _: {
|
||||||
{ lib, osConfig, ... }:
|
|
||||||
let
|
|
||||||
cfg = osConfig.features.direnv;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
programs.direnv = {
|
programs.direnv = {
|
||||||
enable = true;
|
enable = true;
|
||||||
nix-direnv.enable = true;
|
nix-direnv.enable = true;
|
||||||
@@ -41,5 +23,4 @@
|
|||||||
|
|
||||||
xdg.configFile."direnv/lib/use_dev.sh".source = ./use_dev.sh;
|
xdg.configFile."direnv/lib/use_dev.sh".source = ./use_dev.sh;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,7 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
|
{ user, ... }:
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
user,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.docker;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.docker.enable = lib.mkEnableOption "docker";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
virtualisation.docker = {
|
virtualisation.docker = {
|
||||||
enable = true;
|
enable = true;
|
||||||
logDriver = "json-file";
|
logDriver = "json-file";
|
||||||
@@ -20,5 +9,4 @@
|
|||||||
|
|
||||||
users.users.${user}.extraGroups = [ "docker" ];
|
users.users.${user}.extraGroups = [ "docker" ];
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,9 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
|
{ config, userKeys, ... }:
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
userKeys,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.filedrop;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.filedrop = {
|
|
||||||
enable = lib.mkEnableOption "filedrop sftp service";
|
|
||||||
|
|
||||||
sopsFile = lib.mkOption {
|
|
||||||
type = lib.types.path;
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
sops.secrets.filedrop-authorized-keys = {
|
sops.secrets.filedrop-authorized-keys = {
|
||||||
inherit (cfg) sopsFile;
|
sopsFile = ../secrets/floo.yaml;
|
||||||
mode = "0444";
|
mode = "0444";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -57,5 +39,4 @@
|
|||||||
X11Forwarding no
|
X11Forwarding no
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,7 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.gaming;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.gaming.enable = lib.mkEnableOption "gaming";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
programs.steam = {
|
programs.steam = {
|
||||||
enable = true;
|
enable = true;
|
||||||
remotePlay.openFirewall = true;
|
remotePlay.openFirewall = true;
|
||||||
@@ -22,5 +11,4 @@
|
|||||||
|
|
||||||
environment.systemPackages = [ pkgs.prismlauncher ];
|
environment.systemPackages = [ pkgs.prismlauncher ];
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
nixos =
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
options.features.git.enable = lib.mkEnableOption "git";
|
|
||||||
};
|
|
||||||
|
|
||||||
home =
|
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
inputs,
|
|
||||||
osConfig,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = osConfig.features.git;
|
|
||||||
packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
home.packages = [
|
|
||||||
pkgs.git
|
|
||||||
packages.git-linearize
|
|
||||||
packages.ggman
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,43 +1,9 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos = _: {
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.gnupg;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.gnupg = {
|
|
||||||
enable = lib.mkEnableOption "gnupg";
|
|
||||||
|
|
||||||
yubikey.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
|
||||||
lib.mkMerge [
|
|
||||||
{
|
|
||||||
programs.gnupg.agent = {
|
programs.gnupg.agent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableSSHSupport = true;
|
enableSSHSupport = true;
|
||||||
enableExtraSocket = true;
|
enableExtraSocket = true;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
(lib.mkIf cfg.yubikey.enable {
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
yubikey-personalization
|
|
||||||
yubikey-manager
|
|
||||||
];
|
|
||||||
|
|
||||||
services.pcscd.enable = true;
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
28
features/greeter.nix
Normal file
28
features/greeter.nix
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
nixos =
|
||||||
|
{ lib, inputs, ... }:
|
||||||
|
{
|
||||||
|
programs.regreet = {
|
||||||
|
enable = true;
|
||||||
|
# single output to avoid stretching across monitors
|
||||||
|
cageArgs = [
|
||||||
|
"-s"
|
||||||
|
"-m"
|
||||||
|
"last"
|
||||||
|
];
|
||||||
|
font = {
|
||||||
|
name = lib.mkForce "JetBrainsMono Nerd Font";
|
||||||
|
size = lib.mkForce 14;
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
background = {
|
||||||
|
path = lib.mkForce "${inputs.assets}/wallpaper.png";
|
||||||
|
fit = lib.mkForce "Cover";
|
||||||
|
};
|
||||||
|
GTK = {
|
||||||
|
application_prefer_dark_theme = lib.mkForce true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
pkgs,
|
||||||
|
config,
|
||||||
inputs,
|
inputs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
cfg = config.features.harmonia;
|
|
||||||
hosts = [
|
hosts = [
|
||||||
"fw16"
|
"fw16"
|
||||||
"tower"
|
"tower"
|
||||||
@@ -19,9 +17,6 @@
|
|||||||
flakeRef = inputs.self.outPath;
|
flakeRef = inputs.self.outPath;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.features.harmonia.enable = lib.mkEnableOption "harmonia";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
services.harmonia.cache = {
|
services.harmonia.cache = {
|
||||||
enable = true;
|
enable = true;
|
||||||
signKeyPaths = [ config.sops.secrets.nix-signing-key.path ];
|
signKeyPaths = [ config.sops.secrets.nix-signing-key.path ];
|
||||||
@@ -43,10 +38,14 @@
|
|||||||
path = [ config.nix.package ];
|
path = [ config.nix.package ];
|
||||||
};
|
};
|
||||||
|
|
||||||
# restart cache-builder after every nixos switch (non-blocking)
|
systemd.timers.cache-builder = {
|
||||||
system.activationScripts.cache-builder = lib.stringAfter [ "specialfs" ] ''
|
description = "Periodically build all host closures";
|
||||||
${config.systemd.package}/bin/systemctl restart --no-block cache-builder.service || true
|
wantedBy = [ "timers.target" ];
|
||||||
'';
|
timerConfig = {
|
||||||
|
OnUnitActiveSec = "15min";
|
||||||
|
OnBootSec = "5min";
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
nixos =
|
nixos =
|
||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.features.initrd-ssh;
|
|
||||||
keyDir = "/etc/secrets/initrd";
|
keyDir = "/etc/secrets/initrd";
|
||||||
|
|
||||||
mkIpString =
|
mkIpString =
|
||||||
@@ -16,9 +15,8 @@
|
|||||||
"${address}::${gateway}:${netmask}::${interface}:none";
|
"${address}::${gateway}:${netmask}::${interface}:none";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.features.initrd-ssh = {
|
options = {
|
||||||
enable = lib.mkEnableOption "initrd ssh";
|
initrd-ssh = {
|
||||||
|
|
||||||
ip = {
|
ip = {
|
||||||
enable = lib.mkEnableOption "static IP for initrd (otherwise DHCP)";
|
enable = lib.mkEnableOption "static IP for initrd (otherwise DHCP)";
|
||||||
|
|
||||||
@@ -49,19 +47,14 @@
|
|||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = {
|
||||||
boot.initrd.availableKernelModules = [ cfg.networkModule ];
|
boot.initrd.kernelModules = [ config.initrd-ssh.networkModule ];
|
||||||
boot.initrd.kernelModules = [ cfg.networkModule ];
|
boot.kernelParams = lib.mkIf config.initrd-ssh.ip.enable [
|
||||||
boot.kernelParams = lib.mkIf cfg.ip.enable [
|
"ip=${mkIpString config.initrd-ssh.ip}"
|
||||||
"ip=${mkIpString cfg.ip}"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.systemd.enable = true;
|
|
||||||
|
|
||||||
# remote unlock may take a while; don't let device units give up
|
|
||||||
boot.initrd.systemd.settings.Manager.DefaultDeviceTimeoutSec = "infinity";
|
|
||||||
|
|
||||||
boot.initrd.network = {
|
boot.initrd.network = {
|
||||||
enable = true;
|
enable = true;
|
||||||
ssh = {
|
ssh = {
|
||||||
@@ -71,20 +64,12 @@
|
|||||||
"${keyDir}/ssh_host_rsa_key"
|
"${keyDir}/ssh_host_rsa_key"
|
||||||
"${keyDir}/ssh_host_ed25519_key"
|
"${keyDir}/ssh_host_ed25519_key"
|
||||||
];
|
];
|
||||||
inherit (cfg) authorizedKeys;
|
inherit (config.initrd-ssh) authorizedKeys;
|
||||||
};
|
};
|
||||||
|
postCommands = ''
|
||||||
|
echo 'cryptsetup-askpass' >> /root/.profile
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# systemd-networkd retries DHCP indefinitely, unlike udhcpc
|
|
||||||
boot.initrd.systemd.network.networks = lib.mkIf (!cfg.ip.enable) {
|
|
||||||
"10-initrd" = {
|
|
||||||
matchConfig.Driver = cfg.networkModule;
|
|
||||||
networkConfig.DHCP = "yes";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# forward LUKS password prompt to the SSH session
|
|
||||||
boot.initrd.systemd.users.root.shell = "/bin/systemd-tty-ask-password-agent";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,25 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
let
|
|
||||||
cfg = config.features.localisation;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
options.features.localisation = {
|
options = {
|
||||||
enable = lib.mkEnableOption "localisation";
|
localisation = {
|
||||||
|
|
||||||
timeZone = lib.mkOption {
|
timeZone = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "Europe/Ljubljana";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
defaultLocale = lib.mkOption {
|
defaultLocale = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "en_US.UTF-8";
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = {
|
||||||
time.timeZone = cfg.timeZone;
|
time.timeZone = config.localisation.timeZone;
|
||||||
i18n.defaultLocale = cfg.defaultLocale;
|
i18n.defaultLocale = config.localisation.defaultLocale;
|
||||||
|
|
||||||
# NOTE:(@janezicmatej) some apps (e.g. java) need TZ env var explicitly
|
# NOTE:(@janezicmatej) some apps (e.g. java) need TZ env var explicitly
|
||||||
environment.variables.TZ = cfg.timeZone;
|
environment.variables.TZ = config.localisation.timeZone;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,4 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
options.features.neovim = {
|
|
||||||
enable = lib.mkEnableOption "neovim";
|
|
||||||
|
|
||||||
dotfiles = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.path;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
home =
|
home =
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
@@ -19,27 +6,28 @@
|
|||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
inputs,
|
inputs,
|
||||||
osConfig,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
cfg = osConfig.features.neovim;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
config = lib.mkIf cfg.enable (
|
options = {
|
||||||
lib.mkMerge [
|
neovim.dotfiles = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
(lib.optionalAttrs (options ? stylix) {
|
(lib.optionalAttrs (options ? stylix) {
|
||||||
# disable stylix neovim target when stylix is present
|
# disable stylix neovim target when stylix is present (loaded by desktop feature)
|
||||||
stylix.targets.neovim.enable = false;
|
stylix.targets.neovim.enable = false;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
xdg.configFile."nvim" = lib.mkIf (cfg.dotfiles != null) {
|
xdg.configFile."nvim" = lib.mkIf (config.neovim.dotfiles != null) {
|
||||||
source = cfg.dotfiles;
|
source = config.neovim.dotfiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.neovim = {
|
programs.neovim = {
|
||||||
enable = true;
|
enable = true;
|
||||||
sideloadInitLua = true;
|
|
||||||
vimAlias = true;
|
vimAlias = true;
|
||||||
defaultEditor = true;
|
defaultEditor = true;
|
||||||
package = inputs.neovim-nightly-overlay.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
package = inputs.neovim-nightly-overlay.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
||||||
@@ -76,7 +64,6 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
]
|
];
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,9 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos = _: {
|
||||||
{ config, lib, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.features.networkmanager;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.networkmanager.enable = lib.mkEnableOption "networkmanager";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
networking.networkmanager.enable = true;
|
networking.networkmanager.enable = true;
|
||||||
networking.nameservers = [
|
networking.nameservers = [
|
||||||
"1.1.1.1"
|
"1.1.1.1"
|
||||||
"8.8.8.8"
|
"8.8.8.8"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos = _: {
|
||||||
{ config, lib, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.features.nix-ld;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.nix-ld.enable = lib.mkEnableOption "nix-ld";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
programs.nix-ld.enable = true;
|
programs.nix-ld.enable = true;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
{
|
|
||||||
nixos =
|
|
||||||
{ config, lib, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.features.nix-settings;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.nix-settings = {
|
|
||||||
enable = lib.mkEnableOption "nix settings";
|
|
||||||
|
|
||||||
towerCache.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
gc = {
|
|
||||||
dates = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "monthly";
|
|
||||||
};
|
|
||||||
|
|
||||||
olderThan = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "30d";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
optimise.dates = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
default = [ "monthly" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
nix = {
|
|
||||||
settings = {
|
|
||||||
experimental-features = [
|
|
||||||
"nix-command"
|
|
||||||
"flakes"
|
|
||||||
];
|
|
||||||
download-buffer-size = 2 * 1024 * 1024 * 1024;
|
|
||||||
download-attempts = 3;
|
|
||||||
fallback = true;
|
|
||||||
warn-dirty = false;
|
|
||||||
substituters = [
|
|
||||||
"https://cache.nixos.org"
|
|
||||||
"https://nix-community.cachix.org?priority=45"
|
|
||||||
]
|
|
||||||
++ lib.optional cfg.towerCache.enable "http://tower:5000?priority=50";
|
|
||||||
trusted-public-keys = [
|
|
||||||
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
|
|
||||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
|
||||||
]
|
|
||||||
++ lib.optional cfg.towerCache.enable "matej.nix-1:TdbemLVYblvAxqJcwb3mVKmmr3cfzXbMcZHE5ILnZDE=";
|
|
||||||
};
|
|
||||||
|
|
||||||
gc = {
|
|
||||||
automatic = true;
|
|
||||||
inherit (cfg.gc) dates;
|
|
||||||
options = "--delete-older-than ${cfg.gc.olderThan}";
|
|
||||||
};
|
|
||||||
|
|
||||||
optimise = {
|
|
||||||
automatic = true;
|
|
||||||
inherit (cfg.optimise) dates;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
nixos =
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
user,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.onepassword;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.onepassword.enable = lib.mkEnableOption "1password";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
programs._1password.enable = true;
|
|
||||||
programs._1password-gui = {
|
|
||||||
enable = true;
|
|
||||||
polkitPolicyOwners = [ user ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,18 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
let
|
|
||||||
cfg = config.features.openssh;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
options.features.openssh = {
|
options = {
|
||||||
enable = lib.mkEnableOption "openssh";
|
openssh.port = lib.mkOption {
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.port;
|
type = lib.types.port;
|
||||||
default = 22;
|
default = 22;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = {
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
ports = [ cfg.port ];
|
ports = [ config.openssh.port ];
|
||||||
settings = {
|
settings = {
|
||||||
PasswordAuthentication = false;
|
PasswordAuthentication = false;
|
||||||
AllowUsers = null;
|
AllowUsers = null;
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
nixos =
|
|
||||||
{ config, lib, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.features.power;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.power = {
|
|
||||||
enable = lib.mkEnableOption "laptop power management";
|
|
||||||
|
|
||||||
resumeDevice = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
lidSwitch = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "suspend-then-hibernate";
|
|
||||||
};
|
|
||||||
|
|
||||||
powerKey = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "suspend-then-hibernate";
|
|
||||||
};
|
|
||||||
|
|
||||||
idleAction = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "suspend-then-hibernate";
|
|
||||||
};
|
|
||||||
|
|
||||||
idleActionSec = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "15min";
|
|
||||||
};
|
|
||||||
|
|
||||||
hibernateDelaySec = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "30min";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
boot.resumeDevice = lib.mkIf (cfg.resumeDevice != null) cfg.resumeDevice;
|
|
||||||
|
|
||||||
services.logind.settings.Login = {
|
|
||||||
HandleLidSwitch = cfg.lidSwitch;
|
|
||||||
HandlePowerKey = cfg.powerKey;
|
|
||||||
IdleAction = cfg.idleAction;
|
|
||||||
IdleActionSec = cfg.idleActionSec;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.sleep.settings.Sleep = {
|
|
||||||
HibernateDelaySec = cfg.hibernateDelaySec;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,5 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos = _: {
|
||||||
{ config, lib, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.features.printing;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.printing.enable = lib.mkEnableOption "printing";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
services.printing.enable = true;
|
services.printing.enable = true;
|
||||||
services.avahi = {
|
services.avahi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -15,5 +7,4 @@
|
|||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,7 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
|
{ config, user, ... }:
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
user,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.remote-base;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.remote-base.enable = lib.mkEnableOption "remote-base";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
sops.secrets.user-password = {
|
sops.secrets.user-password = {
|
||||||
sopsFile = ../secrets/common.yaml;
|
sopsFile = ../secrets/common.yaml;
|
||||||
neededForUsers = true;
|
neededForUsers = true;
|
||||||
@@ -21,5 +10,4 @@
|
|||||||
users.mutableUsers = false;
|
users.mutableUsers = false;
|
||||||
users.users.${user}.hashedPasswordFile = config.sops.secrets.user-password.path;
|
users.users.${user}.hashedPasswordFile = config.sops.secrets.user-password.path;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
16
features/shell-minimal.nix
Normal file
16
features/shell-minimal.nix
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
nixos = _: {
|
||||||
|
programs.zsh.enable = true;
|
||||||
|
environment.etc."zshenv".text = ''
|
||||||
|
export ZDOTDIR=$HOME/.config/zsh
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
starship
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,23 +1,16 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos = _: {
|
||||||
{ lib, ... }:
|
programs.zsh.enable = true;
|
||||||
{
|
environment.etc."zshenv".text = ''
|
||||||
options.features.shell.enable = lib.mkEnableOption "shell extras";
|
export ZDOTDIR=$HOME/.config/zsh
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
home =
|
home =
|
||||||
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
osConfig,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = osConfig.features.shell;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
|
starship
|
||||||
fzf
|
fzf
|
||||||
htop
|
htop
|
||||||
jc
|
jc
|
||||||
@@ -29,5 +22,4 @@
|
|||||||
tmux
|
tmux
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,7 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos =
|
||||||
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.sway;
|
|
||||||
desktopCfg = config.features.desktop;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.sway = {
|
|
||||||
enable = lib.mkEnableOption "sway window manager";
|
|
||||||
|
|
||||||
greeter.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
|
||||||
lib.mkMerge [
|
|
||||||
{
|
|
||||||
# soft dependency
|
|
||||||
features.desktop.enable = lib.mkDefault true;
|
|
||||||
|
|
||||||
# hard dependency
|
|
||||||
assertions = [
|
|
||||||
{
|
|
||||||
assertion = desktopCfg.enable;
|
|
||||||
message = "features.sway requires features.desktop";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
programs.sway = {
|
programs.sway = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.swayfx;
|
package = pkgs.swayfx;
|
||||||
@@ -41,8 +9,6 @@
|
|||||||
extraSessionCommands = ''
|
extraSessionCommands = ''
|
||||||
# fix for java awt apps not rendering
|
# fix for java awt apps not rendering
|
||||||
export _JAVA_AWT_WM_NONREPARENTING=1
|
export _JAVA_AWT_WM_NONREPARENTING=1
|
||||||
# propagate XDG_DATA_DIRS to dbus/systemd for d-bus activated apps
|
|
||||||
dbus-update-activation-environment --systemd XDG_DATA_DIRS
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -68,33 +34,5 @@
|
|||||||
cliphist
|
cliphist
|
||||||
zenity
|
zenity
|
||||||
];
|
];
|
||||||
}
|
|
||||||
|
|
||||||
# greeter
|
|
||||||
(lib.mkIf cfg.greeter.enable {
|
|
||||||
programs.regreet = {
|
|
||||||
enable = true;
|
|
||||||
cageArgs = [
|
|
||||||
"-s"
|
|
||||||
"-m"
|
|
||||||
"last"
|
|
||||||
];
|
|
||||||
font = {
|
|
||||||
name = lib.mkForce "JetBrainsMono Nerd Font";
|
|
||||||
size = lib.mkForce 14;
|
|
||||||
};
|
|
||||||
settings = {
|
|
||||||
background = {
|
|
||||||
path = lib.mkForce (toString desktopCfg.theme.wallpaper);
|
|
||||||
fit = lib.mkForce "Cover";
|
|
||||||
};
|
|
||||||
GTK = {
|
|
||||||
application_prefer_dark_theme = lib.mkForce true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,8 @@
|
|||||||
{
|
{
|
||||||
nixos =
|
nixos = _: {
|
||||||
{ config, lib, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.features.tailscale;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.tailscale.enable = lib.mkEnableOption "tailscale";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
services.tailscale = {
|
services.tailscale = {
|
||||||
enable = true;
|
enable = true;
|
||||||
useRoutingFeatures = "both";
|
useRoutingFeatures = "both";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
{
|
|
||||||
nixos =
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.udev;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.udev = {
|
|
||||||
enable = lib.mkEnableOption "custom udev rules";
|
|
||||||
|
|
||||||
kindle.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
ledger.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
keyboard-zsa.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
|
||||||
lib.mkMerge [
|
|
||||||
(lib.mkIf cfg.kindle.enable {
|
|
||||||
# NOTE:(@janezicmatej) uses services.udev.packages instead of extraRules
|
|
||||||
# because extraRules writes to 99-local.rules which is too late for uaccess
|
|
||||||
services.udev.packages = [
|
|
||||||
pkgs.libmtp
|
|
||||||
(pkgs.writeTextFile {
|
|
||||||
name = "kindle-udev-rules";
|
|
||||||
text = ''
|
|
||||||
ACTION!="remove", SUBSYSTEM=="usb", ATTRS{idVendor}=="1949", TAG+="uaccess"
|
|
||||||
'';
|
|
||||||
destination = "/etc/udev/rules.d/70-kindle.rules";
|
|
||||||
})
|
|
||||||
];
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf cfg.ledger.enable {
|
|
||||||
hardware.ledger.enable = true;
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf cfg.keyboard-zsa.enable {
|
|
||||||
hardware.keyboard.zsa.enable = true;
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -9,11 +9,16 @@ in
|
|||||||
sshAuthorizedKeys = sshKeys;
|
sshAuthorizedKeys = sshKeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
nixos = _: {
|
nixos =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
programs.zsh.enable = true;
|
||||||
|
|
||||||
users.users.matej = {
|
users.users.matej = {
|
||||||
uid = 1000;
|
uid = 1000;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
home = "/home/matej";
|
home = "/home/matej";
|
||||||
|
shell = pkgs.zsh;
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
openssh.authorizedKeys.keys = sshKeys;
|
openssh.authorizedKeys.keys = sshKeys;
|
||||||
};
|
};
|
||||||
|
|||||||
72
features/vm-9p-automount.nix
Normal file
72
features/vm-9p-automount.nix
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
nixos =
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (config.vm-9p-automount) user;
|
||||||
|
inherit (config.users.users.${user}) home group;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
vm-9p-automount = {
|
||||||
|
user = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
prefix = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "m_";
|
||||||
|
};
|
||||||
|
|
||||||
|
basePath = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "${home}/mnt";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
systemd.services.vm-9p-automount = {
|
||||||
|
description = "Auto-discover and mount 9p shares";
|
||||||
|
after = [
|
||||||
|
"local-fs.target"
|
||||||
|
"nss-user-lookup.target"
|
||||||
|
"systemd-modules-load.service"
|
||||||
|
];
|
||||||
|
wants = [ "systemd-modules-load.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = pkgs.writeShellScript "vm-9p-automount" ''
|
||||||
|
BASE="${config.vm-9p-automount.basePath}"
|
||||||
|
PREFIX="${config.vm-9p-automount.prefix}"
|
||||||
|
mkdir -p "$BASE"
|
||||||
|
chown ${user}:${group} "$BASE"
|
||||||
|
|
||||||
|
for tagfile in $(find /sys/devices -name mount_tag 2>/dev/null); do
|
||||||
|
[ -f "$tagfile" ] || continue
|
||||||
|
tag=$(tr -d '\0' < "$tagfile")
|
||||||
|
|
||||||
|
case "$tag" in
|
||||||
|
"$PREFIX"*) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
name="''${tag#"$PREFIX"}"
|
||||||
|
target="$BASE/$name"
|
||||||
|
|
||||||
|
mkdir -p "$target"
|
||||||
|
${pkgs.util-linux}/bin/mount -t 9p "$tag" "$target" \
|
||||||
|
-o trans=virtio,version=9p2000.L || continue
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -6,52 +6,28 @@
|
|||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
cfg = config.features.vm-guest;
|
|
||||||
autoUser = cfg.automount.user;
|
|
||||||
autoHome = config.users.users.${autoUser}.home;
|
|
||||||
autoGroup = config.users.users.${autoUser}.group;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
options.features.vm-guest = {
|
options = {
|
||||||
enable = lib.mkEnableOption "qemu vm guest";
|
vm-guest.headless = lib.mkOption {
|
||||||
|
|
||||||
headless = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
automount = {
|
|
||||||
enable = lib.mkEnableOption "9p share automount";
|
|
||||||
|
|
||||||
user = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
prefix = lib.mkOption {
|
config = {
|
||||||
type = lib.types.str;
|
services.qemuGuest.enable = true;
|
||||||
default = "m_";
|
services.spice-vdagentd.enable = lib.mkIf (!config.vm-guest.headless) true;
|
||||||
};
|
|
||||||
|
|
||||||
basePath = lib.mkOption {
|
boot.kernelParams = lib.mkIf config.vm-guest.headless [ "console=ttyS0,115200" ];
|
||||||
type = lib.types.str;
|
|
||||||
default = "${autoHome}/mnt";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
|
||||||
lib.mkMerge [
|
|
||||||
{
|
|
||||||
services.spice-vdagentd.enable = lib.mkIf (!cfg.headless) true;
|
|
||||||
|
|
||||||
boot.kernelParams = lib.mkIf cfg.headless [ "console=ttyS0,115200" ];
|
|
||||||
|
|
||||||
# 9p autoloads on first mount
|
|
||||||
boot.initrd.availableKernelModules = [
|
boot.initrd.availableKernelModules = [
|
||||||
"9p"
|
"9p"
|
||||||
"9pnet_virtio"
|
"9pnet_virtio"
|
||||||
];
|
];
|
||||||
|
boot.kernelModules = [
|
||||||
|
"9p"
|
||||||
|
"9pnet_virtio"
|
||||||
|
];
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
useDHCP = true;
|
useDHCP = true;
|
||||||
@@ -64,49 +40,8 @@
|
|||||||
curl
|
curl
|
||||||
wget
|
wget
|
||||||
htop
|
htop
|
||||||
|
sshfs
|
||||||
];
|
];
|
||||||
}
|
|
||||||
|
|
||||||
(lib.mkIf cfg.automount.enable {
|
|
||||||
systemd.services.vm-9p-automount = {
|
|
||||||
description = "Auto-discover and mount 9p shares";
|
|
||||||
after = [
|
|
||||||
"local-fs.target"
|
|
||||||
"nss-user-lookup.target"
|
|
||||||
"systemd-modules-load.service"
|
|
||||||
];
|
|
||||||
wants = [ "systemd-modules-load.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
ExecStart = pkgs.writeShellScript "vm-9p-automount" ''
|
|
||||||
BASE="${cfg.automount.basePath}"
|
|
||||||
PREFIX="${cfg.automount.prefix}"
|
|
||||||
mkdir -p "$BASE"
|
|
||||||
chown ${autoUser}:${autoGroup} "$BASE"
|
|
||||||
|
|
||||||
for tagfile in $(find /sys/devices -name mount_tag 2>/dev/null); do
|
|
||||||
[ -f "$tagfile" ] || continue
|
|
||||||
tag=$(tr -d '\0' < "$tagfile")
|
|
||||||
|
|
||||||
case "$tag" in
|
|
||||||
"$PREFIX"*) ;;
|
|
||||||
*) continue ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
name="''${tag#"$PREFIX"}"
|
|
||||||
target="$BASE/$name"
|
|
||||||
|
|
||||||
mkdir -p "$target"
|
|
||||||
${pkgs.util-linux}/bin/mount -t 9p "$tag" "$target" \
|
|
||||||
-o trans=virtio,version=9p2000.L || continue
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
features/yubikey.nix
Normal file
12
features/yubikey.nix
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
nixos =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
yubikey-personalization
|
||||||
|
yubikey-manager
|
||||||
|
];
|
||||||
|
|
||||||
|
services.pcscd.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
{
|
|
||||||
nixos =
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
user,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.features.zsh;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.features.zsh = {
|
|
||||||
enable = lib.mkEnableOption "zsh";
|
|
||||||
|
|
||||||
loginShell.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
|
||||||
lib.mkMerge [
|
|
||||||
{
|
|
||||||
programs.zsh.enable = true;
|
|
||||||
environment.etc."zshenv".text = ''
|
|
||||||
export ZDOTDIR=$HOME/.config/zsh
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
|
|
||||||
(lib.mkIf cfg.loginShell.enable {
|
|
||||||
users.users.${user}.shell = pkgs.zsh;
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
home =
|
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
osConfig,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = osConfig.features.zsh;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
home.packages = [ pkgs.starship ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
60
flake.lock
generated
60
flake.lock
generated
@@ -106,11 +106,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776613567,
|
"lastModified": 1773889306,
|
||||||
"narHash": "sha256-gC9Cp5ibBmGD5awCA9z7xy6MW6iJufhazTYJOiGlCUI=",
|
"narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "32f4236bfc141ae930b5ba2fb604f561fed5219d",
|
"rev": "5ad85c82cc52264f4beddc934ba57f3789f28347",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -273,11 +273,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776777932,
|
"lastModified": 1775556024,
|
||||||
"narHash": "sha256-0R3Yow/NzSeVGUke5tL7CCkqmss4Vmi6BbV6idHzq/8=",
|
"narHash": "sha256-j1u/859OVS54rGlsvFqJdwKPEnFYCI+4pyfTiSfv1Xc=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "5d5640599a0050b994330328b9fd45709c909720",
|
"rev": "4bdfeff1d9b7473e6e58f73f5809576e8a69e406",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -317,11 +317,11 @@
|
|||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776729909,
|
"lastModified": 1775520277,
|
||||||
"narHash": "sha256-wGu/N42PJqrj8ju9GoXdppg4rwaKzZqdAjsgxJbCvfY=",
|
"narHash": "sha256-dUI8/Mc6CfA+EmfrYByt+oNIEvdRLtSSDVS54O0YpBM=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "neovim-nightly-overlay",
|
"repo": "neovim-nightly-overlay",
|
||||||
"rev": "ff21a18bde28b4c8ca0bc1f9a5b7186a1b89a3d1",
|
"rev": "b63186e453b0ad340760648293aa1ccf75528c46",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -333,11 +333,11 @@
|
|||||||
"neovim-src": {
|
"neovim-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776727374,
|
"lastModified": 1775514165,
|
||||||
"narHash": "sha256-iP5SviNXW5W+ay4ZmwjDFsfQjfM+fYlUxRlLPHjpwWI=",
|
"narHash": "sha256-mAUtXA5BfCH5SRInzfJdaHY9egHrVLED0DsQzgBW4Fk=",
|
||||||
"owner": "neovim",
|
"owner": "neovim",
|
||||||
"repo": "neovim",
|
"repo": "neovim",
|
||||||
"rev": "901b3f0c394a53961781ebeee682e64ad690a242",
|
"rev": "b36eafd5dafae561763e5dc2ba73b3f0b74c63fe",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -364,11 +364,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776329215,
|
"lastModified": 1775464765,
|
||||||
"narHash": "sha256-a8BYi3mzoJ/AcJP8UldOx8emoPRLeWqALZWu4ZvjPXw=",
|
"narHash": "sha256-nex6TL2x1/sVHCyDWcvl1t/dbTedb9bAGC4DLf/pmYk=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "b86751bc4085f48661017fa226dee99fab6c651b",
|
"rev": "83e29f2b8791f6dec20804382fcd9a666d744c07",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -395,11 +395,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-master": {
|
"nixpkgs-master": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776807375,
|
"lastModified": 1775560693,
|
||||||
"narHash": "sha256-LDnHG0T54OEHyRydmGUlAND8ham0KrRNWjgoS+6GUd4=",
|
"narHash": "sha256-V1y4hd0R0XYG5GMpdj0W9h6976r6kZV5vcmKysclmfE=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "553ecb1686a2edb75dee44c9f72e1674e6adc26a",
|
"rev": "987687fd632e29817fc9c9d96eddba7d264510c0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -411,11 +411,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-stable": {
|
"nixpkgs-stable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776560675,
|
"lastModified": 1775305101,
|
||||||
"narHash": "sha256-p68udKWWh7+V4ZPpcMDq0gTHWNZJnr4JPI+kHPPE40o=",
|
"narHash": "sha256-/74n1oQPtKG52Yw41cbToxspxHbYz6O3vi+XEw16Qe8=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e07580dae39738e46609eaab8b154de2488133ce",
|
"rev": "36a601196c4ebf49e035270e10b2d103fe39076b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -427,11 +427,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776548001,
|
"lastModified": 1775423009,
|
||||||
"narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=",
|
"narHash": "sha256-vPKLpjhIVWdDrfiUM8atW6YkIggCEKdSAlJPzzhkQlw=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc",
|
"rev": "68d8aa3d661f0e6bd5862291b5bb263b2a6595c9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -550,11 +550,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776771786,
|
"lastModified": 1775365543,
|
||||||
"narHash": "sha256-DRFGPfFV6hbrfO9a1PH1FkCi7qR5FgjSqsQGGvk1rdI=",
|
"narHash": "sha256-f50qrK0WwZ9z5EdaMGWOTtALgSF7yb7XwuE7LjCuDmw=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "bef289e2248991f7afeb95965c82fbcd8ff72598",
|
"rev": "a4ee2de76efb759fe8d4868c33dec9937897916f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -583,11 +583,11 @@
|
|||||||
"tinted-zed": "tinted-zed"
|
"tinted-zed": "tinted-zed"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776170745,
|
"lastModified": 1775429060,
|
||||||
"narHash": "sha256-Tl1aZVP5EIlT+k0+iAKH018GLHJpLz3hhJ0LNQOWxCc=",
|
"narHash": "sha256-wbFF5cRxQOCzL/wHOKYm21t5AHPH2Lfp0mVPCOAvEoc=",
|
||||||
"owner": "danth",
|
"owner": "danth",
|
||||||
"repo": "stylix",
|
"repo": "stylix",
|
||||||
"rev": "e3861617645a43c9bbefde1aa6ac54dd0a44bfa9",
|
"rev": "d27951a6539951d87f75cf0a7cda8a3a24016019",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
117
flake/hosts.nix
117
flake/hosts.nix
@@ -15,29 +15,25 @@ in
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
user = "matej";
|
user = "matej";
|
||||||
features = [
|
features = [
|
||||||
"bootloader"
|
|
||||||
"claude"
|
|
||||||
"desktop"
|
|
||||||
"dev"
|
|
||||||
"direnv"
|
|
||||||
"docker"
|
|
||||||
"gaming"
|
|
||||||
"git"
|
|
||||||
"gnupg"
|
|
||||||
"localisation"
|
|
||||||
"neovim"
|
|
||||||
"networkmanager"
|
|
||||||
"nix-ld"
|
|
||||||
"nix-settings"
|
|
||||||
"onepassword"
|
|
||||||
"openssh"
|
"openssh"
|
||||||
"power"
|
"localisation"
|
||||||
"printing"
|
"gnupg"
|
||||||
"shell"
|
"shell"
|
||||||
|
"desktop"
|
||||||
"sway"
|
"sway"
|
||||||
|
"greeter"
|
||||||
|
"printing"
|
||||||
|
"networkmanager"
|
||||||
|
"docker"
|
||||||
"tailscale"
|
"tailscale"
|
||||||
"udev"
|
"nix-ld"
|
||||||
"zsh"
|
"yubikey"
|
||||||
|
"calibre"
|
||||||
|
"gaming"
|
||||||
|
"direnv"
|
||||||
|
"neovim"
|
||||||
|
"dev"
|
||||||
|
"claude"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,30 +41,27 @@ in
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
user = "matej";
|
user = "matej";
|
||||||
features = [
|
features = [
|
||||||
"bootloader"
|
|
||||||
"claude"
|
|
||||||
"desktop"
|
|
||||||
"dev"
|
|
||||||
"direnv"
|
|
||||||
"docker"
|
|
||||||
"gaming"
|
|
||||||
"git"
|
|
||||||
"gnupg"
|
|
||||||
"harmonia"
|
|
||||||
"initrd-ssh"
|
|
||||||
"localisation"
|
|
||||||
"neovim"
|
|
||||||
"networkmanager"
|
|
||||||
"nix-ld"
|
|
||||||
"nix-settings"
|
|
||||||
"onepassword"
|
|
||||||
"openssh"
|
"openssh"
|
||||||
"printing"
|
"localisation"
|
||||||
|
"gnupg"
|
||||||
"shell"
|
"shell"
|
||||||
|
"desktop"
|
||||||
"sway"
|
"sway"
|
||||||
|
"greeter"
|
||||||
|
"printing"
|
||||||
|
"networkmanager"
|
||||||
|
"docker"
|
||||||
"tailscale"
|
"tailscale"
|
||||||
"udev"
|
"nix-ld"
|
||||||
"zsh"
|
"yubikey"
|
||||||
|
"calibre"
|
||||||
|
"gaming"
|
||||||
|
"initrd-ssh"
|
||||||
|
"direnv"
|
||||||
|
"neovim"
|
||||||
|
"dev"
|
||||||
|
"claude"
|
||||||
|
"harmonia"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,9 +70,7 @@ in
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
user = "matej";
|
user = "matej";
|
||||||
features = [
|
features = [
|
||||||
"nix-settings"
|
|
||||||
"openssh"
|
"openssh"
|
||||||
"zsh"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,14 +78,11 @@ in
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
user = "matej";
|
user = "matej";
|
||||||
features = [
|
features = [
|
||||||
"bootloader"
|
|
||||||
"localisation"
|
|
||||||
"nix-settings"
|
|
||||||
"openssh"
|
"openssh"
|
||||||
"remote-base"
|
"localisation"
|
||||||
"shell"
|
"shell"
|
||||||
"tailscale"
|
"tailscale"
|
||||||
"zsh"
|
"remote-base"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,14 +91,12 @@ in
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
user = "matej";
|
user = "matej";
|
||||||
features = [
|
features = [
|
||||||
"filedrop"
|
|
||||||
"localisation"
|
|
||||||
"nix-settings"
|
|
||||||
"openssh"
|
"openssh"
|
||||||
"remote-base"
|
"localisation"
|
||||||
"shell"
|
"shell"
|
||||||
"tailscale"
|
"tailscale"
|
||||||
"zsh"
|
"remote-base"
|
||||||
|
"filedrop"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -118,15 +104,14 @@ in
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
user = "matej";
|
user = "matej";
|
||||||
features = [
|
features = [
|
||||||
"bootloader"
|
|
||||||
"desktop"
|
|
||||||
"gnupg"
|
|
||||||
"localisation"
|
"localisation"
|
||||||
"networkmanager"
|
"gnupg"
|
||||||
"nix-settings"
|
"shell-minimal"
|
||||||
|
"desktop-minimal"
|
||||||
"sway"
|
"sway"
|
||||||
"udev"
|
"greeter"
|
||||||
"zsh"
|
"networkmanager"
|
||||||
|
"yubikey"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -134,18 +119,16 @@ in
|
|||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
user = "matej";
|
user = "matej";
|
||||||
features = [
|
features = [
|
||||||
"claude"
|
|
||||||
"dev"
|
|
||||||
"docker"
|
|
||||||
"git"
|
|
||||||
"gnupg"
|
|
||||||
"localisation"
|
|
||||||
"neovim"
|
|
||||||
"nix-settings"
|
|
||||||
"openssh"
|
"openssh"
|
||||||
|
"localisation"
|
||||||
|
"gnupg"
|
||||||
"shell"
|
"shell"
|
||||||
"vm-guest"
|
"vm-guest"
|
||||||
"zsh"
|
"vm-9p-automount"
|
||||||
|
"docker"
|
||||||
|
"neovim"
|
||||||
|
"claude"
|
||||||
|
"dev"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
_:
|
{ inputs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
flake.overlays.default = _: _: { };
|
flake.overlays.default =
|
||||||
|
_: prev:
|
||||||
|
let
|
||||||
|
pkgs-stable = import inputs.nixpkgs-stable {
|
||||||
|
inherit (prev.stdenv.hostPlatform) system;
|
||||||
|
inherit (prev) config;
|
||||||
|
};
|
||||||
|
pkgs-master = import inputs.nixpkgs-master {
|
||||||
|
inherit (prev.stdenv.hostPlatform) system;
|
||||||
|
inherit (prev) config;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit (pkgs-master) claude-code;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
{
|
{
|
||||||
imports = [ inputs.disko.nixosModules.disko ];
|
imports = [ inputs.disko.nixosModules.disko ];
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
disko.devices.disk.main = {
|
disko.devices.disk.main = {
|
||||||
type = "disk";
|
type = "disk";
|
||||||
device = "/dev/nvme0n1";
|
device = "/dev/nvme0n1";
|
||||||
@@ -29,5 +32,10 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
localisation = {
|
||||||
|
timeZone = "Europe/Ljubljana";
|
||||||
|
defaultLocale = "en_US.UTF-8";
|
||||||
|
};
|
||||||
|
|
||||||
system.stateVersion = "25.11";
|
system.stateVersion = "25.11";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
features.nix-settings.towerCache.enable = false;
|
|
||||||
# no hardware firmware needed in a VM
|
# no hardware firmware needed in a VM
|
||||||
hardware.enableRedistributableFirmware = lib.mkForce false;
|
hardware.enableRedistributableFirmware = lib.mkForce false;
|
||||||
hardware.wirelessRegulatoryDatabase = lib.mkForce false;
|
hardware.wirelessRegulatoryDatabase = lib.mkForce false;
|
||||||
@@ -13,93 +12,37 @@
|
|||||||
documentation.enable = false;
|
documentation.enable = false;
|
||||||
environment.defaultPackages = [ ];
|
environment.defaultPackages = [ ];
|
||||||
|
|
||||||
# qcow2, no channel copy; post-processed with parallel zstd on qcow2 v3
|
# compressed qcow2, no channel copy
|
||||||
# (~half the size of zlib v2, faster decompress)
|
|
||||||
image.modules.qemu =
|
image.modules.qemu =
|
||||||
{ config, modulesPath, ... }:
|
{ config, modulesPath, ... }:
|
||||||
{
|
{
|
||||||
system.build.image = lib.mkForce (
|
system.build.image = lib.mkForce (
|
||||||
let
|
import (modulesPath + "/../lib/make-disk-image.nix") {
|
||||||
rawImage = import (modulesPath + "/../lib/make-disk-image.nix") {
|
|
||||||
inherit lib config pkgs;
|
inherit lib config pkgs;
|
||||||
inherit (config.virtualisation) diskSize;
|
inherit (config.virtualisation) diskSize;
|
||||||
inherit (config.image) baseName;
|
inherit (config.image) baseName;
|
||||||
format = "qcow2";
|
format = "qcow2-compressed";
|
||||||
copyChannel = false;
|
copyChannel = false;
|
||||||
partitionTableType = "legacy";
|
partitionTableType = "legacy";
|
||||||
};
|
}
|
||||||
inherit (config.image) baseName;
|
|
||||||
in
|
|
||||||
pkgs.runCommand baseName { nativeBuildInputs = [ pkgs.qemu-utils ]; } ''
|
|
||||||
mkdir -p $out
|
|
||||||
# qemu-img caps -m at 16
|
|
||||||
cores="''${NIX_BUILD_CORES:-4}"
|
|
||||||
[ "$cores" -gt 0 ] || cores=4
|
|
||||||
[ "$cores" -gt 16 ] && cores=16
|
|
||||||
qemu-img convert \
|
|
||||||
-f qcow2 \
|
|
||||||
-O qcow2 \
|
|
||||||
-c \
|
|
||||||
-o compression_type=zstd \
|
|
||||||
-m "$cores" \
|
|
||||||
${rawImage}/${baseName}.qcow2 \
|
|
||||||
$out/${baseName}.qcow2
|
|
||||||
''
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
# auto-login on serial console
|
vm-guest.headless = true;
|
||||||
services.getty.autologinUser = "matej";
|
|
||||||
|
|
||||||
# enable zsh in home-manager so starship init gets wired up
|
vm-9p-automount.user = "matej";
|
||||||
home-manager.users.matej.programs.zsh = {
|
|
||||||
enable = true;
|
localisation = {
|
||||||
dotDir = "/home/matej/.config/zsh";
|
timeZone = "UTC";
|
||||||
shellAliases.dsp = "claude --dangerously-skip-permissions";
|
defaultLocale = "en_US.UTF-8";
|
||||||
};
|
};
|
||||||
|
|
||||||
home-manager.users.matej.programs.starship = {
|
home-manager.users.matej = {
|
||||||
enable = true;
|
neovim.dotfiles = inputs.nvim;
|
||||||
settings = {
|
|
||||||
add_newline = false;
|
|
||||||
format = "$username$hostname$directory$character";
|
|
||||||
hostname = {
|
|
||||||
ssh_only = false;
|
|
||||||
style = "bold blue";
|
|
||||||
format = "[@$hostname]($style)";
|
|
||||||
};
|
};
|
||||||
username = {
|
|
||||||
show_always = true;
|
|
||||||
style_user = "bold blue";
|
|
||||||
format = "[$user]($style)";
|
|
||||||
};
|
|
||||||
directory.format = " [$path]($style) ";
|
|
||||||
character = {
|
|
||||||
success_symbol = "[>](bold green)";
|
|
||||||
error_symbol = "[>](bold red)";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
features.vm-guest.headless = true;
|
|
||||||
features.vm-guest.automount = {
|
|
||||||
enable = true;
|
|
||||||
user = "matej";
|
|
||||||
};
|
|
||||||
features.neovim.dotfiles = inputs.nvim;
|
|
||||||
|
|
||||||
# ensure .config exists with correct ownership before automount
|
# ensure .config exists with correct ownership before automount
|
||||||
systemd.tmpfiles.rules = [ "d /home/matej/.config 0700 matej users -" ];
|
systemd.tmpfiles.rules = [ "d /home/matej/.config 0755 matej users -" ];
|
||||||
|
|
||||||
# TODO:(@janezicmatej) replace ssh with virtio-console (hvc0) when qemu 11.0 lands
|
|
||||||
# https://www.mail-archive.com/qemu-devel@nongnu.org/msg1162844.html
|
|
||||||
# accept any ssh key (ephemeral localhost-only vm)
|
|
||||||
services.openssh.settings.AuthorizedKeysCommand =
|
|
||||||
let
|
|
||||||
acceptKey = pkgs.writeShellScript "ephvm-accept-key" ''echo "$1 $2"'';
|
|
||||||
in
|
|
||||||
"${acceptKey} %t %k";
|
|
||||||
services.openssh.settings.AuthorizedKeysCommandUser = "nobody";
|
|
||||||
|
|
||||||
# writable claude config via 9p
|
# writable claude config via 9p
|
||||||
fileSystems."/home/matej/.config/claude" = {
|
fileSystems."/home/matej/.config/claude" = {
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
{
|
{
|
||||||
imports = [ inputs.disko.nixosModules.disko ];
|
imports = [ inputs.disko.nixosModules.disko ];
|
||||||
|
|
||||||
features.filedrop.sopsFile = ../../secrets/floo.yaml;
|
|
||||||
|
|
||||||
boot.loader.grub.enable = true;
|
boot.loader.grub.enable = true;
|
||||||
|
|
||||||
disko.devices.disk.main = {
|
disko.devices.disk.main = {
|
||||||
@@ -28,5 +26,10 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
localisation = {
|
||||||
|
timeZone = "Europe/Ljubljana";
|
||||||
|
defaultLocale = "en_US.UTF-8";
|
||||||
|
};
|
||||||
|
|
||||||
system.stateVersion = "25.11";
|
system.stateVersion = "25.11";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,15 +10,18 @@
|
|||||||
inputs.nixos-hardware.nixosModules.framework-16-amd-ai-300-series
|
inputs.nixos-hardware.nixosModules.framework-16-amd-ai-300-series
|
||||||
];
|
];
|
||||||
|
|
||||||
features.desktop = {
|
localisation = {
|
||||||
apps.enable = false;
|
timeZone = "Europe/Ljubljana";
|
||||||
internalCA.enable = false;
|
defaultLocale = "en_US.UTF-8";
|
||||||
};
|
};
|
||||||
features.gnupg.yubikey.enable = true;
|
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
# TODO:(@janezicmatej) replace device path with actual SSD device
|
||||||
disko.devices.disk.main = {
|
disko.devices.disk.main = {
|
||||||
type = "disk";
|
type = "disk";
|
||||||
device = "/dev/sda";
|
device = "/dev/nvme1n1";
|
||||||
content = {
|
content = {
|
||||||
type = "gpt";
|
type = "gpt";
|
||||||
partitions = {
|
partitions = {
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
hardware.firmware = [ pkgs.linux-firmware ];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"nvme"
|
|
||||||
"xhci_pci"
|
|
||||||
"thunderbolt"
|
|
||||||
"usbhid"
|
|
||||||
"uas"
|
|
||||||
"sd_mod"
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
|
||||||
boot.kernelModules = [ "kvm-amd" ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
|
||||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
options,
|
pkgs,
|
||||||
inputs,
|
inputs,
|
||||||
|
options,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
@@ -10,23 +11,37 @@
|
|||||||
inputs.nixos-hardware.nixosModules.framework-16-amd-ai-300-series
|
inputs.nixos-hardware.nixosModules.framework-16-amd-ai-300-series
|
||||||
];
|
];
|
||||||
|
|
||||||
features.bootloader.plymouth.enable = true;
|
localisation = {
|
||||||
features.desktop.bluetooth.enable = true;
|
timeZone = "Europe/Ljubljana";
|
||||||
features.gnupg.yubikey.enable = true;
|
defaultLocale = "en_US.UTF-8";
|
||||||
features.udev = {
|
|
||||||
ledger.enable = true;
|
|
||||||
keyboard-zsa.enable = true;
|
|
||||||
};
|
};
|
||||||
features.power.resumeDevice = "/dev/disk/by-uuid/ff4750e7-3a9f-42c2-bb68-c458a6560540";
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
boot.kernelParams = [ "pcie_aspm.policy=powersupersave" ];
|
boot.kernelParams = [ "pcie_aspm.policy=powersupersave" ];
|
||||||
|
|
||||||
|
boot.resumeDevice = "/dev/disk/by-uuid/ff4750e7-3a9f-42c2-bb68-c458a6560540";
|
||||||
|
|
||||||
|
services.logind.settings.Login = {
|
||||||
|
HandleLidSwitch = "suspend-then-hibernate";
|
||||||
|
HandlePowerKey = "suspend-then-hibernate";
|
||||||
|
IdleAction = "suspend-then-hibernate";
|
||||||
|
IdleActionSec = "15min";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.sleep.settings.Sleep = {
|
||||||
|
HibernateDelaySec = "30min";
|
||||||
|
};
|
||||||
|
|
||||||
programs.nix-ld.libraries = options.programs.nix-ld.libraries.default;
|
programs.nix-ld.libraries = options.programs.nix-ld.libraries.default;
|
||||||
|
|
||||||
services.gnome.gnome-keyring.enable = true;
|
services.gnome.gnome-keyring.enable = true;
|
||||||
services.teamviewer.enable = true;
|
services.teamviewer.enable = true;
|
||||||
|
|
||||||
services.hardware.bolt.enable = true;
|
services.hardware.bolt.enable = true;
|
||||||
|
hardware.keyboard.zsa.enable = true;
|
||||||
|
hardware.ledger.enable = true;
|
||||||
hardware.bluetooth.powerOnBoot = true;
|
hardware.bluetooth.powerOnBoot = true;
|
||||||
hardware.inputmodule.enable = true;
|
hardware.inputmodule.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
{ lib, userKeys, ... }:
|
{ lib, ... }:
|
||||||
{
|
{
|
||||||
features.nix-settings.towerCache.enable = false;
|
|
||||||
image.modules.iso-installer = {
|
image.modules.iso-installer = {
|
||||||
isoImage.squashfsCompression = "zstd -Xcompression-level 6";
|
isoImage.squashfsCompression = "zstd -Xcompression-level 6";
|
||||||
};
|
};
|
||||||
|
|
||||||
# live iso: passwordless login and sudo
|
# live iso: passwordless login and sudo
|
||||||
users.users.matej.initialHashedPassword = "";
|
users.users.matej.initialHashedPassword = "";
|
||||||
users.users.root.openssh.authorizedKeys.keys = userKeys.sshAuthorizedKeys;
|
users.users.root.openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQGLdINKzs+sEy62Pefng0bcedgU396+OryFgeH99/c janezicmatej"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDk00+Km03epQXQs+xEwwH3zcurACzkEH+kDOPBw6RQe openpgp:0xB095D449"
|
||||||
|
];
|
||||||
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
|
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
|
||||||
security.sudo.wheelNeedsPassword = false;
|
security.sudo.wheelNeedsPassword = false;
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,38 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
userKeys,
|
userKeys,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
{
|
{
|
||||||
features.nix-settings.towerCache.enable = false;
|
imports = [
|
||||||
features.bootloader = {
|
inputs.lanzaboote.nixosModules.lanzaboote
|
||||||
mode = "lanzaboote";
|
];
|
||||||
plymouth.enable = true;
|
|
||||||
};
|
|
||||||
features.desktop.bluetooth.enable = true;
|
|
||||||
features.gnupg.yubikey.enable = true;
|
|
||||||
features.udev = {
|
|
||||||
ledger.enable = true;
|
|
||||||
keyboard-zsa.enable = true;
|
|
||||||
};
|
|
||||||
features.initrd-ssh = {
|
|
||||||
networkModule = "r8169";
|
|
||||||
authorizedKeys = userKeys.sshAuthorizedKeys;
|
|
||||||
};
|
|
||||||
|
|
||||||
# nix store signing
|
# nix store signing
|
||||||
sops.secrets.nix-signing-key.sopsFile = ../../secrets/tower.yaml;
|
sops.secrets.nix-signing-key.sopsFile = ../../secrets/tower.yaml;
|
||||||
nix.settings.secret-key-files = [ config.sops.secrets.nix-signing-key.path ];
|
nix.settings.secret-key-files = [ config.sops.secrets.nix-signing-key.path ];
|
||||||
|
|
||||||
|
localisation = {
|
||||||
|
timeZone = "Europe/Ljubljana";
|
||||||
|
defaultLocale = "en_US.UTF-8";
|
||||||
|
};
|
||||||
|
|
||||||
|
initrd-ssh = {
|
||||||
|
networkModule = "r8169";
|
||||||
|
authorizedKeys = userKeys.sshAuthorizedKeys;
|
||||||
|
};
|
||||||
|
|
||||||
|
# lanzaboote secure boot
|
||||||
boot.kernelParams = [ "btusb.reset=1" ];
|
boot.kernelParams = [ "btusb.reset=1" ];
|
||||||
# early kms so plymouth lands on amdgpu, not simpledrm
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
hardware.amdgpu.initrd.enable = true;
|
boot.loader.systemd-boot.enable = lib.mkForce false;
|
||||||
|
boot.lanzaboote = {
|
||||||
|
enable = true;
|
||||||
|
pkiBundle = "/var/lib/sbctl";
|
||||||
|
};
|
||||||
|
|
||||||
services.udisks2.enable = true;
|
services.udisks2.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -27,19 +27,7 @@ let
|
|||||||
hostConfig = ../hosts/${name}/configuration.nix;
|
hostConfig = ../hosts/${name}/configuration.nix;
|
||||||
hostHWConfig = ../hosts/${name}/hardware-configuration.nix;
|
hostHWConfig = ../hosts/${name}/hardware-configuration.nix;
|
||||||
|
|
||||||
# auto-discover all features, excluding user-* and default.nix
|
# load feature with path check
|
||||||
featureDir = builtins.readDir ../features;
|
|
||||||
allFeatureNames = lib.pipe featureDir [
|
|
||||||
(lib.filterAttrs (
|
|
||||||
n: t:
|
|
||||||
(t == "regular" && lib.hasSuffix ".nix" n && n != "default.nix" && !lib.hasPrefix "user-" n)
|
|
||||||
|| (t == "directory" && builtins.pathExists ../features/${n}/default.nix)
|
|
||||||
))
|
|
||||||
builtins.attrNames
|
|
||||||
(map (n: lib.removeSuffix ".nix" n))
|
|
||||||
];
|
|
||||||
|
|
||||||
# load all features unconditionally
|
|
||||||
loadFeature =
|
loadFeature =
|
||||||
f:
|
f:
|
||||||
assert
|
assert
|
||||||
@@ -47,7 +35,7 @@ let
|
|||||||
|| throw "feature '${f}' not found at ${toString (featurePath f)}";
|
|| throw "feature '${f}' not found at ${toString (featurePath f)}";
|
||||||
import (featurePath f);
|
import (featurePath f);
|
||||||
|
|
||||||
loadedFeatures = map loadFeature allFeatureNames;
|
loadedFeatures = map loadFeature features;
|
||||||
|
|
||||||
# load user feature with path check
|
# load user feature with path check
|
||||||
userFeature =
|
userFeature =
|
||||||
@@ -67,27 +55,17 @@ let
|
|||||||
# collect nixos and home modules from all features
|
# collect nixos and home modules from all features
|
||||||
nixosMods = map (f: f.nixos) (builtins.filter (f: f ? nixos) allFeatures);
|
nixosMods = map (f: f.nixos) (builtins.filter (f: f ? nixos) allFeatures);
|
||||||
homeMods = map (f: f.home) (builtins.filter (f: f ? home) allFeatures);
|
homeMods = map (f: f.home) (builtins.filter (f: f ? home) allFeatures);
|
||||||
|
|
||||||
# translate features list to enable flags
|
|
||||||
featureEnableModule =
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
config.features = lib.genAttrs features (_: {
|
|
||||||
enable = true;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
nixpkgs.lib.nixosSystem {
|
nixpkgs.lib.nixosSystem {
|
||||||
inherit system;
|
inherit system;
|
||||||
modules = [
|
modules = [
|
||||||
|
../nix.nix
|
||||||
inputs.sops-nix.nixosModules.sops
|
inputs.sops-nix.nixosModules.sops
|
||||||
inputs.stylix.nixosModules.stylix
|
|
||||||
|
|
||||||
{ nixpkgs.overlays = overlays; }
|
{ nixpkgs.overlays = overlays; }
|
||||||
{ nixpkgs.config.allowUnfree = true; }
|
{ nixpkgs.config.allowUnfree = true; }
|
||||||
{ networking.hostName = name; }
|
{ networking.hostName = name; }
|
||||||
|
|
||||||
featureEnableModule
|
|
||||||
hostConfig
|
hostConfig
|
||||||
]
|
]
|
||||||
++ lib.optional (builtins.pathExists hostHWConfig) hostHWConfig
|
++ lib.optional (builtins.pathExists hostHWConfig) hostHWConfig
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
inherit (pkgs) stdenv lib;
|
|
||||||
version = "2.1.116";
|
|
||||||
|
|
||||||
# upstream ships platform-native binaries as separate npm packages under
|
|
||||||
# @anthropic-ai/claude-code-<platform>; the wrapper package is just a
|
|
||||||
# postinstall shim that copies the matching one into place
|
|
||||||
sources = {
|
|
||||||
"x86_64-linux" = {
|
|
||||||
slug = "linux-x64";
|
|
||||||
hash = "sha256-QEjJ4CRk35TubDNW02Dzcu+EMRLLndJUXJeP3BFT3b8=";
|
|
||||||
};
|
|
||||||
"aarch64-linux" = {
|
|
||||||
slug = "linux-arm64";
|
|
||||||
hash = "sha256-/Hqp8GQx8Hub8K4w0Fnx/AksksY61vRC44XxrJVwF5w=";
|
|
||||||
};
|
|
||||||
"x86_64-darwin" = {
|
|
||||||
slug = "darwin-x64";
|
|
||||||
hash = "sha256-O3J/ew2fWbUQePs6tHEhK0Q9E3Mx/BDSL7b7NL3FRc8=";
|
|
||||||
};
|
|
||||||
"aarch64-darwin" = {
|
|
||||||
slug = "darwin-arm64";
|
|
||||||
hash = "sha256-O41sf7b05SJfXVjszMeTp838mja+PgZ+aEKykLsHeNo=";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
source =
|
|
||||||
sources.${stdenv.hostPlatform.system}
|
|
||||||
or (throw "claude-code: unsupported system ${stdenv.hostPlatform.system}");
|
|
||||||
in
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
pname = "claude-code";
|
|
||||||
inherit version;
|
|
||||||
|
|
||||||
src = pkgs.fetchzip {
|
|
||||||
url = "https://registry.npmjs.org/@anthropic-ai/claude-code-${source.slug}/-/claude-code-${source.slug}-${version}.tgz";
|
|
||||||
inherit (source) hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs.makeWrapper
|
|
||||||
]
|
|
||||||
++ lib.optionals stdenv.hostPlatform.isLinux [ pkgs.patchelf ];
|
|
||||||
|
|
||||||
dontBuild = true;
|
|
||||||
dontConfigure = true;
|
|
||||||
dontStrip = true;
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
install -Dm755 claude $out/bin/claude
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
# NOTE:(@janezicmatej) upstream is a bun single-file-executable; the
|
|
||||||
# embedded script payload sits at the tail of the ELF, so autoPatchelfHook's
|
|
||||||
# section-layout changes corrupt it — only the interpreter can be rewritten
|
|
||||||
postFixup =
|
|
||||||
lib.optionalString stdenv.hostPlatform.isLinux ''
|
|
||||||
patchelf --set-interpreter ${stdenv.cc.bintools.dynamicLinker} $out/bin/claude
|
|
||||||
''
|
|
||||||
+ ''
|
|
||||||
wrapProgram $out/bin/claude \
|
|
||||||
--set DISABLE_AUTOUPDATER 1 \
|
|
||||||
--set-default FORCE_AUTOUPDATE_PLUGINS 1 \
|
|
||||||
--set DISABLE_INSTALLATION_CHECKS 1 \
|
|
||||||
--unset DEV \
|
|
||||||
--prefix PATH : ${
|
|
||||||
lib.makeBinPath (
|
|
||||||
[
|
|
||||||
pkgs.procps
|
|
||||||
]
|
|
||||||
++ lib.optionals stdenv.hostPlatform.isLinux [
|
|
||||||
pkgs.bubblewrap
|
|
||||||
pkgs.socat
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = {
|
|
||||||
description = "Agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster";
|
|
||||||
homepage = "https://github.com/anthropics/claude-code";
|
|
||||||
downloadPage = "https://www.npmjs.com/package/@anthropic-ai/claude-code";
|
|
||||||
license = lib.licenses.unfree;
|
|
||||||
mainProgram = "claude";
|
|
||||||
platforms = lib.attrNames sources;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
#!/usr/bin/env nix-shell
|
|
||||||
#!nix-shell -i bash -p curl jq nix
|
|
||||||
# shellcheck shell=bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
PKG_FILE="$SCRIPT_DIR/package.nix"
|
|
||||||
|
|
||||||
# keep in sync with the `sources` attrset in package.nix
|
|
||||||
PLATFORMS=(linux-x64 linux-arm64 darwin-x64 darwin-arm64)
|
|
||||||
|
|
||||||
prefetch() {
|
|
||||||
local url="$1"
|
|
||||||
nix --extra-experimental-features 'nix-command flakes' \
|
|
||||||
store prefetch-file --unpack --json "$url" 2>/dev/null | jq -r '.hash'
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
echo "fetching latest version from npm..."
|
|
||||||
local latest current
|
|
||||||
latest=$(curl -sf "https://registry.npmjs.org/@anthropic-ai/claude-code/latest" | jq -r '.version')
|
|
||||||
current=$(grep 'version = ' "$PKG_FILE" | head -1 | sed 's/.*"\(.*\)".*/\1/')
|
|
||||||
|
|
||||||
if [[ "$current" == "$latest" ]]; then
|
|
||||||
echo "claude-code already at $latest"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "updating claude-code: $current -> $latest"
|
|
||||||
|
|
||||||
sed -i "s|version = \"$current\"|version = \"$latest\"|" "$PKG_FILE"
|
|
||||||
|
|
||||||
local slug url new_hash old_hash
|
|
||||||
for slug in "${PLATFORMS[@]}"; do
|
|
||||||
url="https://registry.npmjs.org/@anthropic-ai/claude-code-${slug}/-/claude-code-${slug}-${latest}.tgz"
|
|
||||||
echo " prefetching $slug..."
|
|
||||||
new_hash=$(prefetch "$url")
|
|
||||||
old_hash=$(awk -v slug="$slug" '
|
|
||||||
$0 ~ "slug = \"" slug "\";" { found=1; next }
|
|
||||||
found && /hash = "sha256-/ {
|
|
||||||
match($0, /sha256-[A-Za-z0-9+\/]+=*/)
|
|
||||||
print substr($0, RSTART, RLENGTH)
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
' "$PKG_FILE")
|
|
||||||
sed -i "s|$old_hash|$new_hash|" "$PKG_FILE"
|
|
||||||
echo " $new_hash"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "claude-code updated to $latest"
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
@@ -27,44 +27,23 @@ info() {
|
|||||||
|
|
||||||
# globals for cleanup trap
|
# globals for cleanup trap
|
||||||
CLEANUP_OVERLAY=""
|
CLEANUP_OVERLAY=""
|
||||||
CLEANUP_TMPDIR=""
|
|
||||||
QEMU_PID=""
|
|
||||||
VM_READY=false
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
[ -n "$QEMU_PID" ] && kill "$QEMU_PID" 2>/dev/null && wait "$QEMU_PID" 2>/dev/null
|
|
||||||
[ -n "$CLEANUP_OVERLAY" ] && rm -rf "$CLEANUP_OVERLAY"
|
[ -n "$CLEANUP_OVERLAY" ] && rm -rf "$CLEANUP_OVERLAY"
|
||||||
# preserve tmpdir on abnormal exit so the qemu log survives for inspection
|
|
||||||
if [ -n "$CLEANUP_TMPDIR" ]; then
|
|
||||||
if [ "$VM_READY" = true ]; then
|
|
||||||
rm -rf "$CLEANUP_TMPDIR"
|
|
||||||
else
|
|
||||||
echo "qemu log preserved: $CLEANUP_TMPDIR/qemu.log" >&2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
# returns 0 once the guest's sshd is speaking (first bytes are "SSH-")
|
|
||||||
awaiting_ssh_banner() {
|
|
||||||
local port="$1"
|
|
||||||
local banner
|
|
||||||
banner=$(timeout 2 bash -c "exec 3<>/dev/tcp/localhost/$port; head -c 4 <&3" 2>/dev/null) || return 1
|
|
||||||
[ "$banner" = "SSH-" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: ephvm-run.sh [options]
|
Usage: ephvm-run.sh [options]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--mount <path> Mount host directory into VM (repeatable)
|
--mount <path> Mount host directory into VM (repeatable)
|
||||||
--no-claude Skip mounting claude config dir
|
--claude Mount claude config dir (requires CLAUDE_CONFIG_DIR)
|
||||||
--disk-size <size> Resize guest disk (e.g. 50G)
|
--disk-size <size> Resize guest disk (e.g. 50G)
|
||||||
--memory <size> VM memory (default: 4G)
|
--memory <size> VM memory (default: 8G)
|
||||||
--cpus <n> VM CPUs (default: 2)
|
--cpus <n> VM CPUs (default: 4)
|
||||||
--ssh-port <port> Use specific SSH port (default: auto)
|
--ssh-port <port> SSH port forward (default: 2222)
|
||||||
--serial Attach to serial console instead of SSH
|
|
||||||
-h, --help Show usage
|
-h, --help Show usage
|
||||||
EOF
|
EOF
|
||||||
exit "${1:-0}"
|
exit "${1:-0}"
|
||||||
@@ -73,9 +52,7 @@ EOF
|
|||||||
main() {
|
main() {
|
||||||
setup_colors
|
setup_colors
|
||||||
|
|
||||||
[ "$EUID" -eq 0 ] && die "ephvm-run.sh must not run as root"
|
local ssh_port=2222 memory=8G cpus=4 claude=false disk_size=""
|
||||||
|
|
||||||
local ssh_port="" memory=4G cpus=2 claude=true disk_size="" serial=false
|
|
||||||
local -a mounts=()
|
local -a mounts=()
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
@@ -84,8 +61,8 @@ main() {
|
|||||||
mounts+=("$2")
|
mounts+=("$2")
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--no-claude)
|
--claude)
|
||||||
claude=false
|
claude=true
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--disk-size)
|
--disk-size)
|
||||||
@@ -104,10 +81,6 @@ main() {
|
|||||||
ssh_port="$2"
|
ssh_port="$2"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--serial)
|
|
||||||
serial=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-h | --help) usage ;;
|
-h | --help) usage ;;
|
||||||
*)
|
*)
|
||||||
echo "${red}error:${reset} unknown option: $1" >&2
|
echo "${red}error:${reset} unknown option: $1" >&2
|
||||||
@@ -118,9 +91,7 @@ main() {
|
|||||||
|
|
||||||
info "building ephvm image..."
|
info "building ephvm image..."
|
||||||
local image_dir image
|
local image_dir image
|
||||||
[ -n "${EPHVM_FLAKE:-}" ] || die "EPHVM_FLAKE must be set to the flake directory"
|
image_dir=$(nix build --no-link --print-out-paths .#nixosConfigurations.ephvm.config.system.build.images.qemu)
|
||||||
local flake="$EPHVM_FLAKE"
|
|
||||||
image_dir=$(nix build --no-link --print-out-paths "${flake}#nixosConfigurations.ephvm.config.system.build.images.qemu")
|
|
||||||
image=$(find "$image_dir" -name '*.qcow2' -print -quit)
|
image=$(find "$image_dir" -name '*.qcow2' -print -quit)
|
||||||
[ -n "$image" ] || die "no qcow2 image found in $image_dir"
|
[ -n "$image" ] || die "no qcow2 image found in $image_dir"
|
||||||
|
|
||||||
@@ -130,49 +101,31 @@ main() {
|
|||||||
CLEANUP_OVERLAY=$(mktemp -d)
|
CLEANUP_OVERLAY=$(mktemp -d)
|
||||||
local overlay="$CLEANUP_OVERLAY/overlay.qcow2"
|
local overlay="$CLEANUP_OVERLAY/overlay.qcow2"
|
||||||
qemu-img create -f qcow2 -b "$(realpath "$image")" -F qcow2 "$overlay" "$disk_size"
|
qemu-img create -f qcow2 -b "$(realpath "$image")" -F qcow2 "$overlay" "$disk_size"
|
||||||
drive_arg="if=none,id=hd0,file=$overlay,format=qcow2,cache=writeback,aio=threads,discard=unmap,detect-zeroes=unmap"
|
drive_arg="file=$overlay,format=qcow2"
|
||||||
else
|
else
|
||||||
drive_arg="if=none,id=hd0,file=$image,format=qcow2,snapshot=on,cache=writeback,aio=threads,discard=unmap,detect-zeroes=unmap"
|
drive_arg="file=$image,format=qcow2,snapshot=on"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
command -v qemu-system-x86_64 &>/dev/null || die "qemu-system-x86_64 not found"
|
local accel="tcg"
|
||||||
[ -r /dev/kvm ] || die "/dev/kvm not readable; kvm is required"
|
[ -r /dev/kvm ] && accel="kvm"
|
||||||
|
|
||||||
# auto-allocate ssh port unless serial mode
|
|
||||||
if [ "$serial" = false ] && [ -z "$ssh_port" ]; then
|
|
||||||
ssh_port=10022
|
|
||||||
while ss -tln | grep -q ":${ssh_port}\b"; do
|
|
||||||
ssh_port=$((ssh_port + 1))
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
local nic_arg="user,model=virtio-net-pci"
|
|
||||||
if [ -n "$ssh_port" ]; then
|
|
||||||
nic_arg="user,model=virtio-net-pci,hostfwd=tcp:127.0.0.1:${ssh_port}-:22"
|
|
||||||
fi
|
|
||||||
|
|
||||||
local -a qemu_args=(
|
local -a qemu_args=(
|
||||||
qemu-system-x86_64
|
qemu-system-x86_64
|
||||||
-accel kvm
|
-accel "$accel"
|
||||||
-cpu host
|
|
||||||
-m "$memory"
|
-m "$memory"
|
||||||
-smp "$cpus"
|
-smp "$cpus"
|
||||||
-drive "$drive_arg"
|
-drive "$drive_arg"
|
||||||
-device "virtio-blk-pci,drive=hd0"
|
-nic "user,hostfwd=tcp::${ssh_port}-:22"
|
||||||
-device virtio-rng-pci
|
|
||||||
-nic "$nic_arg"
|
|
||||||
-nographic
|
-nographic
|
||||||
-sandbox "on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if [ "$accel" != "tcg" ]; then
|
||||||
|
qemu_args+=(-cpu host)
|
||||||
|
fi
|
||||||
|
|
||||||
local fs_id=0 mount_path name tag
|
local fs_id=0 mount_path name tag
|
||||||
for mount_path in "${mounts[@]}"; do
|
for mount_path in "${mounts[@]}"; do
|
||||||
[ -e "$mount_path" ] || die "--mount path does not exist: $mount_path"
|
|
||||||
mount_path=$(realpath "$mount_path")
|
mount_path=$(realpath "$mount_path")
|
||||||
# qemu parses -virtfs as csv, a comma in the path would inject options
|
|
||||||
case "$mount_path" in
|
|
||||||
*,*) die "--mount path may not contain commas: $mount_path" ;;
|
|
||||||
esac
|
|
||||||
name=$(basename "$mount_path")
|
name=$(basename "$mount_path")
|
||||||
tag="m_${name:0:29}"
|
tag="m_${name:0:29}"
|
||||||
qemu_args+=(
|
qemu_args+=(
|
||||||
@@ -182,13 +135,10 @@ main() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ "$claude" = true ]; then
|
if [ "$claude" = true ]; then
|
||||||
[ -n "${CLAUDE_CONFIG_DIR:-}" ] || die "CLAUDE_CONFIG_DIR must be set (use --no-claude to skip)"
|
[ -n "${CLAUDE_CONFIG_DIR:-}" ] || die "--claude requires CLAUDE_CONFIG_DIR to be set"
|
||||||
mkdir -p "$CLAUDE_CONFIG_DIR"
|
mkdir -p "$CLAUDE_CONFIG_DIR"
|
||||||
local claude_dir
|
local claude_dir
|
||||||
claude_dir=$(realpath "$CLAUDE_CONFIG_DIR")
|
claude_dir=$(realpath "$CLAUDE_CONFIG_DIR")
|
||||||
case "$claude_dir" in
|
|
||||||
*,*) die "claude config dir may not contain commas: $claude_dir" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
qemu_args+=(
|
qemu_args+=(
|
||||||
-virtfs "local,path=$claude_dir,mount_tag=claude,security_model=none,id=fs${fs_id}"
|
-virtfs "local,path=$claude_dir,mount_tag=claude,security_model=none,id=fs${fs_id}"
|
||||||
@@ -197,42 +147,10 @@ main() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
info "---"
|
info "---"
|
||||||
[ -n "$ssh_port" ] && info "SSH: ssh -p $ssh_port matej@localhost"
|
info "Accel: $accel | SSH: ssh -p $ssh_port matej@localhost"
|
||||||
info "---"
|
info "---"
|
||||||
|
|
||||||
if [ "$serial" = true ]; then
|
|
||||||
exec "${qemu_args[@]}"
|
exec "${qemu_args[@]}"
|
||||||
fi
|
|
||||||
|
|
||||||
CLEANUP_TMPDIR=$(mktemp -d)
|
|
||||||
local qemu_log="$CLEANUP_TMPDIR/qemu.log"
|
|
||||||
|
|
||||||
# start qemu in background and auto-ssh
|
|
||||||
"${qemu_args[@]}" &>"$qemu_log" &
|
|
||||||
QEMU_PID=$!
|
|
||||||
|
|
||||||
# throwaway ssh key (vm accepts any key via AuthorizedKeysCommand)
|
|
||||||
local ssh_key="$CLEANUP_TMPDIR/id_ed25519"
|
|
||||||
ssh-keygen -t ed25519 -f "$ssh_key" -N "" -q
|
|
||||||
|
|
||||||
info "waiting for vm (port $ssh_port)..."
|
|
||||||
local attempts=0
|
|
||||||
# poll for the real SSH banner, not TCP accept: qemu's user-mode nic
|
|
||||||
# accepts host-side the moment qemu starts, well before guest sshd is up
|
|
||||||
while ! awaiting_ssh_banner "$ssh_port"; do
|
|
||||||
attempts=$((attempts + 1))
|
|
||||||
[ $attempts -gt 120 ] && die "vm did not become ready in 60s"
|
|
||||||
kill -0 "$QEMU_PID" 2>/dev/null || die "qemu exited unexpectedly"
|
|
||||||
sleep 0.5
|
|
||||||
done
|
|
||||||
VM_READY=true
|
|
||||||
|
|
||||||
ssh -p "$ssh_port" -t \
|
|
||||||
-i "$ssh_key" \
|
|
||||||
-o StrictHostKeyChecking=no \
|
|
||||||
-o UserKnownHostsFile=/dev/null \
|
|
||||||
-o LogLevel=ERROR \
|
|
||||||
matej@localhost
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user