Factor main into components

This commit is contained in:
Andrew Kvalheim 2021-12-02 11:48:45 -08:00
parent fa76db2597
commit a1533d1b31
12 changed files with 814 additions and 862 deletions

View file

@ -1,51 +1,23 @@
// # Installation
//
// 1. Copy `halmakish.xkb` to `/usr/share/X11/xkb/symbols/halmakish`.
//
// 2. Insert into `/usr/share/X11/xkb/rules/evdev.xml`:
// ```xml
// <layout>
// <configItem>
// <name>halmakish</name>
// <shortDescription>hm</shortDescription>
// <description>Halmakish</description>
// <languageList>
// <iso639Id>eng</iso639Id>
// </languageList>
// </configItem>
// <variantList>
// <variant>
// <configItem>
// <name>basic</name>
// <description>Halmakish</description>
// </configItem>
// </variant>
// </variantList>
// </layout>
// ```
//
// 3. Run `sudo dpkg-reconfigure xkb-data`.
partial alphanumeric_keys modifier_keys
xkb_symbols "basic" {
name[Group1]= "Halmakish (Basic)";
// key <TLDE> { [ grave, asciitilde ] };
// key <AE01> { [ 1, exclam ] };
// key <AE02> { [ 2, at ] };
// key <AE03> { [ 3, numbersign ] };
// key <AE04> { [ 4, dollar ] };
// key <AE05> { [ 5, percent ] };
// key <AE06> { [ 6, asciicircum ] };
// key <AE07> { [ 7, ampersand ] };
// key <AE08> { [ 8, asterisk ] };
// key <AE09> { [ 9, less ] };
// key <AE10> { [ 0, greater ] };
// key <AE11> { [ minus, underscore ] };
// key <TLDE> { [ grave, asciitilde ] };
// key <AE01> { [ 1, exclam ] };
// key <AE02> { [ 2, at ] };
// key <AE03> { [ 3, numbersign ] };
// key <AE04> { [ 4, dollar ] };
// key <AE05> { [ 5, percent ] };
// key <AE06> { [ 6, asciicircum ] };
// key <AE07> { [ 7, ampersand ] };
// key <AE08> { [ 8, asterisk ] };
// key <AE09> { [ 9, less ] };
// key <AE10> { [ 0, greater ] };
// key <AE11> { [ minus, underscore ] };
// key <AE12> { [ equal, plus ] };
key <BKSP> { [ BackSpace, BackSpace, Delete ] };
key <TAB> { [ Tab, Tab, Escape ] };
key <TAB> { [ Tab, Tab, Escape ] };
key <AD01> { [ f, F, ampersand ] };
key <AD02> { [ l, L, bracketleft ] };
key <AD03> { [ r, R, bracketright ] };
@ -58,7 +30,7 @@ xkb_symbols "basic" {
key <AD10> { [ j, J, asterisk ] };
key <AD11> { [ leftdoublequotemark, rightdoublequotemark, quotedbl ] };
key <AD12> { [ parenleft, parenright ] };
// key <BKSL> { [ backslash, bar ] };
// key <BKSL> { [ backslash, bar ] };
key <CAPS> { [ BackSpace, BackSpace, Delete ] };
key <AC01> { [ s, S, numbersign ] };

508
common/home.nix Normal file
View file

@ -0,0 +1,508 @@
{ config, lib, pkgs, ... }:
let
iosevkaCommon = {
widths = {
normal = { css = "normal"; menu = 5; shape = 500; };
};
weights = {
regular = { css = 400; menu = 400; shape = 400; };
bold = { css = 700; menu = 700; shape = 800; };
};
slopes = {
upright = { angle = 0; css = "normal"; menu = "upright"; shape = "upright"; };
italic = { angle = 9.4; css = "italic"; menu = "italic"; shape = "italic"; };
};
variants.design = {
digit-form = "old-style";
capital-a = "curly-serifless";
capital-g = "toothless-corner-serifless-hooked";
capital-k = "curly-serifless";
capital-u = "toothless-corner";
capital-r = "standing";
capital-v = "curly";
capital-w = "curly";
capital-x = "curly-serifless";
capital-y = "curly-serifless";
capital-z = "curly-serifless";
a = "double-storey-toothless-corner";
b = "toothless-corner";
d = "toothless-corner-serifless";
f = "flat-hook-crossbar-at-x-height";
g = "earless-corner";
i = "serifed-flat-tailed";
j = "flat-hook-serifed";
l = "flat-tailed";
m = "earless-corner-double-arch-short-leg";
n = "earless-corner-straight";
p = "earless-corner";
q = "earless-corner";
r = "earless-corner";
t = "flat-hook-short-neck2";
u = "toothless-corner";
w = "curly";
x = "curly-serifless";
y = "curly";
z = "curly-serifless";
zero = "slashed";
two = "straight-neck";
three = "flat-top";
four = "semi-open-non-crossing";
five = "oblique-upper-left-bar";
six = "straight-bar";
seven = "bend-serifless";
eight = "crossing-asymmetric";
nine = "straight-bar";
tilde = "low";
asterisk = "hex-low";
underscore = "above-baseline";
caret = "low";
brace = "curly";
at = "short";
dollar = "open-cap";
cent = "open";
percent = "dots";
bar = "force-upright";
};
};
iosevka-custom-proportional = pkgs.iosevka.override {
set = "custom-proportional";
privateBuildPlan = iosevkaCommon // {
family = "Iosevka Custom Proportional";
spacing = "quasi-proportional";
ligations = { inherits = "javascript"; };
};
};
iosevka-custom-mono = pkgs.iosevka.override {
set = "custom-mono";
privateBuildPlan = iosevkaCommon // {
family = "Iosevka Custom Mono";
ligations = { inherits = "javascript"; };
};
};
iosevka-custom-term = pkgs.iosevka.override {
set = "custom-term";
privateBuildPlan = iosevkaCommon // {
family = "Iosevka Custom Term";
spacing = "term";
no-ligation = true;
};
};
palette = import ./palette.nix;
in
{
# Home manager
programs.home-manager.enable = true;
nixpkgs.config.allowUnfree = true;
manual.html.enable = true;
home.username = "ak";
home.homeDirectory = "/home/ak";
# Applications
home.packages = with pkgs; [
delta
dnsutils
fd
file
firefox-wayland
gnome.gnome-tweaks
gnome.zenity
gnomeExtensions.system-monitor
gnomeExtensions.tray-icons-reloaded
gnupg
gopass
htop
iosevka-custom-mono
iosevka-custom-proportional
iosevka-custom-term
killall
lsof
moreutils
mtr
multitail
ncdu
nix-top
nix-tree
nixpkgs-fmt
pwgen
ripgrep
roboto
rsync
shellcheck
tig
trash-cli
vscodium
yaru-theme
];
fonts.fontconfig.enable = true;
programs = {
bat.enable = true;
direnv = {
enable = true;
nix-direnv.enable = true;
stdlib = ''
_gopass_await() {
gopass show "$@" 2>( \
zenity --progress --auto-close --no-cancel --pulsate \
--title 'Please tap the hardware key' \
--text "gopass show $*" \
)
}
use_gopass() {
eval "$(_gopass_await "$@")"
}
'';
};
exa = { enable = true; enableAliases = true; };
fzf = rec {
enable = true;
enableZshIntegration = true;
defaultOptions = [ "--height 33%" "--reverse" ];
defaultCommand = "fd --one-file-system --type file"; # --no-ignore-parent pending https://github.com/sharkdp/fd/pull/817 (fd v9)
fileWidgetCommand = defaultCommand;
changeDirWidgetCommand = "fd --one-file-system --type directory"; # --no-ignore-parent pending https://github.com/sharkdp/fd/pull/817 (fd v9)
};
git = {
enable = true;
aliases = {
ff = "merge --ff-only";
puff = "pull --ff-only";
recent = "!git --no-pager log --max-count 8 --pretty=tformat:\"%w($(tput cols),0,8)%C(cyan)%h%Creset %C(yellow)%cr:%C(magenta)%d%Creset %s\"";
};
delta = {
enable = true;
options = {
file-renamed-label = "moved:";
line-numbers-left-format = "{nm:>1} ";
line-numbers-left-style = "#444444";
line-numbers-minus-style = "#872843 bold";
line-numbers-plus-style = "#5c7b2a bold";
line-numbers-right-format = "{np:>1}";
line-numbers-right-style = "#444444";
line-numbers-zero-style = "#444444 bold";
minus-emph-style = "#827c7d #42282d";
minus-empty-line-marker-style = "normal #42282d";
minus-non-emph-style = "#444444";
minus-style = "#827c7d #42282d";
plus-emph-style = "syntax #343e28";
plus-empty-line-marker-style = "normal #343e28";
plus-non-emph-style = "syntax";
plus-style = "syntax #343e28";
syntax-theme = "Monokai Extended";
whitespace-error-style = "reverse white";
full = {
file-style = "white bold";
file-decoration-style = "omit";
hunk-header-style = "omit";
line-numbers = true;
};
};
};
extraConfig = {
core.autocrlf = "input";
diff.algorithm = "patience";
init.defaultBranch = "main";
merge.commit = false;
push.followTags = true;
tig = {
line-graphics = "utf-8";
main-view-date = "custom";
main-view-date-format = "%F %H:%M";
main-view-id-display = true;
show-changes = false;
tab-size = 4;
truncation-delimiter = "utf-8";
vertical-split = false;
color = {
author = "color8 default";
cursor = "black magenta bold";
graph-commit = "magenta default";
date = "yellow default";
id = "cyan default";
main-head = "magenta default bold";
main-local-tag = "green default";
main-ref = "magenta default";
main-remote = "blue default";
main-tag = "green default";
main-tracked = "blue default bold";
palette-0 = "color8 default";
palette-1 = "color8 default";
palette-2 = "color8 default";
palette-3 = "color8 default";
palette-4 = "color8 default";
palette-5 = "color8 default";
palette-6 = "color8 default";
palette-7 = "color8 default";
palette-8 = "color8 default";
palette-9 = "color8 default";
palette-10 = "color8 default";
palette-11 = "color8 default";
palette-12 = "color8 default";
palette-13 = "color8 default";
search-result = "black white bold";
title-blur = "white black";
title-focus = "white black bold";
};
};
};
ignores = [
".direnv/"
".envrc"
".envrc.nix"
".vscode/"
];
iniContent.core.pager = lib.mkForce "${pkgs.delta}/bin/delta --color-only --features full"; # Set feature
userName = "Andrew Kvalheim";
userEmail = "Andrew@Kvalhe.im";
};
jq.enable = true;
kitty = {
enable = true;
font = {
package = iosevka-custom-term;
name = "Iosevka Custom Term";
size = 11;
};
keybindings = {
"shift+left" = "previous_tab";
"ctrl+shift+left" = "move_tab_backward";
"shift+right" = "next_tab";
"ctrl+shift+right" = "move_tab_forward";
"shift+down" = "previous_window";
"ctrl+shift+up" = "move_window_backward";
"shift+up" = "next_window";
"ctrl+shift+down" = "move_window_forward";
"alt+down" = "resize_window shorter";
"alt+up" = "resize_window taller";
};
settings = {
# Mouse
click_interval = "0.25";
focus_follows_mouse = "yes";
mouse_hide_wait = "0";
select_by_word_characters = "-_?&%+#";
# Windows
hide_window_decorations = true;
scrollback_lines = "16384";
enabled_layouts = "vertical, horizontal";
# Workaround for https://github.com/kovidgoyal/kitty/issues/3180
touch_scroll_multiplier = "10";
# Sounds
enable_audio_bell = "no";
# Font
bold_font = "Iosevka Custom Term Bold";
italic_font = "Iosevka Custom Term Italic";
bold_italic_font = "Iosevka Custom Term Bold Italic";
active_tab_font_style = "bold";
inactive_tab_font_style = "bold";
# Cursor
cursor_shape = "beam";
# URLs
url_style = "single";
# Colors
wayland_titlebar_color = palette.black;
foreground = palette.white;
background = palette.black;
cursor = palette.orange;
url_color = palette.white;
active_border_color = palette.dark-gray;
inactive_border_color = palette.dark-gray;
bell_border_color = palette.red;
active_tab_foreground = palette.white;
active_tab_background = palette.dark-gray;
inactive_tab_foreground = palette.gray;
inactive_tab_background = palette.dark-gray;
selection_foreground = palette.black;
selection_background = palette.orange;
color0 = palette.dark-gray;
color1 = palette.red;
color2 = palette.green;
color3 = palette.yellow;
color4 = palette.blue;
color5 = palette.orange;
color6 = palette.purple;
color7 = palette.white;
color8 = palette.gray;
color9 = palette.red;
color10 = palette.green;
color11 = palette.yellow;
color12 = palette.blue;
color13 = palette.orange;
color14 = palette.purple;
color15 = palette.white;
};
};
zsh = {
enable = true;
autocd = false;
history = {
expireDuplicatesFirst = true;
extended = true;
ignoreDups = false;
ignoreSpace = true;
save = 100000000;
size = 1000000000;
};
sessionVariables = {
HIST_STAMPS = "yyyy-mm-dd";
REPORTTIME = 10;
WORDCHARS = "_.~;!#$%^";
};
initExtra = ''
setopt HIST_FIND_NO_DUPS
setopt NOCLOBBER
setopt PUSHD_SILENT
export DIRENV_LOG_FORMAT="$(print -P "%B%F{8} %%s%f")"
TIMEFMT="$(print -P "%B%F{8} Duration: %%*Es, CPU: %%P, Memory: %%MkB%f")"
git() {
if [[ "$1" == 'clone' && "$2" =~ '^https://(github\.com|gitlab\.com)/([^/]+)/[^/]+' ]]; then
shift
echo "Detected origin name ''\'''${match[2]}'" >&2
command git clone --origin "''${match[2]}" "$@"
elif [[ "$1" == 'checkout' ]]; then
echo 'Reminder: Use `git switch` or `git restore` instead.' >&2
command git "$@"
else
command git "$@"
fi
}
rd() { diff --recursive --unified "$@" | delta }
rdw() { diff --ignore-all-space --recursive --unified "$@" | delta }
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
'';
shellAliases = {
a = "git add --patch";
b = "git switch --create";
c = "git commit";
cat = "bat --plain";
code = "codium";
d = "git diff ':!*.lock'";
ds = "git diff --staged ':!*.lock'";
e = "exa --all --group-directories-first --long --header --time-style long-iso";
et = "exa --all --group-directories-first --long --header --time-style long-iso --tree";
gf = "git fetch --all --jobs 4 --prune";
gff = "git fetch --all --jobs 4 --prune && git merge --ff-only";
h = "tig --all";
mv = "mv --no-clobber --verbose";
p = "gopass";
rebase = "noglob git rebase --autostash --autosquash --interactive";
rm = "rm --one-file-system --verbose";
s = "git status";
stash = "git stash save --include-untracked";
undo = "git restore --patch";
watch = "watch --color";
};
prezto = {
enable = true;
pmodules = [
"environment"
"terminal"
"spectrum"
"completion"
"syntax-highlighting"
"history-substring-search"
"prompt"
"git"
];
prompt.theme = "powerlevel10k";
syntaxHighlighting.styles = {
arg0 = "fg=white,bold";
precommand = "fg=white"; # Pending https://github.com/zsh-users/zsh-syntax-highlighting/issues/432
reserved-word = "fg=blue";
};
terminal = {
autoTitle = true;
multiplexerTitleFormat = "%1~";
tabTitleFormat = "%1~";
windowTitleFormat = "%1~";
};
extraConfig = ''
zstyle ':prezto:module:git:alias' skip 'yes'
'';
};
};
};
# Environment
home.sessionVariables = rec {
ANSIBLE_NOCOWS = true;
EDITOR = "${pkgs.vscodium}/bin/codium --wait";
EXA_COLORS = lib.concatStringsSep ":" (lib.attrsets.mapAttrsToList (k: v: "${k}=${v}") {
ur = "2;37"; # the user-read permission bit
uw = "2;37"; # the user-write permission bit
ux = "1;32"; # the user-execute permission bit for regular files
ue = "1;32"; # the user-execute for other file kinds
gr = "2;37"; # the group-read permission bit
gw = "2;37"; # the group-write permission bit
gx = "2;37"; # the group-execute permission bit
tr = "1;35"; # the others-read permission bit
tw = "1;31"; # the others-write permission bit
tx = "2;37"; # the others-execute permission bit
su = "1;33"; # setuid, setgid, and sticky permission bits for files
sf = "1;33"; # setuid, setgid, and sticky for other file kinds
xa = "1;33"; # the extended attribute indicator
sn = "2;37"; # the numbers of a files size
ub = "1;37"; # the units of a files size if it is lower than 1 KB/Kib
uk = "1;34"; # the units of a files size if it is between 1 KB/KiB and 1 MB/MiB
um = "1;33"; # the units of a files size if it is between 1 MB/MiB and 1 GB/GiB
ug = "1;31"; # the units of a files size if it is between 1 GB/GiB and 1 TB/TiB
ut = "1;31"; # the units of a files size if it is 1 TB/TiB or higher
uu = "30"; # a user thats you
un = "31"; # a user thats someone else
gu = "30"; # a group that you belong to
gn = "31"; # a group you arent a member of
da = "2;3;37"; # a files date
lp = "2;37"; # the path of a symlink
cc = "1;33"; # an escaped character in a filename
});
LS_COLORS = lib.concatStringsSep ":" (lib.attrsets.mapAttrsToList (k: v: "${k}=${v}") {
di = "1;36"; # directories
ex = "32"; # executable files
fi = "37"; # regular files
pi = "3;34"; # named pipes
so = "3;34"; # sockets
bd = "1;34"; # block devices
cd = "1;34"; # character devices
ln = "35"; # symlinks
or = "31"; # symlinks with no target
});
VISUAL = EDITOR;
VSCODE_GALLERY_CACHE_URL = "https://vscode.blob.core.windows.net/gallery/index";
VSCODE_GALLERY_CONTROL_URL = "";
VSCODE_GALLERY_ITEM_URL = "https://marketplace.visualstudio.com/items";
VSCODE_GALLERY_RECOMMENDATIONS_URL = "";
VSCODE_GALLERY_SERVICE_URL = "https://marketplace.visualstudio.com/_apis/public/gallery";
};
home.file.".XCompose".source = ./Compose; # TODO: Clear `~/.cache/gtk-3.0/compose` on change
home.file.".p10k.zsh".source = ./p10k.zsh;
# Workaround for https://github.com/NixOS/nixpkgs/issues/101616
home.file."${config.xdg.configHome}/autostart/gnome-keyring-ssh.desktop".text = ''
[Desktop Entry]
Type=Application
Name=SSH Key Agent
Hidden=true
'';
}

225
common/nixos.nix Normal file
View file

@ -0,0 +1,225 @@
{ config, lib, pkgs, ... }:
let
palette = import ./palette.nix;
in
{
imports = [
<nixpkgs/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix>
../packages/kmonad.nix
];
# Nix
nix.autoOptimiseStore = true;
nix.gc = { automatic = true; options = "--delete-older-than 7d"; };
nix.extraOptions = ''
# Recommended by nix-direnv
keep-outputs = true
keep-derivations = true
'';
nixpkgs.config.allowUnfree = true;
# Boot
boot.loader.systemd-boot.enable = true;
boot.loader.systemd-boot.memtest86.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.plymouth.enable = true;
# Swap
zramSwap.enable = true;
# Filesystems
boot.initrd.luks = {
gpgSupport = true;
devices.pv = {
device = "/dev/disk/by-partlabel/pv-enc";
allowDiscards = true;
fallbackToPassword = true;
gpgCard.encryptedPass = ./local/luks-passphrase.gpg;
gpgCard.publicKey = ./andrew.asc;
};
};
fileSystems."/".options = [ "noatime" ];
boot.cleanTmpDir = true;
# Time and locale
time.timeZone = "America/Los_Angeles";
i18n.extraLocaleSettings.LC_TIME = "en_DK.UTF-8";
# Networking
networking.useDHCP = false; # Future default
networking.domain = "home.arpa";
networking.search = [ "home.arpa" ];
# Workaround for `avahi-daemon[1234]: Failed to read /etc/avahi/services.`
# Upstream: https://github.com/lathiat/avahi/blob/v0.8/avahi-daemon/static-services.c#L917-L919
system.activationScripts.etcAvahiServices = "mkdir -p /etc/avahi/services";
# Console
console.colors = map (lib.removePrefix "#") [
"#000000" palette.red palette.green palette.yellow palette.blue palette.orange palette.purple palette.white
palette.gray palette.red palette.green palette.yellow palette.blue palette.orange palette.purple palette.white
];
# Keyboard
services.xserver.extraLayouts.halmakish = {
description = "Halmakish";
languages = [ "eng" ];
symbolsFile = ./halmakish.xkb;
};
services.xserver.layout = "halmakish";
console.useXkbConfig = true;
kmonad = {
enable = true;
keyboards.default.config = builtins.readFile ./halmakish.kbd;
};
# Power
systemd.ctrlAltDelUnit = "poweroff.target";
# Authentication
security.pam.u2f = {
enable = true;
appId = "pam://main";
control = "sufficient";
cue = true;
};
# Authorization
security.sudo.extraRules = [
{
groups = [ "wheel" ];
commands = [
{ command = "/run/current-system/sw/bin/nix-channel --update"; options = [ "NOPASSWD" ]; }
{ command = "/run/current-system/sw/bin/nixos-rebuild boot"; options = [ "NOPASSWD" ]; }
{ command = "/run/current-system/sw/bin/nixos-rebuild switch"; options = [ "NOPASSWD" ]; }
{ command = "/run/current-system/sw/bin/poweroff"; options = [ "NOPASSWD" ]; }
];
}
];
# SSH
services.openssh.enable = true;
# Mail
services.postfix = {
enable = true;
config = {
relayhost = "[email-smtp.us-west-2.amazonaws.com]:587";
smtp_use_tls = "yes";
smtp_tls_security_level = "encrypt";
smtp_tls_note_starttls_offer = "yes";
smtp_sasl_auth_enable = "yes";
smtp_sasl_security_options = "noanonymous";
smtp_sasl_password_maps = "hash:/var/lib/postfix/conf/smtp_sasl_password_maps";
};
origin = "andrew.kvalhe.im";
destination = []; # Disable local delivery
};
systemd.services."alert@" = {
description = "Alert of failed %I";
serviceConfig.SyslogIdentifier = "%p";
serviceConfig.Type = "oneshot";
serviceConfig.ExecStart = ''
${pkgs.bash}/bin/bash -c "${pkgs.system-sendmail}/bin/sendmail -i root \
<<< $'Subject: %I failed\n\n'\"$(systemctl --full status %I)\""
'';
};
# SMART monitoring
services.smartd = {
enable = true;
notifications.mail.enable = true;
};
# Audio
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa = { enable = true; support32Bit = true; };
pulse.enable = true;
};
# Printer
services.printing.enable = true;
services.printing.drivers = with pkgs; [
brgenml1cupswrapper
];
hardware.printers = {
ensureDefaultPrinter = "DCP-7065DN";
ensurePrinters = [ {
name = "DCP-7065DN";
description = "Brother DCP-7065DN";
model = "brother-BrGenML1-cups-en.ppd";
deviceUri = "lpd://lumberjack/binary_p1";
} ];
};
# Scanner
hardware.sane.enable = true;
hardware.sane.brscan4 = {
enable = true;
netDevices.DCP-7065DN = { model = "DCP-7065DN"; nodename = "lumberjack"; };
};
# Graphical environment
services.xserver.enable = true;
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
# Applications
environment.gnome.excludePackages = with pkgs.gnome; [
epiphany
geary
gnome-maps
gnome-music
gnome-photos
gnome-weather
];
services.pcscd.enable = true;
programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
virtualisation = {
containers.registries.search = ["docker.io"];
docker = { enable = true; enableOnBoot = false; autoPrune.enable = true; };
podman.enable = true;
libvirtd.enable = true;
};
programs.zsh.enable = true;
environment.localBinInPath = true;
# Users
users.mutableUsers = false;
users.groups.ak.gid = 1000;
users.users.ak = {
isNormalUser = true;
uid = 1000;
group = "ak";
extraGroups = [
"wheel"
"networkmanager"
"lp"
"scanner"
"podman"
"docker"
"libvirtd"
];
description = "Andrew";
hashedPassword = builtins.readFile ./local/ak.passwd;
shell = pkgs.zsh;
openssh.authorizedKeys.keys = [ (builtins.readFile ./andrew.pub) ];
};
# Backup
systemd.services.mirror = {
description = "Mirror to closet";
serviceConfig.Type = "oneshot";
serviceConfig.Nice = 10;
onFailure = [ "alert@%n.service" ];
path = with pkgs; [ netcat openssh rsync ];
};
systemd.timers.mirror = {
timerConfig.OnCalendar = "00,12,17:00 America/Los_Angeles";
timerConfig.Persistent = true;
wantedBy = [ "timers.target" ];
};
}

12
common/palette.nix Normal file
View file

@ -0,0 +1,12 @@
{
black = "#1b1b1b";
blue = "#66d9ef";
dark-gray = "#3a3a3a";
gray = "#666666";
green = "#a6e22e";
orange = "#fd971f";
purple = "#ae81ff";
red = "#f92672";
white = "#f8f8f8";
yellow = "#e6db74";
}

View file

@ -1,10 +1,3 @@
;;(defcfg
;; input (device-file "/dev/input/by-path/platform-i8042-serio-0-event-kbd")
;; output (uinput-sink "KMonad output")
;;
;; fallthrough true
;;)
(defsrc
` 1 2 3 4 5 6 7 8 9 0 - = bspc
tab q w e r t y u i o p [ ] \

View file

@ -1,251 +1,14 @@
{ config, lib, pkgs, ... }:
let
attachments = (pkgs.yarn2nix-moretea.mkYarnWorkspace {
src = /home/ak/akorg/project/current/andrew.kvalhe.im/andrew.kvalhe.im;
}).attachments;
iosevkaCommon = {
widths = {
normal = { css = "normal"; menu = 5; shape = 500; };
};
weights = {
regular = { css = 400; menu = 400; shape = 400; };
bold = { css = 700; menu = 700; shape = 800; };
};
slopes = {
upright = { angle = 0; css = "normal"; menu = "upright"; shape = "upright"; };
italic = { angle = 9.4; css = "italic"; menu = "italic"; shape = "italic"; };
};
variants.design = {
digit-form = "old-style";
capital-a = "curly-serifless";
capital-g = "toothless-corner-serifless-hooked";
capital-k = "curly-serifless";
capital-u = "toothless-corner";
capital-r = "standing";
capital-v = "curly";
capital-w = "curly";
capital-x = "curly-serifless";
capital-y = "curly-serifless";
capital-z = "curly-serifless";
a = "double-storey-toothless-corner";
b = "toothless-corner";
d = "toothless-corner-serifless";
f = "flat-hook-crossbar-at-x-height";
g = "earless-corner";
i = "serifed-flat-tailed";
j = "flat-hook-serifed";
l = "flat-tailed";
m = "earless-corner-double-arch-short-leg";
n = "earless-corner-straight";
p = "earless-corner";
q = "earless-corner";
r = "earless-corner";
t = "flat-hook-short-neck2";
u = "toothless-corner";
w = "curly";
x = "curly-serifless";
y = "curly";
z = "curly-serifless";
zero = "slashed";
two = "straight-neck";
three = "flat-top";
four = "semi-open-non-crossing";
five = "oblique-upper-left-bar";
six = "straight-bar";
seven = "bend-serifless";
eight = "crossing-asymmetric";
nine = "straight-bar";
tilde = "low";
asterisk = "hex-low";
underscore = "above-baseline";
caret = "low";
brace = "curly";
at = "short";
dollar = "open-cap";
cent = "open";
percent = "dots";
bar = "force-upright";
};
};
iosevka-custom-proportional = pkgs.iosevka.override {
set = "custom-proportional";
privateBuildPlan = iosevkaCommon // {
family = "Iosevka Custom Proportional";
spacing = "quasi-proportional";
ligations = { inherits = "javascript"; };
};
};
iosevka-custom-mono = pkgs.iosevka.override {
set = "custom-mono";
privateBuildPlan = iosevkaCommon // {
family = "Iosevka Custom Mono";
ligations = { inherits = "javascript"; };
};
};
iosevka-custom-term = pkgs.iosevka.override {
set = "custom-term";
privateBuildPlan = iosevkaCommon // {
family = "Iosevka Custom Term";
spacing = "term";
no-ligation = true;
};
};
palette = {
black = "#1b1b1b";
blue = "#66d9ef";
dark-gray = "#3a3a3a";
gray = "#666666";
green = "#a6e22e";
orange = "#fd971f";
purple = "#ae81ff";
red = "#f92672";
white = "#f8f8f8";
yellow = "#e6db74";
};
in
{
# Home manager
programs.home-manager.enable = true;
home.stateVersion = "21.05"; # Permanent
nixpkgs.config.allowUnfree = true;
manual.html.enable = true;
home.username = "ak";
home.homeDirectory = "/home/ak";
home.packages = with pkgs; [
attachments
awscli2
chromium
curl
darktable
delta
digikam
dnsutils
exiftool
fd
ffmpeg
file
firefox-wayland
gimp-with-plugins
gnome.gnome-boxes
gnome.gnome-tweaks
gnome.zenity
gopass
# (gnomeExtensions.easyScreenCast.overrideAttrs (attrs: rec {
# version = "1.4.0";
# src = fetchFromGitHub {
# owner = "EasyScreenCast";
# repo = "EasyScreenCast";
# rev = version;
# sha256 = "sha256-+lh/hqYC9+DUvLE016KuAY4Ybw8KrqEEG7WG4pUbg2k=";
# };
# }))
gnomeExtensions.system-monitor
gnomeExtensions.tray-icons-reloaded
gnupg
gpsprune
htop
httpie
hugin
imagemagick
inkscape
iosevka-custom-mono
iosevka-custom-proportional
iosevka-custom-term
jitsi-meet-electron
josm
killall
libheif # heif-convert
libreoffice
lsof
minecraft
moreutils
mozjpeg
mtr
multitail
ncdu
netcat
nheko
nix-top
nix-tree
nixpkgs-fmt
nox
oxipng
pwgen
qownnotes
ripgrep
roboto
rsync
shellcheck
signal-desktop
thunderbird
tig
transmission-gtk
trash-cli
v4l-utils
vagrant
vscodium
wget
whois
xorg.xev
yaru-theme
youtube-dl
imports = [
../../common/home.nix
];
fonts.fontconfig.enable = true;
home.sessionVariables = rec {
ANSIBLE_NOCOWS = true;
EDITOR = "${pkgs.vscodium}/bin/codium --wait";
EXA_COLORS = lib.concatStringsSep ":" (lib.attrsets.mapAttrsToList (k: v: "${k}=${v}") {
ur = "2;37"; # the user-read permission bit
uw = "2;37"; # the user-write permission bit
ux = "1;32"; # the user-execute permission bit for regular files
ue = "1;32"; # the user-execute for other file kinds
gr = "2;37"; # the group-read permission bit
gw = "2;37"; # the group-write permission bit
gx = "2;37"; # the group-execute permission bit
tr = "1;35"; # the others-read permission bit
tw = "1;31"; # the others-write permission bit
tx = "2;37"; # the others-execute permission bit
su = "1;33"; # setuid, setgid, and sticky permission bits for files
sf = "1;33"; # setuid, setgid, and sticky for other file kinds
xa = "1;33"; # the extended attribute indicator
sn = "2;37"; # the numbers of a files size
ub = "1;37"; # the units of a files size if it is lower than 1 KB/Kib
uk = "1;34"; # the units of a files size if it is between 1 KB/KiB and 1 MB/MiB
um = "1;33"; # the units of a files size if it is between 1 MB/MiB and 1 GB/GiB
ug = "1;31"; # the units of a files size if it is between 1 GB/GiB and 1 TB/TiB
ut = "1;31"; # the units of a files size if it is 1 TB/TiB or higher
uu = "30"; # a user thats you
un = "31"; # a user thats someone else
gu = "30"; # a group that you belong to
gn = "31"; # a group you arent a member of
da = "2;3;37"; # a files date
lp = "2;37"; # the path of a symlink
cc = "1;33"; # an escaped character in a filename
});
LS_COLORS = lib.concatStringsSep ":" (lib.attrsets.mapAttrsToList (k: v: "${k}=${v}") {
di = "1;36"; # directories
ex = "32"; # executable files
fi = "37"; # regular files
pi = "3;34"; # named pipes
so = "3;34"; # sockets
bd = "1;34"; # block devices
cd = "1;34"; # character devices
ln = "35"; # symlinks
or = "31"; # symlinks with no target
});
VISUAL = EDITOR;
VSCODE_GALLERY_CACHE_URL = "https://vscode.blob.core.windows.net/gallery/index";
VSCODE_GALLERY_CONTROL_URL = "";
VSCODE_GALLERY_ITEM_URL = "https://marketplace.visualstudio.com/items";
VSCODE_GALLERY_RECOMMENDATIONS_URL = "";
VSCODE_GALLERY_SERVICE_URL = "https://marketplace.visualstudio.com/_apis/public/gallery";
};
# Nix
home.stateVersion = "21.05"; # Permanent
# Services
systemd.user.paths.organize-downloads = {
Unit.Description = "Watch downloads";
Path.PathExistsGlob = "%h/Downloads/Screen{s,\\ S}hot\\ *.png";
@ -257,316 +20,46 @@ in
Service.Nice = 10;
};
programs = {
bat.enable = true;
# Applications
home.packages = with pkgs; [
awscli2
chromium
darktable
digikam
exiftool
ffmpeg
gimp-with-plugins
gnome.gnome-boxes
gpsprune
httpie
hugin
imagemagick
inkscape
jitsi-meet-electron
josm
libheif # heif-convert
libreoffice
minecraft
mozjpeg
netcat
nheko
oxipng
qownnotes
signal-desktop
thunderbird
transmission-gtk
v4l-utils
vagrant
whois
xorg.xev
youtube-dl
direnv = {
enable = true;
nix-direnv.enable = true;
stdlib = ''
use_gopass() {
eval "$(gopass-await "$@")"
}
'';
};
(pkgs.yarn2nix-moretea.mkYarnWorkspace {
src = /home/ak/akorg/project/current/andrew.kvalhe.im/andrew.kvalhe.im;
}).attachments
];
exa = { enable = true; enableAliases = true; };
fzf = rec {
enable = true;
enableZshIntegration = true;
defaultOptions = [ "--height 33%" "--reverse" ];
defaultCommand = "fd --one-file-system --type file"; # --no-ignore-parent pending https://github.com/sharkdp/fd/pull/817 (fd v9)
fileWidgetCommand = defaultCommand;
changeDirWidgetCommand = "fd --one-file-system --type directory"; # --no-ignore-parent pending https://github.com/sharkdp/fd/pull/817 (fd v9)
};
git = {
enable = true;
aliases = {
ff = "merge --ff-only";
puff = "pull --ff-only";
recent = "!git --no-pager log --max-count 8 --pretty=tformat:\"%w($(tput cols),0,8)%C(cyan)%h%Creset %C(yellow)%cr:%C(magenta)%d%Creset %s\"";
};
delta = {
enable = true;
options = {
file-renamed-label = "moved:";
line-numbers-left-format = "{nm:>1} ";
line-numbers-left-style = "#444444";
line-numbers-minus-style = "#872843 bold";
line-numbers-plus-style = "#5c7b2a bold";
line-numbers-right-format = "{np:>1}";
line-numbers-right-style = "#444444";
line-numbers-zero-style = "#444444 bold";
minus-emph-style = "#827c7d #42282d";
minus-empty-line-marker-style = "normal #42282d";
minus-non-emph-style = "#444444";
minus-style = "#827c7d #42282d";
plus-emph-style = "syntax #343e28";
plus-empty-line-marker-style = "normal #343e28";
plus-non-emph-style = "syntax";
plus-style = "syntax #343e28";
syntax-theme = "Monokai Extended";
whitespace-error-style = "reverse white";
full = {
file-style = "white bold";
file-decoration-style = "omit";
hunk-header-style = "omit";
line-numbers = true;
};
};
};
extraConfig = {
core.autocrlf = "input";
diff.algorithm = "patience";
init.defaultBranch = "main";
merge.commit = false;
push.followTags = true;
tig = {
line-graphics = "utf-8";
main-view-date = "custom";
main-view-date-format = "%F %H:%M";
main-view-id-display = true;
show-changes = false;
tab-size = 4;
truncation-delimiter = "utf-8";
vertical-split = false;
color = {
author = "color8 default";
cursor = "black magenta bold";
graph-commit = "magenta default";
date = "yellow default";
id = "cyan default";
main-head = "magenta default bold";
main-local-tag = "green default";
main-ref = "magenta default";
main-remote = "blue default";
main-tag = "green default";
main-tracked = "blue default bold";
palette-0 = "color8 default";
palette-1 = "color8 default";
palette-2 = "color8 default";
palette-3 = "color8 default";
palette-4 = "color8 default";
palette-5 = "color8 default";
palette-6 = "color8 default";
palette-7 = "color8 default";
palette-8 = "color8 default";
palette-9 = "color8 default";
palette-10 = "color8 default";
palette-11 = "color8 default";
palette-12 = "color8 default";
palette-13 = "color8 default";
search-result = "black white bold";
title-blur = "white black";
title-focus = "white black bold";
};
};
};
ignores = [
".direnv/"
".envrc"
".envrc.nix"
".vscode/"
];
iniContent.core.pager = lib.mkForce "${pkgs.delta}/bin/delta --color-only --features full"; # Set feature
userName = "Andrew Kvalheim";
userEmail = "Andrew@Kvalhe.im";
};
jq.enable = true;
kitty = {
enable = true;
font = {
package = iosevka-custom-term;
name = "Iosevka Custom Term";
size = 11;
};
keybindings = {
"shift+left" = "previous_tab";
"ctrl+shift+left" = "move_tab_backward";
"shift+right" = "next_tab";
"ctrl+shift+right" = "move_tab_forward";
"shift+down" = "previous_window";
"ctrl+shift+up" = "move_window_backward";
"shift+up" = "next_window";
"ctrl+shift+down" = "move_window_forward";
"alt+down" = "resize_window shorter";
"alt+up" = "resize_window taller";
};
settings = {
# Mouse
click_interval = "0.25";
focus_follows_mouse = "yes";
mouse_hide_wait = "0";
select_by_word_characters = "-_?&%+#";
# Windows
hide_window_decorations = true;
scrollback_lines = "16384";
enabled_layouts = "vertical, horizontal";
# Workaround for https://github.com/kovidgoyal/kitty/issues/3180
touch_scroll_multiplier = "10";
# Sounds
enable_audio_bell = "no";
# Font
bold_font = "Iosevka Custom Term Bold";
italic_font = "Iosevka Custom Term Italic";
bold_italic_font = "Iosevka Custom Term Bold Italic";
active_tab_font_style = "bold";
inactive_tab_font_style = "bold";
# Cursor
cursor_shape = "beam";
# URLs
url_style = "single";
# Colors
wayland_titlebar_color = palette.black;
foreground = palette.white;
background = palette.black;
cursor = palette.orange;
url_color = palette.white;
active_border_color = palette.dark-gray;
inactive_border_color = palette.dark-gray;
bell_border_color = palette.red;
active_tab_foreground = palette.white;
active_tab_background = palette.dark-gray;
inactive_tab_foreground = palette.gray;
inactive_tab_background = palette.dark-gray;
selection_foreground = palette.black;
selection_background = palette.orange;
color0 = palette.dark-gray;
color1 = palette.red;
color2 = palette.green;
color3 = palette.yellow;
color4 = palette.blue;
color5 = palette.orange;
color6 = palette.purple;
color7 = palette.white;
color8 = palette.gray;
color9 = palette.red;
color10 = palette.green;
color11 = palette.yellow;
color12 = palette.blue;
color13 = palette.orange;
color14 = palette.purple;
color15 = palette.white;
};
};
zsh = {
enable = true;
autocd = false;
history = {
expireDuplicatesFirst = true;
extended = true;
ignoreDups = false;
ignoreSpace = true;
save = 100000000;
size = 1000000000;
};
sessionVariables = {
ATTACHMENTS_ENV = "/home/ak/.attachments.env";
HIST_STAMPS = "yyyy-mm-dd";
REPORTTIME = 10;
WORDCHARS = "_.~;!#$%^";
};
initExtra = ''
setopt HIST_FIND_NO_DUPS
setopt NOCLOBBER
setopt PUSHD_SILENT
export DIRENV_LOG_FORMAT="$(print -P "%B%F{8} %%s%f")"
TIMEFMT="$(print -P "%B%F{8} Duration: %%*Es, CPU: %%P, Memory: %%MkB%f")"
git() {
if [[ "$1" == 'clone' && "$2" =~ '^https://(github\.com|gitlab\.com)/([^/]+)/[^/]+' ]]; then
shift
echo "Detected origin name ''\'''${match[2]}'" >&2
command git clone --origin "''${match[2]}" "$@"
elif [[ "$1" == 'checkout' ]]; then
echo 'Reminder: Use `git switch` or `git restore` instead.' >&2
command git "$@"
else
command git "$@"
fi
}
rd() { diff --recursive --unified "$@" | delta }
rdw() { diff --ignore-all-space --recursive --unified "$@" | delta }
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
'';
shellAliases = {
a = "git add --patch";
b = "git switch --create";
c = "git commit";
cat = "bat --plain";
code = "codium";
d = "git diff ':!*.lock'";
ds = "git diff --staged ':!*.lock'";
e = "exa --all --group-directories-first --long --header --time-style long-iso";
et = "exa --all --group-directories-first --long --header --time-style long-iso --tree";
gf = "git fetch --all --jobs 4 --prune";
gff = "git fetch --all --jobs 4 --prune && git merge --ff-only";
h = "tig --all";
mv = "mv --no-clobber --verbose";
p = "gopass";
rebase = "noglob git rebase --autostash --autosquash --interactive";
rm = "rm --one-file-system --verbose";
s = "git status";
stash = "git stash save --include-untracked";
undo = "git restore --patch";
watch = "watch --color";
};
prezto = {
enable = true;
pmodules = [
"environment"
"terminal"
"spectrum"
"completion"
"syntax-highlighting"
"history-substring-search"
"prompt"
"git"
];
prompt.theme = "powerlevel10k";
syntaxHighlighting.styles = {
arg0 = "fg=white,bold";
precommand = "fg=white"; # Pending https://github.com/zsh-users/zsh-syntax-highlighting/issues/432
reserved-word = "fg=blue";
};
terminal = {
autoTitle = true;
multiplexerTitleFormat = "%1~";
tabTitleFormat = "%1~";
windowTitleFormat = "%1~";
};
extraConfig = ''
zstyle ':prezto:module:git:alias' skip 'yes'
'';
};
};
};
# TODO: Clear `~/.cache/gtk-3.0/compose` when this is updated
home.file.".XCompose".source = ./Compose;
home.file.".p10k.zsh".source = ./p10k.zsh;
# Workaround for https://github.com/NixOS/nixpkgs/issues/101616
home.file."${config.xdg.configHome}/autostart/gnome-keyring-ssh.desktop".text = ''
[Desktop Entry]
Type=Application
Name=SSH Key Agent
Hidden=true
'';
# Environment
home.sessionPath = [ "$HOME/.cargo/bin" ];
home.sessionVariables.ATTACHMENTS_ENV = "/home/ak/.attachments.env";
}

View file

@ -1,39 +1,15 @@
{ config, lib, pkgs, ... }:
let
palette = {
black = "#1b1b1b";
blue = "#66d9ef";
dark-gray = "#3a3a3a";
gray = "#666666";
green = "#a6e22e";
orange = "#fd971f";
purple = "#ae81ff";
red = "#f92672";
white = "#f8f8f8";
yellow = "#e6db74";
};
in
{
imports =
[
<nixpkgs/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix>
<nixos-hardware/lenovo/thinkpad/p14s/amd/gen2>
/etc/nixos/hardware-configuration.nix
./kmonad-issue-306.nix
./local/nixos.nix
];
imports = [
../../common/nixos.nix
<nixos-hardware/lenovo/thinkpad/p14s/amd/gen2>
/etc/nixos/hardware-configuration.nix
./local/nixos.nix
];
# Nix
system.stateVersion = "21.05"; # Permanent
nix.autoOptimiseStore = true;
nix.gc = { automatic = true; options = "--delete-older-than 7d"; };
nix.extraOptions = ''
# Recommended by nix-direnv
keep-outputs = true
keep-derivations = true
'';
nixpkgs.config.allowUnfree = true;
# CPU architecture
nixpkgs.localSystem = {
@ -41,31 +17,9 @@ in
system = "x86_64-linux";
};
# Boot
boot.loader.systemd-boot.enable = true;
boot.loader.systemd-boot.memtest86.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.plymouth.enable = true;
# Swap
zramSwap.enable = true;
# Filesystems
boot.initrd.luks = {
gpgSupport = true;
devices.pv = {
device = "/dev/disk/by-partlabel/pv-enc";
allowDiscards = true;
fallbackToPassword = true;
gpgCard.encryptedPass = ./local/luks-passphrase.gpg;
gpgCard.publicKey = ./andrew.asc;
};
};
# TODO: Set `chattr +i` on intermittent mount points
fileSystems = {
"/" = {
options = [ "noatime" ];
};
"/home/ak/annex" = {
device = "closet:/mnt/hdd/home-ak-annex";
fsType = "nfs";
@ -84,8 +38,6 @@ in
options = [ "noauto" "user" ];
};
};
# TODO: Set `chattr +i` on intermittent mount points
boot.cleanTmpDir = true;
# Workaround for:
# - https://github.com/NixOS/nixpkgs/issues/24913
# - https://github.com/NixOS/nixpkgs/issues/9848
@ -100,12 +52,7 @@ in
};
};
# Time and locale
time.timeZone = "America/Los_Angeles";
i18n.extraLocaleSettings.LC_TIME = "en_DK.UTF-8";
# Networking
networking.useDHCP = false; # Future default
networking.hostName = "main";
networking.domain = "home.arpa";
networking.search = [ "home.arpa" ];
@ -117,212 +64,13 @@ in
networking.interfaces.dock.useDHCP = true;
networking.interfaces.jack.useDHCP = true;
networking.interfaces.wifi.useDHCP = true;
# Workaround for `avahi-daemon[1234]: Failed to read /etc/avahi/services.`
# Upstream: https://github.com/lathiat/avahi/blob/v0.8/avahi-daemon/static-services.c#L917-L919
system.activationScripts.etcAvahiServices = "mkdir -p /etc/avahi/services";
# Turn off wifi when jack is connected
# networking.networkmanager.dispatcherScripts = [{ source = pkgs.writeText "dispatch" ''
# case "$1" in
# "")
# case "$2" in
# connectivity-change)
# if [ "$(${pkgs.networkmanager}/bin/nmcli --get-values 'GENERAL.STATE' device show 'jack')" = '20 (unavailable)' ]; then
# logger "Enabling wifi ($2)"
# ${pkgs.networkmanager}/bin/nmcli radio wifi on
# fi
# ;;
# esac
# ;;
# jack)
# case "$2" in
# down)
# logger "Enabling wifi ($1 $2)"
# ${pkgs.networkmanager}/bin/nmcli radio wifi on
# ;;
# up)
# logger "Disabling wifi ($1 $2)"
# ${pkgs.networkmanager}/bin/nmcli radio wifi off
# ;;
# esac
# ;;
# esac
# ''; }];
# Console
console.colors = map (lib.removePrefix "#") [
"#000000" palette.red palette.green palette.yellow palette.blue palette.orange palette.purple palette.white
palette.gray palette.red palette.green palette.yellow palette.blue palette.orange palette.purple palette.white
];
# Keyboard
services.xserver.extraLayouts.halmakish = {
description = "Andrew";
languages = [ "eng" ];
symbolsFile = ./halmakish.xkb;
};
services.xserver.layout = "halmakish";
console.useXkbConfig = true;
kmonad = {
enable = true;
keyboards.default = {
device = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
config = builtins.readFile ./halmakish.kbd;
};
};
# Power
systemd.ctrlAltDelUnit = "poweroff.target";
# Authentication
security.pam.u2f = {
enable = true;
appId = "pam://main";
control = "sufficient";
cue = true;
};
# Authorization
security.sudo.extraRules = [
{
groups = [ "wheel" ];
commands = [
{ command = "/run/current-system/sw/bin/nix-channel --update"; options = [ "NOPASSWD" ]; }
{ command = "/run/current-system/sw/bin/nixos-rebuild boot"; options = [ "NOPASSWD" ]; }
{ command = "/run/current-system/sw/bin/nixos-rebuild switch"; options = [ "NOPASSWD" ]; }
{ command = "/run/current-system/sw/bin/poweroff"; options = [ "NOPASSWD" ]; }
];
}
];
# SSH
services.openssh.enable = true;
kmonad.keyboards.default.device = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
# Mail
services.postfix = {
enable = true;
config = {
relayhost = "[email-smtp.us-west-2.amazonaws.com]:587";
smtp_use_tls = "yes";
smtp_tls_security_level = "encrypt";
smtp_tls_note_starttls_offer = "yes";
smtp_sasl_auth_enable = "yes";
smtp_sasl_security_options = "noanonymous";
smtp_sasl_password_maps = "hash:/var/lib/postfix/conf/smtp_sasl_password_maps";
};
origin = "andrew.kvalhe.im";
destination = []; # Disable local delivery
mapFiles.smtp_sasl_password_maps = ./local/smtp-sasl-password-maps;
};
systemd.services."alert@" = {
description = "Alert of failed %I";
serviceConfig.SyslogIdentifier = "%p";
serviceConfig.Type = "oneshot";
serviceConfig.ExecStart = ''
${pkgs.bash}/bin/bash -c "${pkgs.system-sendmail}/bin/sendmail -i root \
<<< $'Subject: %I failed\n\n'\"$(systemctl --full status %I)\""
'';
};
# SMART monitoring
services.smartd = {
enable = true;
notifications.mail.enable = true;
};
# Audio
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa = { enable = true; support32Bit = true; };
pulse.enable = true;
};
# Printer
services.printing.enable = true;
services.printing.drivers = with pkgs; [
brgenml1cupswrapper
];
hardware.printers = {
ensureDefaultPrinter = "DCP-7065DN";
ensurePrinters = [ {
name = "DCP-7065DN";
description = "Brother DCP-7065DN";
model = "brother-BrGenML1-cups-en.ppd";
deviceUri = "lpd://lumberjack/binary_p1";
} ];
};
# Scanner
hardware.sane.enable = true;
hardware.sane.brscan4 = {
enable = true;
netDevices.DCP-7065DN = { model = "DCP-7065DN"; nodename = "lumberjack"; };
};
# Graphical environment
services.xserver.enable = true;
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
# Applications
# environment.systemPackages = with pkgs; [
# ];
# fonts.fonts = with pkgs; [
# ];
environment.gnome.excludePackages = with pkgs.gnome; [
epiphany
geary
gnome-maps
gnome-music
gnome-photos
gnome-weather
];
services.pcscd.enable = true;
programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
virtualisation = {
containers.registries.search = ["docker.io"];
docker = { enable = true; enableOnBoot = false; autoPrune.enable = true; };
podman.enable = true;
libvirtd.enable = true;
};
programs.zsh.enable = true;
environment.localBinInPath = true;
# Users
users.mutableUsers = false;
users.groups.ak.gid = 1000;
users.users.ak = {
isNormalUser = true;
uid = 1000;
group = "ak";
extraGroups = [
"wheel"
"networkmanager"
"lp"
"scanner"
"podman"
"docker"
"libvirtd"
];
description = "Andrew";
hashedPassword = builtins.readFile ./local/ak.passwd;
shell = pkgs.zsh;
openssh.authorizedKeys.keys = [ (builtins.readFile ./andrew.pub) ];
};
services.postfix.mapFiles.smtp_sasl_password_maps = ./local/smtp-sasl-password-maps;
# Backup
systemd.services.mirror = {
description = "Mirror to closet";
serviceConfig.Type = "oneshot";
serviceConfig.Nice = 10;
onFailure = [ "alert@%n.service" ];
path = with pkgs; [ netcat openssh rsync ];
script = builtins.readFile ./local/mirror.sh;
};
systemd.timers.mirror = {
timerConfig.OnCalendar = "00,12,17:00 America/Los_Angeles";
timerConfig.Persistent = true;
wantedBy = [ "timers.target" ];
};
systemd.services.mirror.script = builtins.readFile ./local/mirror.sh;
}

View file

@ -1,3 +1,4 @@
# Pending https://github.com/kmonad/kmonad/issues/306
# Adapted from https://github.com/pjones/tilde
{ config, lib, pkgs, ... }: