# FredOS-Eee — Asus Eee PC 1000HG, a toy netbook running XFCE. # # Not built from common.nix: stylix, home-manager and hyprland would all # compile from source for i686 (almost nothing is in cache.nixos.org for it) # and wouldn't fit in 1GB anyway. Only locale + users are shared. # # Build on the server, never on the Eee — evaluating this flake alone would # eat its 1GB. { config, lib, pkgs, ... }: let serverKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMbIdOSPjnJYQ7z7n0mHKo8T8PnAkCyIBCmT4KpsHyy/ fred@FredOS-Mediaserver"; in { imports = [ ../settings/locale.nix ../settings/users.nix ]; nixpkgs.overlays = [ (final: prev: { # partial-protected-regular-retry-linux fails on i686; the binary is fine. rsync = prev.rsync.overrideAttrs { doCheck = false; }; # Tests need gjs -> spidermonkey, an hour+ of i686 compile for a check. libsecret = prev.libsecret.overrideAttrs { doCheck = false; }; # libultrahdr misses -latomic on i686; icon themes only need plain convert. imagemagick = prev.imagemagick.override { libultrahdrSupport = false; }; # nixpkgs' own i686 test patch no longer applies; it only touches tests. upower = prev.upower.overrideAttrs (o: { patches = lib.filter (p: !lib.hasSuffix "i686-test-remove-battery-check.patch" (toString p)) o.patches; doCheck = false; }); # 64-bit getint64 tests fail on 32-bit. iniparser = prev.iniparser.overrideAttrs { doCheck = false; }; }) ]; # Portals (flatpak-style sandbox plumbing) drag in gnome-settings-daemon, # cinnamon-desktop and pulseaudio. Nothing here needs them. xdg.portal.enable = lib.mkForce false; # Plain gvfs: no gnome-online-accounts. services.gvfs.package = pkgs.gvfs; nix.settings.experimental-features = [ "nix-command" "flakes" ]; networking.networkmanager.enable = true; services.xserver.enable = true; # IceWM (taskbar, tray and start menu in one small binary) to leave the RAM # for the browser; nm-applet in its tray for wifi. XFCE stays as a fallback # session in the login screen's chooser (log out to reach it). services.xserver.windowManager.icewm.enable = true; services.displayManager.defaultSession = "none+icewm"; programs.nm-applet.enable = true; programs.nm-applet.indicator = false; # IceWM's tray is XEmbed, not appindicator services.xserver.desktopManager.xfce.enable = true; # Thunar thumbnails: tumbler -> libgepub -> webkitgtk, hours of i686 compile. services.tumbler.enable = lib.mkForce false; services.displayManager.autoLogin = { enable = true; user = "fred"; }; services.openssh.enable = true; # The server's key, so it can push closures and poke at the box. Root too: # `eee-update` copies unsigned closures, which only a trusted user may do. users.users.fred.openssh.authorizedKeys.keys = [ serverKey ]; users.users.root.openssh.authorizedKeys.keys = [ serverKey ]; # The Eee lives on other people's networks, so the server can't reach it. # Instead it holds a reverse tunnel open: server's localhost:2222 -> Eee:22 # (`ssh eee` there). The key is made here on first start and only allowed # to open that one forward (hosts/FredOS-Mediaserver.nix). Plain ssh + # Restart=always covers reconnects; ExitOnForwardFailure retries while the # server still holds a dead session's port. systemd.services.server-tunnel = { wantedBy = [ "multi-user.target" ]; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; serviceConfig = { StateDirectory = "server-tunnel"; Restart = "always"; RestartSec = 30; }; preStart = '' [ -f $STATE_DIRECTORY/id_ed25519 ] || \ ${pkgs.openssh}/bin/ssh-keygen -q -t ed25519 -N "" -C "eee-tunnel" -f $STATE_DIRECTORY/id_ed25519 ''; script = '' exec ${pkgs.openssh}/bin/ssh -N -i $STATE_DIRECTORY/id_ed25519 \ -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes \ -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=$STATE_DIRECTORY/known_hosts \ -R 2222:localhost:22 fred@nordhammer.it ''; }; # Firefox is marked unsupported on i686 (Mozilla dropped 32-bit Linux), so # WebKit is the only engine left that handles the modern web. # NetSurf: no JavaScript, so news sites load as plain pages on this CPU. environment.systemPackages = [ pkgs.epiphany pkgs.netsurf-browser # netsurf ships no .desktop file, so it's missing from the menu. (pkgs.makeDesktopItem { name = "netsurf"; desktopName = "NetSurf"; exec = "netsurf-gtk3 %u"; icon = "web-browser"; categories = [ "Network" "WebBrowser" ]; }) ]; # 1GB RAM: compressed swap only (disk swap is off, see hardware file). zramSwap.enable = true; # A heavy page (bbc.co.uk) used to freeze everything; now the biggest # process (the browser's web process) dies instead. zram lives in RAM, so # swap never looks full: judge on RAM alone. services.earlyoom.enable = true; services.earlyoom.freeSwapThreshold = 100; # Even with no disk swap it still froze: the kernel kept evicting and # re-reading program code from disk. MGLRU's min_ttl OOM-kills instead # when it can't keep the last 1s of working set in RAM. systemd.tmpfiles.rules = [ "w /sys/kernel/mm/lru_gen/min_ttl_ms - - - - 1000" ]; # The NixOS manual is a big from-source build on i686 for a page nobody reads. documentation.nixos.enable = false; }