From e65504b5f370ea0f27d84346f4b3516fe69b8cce Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 10 May 2025 16:57:19 -0400 Subject: [PATCH 1/4] Add a role for mounting the nix store over 9pfs. This is useful for virtual machines since we can have a persistent /nix/store on the host machine. --- nix/configuration/configuration.nix | 1 + nix/configuration/flake.nix | 213 +++++++++--------- .../hosts/neelix/hardware-configuration.nix | 11 +- nix/configuration/hosts/odo/default.nix | 2 +- nix/configuration/hosts/odo/disk-config.nix | 8 +- .../hosts/odo/hardware-configuration.nix | 2 +- .../hosts/odo/optimized_build.nix | 46 ++-- .../hosts/odo/wrapped-disk-config.nix | 8 + .../hosts/quark/hardware-configuration.nix | 2 +- .../hosts/quark/optimized_build.nix | 46 ++-- .../roles/9pfs_nix_store/default.nix | 77 +++++++ nix/configuration/roles/network/default.nix | 4 +- nix/configuration/roles/wasm/default.nix | 10 +- 13 files changed, 272 insertions(+), 158 deletions(-) create mode 100644 nix/configuration/hosts/odo/wrapped-disk-config.nix create mode 100644 nix/configuration/roles/9pfs_nix_store/default.nix diff --git a/nix/configuration/configuration.nix b/nix/configuration/configuration.nix index 5a1b58f..7907444 100644 --- a/nix/configuration/configuration.nix +++ b/nix/configuration/configuration.nix @@ -9,6 +9,7 @@ { imports = [ ./roles/2ship2harkinian + ./roles/9pfs_nix_store ./roles/alacritty ./roles/ansible ./roles/ares diff --git a/nix/configuration/flake.nix b/nix/configuration/flake.nix index 38ece4e..2e1e840 100644 --- a/nix/configuration/flake.nix +++ b/nix/configuration/flake.nix @@ -29,7 +29,7 @@ # Install on a new machine: # # -# doas nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount hosts/quark/disk-config.nix +# doas nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount hosts/odo/disk-config.nix # nix flake update zsh-histdb --flake . # nix flake update ansible-sshjail --flake . @@ -115,120 +115,131 @@ ./configuration.nix ]; }; - systems = { - odo = { - main = nixpkgs.lib.nixosSystem ( - base_x86_64_linux - // { + systems = + let + additional_iso_modules = [ + (nixpkgs + "/nixos/modules/installer/cd-dvd/iso-image.nix") + # TODO: Figure out how to do image based appliances + # (nixpkgs + "/nixos/modules/profiles/image-based-appliance.nix") + { + isoImage.makeEfiBootable = true; + isoImage.makeUsbBootable = true; + me.buildingIso = true; + me.optimizations.enable = nixpkgs.lib.mkDefault false; + me._9pfs_nix_store.is_iso = true; + } + { + # These are big space hogs. The chance that I need them on an ISO is slim. + me.steam.enable = nixpkgs.lib.mkForce false; + me.pcsx2.enable = nixpkgs.lib.mkForce false; + } + ]; + additional_vm_modules = [ + (nixpkgs + "/nixos/modules/profiles/qemu-guest.nix") + { + networking.dhcpcd.enable = true; + networking.useDHCP = true; + me.optimizations.enable = nixpkgs.lib.mkDefault false; + } + { + # me._9pfs_nix_store.enable = true; + } + ]; + in + { + odo = rec { + main = base_x86_64_linux // { modules = base_x86_64_linux.modules ++ [ ./hosts/odo ]; - } - ); - iso = nixpkgs.lib.nixosSystem ( - base_x86_64_linux - // { - modules = base_x86_64_linux.modules ++ [ - ./hosts/odo - (nixpkgs + "/nixos/modules/installer/cd-dvd/iso-image.nix") - # TODO: Figure out how to do image based appliances - # (nixpkgs + "/nixos/modules/profiles/image-based-appliance.nix") - { - isoImage.makeEfiBootable = true; - isoImage.makeUsbBootable = true; - me.buildingIso = true; - me.optimizations.enable = nixpkgs.lib.mkForce false; - } - ]; - } - ); - }; - quark = { - main = nixpkgs.lib.nixosSystem ( - base_x86_64_linux - // { + }; + iso = main // { + modules = main.modules ++ additional_iso_modules; + }; + vm = main // { + modules = main.modules ++ additional_vm_modules; + }; + vm_iso = main // { + modules = main.modules ++ additional_vm_modules ++ additional_iso_modules; + }; + }; + quark = rec { + main = base_x86_64_linux // { modules = base_x86_64_linux.modules ++ [ ./hosts/quark ]; - } - ); - iso = nixpkgs.lib.nixosSystem ( - base_x86_64_linux - // { - modules = base_x86_64_linux.modules ++ [ - ./hosts/quark - (nixpkgs + "/nixos/modules/installer/cd-dvd/iso-image.nix") - # TODO: Figure out how to do image based appliances - # (nixpkgs + "/nixos/modules/profiles/image-based-appliance.nix") - { - isoImage.makeEfiBootable = true; - isoImage.makeUsbBootable = true; - me.buildingIso = true; - me.optimizations.enable = nixpkgs.lib.mkForce false; - } - ]; - } - ); - }; - neelix = { - main = nixpkgs.lib.nixosSystem ( - base_x86_64_linux - // { + }; + iso = main // { + modules = main.modules ++ additional_iso_modules; + }; + vm = main // { + modules = main.modules ++ additional_vm_modules; + }; + vm_iso = main // { + modules = main.modules ++ additional_vm_modules ++ additional_iso_modules; + }; + }; + neelix = rec { + main = base_x86_64_linux // { modules = base_x86_64_linux.modules ++ [ ./hosts/neelix ]; - } - ); - iso = nixpkgs.lib.nixosSystem ( - base_x86_64_linux - // { - modules = base_x86_64_linux.modules ++ [ - ./hosts/neelix - (nixpkgs + "/nixos/modules/installer/cd-dvd/iso-image.nix") + }; + iso = main // { + modules = main.modules ++ additional_iso_modules; + }; + vm = main // { + modules = main.modules ++ additional_vm_modules; + }; + vm_iso = main // { + modules = main.modules ++ additional_vm_modules ++ additional_iso_modules; + }; + }; + hydra = + let + additional_iso_modules = additional_iso_modules ++ [ { - isoImage.makeEfiBootable = true; - isoImage.makeUsbBootable = true; - me.buildingIso = true; - me.optimizations.enable = nixpkgs.lib.mkForce false; + me.optimizations.enable = true; } ]; - } - ); + in + rec { + main = base_x86_64_linux // { + modules = base_x86_64_linux.modules ++ [ + ./hosts/hydra + ]; + }; + iso = main // { + modules = main.modules ++ additional_iso_modules; + }; + vm = main // { + modules = main.modules ++ additional_vm_modules; + }; + vm_iso = main // { + modules = main.modules ++ additional_vm_modules ++ additional_iso_modules; + }; + }; }; - hydra = { - main = nixpkgs.lib.nixosSystem ( - base_x86_64_linux - // { - modules = base_x86_64_linux.modules ++ [ - ./hosts/hydra - ]; - } - ); - iso = nixpkgs.lib.nixosSystem ( - base_x86_64_linux - // { - modules = base_x86_64_linux.modules ++ [ - ./hosts/hydra - (nixpkgs + "/nixos/modules/installer/cd-dvd/iso-image.nix") - { - isoImage.makeEfiBootable = true; - isoImage.makeUsbBootable = true; - me.buildingIso = true; - } - ]; - } - ); - }; - }; in { - nixosConfigurations.odo = systems.odo.main; - iso.odo = systems.odo.iso.config.system.build.isoImage; - nixosConfigurations.quark = systems.quark.main; - iso.quark = systems.quark.iso.config.system.build.isoImage; - nixosConfigurations.neelix = systems.neelix.main; - iso.neelix = systems.neelix.iso.config.system.build.isoImage; - nixosConfigurations.hydra = systems.hydra.main; - iso.hydra = systems.hydra.iso.config.system.build.isoImage; + nixosConfigurations.odo = nixpkgs.lib.nixosSystem systems.odo.main; + iso.odo = (nixpkgs.lib.nixosSystem systems.odo.iso).config.system.build.isoImage; + nixosConfigurations.vm_odo = nixpkgs.lib.nixosSystem systems.odo.vm; + vm_iso.odo = (nixpkgs.lib.nixosSystem systems.odo.vm_iso).config.system.build.isoImage; + + nixosConfigurations.quark = nixpkgs.lib.nixosSystem systems.quark.main; + iso.quark = (nixpkgs.lib.nixosSystem systems.quark.iso).config.system.build.isoImage; + nixosConfigurations.vm_quark = nixpkgs.lib.nixosSystem systems.quark.vm; + vm_iso.quark = (nixpkgs.lib.nixosSystem systems.quark.vm_iso).config.system.build.isoImage; + + nixosConfigurations.neelix = nixpkgs.lib.nixosSystem systems.neelix.main; + iso.neelix = (nixpkgs.lib.nixosSystem systems.neelix.iso).config.system.build.isoImage; + nixosConfigurations.vm_neelix = nixpkgs.lib.nixosSystem systems.neelix.vm; + vm_iso.neelix = (nixpkgs.lib.nixosSystem systems.neelix.vm_iso).config.system.build.isoImage; + + nixosConfigurations.hydra = nixpkgs.lib.nixosSystem systems.hydra.main; + iso.hydra = (nixpkgs.lib.nixosSystem systems.hydra.iso).config.system.build.isoImage; + nixosConfigurations.vm_hydra = nixpkgs.lib.nixosSystem systems.hydra.vm; + vm_iso.hydra = (nixpkgs.lib.nixosSystem systems.hydra.vm_iso).config.system.build.isoImage; }; } diff --git a/nix/configuration/hosts/neelix/hardware-configuration.nix b/nix/configuration/hosts/neelix/hardware-configuration.nix index b583e6a..fe3c1cb 100644 --- a/nix/configuration/hosts/neelix/hardware-configuration.nix +++ b/nix/configuration/hosts/neelix/hardware-configuration.nix @@ -14,7 +14,14 @@ (modulesPath + "/installer/scan/not-detected.nix") ]; - boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" ]; + boot.initrd.availableKernelModules = [ + "xhci_pci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + "sdhci_pci" + ]; boot.initrd.kernelModules = [ ]; boot.kernelModules = [ ]; boot.extraModulePackages = [ ]; @@ -23,7 +30,7 @@ # (the default) this is the recommended approach. When using systemd-networkd it's # still possible to use this option, but it's recommended to use it in conjunction # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - networking.useDHCP = lib.mkDefault true; + # networking.useDHCP = lib.mkDefault true; # networking.interfaces.eno1.useDHCP = lib.mkDefault true; # networking.interfaces.wlp58s0.useDHCP = lib.mkDefault true; diff --git a/nix/configuration/hosts/odo/default.nix b/nix/configuration/hosts/odo/default.nix index a7e64f6..c950775 100644 --- a/nix/configuration/hosts/odo/default.nix +++ b/nix/configuration/hosts/odo/default.nix @@ -7,7 +7,7 @@ { imports = [ ./hardware-configuration.nix - ./disk-config.nix + ./wrapped-disk-config.nix ./optimized_build.nix ./distributed_build.nix ./power_management.nix diff --git a/nix/configuration/hosts/odo/disk-config.nix b/nix/configuration/hosts/odo/disk-config.nix index dc31c68..4575e94 100644 --- a/nix/configuration/hosts/odo/disk-config.nix +++ b/nix/configuration/hosts/odo/disk-config.nix @@ -1,14 +1,8 @@ # Manual Step: # Check if drive supports 4kn: nvme id-ns -H /dev/nvme0n1 # Format the drive to 4kn: nvme format --lbaf=1 /dev/nvme0n1 -{ - config, - lib, - pkgs, - ... -}: -lib.mkIf (!config.me.buildingIso) { +{ disko.devices = { disk = { main = { diff --git a/nix/configuration/hosts/odo/hardware-configuration.nix b/nix/configuration/hosts/odo/hardware-configuration.nix index 1852fa3..d463cf9 100644 --- a/nix/configuration/hosts/odo/hardware-configuration.nix +++ b/nix/configuration/hosts/odo/hardware-configuration.nix @@ -27,7 +27,7 @@ # (the default) this is the recommended approach. When using systemd-networkd it's # still possible to use this option, but it's recommended to use it in conjunction # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - networking.useDHCP = lib.mkDefault true; + # networking.useDHCP = lib.mkDefault true; # networking.interfaces.eno1.useDHCP = lib.mkDefault true; # networking.interfaces.wlp58s0.useDHCP = lib.mkDefault true; diff --git a/nix/configuration/hosts/odo/optimized_build.nix b/nix/configuration/hosts/odo/optimized_build.nix index 7315afa..3f5b975 100644 --- a/nix/configuration/hosts/odo/optimized_build.nix +++ b/nix/configuration/hosts/odo/optimized_build.nix @@ -56,31 +56,35 @@ (final: prev: { haskellPackages = prev.haskellPackages.extend ( final': prev': { - crypton = pkgs-unoptimized.haskellPackages.crypton; - crypton-connection = pkgs-unoptimized.haskellPackages.crypton-connection; - crypton-x509 = pkgs-unoptimized.haskellPackages.crypton-x509; - crypton-x509-store = pkgs-unoptimized.haskellPackages.crypton-x509-store; - crypton-x509-system = pkgs-unoptimized.haskellPackages.crypton-x509-system; - crypton-x509-validation = pkgs-unoptimized.haskellPackages.crypton-x509-validation; - hspec-wai = pkgs-unoptimized.haskellPackages.hspec-wai; - http-client-tls = pkgs-unoptimized.haskellPackages.http-client-tls; - http2 = pkgs-unoptimized.haskellPackages.http2; - pandoc = pkgs-unoptimized.haskellPackages.pandoc; - pandoc-cli = pkgs-unoptimized.haskellPackages.pandoc-cli; - pandoc-lua-engine = pkgs-unoptimized.haskellPackages.pandoc-lua-engine; - pandoc-server = pkgs-unoptimized.haskellPackages.pandoc-server; - servant-server = pkgs-unoptimized.haskellPackages.servant-server; - tls = pkgs-unoptimized.haskellPackages.tls; - wai-app-static = pkgs-unoptimized.haskellPackages.wai-app-static; - wai-extra = pkgs-unoptimized.haskellPackages.wai-extra; - warp = pkgs-unoptimized.haskellPackages.warp; + inherit (pkgs-unoptimized.haskellPackages) + crypton + crypton-connection + crypton-x509 + crypton-x509-store + crypton-x509-system + crypton-x509-validation + hspec-wai + http-client-tls + http2 + pandoc + pandoc-cli + pandoc-lua-engine + pandoc-server + servant-server + tls + wai-app-static + wai-extra + warp + ; } ); }) (final: prev: { - gsl = pkgs-unoptimized.gsl; - redis = pkgs-unoptimized.redis; - valkey = pkgs-unoptimized.valkey; + inherit (pkgs-unoptimized) + gsl + redis + valkey + ; }) ]; diff --git a/nix/configuration/hosts/odo/wrapped-disk-config.nix b/nix/configuration/hosts/odo/wrapped-disk-config.nix new file mode 100644 index 0000000..78e5f86 --- /dev/null +++ b/nix/configuration/hosts/odo/wrapped-disk-config.nix @@ -0,0 +1,8 @@ +{ + config, + lib, + pkgs, + ... +}: + +lib.mkIf (!config.me.buildingIso) (import ./disk-config.nix) diff --git a/nix/configuration/hosts/quark/hardware-configuration.nix b/nix/configuration/hosts/quark/hardware-configuration.nix index 1852fa3..d463cf9 100644 --- a/nix/configuration/hosts/quark/hardware-configuration.nix +++ b/nix/configuration/hosts/quark/hardware-configuration.nix @@ -27,7 +27,7 @@ # (the default) this is the recommended approach. When using systemd-networkd it's # still possible to use this option, but it's recommended to use it in conjunction # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - networking.useDHCP = lib.mkDefault true; + # networking.useDHCP = lib.mkDefault true; # networking.interfaces.eno1.useDHCP = lib.mkDefault true; # networking.interfaces.wlp58s0.useDHCP = lib.mkDefault true; diff --git a/nix/configuration/hosts/quark/optimized_build.nix b/nix/configuration/hosts/quark/optimized_build.nix index aecdd43..851201b 100644 --- a/nix/configuration/hosts/quark/optimized_build.nix +++ b/nix/configuration/hosts/quark/optimized_build.nix @@ -50,31 +50,35 @@ (final: prev: { haskellPackages = prev.haskellPackages.extend ( final': prev': { - crypton = pkgs-unoptimized.haskellPackages.crypton; - crypton-connection = pkgs-unoptimized.haskellPackages.crypton-connection; - crypton-x509 = pkgs-unoptimized.haskellPackages.crypton-x509; - crypton-x509-store = pkgs-unoptimized.haskellPackages.crypton-x509-store; - crypton-x509-system = pkgs-unoptimized.haskellPackages.crypton-x509-system; - crypton-x509-validation = pkgs-unoptimized.haskellPackages.crypton-x509-validation; - hspec-wai = pkgs-unoptimized.haskellPackages.hspec-wai; - http-client-tls = pkgs-unoptimized.haskellPackages.http-client-tls; - http2 = pkgs-unoptimized.haskellPackages.http2; - pandoc = pkgs-unoptimized.haskellPackages.pandoc; - pandoc-cli = pkgs-unoptimized.haskellPackages.pandoc-cli; - pandoc-lua-engine = pkgs-unoptimized.haskellPackages.pandoc-lua-engine; - pandoc-server = pkgs-unoptimized.haskellPackages.pandoc-server; - servant-server = pkgs-unoptimized.haskellPackages.servant-server; - tls = pkgs-unoptimized.haskellPackages.tls; - wai-app-static = pkgs-unoptimized.haskellPackages.wai-app-static; - wai-extra = pkgs-unoptimized.haskellPackages.wai-extra; - warp = pkgs-unoptimized.haskellPackages.warp; + inherit (pkgs-unoptimized.haskellPackages) + crypton + crypton-connection + crypton-x509 + crypton-x509-store + crypton-x509-system + crypton-x509-validation + hspec-wai + http-client-tls + http2 + pandoc + pandoc-cli + pandoc-lua-engine + pandoc-server + servant-server + tls + wai-app-static + wai-extra + warp + ; } ); }) (final: prev: { - gsl = pkgs-unoptimized.gsl; - redis = pkgs-unoptimized.redis; - valkey = pkgs-unoptimized.valkey; + inherit (pkgs-unoptimized) + gsl + redis + valkey + ; }) ]; diff --git a/nix/configuration/roles/9pfs_nix_store/default.nix b/nix/configuration/roles/9pfs_nix_store/default.nix new file mode 100644 index 0000000..a459c80 --- /dev/null +++ b/nix/configuration/roles/9pfs_nix_store/default.nix @@ -0,0 +1,77 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + imports = [ ]; + + options.me = { + _9pfs_nix_store.enable = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = "Whether we want to mount /nix/store over 9pfs (useful in virtual machines to share a directory from the host as a persistent nix store."; + }; + + _9pfs_nix_store.is_iso = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = "Whether this build is for an ISO. It changes how we mount the nix store."; + }; + }; + + config = lib.mkIf config.me._9pfs_nix_store.enable ( + lib.mkMerge [ + (lib.mkIf config.me._9pfs_nix_store.is_iso { + # fileSystems = { + # "/nix/store" = lib.mkForce { + # fsType = "overlay"; + # device = "overlay"; + # options = [ + # "lowerdir=/nix/.ro-store" + # "upperdir=/store" + # "workdir=/work" + # ]; + # depends = [ + # "/nix/.ro-store" + # "/store" + # "/work" + # ]; + # }; + + # "/store" = lib.mkForce { + # fsType = "9p"; + # device = "nixstore"; + # options = [ + # "trans=virtio" + # "version=9p2000.L" + # "x-systemd.requires=modprobe@9pnet_virtio.service" + # "msize=16384" # Maximum packet size. Increasing this should improve performance at the cost of increased memory usage. + # "cache=loose" + # ]; + # }; + # }; + }) + (lib.mkIf (!config.me._9pfs_nix_store.is_iso) { + fileSystems = { + "/nix/store" = lib.mkForce { + fsType = "9p"; + device = "nixstore"; + neededForBoot = true; + options = [ + "trans=virtio" + "version=9p2000.L" + "x-systemd.requires=modprobe@9pnet_virtio.service" + "msize=16384" # Maximum packet size. Increasing this should improve performance at the cost of increased memory usage. + "cache=loose" + ]; + }; + }; + }) + ] + ); +} diff --git a/nix/configuration/roles/network/default.nix b/nix/configuration/roles/network/default.nix index 7e11876..6d87538 100644 --- a/nix/configuration/roles/network/default.nix +++ b/nix/configuration/roles/network/default.nix @@ -18,8 +18,8 @@ { imports = [ ]; - networking.dhcpcd.enable = false; - networking.useDHCP = false; + networking.dhcpcd.enable = lib.mkDefault false; + networking.useDHCP = lib.mkDefault false; networking.nameservers = [ "194.242.2.2#doh.mullvad.net" "2a07:e340::2#doh.mullvad.net" diff --git a/nix/configuration/roles/wasm/default.nix b/nix/configuration/roles/wasm/default.nix index 3ce9433..8f8a696 100644 --- a/nix/configuration/roles/wasm/default.nix +++ b/nix/configuration/roles/wasm/default.nix @@ -24,7 +24,15 @@ environment.systemPackages = with pkgs; [ wabt wasm-bindgen-cli - pkgs-unoptimized.binaryen # for wasm-opt + binaryen # for wasm-opt + ]; + + nixpkgs.overlays = [ + (final: prev: { + inherit (pkgs-unoptimized) + binaryen + ; + }) ]; } ] From 5b7cae49c3891438310442c9005dc19ad77f3018 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 10 May 2025 20:40:49 -0400 Subject: [PATCH 2/4] Removing the 9pfs nix store. The experiment was good for mounting directories with various overlay patterns from the host to the guest, but using it specifically for /nix/store was a bad idea. It would be better to just serve the host nix store with nix-serve -p 8080 and add that as a substituter during install. --- nix/configuration/configuration.nix | 1 - nix/configuration/flake.nix | 4 - .../roles/9pfs_nix_store/default.nix | 77 ------------------- 3 files changed, 82 deletions(-) delete mode 100644 nix/configuration/roles/9pfs_nix_store/default.nix diff --git a/nix/configuration/configuration.nix b/nix/configuration/configuration.nix index 7907444..5a1b58f 100644 --- a/nix/configuration/configuration.nix +++ b/nix/configuration/configuration.nix @@ -9,7 +9,6 @@ { imports = [ ./roles/2ship2harkinian - ./roles/9pfs_nix_store ./roles/alacritty ./roles/ansible ./roles/ares diff --git a/nix/configuration/flake.nix b/nix/configuration/flake.nix index 2e1e840..c3c0f93 100644 --- a/nix/configuration/flake.nix +++ b/nix/configuration/flake.nix @@ -126,7 +126,6 @@ isoImage.makeUsbBootable = true; me.buildingIso = true; me.optimizations.enable = nixpkgs.lib.mkDefault false; - me._9pfs_nix_store.is_iso = true; } { # These are big space hogs. The chance that I need them on an ISO is slim. @@ -141,9 +140,6 @@ networking.useDHCP = true; me.optimizations.enable = nixpkgs.lib.mkDefault false; } - { - # me._9pfs_nix_store.enable = true; - } ]; in { diff --git a/nix/configuration/roles/9pfs_nix_store/default.nix b/nix/configuration/roles/9pfs_nix_store/default.nix deleted file mode 100644 index a459c80..0000000 --- a/nix/configuration/roles/9pfs_nix_store/default.nix +++ /dev/null @@ -1,77 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: - -{ - imports = [ ]; - - options.me = { - _9pfs_nix_store.enable = lib.mkOption { - type = lib.types.bool; - default = false; - example = true; - description = "Whether we want to mount /nix/store over 9pfs (useful in virtual machines to share a directory from the host as a persistent nix store."; - }; - - _9pfs_nix_store.is_iso = lib.mkOption { - type = lib.types.bool; - default = false; - example = true; - description = "Whether this build is for an ISO. It changes how we mount the nix store."; - }; - }; - - config = lib.mkIf config.me._9pfs_nix_store.enable ( - lib.mkMerge [ - (lib.mkIf config.me._9pfs_nix_store.is_iso { - # fileSystems = { - # "/nix/store" = lib.mkForce { - # fsType = "overlay"; - # device = "overlay"; - # options = [ - # "lowerdir=/nix/.ro-store" - # "upperdir=/store" - # "workdir=/work" - # ]; - # depends = [ - # "/nix/.ro-store" - # "/store" - # "/work" - # ]; - # }; - - # "/store" = lib.mkForce { - # fsType = "9p"; - # device = "nixstore"; - # options = [ - # "trans=virtio" - # "version=9p2000.L" - # "x-systemd.requires=modprobe@9pnet_virtio.service" - # "msize=16384" # Maximum packet size. Increasing this should improve performance at the cost of increased memory usage. - # "cache=loose" - # ]; - # }; - # }; - }) - (lib.mkIf (!config.me._9pfs_nix_store.is_iso) { - fileSystems = { - "/nix/store" = lib.mkForce { - fsType = "9p"; - device = "nixstore"; - neededForBoot = true; - options = [ - "trans=virtio" - "version=9p2000.L" - "x-systemd.requires=modprobe@9pnet_virtio.service" - "msize=16384" # Maximum packet size. Increasing this should improve performance at the cost of increased memory usage. - "cache=loose" - ]; - }; - }; - }) - ] - ); -} From e08d93425a01739692016ecacda56642d9e04b27 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 10 May 2025 21:00:33 -0400 Subject: [PATCH 3/4] Remove games from VMs. --- nix/configuration/flake.nix | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/nix/configuration/flake.nix b/nix/configuration/flake.nix index c3c0f93..5486033 100644 --- a/nix/configuration/flake.nix +++ b/nix/configuration/flake.nix @@ -34,7 +34,7 @@ # nix flake update zsh-histdb --flake . # nix flake update ansible-sshjail --flake . # for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done -# nixos-install --flake ".#quark" +# nixos-install --flake ".#quark" --substituters "http://10.0.2.2:8080" # { @@ -125,7 +125,7 @@ isoImage.makeEfiBootable = true; isoImage.makeUsbBootable = true; me.buildingIso = true; - me.optimizations.enable = nixpkgs.lib.mkDefault false; + me.optimizations.enable = nixpkgs.lib.mkForce false; } { # These are big space hogs. The chance that I need them on an ISO is slim. @@ -138,7 +138,15 @@ { networking.dhcpcd.enable = true; networking.useDHCP = true; - me.optimizations.enable = nixpkgs.lib.mkDefault false; + me.optimizations.enable = nixpkgs.lib.mkForce false; + } + { + # I don't need games on a virtual machine. + me.steam.enable = nixpkgs.lib.mkForce false; + me.pcsx2.enable = nixpkgs.lib.mkForce false; + me.sm64ex.enable = nixpkgs.lib.mkForce false; + me.shipwright.enable = nixpkgs.lib.mkForce false; + me.ship2harkinian.enable = nixpkgs.lib.mkForce false; } ]; in From c68c069667a1ac6d91cc5f0511338ec8311cb0a3 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 10 May 2025 21:29:37 -0400 Subject: [PATCH 4/4] Add a new ionlybootzfs host for the test VM. This way it will install far less software. --- nix/configuration/configuration.nix | 1 + nix/configuration/flake.nix | 27 +++- .../hosts/ionlybootzfs/DEPLOY_BOOT | 19 +++ .../hosts/ionlybootzfs/DEPLOY_SWITCH | 19 +++ nix/configuration/hosts/ionlybootzfs/ISO | 12 ++ .../hosts/ionlybootzfs/default.nix | 49 ++++++ .../hosts/ionlybootzfs/disk-config.nix | 142 ++++++++++++++++++ .../ionlybootzfs/hardware-configuration.nix | 38 +++++ .../hosts/ionlybootzfs/optimized_build.nix | 131 ++++++++++++++++ .../ionlybootzfs/wrapped-disk-config.nix | 8 + nix/configuration/roles/ssh/files/ssh_config | 4 + 11 files changed, 448 insertions(+), 2 deletions(-) create mode 100755 nix/configuration/hosts/ionlybootzfs/DEPLOY_BOOT create mode 100755 nix/configuration/hosts/ionlybootzfs/DEPLOY_SWITCH create mode 100755 nix/configuration/hosts/ionlybootzfs/ISO create mode 100644 nix/configuration/hosts/ionlybootzfs/default.nix create mode 100644 nix/configuration/hosts/ionlybootzfs/disk-config.nix create mode 100644 nix/configuration/hosts/ionlybootzfs/hardware-configuration.nix create mode 100644 nix/configuration/hosts/ionlybootzfs/optimized_build.nix create mode 100644 nix/configuration/hosts/ionlybootzfs/wrapped-disk-config.nix diff --git a/nix/configuration/configuration.nix b/nix/configuration/configuration.nix index 5a1b58f..08e27fe 100644 --- a/nix/configuration/configuration.nix +++ b/nix/configuration/configuration.nix @@ -170,6 +170,7 @@ ipcalc gptfdisk # for cgdisk nix-output-monitor # For better view into nixos-rebuild + nix-serve-ng # Serve nix store over http ]; services.openssh = { diff --git a/nix/configuration/flake.nix b/nix/configuration/flake.nix index 5486033..aa70896 100644 --- a/nix/configuration/flake.nix +++ b/nix/configuration/flake.nix @@ -29,12 +29,12 @@ # Install on a new machine: # # -# doas nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount hosts/odo/disk-config.nix +# doas nix --substituters "http://10.0.2.2:8080?trusted=1 https://cache.nixos.org/" --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount hosts/odo/disk-config.nix # nix flake update zsh-histdb --flake . # nix flake update ansible-sshjail --flake . # for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done -# nixos-install --flake ".#quark" --substituters "http://10.0.2.2:8080" +# nixos-install --substituters "http://10.0.2.2:8080?trusted=1 https://cache.nixos.org/" --flake ".#vm_ionlybootzfs" # { @@ -223,6 +223,23 @@ modules = main.modules ++ additional_vm_modules ++ additional_iso_modules; }; }; + ionlybootzfs = rec { + main = base_x86_64_linux // { + modules = base_x86_64_linux.modules ++ [ + ./hosts/ionlybootzfs + ]; + }; + iso = main // { + modules = main.modules ++ additional_iso_modules; + }; + vm = main // { + modules = main.modules ++ additional_vm_modules; + }; + vm_iso = main // { + modules = main.modules ++ additional_vm_modules ++ additional_iso_modules; + }; + }; + }; in { @@ -245,5 +262,11 @@ iso.hydra = (nixpkgs.lib.nixosSystem systems.hydra.iso).config.system.build.isoImage; nixosConfigurations.vm_hydra = nixpkgs.lib.nixosSystem systems.hydra.vm; vm_iso.hydra = (nixpkgs.lib.nixosSystem systems.hydra.vm_iso).config.system.build.isoImage; + + nixosConfigurations.ionlybootzfs = nixpkgs.lib.nixosSystem systems.ionlybootzfs.main; + iso.ionlybootzfs = (nixpkgs.lib.nixosSystem systems.ionlybootzfs.iso).config.system.build.isoImage; + nixosConfigurations.vm_ionlybootzfs = nixpkgs.lib.nixosSystem systems.ionlybootzfs.vm; + vm_iso.ionlybootzfs = + (nixpkgs.lib.nixosSystem systems.ionlybootzfs.vm_iso).config.system.build.isoImage; }; } diff --git a/nix/configuration/hosts/ionlybootzfs/DEPLOY_BOOT b/nix/configuration/hosts/ionlybootzfs/DEPLOY_BOOT new file mode 100755 index 0000000..0abb296 --- /dev/null +++ b/nix/configuration/hosts/ionlybootzfs/DEPLOY_BOOT @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: "${JOBS:="1"}" + +#TARGET=10.216.1.14 +# TARGET=192.168.211.250 +TARGET="ionlybootzfs" + +nix flake update zsh-histdb --flake "$DIR/../../" +nix flake update ansible-sshjail --flake "$DIR/../../" +for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done + +nixos-rebuild boot --flake "$DIR/../../#ionlybootzfs" --target-host "$TARGET" --build-host "$TARGET" --fast --use-remote-sudo --max-jobs "$JOBS" "${@}" |& nom + +# rsync -av --progress --delete --exclude=.git "$DIR/../../../configuration" "talexander@${TARGET}:/persist/manual/" && ssh talexander@${TARGET} 'cd /persist/manual/configuration && nix flake update zsh-histdb && nix flake update ansible-sshjail && doas nice -n 19 nixos-rebuild boot --flake /persist/manual/configuration#ionlybootzfs' diff --git a/nix/configuration/hosts/ionlybootzfs/DEPLOY_SWITCH b/nix/configuration/hosts/ionlybootzfs/DEPLOY_SWITCH new file mode 100755 index 0000000..ca52753 --- /dev/null +++ b/nix/configuration/hosts/ionlybootzfs/DEPLOY_SWITCH @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: "${JOBS:="1"}" + +#TARGET=10.216.1.14 +# TARGET=192.168.211.250 +TARGET=ionlybootzfs + +nix flake update zsh-histdb --flake "$DIR/../../" +nix flake update ansible-sshjail --flake "$DIR/../../" +for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done + +nixos-rebuild switch --flake "$DIR/../../#ionlybootzfs" --target-host "$TARGET" --build-host "$TARGET" --fast --use-remote-sudo --max-jobs "$JOBS" "${@}" |& nom + +# rsync -av --progress --delete --exclude=.git "$DIR/../../../configuration" "talexander@${TARGET}:/persist/manual/" && ssh talexander@${TARGET} 'cd /persist/manual/configuration && nix flake update zsh-histdb && nix flake update ansible-sshjail && doas nice -n 19 nixos-rebuild switch --flake /persist/manual/configuration#ionlybootzfs' diff --git a/nix/configuration/hosts/ionlybootzfs/ISO b/nix/configuration/hosts/ionlybootzfs/ISO new file mode 100755 index 0000000..8ac1918 --- /dev/null +++ b/nix/configuration/hosts/ionlybootzfs/ISO @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: "${JOBS:="1"}" + +nix flake update zsh-histdb --flake "$DIR/../../" +nix flake update ansible-sshjail --flake "$DIR/../../" +for f in /persist/manual/manual_add_to_store/*; do nix-store --add-fixed sha256 "$f"; done +nix build --extra-experimental-features nix-command --extra-experimental-features flakes "$DIR/../..#iso.ionlybootzfs" --max-jobs "$JOBS" "${@}" |& nom diff --git a/nix/configuration/hosts/ionlybootzfs/default.nix b/nix/configuration/hosts/ionlybootzfs/default.nix new file mode 100644 index 0000000..33aafa8 --- /dev/null +++ b/nix/configuration/hosts/ionlybootzfs/default.nix @@ -0,0 +1,49 @@ +# +# Testing: +# doas "$(nix-build '' --no-out-link -A 'qemu')/bin/qemu-system-x86_64" \ +# -accel kvm \ +# -cpu host \ +# -smp cores=8 \ +# -m 32768 \ +# -drive "file=$(nix-build '' --no-out-link -A 'OVMF.fd')/FV/OVMF.fd,if=pflash,format=raw,readonly=on" \ +# -drive file=/tmp/localdisk.img,if=none,id=nvm,format=raw \ +# -device nvme,serial=deadbeef,drive=nvm \ +# -nic user,hostfwd=tcp::60022-:22 \ +# -boot order=d \ +# -cdrom "$(readlink -f /persist/machine_setup/nix/configuration/result/iso/nixos*.iso)" \ +# -display vnc=127.0.0.1:0 +# + +{ + config, + lib, + pkgs, + ... +}: +{ + imports = [ + ./wrapped-disk-config.nix + ./hardware-configuration.nix + ./optimized_build.nix + ]; + + # Generate with `head -c4 /dev/urandom | od -A none -t x4` + networking.hostId = "fbd233d8"; + + networking.hostName = "ionlybootzfs"; # Define your hostname. + + time.timeZone = "America/New_York"; + i18n.defaultLocale = "en_US.UTF-8"; + + me.optimizations.enable = false; + me.secureBoot.enable = true; + + # Mount tmpfs at /tmp + boot.tmp.useTmpfs = true; + + me.emacs_flavor = "plainmacs"; + me.graphical = false; + me.wireguard.activated = [ ]; + me.wireguard.deactivated = [ ]; + me.zsh.enable = true; +} diff --git a/nix/configuration/hosts/ionlybootzfs/disk-config.nix b/nix/configuration/hosts/ionlybootzfs/disk-config.nix new file mode 100644 index 0000000..4575e94 --- /dev/null +++ b/nix/configuration/hosts/ionlybootzfs/disk-config.nix @@ -0,0 +1,142 @@ +# Manual Step: +# Check if drive supports 4kn: nvme id-ns -H /dev/nvme0n1 +# Format the drive to 4kn: nvme format --lbaf=1 /dev/nvme0n1 + +{ + disko.devices = { + disk = { + main = { + type = "disk"; + device = "/dev/nvme0n1"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ + "umask=0077" + "noatime" + "discard" + ]; + }; + }; + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; + }; + }; + }; + }; + }; + zpool = { + zroot = { + type = "zpool"; + # mode = "mirror"; + # Workaround: cannot import 'zroot': I/O error in disko tests + options.cachefile = "none"; + options = { + ashift = "12"; + compatibility = "openzfs-2.2-freebsd"; + autotrim = "on"; + }; + rootFsOptions = { + acltype = "posixacl"; + atime = "off"; + relatime = "off"; + xattr = "sa"; + mountpoint = "none"; + compression = "lz4"; + canmount = "off"; + utf8only = "on"; + dnodesize = "auto"; + normalization = "formD"; + }; + + datasets = { + "linux/nix" = { + type = "zfs_fs"; + options.mountpoint = "none"; + options = { + encryption = "aes-256-gcm"; + keyformat = "passphrase"; + # keylocation = "file:///tmp/secret.key"; + }; + }; + "linux/nix/root" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/root@blank$' || zfs snapshot zroot/linux/nix/root@blank"; + }; + "linux/nix/nix" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/nix"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/nix@blank$' || zfs snapshot zroot/linux/nix/nix@blank"; + options = { + recordsize = "16MiB"; + compression = "zstd-19"; + }; + }; + "linux/nix/home" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/home"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/home@blank$' || zfs snapshot zroot/linux/nix/home@blank"; + }; + "linux/nix/persist" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/persist"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/persist@blank$' || zfs snapshot zroot/linux/nix/persist@blank"; + }; + "linux/nix/state" = { + type = "zfs_fs"; + options.mountpoint = "legacy"; + mountpoint = "/state"; + postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot/linux/nix/state@blank$' || zfs snapshot zroot/linux/nix/state@blank"; + }; + }; + }; + }; + }; + + # Make sure all persistent volumes are marked as neededForBoot + # + # Also mounts /home so it is mounted before the user home directories are created. + fileSystems."/persist".neededForBoot = true; + fileSystems."/state".neededForBoot = true; + fileSystems."/home".neededForBoot = true; + + fileSystems."/".options = [ + "noatime" + "norelatime" + ]; + fileSystems."/nix".options = [ + "noatime" + "norelatime" + ]; + fileSystems."/persist".options = [ + "noatime" + "norelatime" + ]; + fileSystems."/state".options = [ + "noatime" + "norelatime" + ]; + fileSystems."/home".options = [ + "noatime" + "norelatime" + ]; + + # Only attempt to decrypt the main pool. Otherwise it attempts to decrypt pools that aren't even used. + boot.zfs.requestEncryptionCredentials = [ "zroot/linux/nix" ]; +} diff --git a/nix/configuration/hosts/ionlybootzfs/hardware-configuration.nix b/nix/configuration/hosts/ionlybootzfs/hardware-configuration.nix new file mode 100644 index 0000000..72e2137 --- /dev/null +++ b/nix/configuration/hosts/ionlybootzfs/hardware-configuration.nix @@ -0,0 +1,38 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + pkgs, + modulesPath, + ... +}: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ + "xhci_pci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + "sdhci_pci" + ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.dhcpcd.enable = lib.mkForce true; + networking.useDHCP = lib.mkForce true; + # systemd.network.enable = true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/nix/configuration/hosts/ionlybootzfs/optimized_build.nix b/nix/configuration/hosts/ionlybootzfs/optimized_build.nix new file mode 100644 index 0000000..3f5b975 --- /dev/null +++ b/nix/configuration/hosts/ionlybootzfs/optimized_build.nix @@ -0,0 +1,131 @@ +{ + config, + lib, + pkgs, + pkgs-unoptimized, + ... +}: +{ + imports = [ ]; + + config = lib.mkMerge [ + { } + (lib.mkIf (!config.me.optimizations.enable) { + boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_6_14; + }) + (lib.mkIf (config.me.optimizations.enable) { + nixpkgs.hostPlatform = { + gcc.arch = "znver4"; + gcc.tune = "znver4"; + system = "x86_64-linux"; + }; + + nixpkgs.overlays = [ + ( + final: prev: + let + addConfig = + additionalConfig: pkg: + pkg.override (oldconfig: { + structuredExtraConfig = pkg.structuredExtraConfig // additionalConfig; + }); + in + { + linux_me = addConfig { + # Full preemption + PREEMPT = lib.mkOverride 60 lib.kernel.yes; + PREEMPT_VOLUNTARY = lib.mkOverride 60 lib.kernel.no; + + # Google's BBRv3 TCP congestion Control + TCP_CONG_BBR = lib.kernel.yes; + DEFAULT_BBR = lib.kernel.yes; + + # Preemptive Full Tickless Kernel at 300Hz + HZ = lib.kernel.freeform "300"; + HZ_300 = lib.kernel.yes; + HZ_1000 = lib.kernel.no; + } prev.linux_6_14; + # gsl = prev.gsl.overrideAttrs (old: { + # # gsl tests fails when optimizations are enabled. + # # > FAIL: cholesky_invert unscaled hilbert ( 4, 4)[0,2]: 2.55795384873636067e-13 0 + # # > (2.55795384873636067e-13 observed vs 0 expected) [28259614] + # doCheck = false; + # }); + } + ) + (final: prev: { + haskellPackages = prev.haskellPackages.extend ( + final': prev': { + inherit (pkgs-unoptimized.haskellPackages) + crypton + crypton-connection + crypton-x509 + crypton-x509-store + crypton-x509-system + crypton-x509-validation + hspec-wai + http-client-tls + http2 + pandoc + pandoc-cli + pandoc-lua-engine + pandoc-server + servant-server + tls + wai-app-static + wai-extra + warp + ; + } + ); + }) + (final: prev: { + inherit (pkgs-unoptimized) + gsl + redis + valkey + ; + }) + ]; + + boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_me; + }) + (lib.mkIf (!config.me.buildingIso) { + nix.settings.system-features = lib.mkForce [ + "gccarch-znver4" + "gccarch-skylake" + # "gccarch-alderlake" missing WAITPKG + "gccarch-x86-64-v3" + "gccarch-x86-64-v4" + "benchmark" + "big-parallel" + "kvm" + "nixos-test" + ]; + + # Keep ALL dependencies so we can rebuild offline. This DRASTICALLY increase disk usage, but disk space is cheap. + # system.includeBuildDependencies = true; + + # This also should enable building offline? TODO: test. + nix.extraOptions = '' + keep-outputs = true + keep-derivations = true + ''; + + # # building ON + # nixpkgs.localSystem = { system = "aarch64-linux"; }; + # # building FOR + # nixpkgs.crossSystem = { system = "aarch64-linux"; }; + + # nixpkgs.config = { + # replaceStdenv = ({ pkgs }: pkgs.clangStdenv); + # }; + # or maybe an overlay + # stdenv = prev.clangStdenv; + + }) + (lib.mkIf (config.me.buildingIso) { + boot.supportedFilesystems.zfs = true; + }) + ]; +} diff --git a/nix/configuration/hosts/ionlybootzfs/wrapped-disk-config.nix b/nix/configuration/hosts/ionlybootzfs/wrapped-disk-config.nix new file mode 100644 index 0000000..78e5f86 --- /dev/null +++ b/nix/configuration/hosts/ionlybootzfs/wrapped-disk-config.nix @@ -0,0 +1,8 @@ +{ + config, + lib, + pkgs, + ... +}: + +lib.mkIf (!config.me.buildingIso) (import ./disk-config.nix) diff --git a/nix/configuration/roles/ssh/files/ssh_config b/nix/configuration/roles/ssh/files/ssh_config index 9cd7997..51870a7 100644 --- a/nix/configuration/roles/ssh/files/ssh_config +++ b/nix/configuration/roles/ssh/files/ssh_config @@ -34,5 +34,9 @@ Host hydra ProxyJump talexander@mrmanager HostName 10.215.1.219 +Host ionlybootzfs + HostName 127.0.0.1 + Port 60022 + Host * Compression yes