| ID | 26ecd52b-1c5c-46b8-8eb9-fe827a753f0a |
|---|---|
| DeertopiaVisibility | public |
Sydnix
unimplemented! (keyword)
{:type "keyword",
:affiliated {},
:key "TAGS",
:value "nix",
:position
{:start {:line 7, :column 1, :offset 145},
:end {:line 8, :column 1, :offset 157}}}
A second try at NixOS, now that I have a better idea of what I'm doing. The effort is largely inspired by my darling Faye's glorious wishsys.
The Sydnix repo hosts the system and home configurations for my personal computers (the topic of this particular document), my Emacs config, a few oddballs such as my Team Fortress 2 and Quake Live configs, and my home server.
Inbox
Conventions
User configuration
In order of descending preference, user programs should be configured by...
home-manager's modules.
Wrappers, with config files optionally living somewhere under /persist/dots.
home.fileand similar.Mutable symlinks using
home.fileandmkOutOfStoreSymlink.
doge
Repo structure
hosts/
Each directory hosts/«HOST» is expected to configure a single specific device, where «HOST» is the device's exact hostname. Said directory «HOST» should have at least the following structure:
hosts
└── «HOST»
├── configuration.nix
└── system.nix
Where configuration.nix is the main entry point imported by the top-level flake, and system.nix evaluates to a string corresponding to the system option to be used.
users/
Similarly to the hosts directory, each sub-directory users/«USER» is assumed to have some structure, and that «USER» is the precise username desired.
users
└── «USER»
└── default.nix
Where default.nix returns an attrset of form
{
# The NixOS option `users.users.«USER»` will be set to result of
# `systemConfiguration`.
systemConfiguration = { config, pkgs, lib, ... }: {
# isNormalUser = true;
# extraGroups = [ "wheel" ];
# ...
};
# Home-manager configuration
homeConfiguration = { config, pkgs, lib, ... }: {
# home.packages = [ pkgs.hello ];
# ...
};
}
modules/
modules
├── home
│  └── «Various home-manager modules»…
└── nixos
├── defaults
│  └── «NixOS modules that are *enabled by default*»…
├── deertopia
│  └── «NixOS modules that are *specific to Deertopia*»…
└── «Various NixOS modules»…
Impermanence and persistence
I use impermanence to wipe most of my file-system on boot.
Boot process
What follows is an overview of modules/nixos/impermanence/rollback.nix.
On boot, ...
The existing subvolume root filesystem will be moved to a 'death row' directory, where it will live for about three days before deletion. Precisely, «btrfs-filesystem»/«root-subvolume» is moved to «btrfs-filesystem»/old-roots/«timestamp». The brief grace period allows for easy recovery in the (very common) case where files are unintentionally deleted due to the user's silly human negligence.
A new, blank subvolume is created in place of the previous. Precisely, the subvolume «btrfs-filesystem»/«root-subvolume» is created.
Any subvolumes under «btrfs-filesystem»/old-roots older than three days are deleted.
The /persist directory
- /persist/root
Persistent files to be linked into the real root, /. These are managed by Impermanence.
- /persist/home/«user»
Persistent files to be linked into the analogous location under the real home, /home/«user». These are managed by Impermanence.
- /persist/vault/«user»
Persistent files belonging to specific users. This differs from the persistent home directories in that files are not necessarily linked anywhere.
- /persist/private-keys
The private key counterparts to the keys listed in this repository's own public-keys directory.
Deferring Emacs packages
Nearly all configuration of Emacs packages happens under the use-package macro. use-package has various keywords with special syntax for common tasks, such as instrumenting hooks, setting keybindings, and customising variables. You may be surprised to learn that these are not just syntactic sugar }:) (I was).
As an example, this
(use-package which-key
:hook (on-first-input . which-key-mode)
:custom
(which-key-allow-evil-operators t)
(which-key-show-operator-state-maps t)
is not the same as this
(use-package which-key
:config
(add-hook 'on-first-input #'which-key-mode)
(setq which-key-allow-evil-operators t)
(setq which-key-show-operator-state-maps t)
The difference connects to another silly obsession of the Emacs hacker: startup time. use-package's special keywords will defer the loading of the package ([cite:@systemcrafters2021how]) . E.g., instead of loading which-key on startup, it will be loaded when the on-first-input hook is first called.
on-first-input is one of many useful hooks provided by the package on.el specialised for fine-grained control of package loading.
Naming conventions in my Emacs config
As with the rest of the config, these are largely adapted from Doom's ([cite:@lissner2022contributing]). }:3
syd-[-]«NAME»Typical ‘namespaced’ Elisp convention ([cite:@gnu2020conventions]).
«NAME»-hProcedure defined specifically to be added to a hook.
«NAME»-aProcedure defined specifically as advice.
Hosts
nixos-testbed
Configuration for the VM I'm currently using as a test-bed, before moving to my real desktop.
deertopia
My home server.
Users
crumb
Me }:). My primary user for programming and playing TF2.
lain
A bit on the nose for a transfemme into computers, but my chosen name is also Madeleine.
Used as a server admin account with little configuration.
sydnix-cli
sydnix-cli is a command-line utility written in Clojure wrapping various Sydnix-related scripts.
Tasks
PROJ [#A] Documentation
Module API/option docs unimplemented! (statistics-cookie)
{:type "statistics-cookie",
:begin 6397,
:end 6403,
:value "[2/30]",
:post-blank 0,
:position
{:start {:line 181, :column 33, :offset 6397},
:end {:line 181, :column 39, :offset 6403}}}
unimplemented! (statistics-cookie)
{:type "statistics-cookie",
:begin 6397,
:end 6403,
:value "[2/30]",
:post-blank 0,
:position
{:start {:line 181, :column 33, :offset 6397},
:end {:line 181, :column 39, :offset 6403}}}
Concepts unimplemented! (statistics-cookie)
{:type "statistics-cookie",
:begin 7932,
:end 7935,
:value "[/]",
:post-blank 0,
:position
{:start {:line 214, :column 19, :offset 7932},
:end {:line 214, :column 22, :offset 7935}}}
unimplemented! (statistics-cookie)
{:type "statistics-cookie",
:begin 7932,
:end 7935,
:value "[/]",
:post-blank 0,
:position
{:start {:line 214, :column 19, :offset 7932},
:end {:line 214, :column 22, :offset 7935}}}
PROJ [#A] Code clean-up
Remove uses of with lib;
Refactor modules/ directory
modules
├── home
│ ├── sydnix
│ │ ├── crumb
│ │ │ └── «My configurations»
│ │ └── «Personal Sydnix modules»
│ └── «Home-manager modules that could be upstreamed»
└── nixos
├── sydnix
│ ├── webdav.nix
│ └── deertopia
│ └── «Deertopia-specific modules»
└── «NixOS modules that could be upstreamed»
Import sydnix-cli and port-tools via flake's self.packages
Refactor default modules
All code in default.nix and defaults/ should be moved into individual modules. default.nix's role is then subjugated to enabling those modules and bundling them under a single enable switch.
Deprecate sydnix.deertopia.webdav
I believe Copyparty has a built-in WebDAV server. This would allow more refined permissions, and is one less required service.
sydnix.deertopia.nginx.vhosts should not set a root by default
It's currently only useful for the www and dav vhosts, and otherwise is nothing but a potential problem-causer.
lib.sydnix
mkMutableSymlinklistNixDirectory
Complete ten Nix TODOs
Log completed TODOs here:
Refactor users/crumb/programs/*.nix into proper modules
IDEA Replace sops-nix with age-nix
Desktop environment
Niri
wbg
Waybar
Swaylock
IDEA Dispatch notification after completion of long-running command
Move this file into Org-roam and out of VC
Emacs
Move Nixcord input back to upsteam
My PR was merged
Firefox
Extensions
Settings
Search engines
Kagi
DuckDuckGo
Wikipedia
YouTube
Hackage
Hoogle
Nixpkgs
Nixopt
Rename user crumb to msyds
Bash
shopt -s histverify
Don’t execute expanded result immediately.
Add passwordFile option to programs.gh module
Add programs.glab module
Move inputs.* imports in nixosConfigurations to their own modules
Syncthing module shouldn't expose devices
Define services.syncthing.settings.devices as constant. Folders can still list devices by name, but not ID.
Dotfile management
This is about the management of configuration files. Nix wrappers, Nix modules, deployment, and the like.
Emacs
Managed by users/crumb/programs/emacs.nix.
See configuration notes here.
Bash
Managed by the Home-manager module.
(neo)vim
Managed by a hand-rolled wrapper. See users/crumb/programs/nvim.nix.
Readline
Declaratively install Jellyfin plugins
Disko
Refactor Disko configs to be more reusable
Replace uses of GPG with age
I don't know anything about either.
pass → passage
Firefox integration
Secret-management
Git config
Convenient way to wrap programs
wrapper-manager looks like it will be really annoying to integrate into my config without a NixOS/HM module.
tf2.nix
Declaratively configure tf2
tf2Packages?
Mastercomfig integration?
Define aliases / bindings from nix?
mpd
mpdscribble
syncthing
impermanence
sydnix.defaults module
Split up flake.nix into a file per output
default package sets
Some examples of what I mean:
defaultPackages.essential = trueto installneovimandgit;defaultPackages.development = trueforjjand Emacs.defaultPackages.desktop = trueforcantata,obs,vlc,vesktop,soulseek;
Naturally, one would expect some way to say "all these, except this and that."
Set environment variables
$EDITOR
See choose-editor.
System maintenance scripts
It might be a good idea to namespace these as subcommands of a single binary.
nix-clean
Collect garbage, clean up boot entries, delete old generations...
https://discourse.nixos.org/t/what-to-do-with-a-full-boot-partition/2049
choose-editor
| ID | 5b4ee1e4-fad7-4783-8e98-301b41579a63 |
|---|---|
| DeertopiaVisibility | public |
If the Emacs daemon is running...
...then run
emacsclient....otherwise, prompt the user to choose between Emacs and Vim
If Emacs: run
emacs.If Vim: In order, try
nvim,vim, thenvi.If neither are available, use
nix run nixpkgs#nvimIf this fails, try
nano.
Support
--pager
rage-edit
forget-host HOST
Remove a given host from ~/.ssh/known_hosts. Something like sed -i -e '/192.168.122.54/d' .ssh/known_hosts.
Confirm by printing diff.
scratch-dir [NAME]
Create a new tempdir called [NAME], and cd into it.
doctor / status
Run various checks on the system.
Sizes of caches. perhaps those listed by
sydnix.impermanence.cache.{files,directories}? Offer to clean them if they're getting old or large.Check for available upgrades. Flake inputs, overlays, emacs packages, etc.
persist status
List persistent files per user, and show their mount strategy.
Show info about
sydnix.impermanence.cachevalues. Extend that option to have "description" and "consequences" fields, which are shown to users before clearing them. e.g.{ sydnix.impermanence.cache.directories.".local/share/emacs/cache" = { description = "Root of all caches for Emacs and Emacs packages."; consequences = [ "All known projects will be forgotten" "All trusted .dir-locals.el files and values will be forgotten" ]; }; }$ sydnix cache clear Recursively remove `~/.local/share/emacs/cache'? - All known projects will be forgotten - All trusted .dir-locals.el files and values will be forgotten [y/n] «more caches…»
persist prepare
Command sydnix persist prepare «file or directory» will
Move a directory to /persist
Optionally mount/bind/symlink it back into place.
Print Nix code necessary to persist it.
Pre-references
The section after this one is a subset of the many places I've learnt from. Most important of all are Doom Emacs and Faye's Wishsys.
Doom Emacs was my gateway drug to Emacs, as well as a continually supportive parent as I've begun to move out — of course, that's a flowerism obfuscating the more direct statement "I've stolen a great deal of their code" }:).
Faye's dazzling Wishsys is an incredibly impressive 3-kloc NixOS config with several hosts, users, and a beautiful level of modularity. Her system has a number of quirks that initially raise eyebrows, but the questioning turns to awe once you understand she really knows what she's doing }:). Faye and her config are entirely responsible for inspiring and motivating my effort expended here, as well as being a wonderful reference as I re-learnt Nix from the ground up. In the most nerdy moment of my life, I've genuinely swooned over this damn config.
References
My darling dearest Faye's wishsys }:D
[cite:@christensen2020erase]
[cite:@ayats2024dropping]
[cite:@zaynetdinov2024you]
[cite:@schafer2017advanced]
[cite:@bosio2023beautifying]
[cite:@zamboni2018beautifying]
[cite:@pant]
[cite:@w]
neeasade/emacs.d — Has an interesting 'module' system.
oantolin/emacs-config — Has some internal packages.
[cite:@karthikchikmagalur2021latex]