From b1bd3d7b5cf5d2dfb94493bb73140e6d8210f401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sat, 9 Apr 2022 18:54:00 +0200 Subject: Refactor Mox support --- README.md | 78 ++++++++++++++++++++++++++++++++++++ flake.lock | 10 ++--- flake.nix | 21 +++++----- medkit-configuration.nix | 55 ------------------------- medkit.nix | 45 --------------------- nixos/default.nix | 1 + nixos/modules/turris-board.nix | 68 ++----------------------------- nixos/modules/turris-defaults.nix | 84 +++++++++++++++++++++++++++++++++++++++ tarball.nix | 57 ++++++++++++++++++++++++++ 9 files changed, 239 insertions(+), 180 deletions(-) create mode 100644 README.md delete mode 100644 medkit-configuration.nix delete mode 100644 medkit.nix create mode 100644 nixos/modules/turris-defaults.nix create mode 100644 tarball.nix diff --git a/README.md b/README.md new file mode 100644 index 0000000..9b6b6e6 --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# NixOS for Turris routers + +This repository contains nix flake to get NixOS running on Turris routers. + +Using NixOS on router has few shortcomings, and you should know about them right +away so here is a list of issues you should expect: + +* NixOS is pretty memory hungry. There are few reasons for this such as Systemd + and specially Journald as those simply required more memory than other + alternatives. But but but... The biggest issue is NixOS itself. The wide range + of configuration options in NixOS result in pretty significant memory being + required on evaluation. The peak is around 2 GB and thus device with 512 MB is + pretty much screwed. Thankfully Nix is not using that memory most of the time, + and thus we can use swap without hampering the performance that much. +* Firewall configuration right now expects at most one NAT network thus forget + about multiple networks. There can't be dedicated network for you IOT devices + or for your guests. +* Hostapd configuration is pretty stupid and is prepared pretty much only for + single Wi-Fi card with single wireless network. Forget about multiple Wi-Fi + networks. + + +## Turris Mox + +Deploying NixOS to the Turris Mox is pretty easy and fast. The advantage is that +aarch64 packages cache is provided by official Hydra builds. + +At minimum, you should use micro SD card with size 8 GB. It is highly suggested +to use some high quality one as we have to use it for swap and that can reduce +lifetime a lot and kill the low quality one very fast. + +### Prepare the SD card + +You need to format the SD card first. The GPT is suggested as the partition +table. You should create two partitions. The second partition is going to be +Swap that should be at least 2GB but 4GB would be better. The first partition +can take the rest of the space and should be formated to the BTRFS. + +It is up to you which tool are you going to use. The instructions here are going +to be for GNU Parted. The following shell log should give you an idea of what +you should do to get the correct layout: + +``` +~# parted /dev/mmcblk1 +(parted) mktable gpt +(parted) mkpart NixTurris 0% -4G +(parted) set 1 boot on +(parted) mkpart NixTurrisSwap -4G 100% +(parted) set 2 swap on +(parted) quit +~# mkfs.btrfs /dev/mmcblk1p1 +~# mkswap /dev/mmcblk1p2 +``` + +Next we need the initial system tarball to unpack to the SD card. For this you +need the Nix with flake support be available on your system with ability to run +aarch64 binaries. That is in general option `extra-platform` with value +`aarch64-linux` and to actually allow access to the interpreter you need +something like `extra-sandbox-paths` with value such as `/usr/bin/qemu-aarch64`. +This way you can build aarch64 package on other platforms. If you are running on +aarch64 then of course you do not have to do this. With all that setup you +should be able to build tarball by navigating to this directory. + +``` +~$ nix registry add nixturris git+https://git.cynerd.cz/nixturris +~$ nix build nixturris#tarball-mox +``` + +The last step is to unpack the tarball to the SD card. + +``` +~# mount /dev/mmcblk1p1 mnt +~# tar -xf result/tarball/nixos-system-aarch64-linux.tar.xz -C mnt +~# umount mnt +~# eject /dev/mmcblk1 +``` + +Now you can take this micro SD card and insert it to your Mox. diff --git a/flake.lock b/flake.lock index 0dd8763..6ec7163 100644 --- a/flake.lock +++ b/flake.lock @@ -14,13 +14,13 @@ "type": "indirect" } }, - "nixpkgs": { + "nixpkgs-stable": { "locked": { - "lastModified": 1648965846, - "narHash": "sha256-xaO0KS+sgZLYrhaQNjVe6eRcOUIM1mEkAjT+dRbPblU=", + "lastModified": 1649490789, + "narHash": "sha256-YrhVxwoofZSx/wLZ4GYET//8vS+uqWX572zvdmP/Etg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0aac710801aec4ba545527cf41a5706028fe6271", + "rev": "c86185d20d708013caf97a6adaa8dc6d72313c75", "type": "github" }, "original": { @@ -33,7 +33,7 @@ "root": { "inputs": { "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "nixpkgs-stable": "nixpkgs-stable" } } }, diff --git a/flake.nix b/flake.nix index 331bf79..850c6c9 100644 --- a/flake.nix +++ b/flake.nix @@ -1,9 +1,9 @@ { description = "Turris flake"; - inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11"; + inputs.nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-21.11"; - outputs = { self, flake-utils, nixpkgs }: { + outputs = { self, flake-utils, nixpkgs-stable }: { overlays.default = final: prev: import ./pkgs { nixpkgs = prev; }; overlay = self.overlays.default; # Backward compatibility @@ -16,7 +16,7 @@ lib = { # The full NixOS system - nixturrisSystem = {board, modules ? [], override ? {}}: let + nixturrisSystem = {nixpkgs ? nixpkgs-stable, board, modules ? [], override ? {}}: let pkgs = if board == "omnia" then nixpkgs.legacyPackages.armv7l-linux else nixpkgs.legacyPackages.aarch64-linux; @@ -29,8 +29,9 @@ } // override); # The minimalized system to decrease amount of ram needed for rebuild # TODO this does not work right now as it requires just load of work to do - nixturrisMinSystem = {modules, ...} @args: + nixturrisMinSystem = {nixpkgs ? nixpkgs-stable, modules, ...} @args: self.lib.nixturrisSystem (args // { + nixpkgs = nixpkgs; modules = modules ++ [ ./nixos/nixos-modules-minfake.nix ]; override = { baseModules = import ./nixos/nixos-modules.nix nixpkgs; @@ -42,23 +43,23 @@ system: { packages = let - createMedkit = board: (self.lib.nixturrisSystem { + createTarball = board: (self.lib.nixturrisSystem { board = board; - modules = [ (import ./medkit.nix board) ]; + modules = [ (import ./tarball.nix board) ]; }).config.system.build.tarball; in { - medkit-mox = createMedkit "mox"; - medkit-omnia = createMedkit "omnia"; + tarball-mox = createTarball "mox"; + tarball-omnia = createTarball "omnia"; } // flake-utils.lib.filterPackages system (flake-utils.lib.flattenTree ( - import ./pkgs { nixpkgs = nixpkgs.legacyPackages."${system}"; } + import ./pkgs { nixpkgs = nixpkgs-stable.legacyPackages."${system}"; } )); # The legacyPackages imported as overlay allows us to use pkgsCross to # cross-compile those packages. - legacyPackages = import nixpkgs { + legacyPackages = import nixpkgs-stable { inherit system; overlays = [ self.overlay ]; crossOverlays = [ self.overlay ]; diff --git a/medkit-configuration.nix b/medkit-configuration.nix deleted file mode 100644 index cb287b1..0000000 --- a/medkit-configuration.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ config, lib, pkgs, ... }: { - boot.loader.grub.enable = false; - boot.loader.generic-extlinux-compatible.enable = true; - boot.kernelParams = [ - "earlyprintk" "console=ttyMV0,115200" "earlycon=ar3700_uart,0xd0012000" - "boot.shell_on_fail" - ]; - boot.kernelPackages = pkgs.linuxPackages_latest; - boot.supportedFilesystems = [ "btrfs" "vfat" "ntfs" ]; - - zramSwap = { - enable = true; - memoryPercent = 100; - }; - swapDevices = [{ - device = "/dev/mmcblk1p2"; - priority = 0; - }]; - - fileSystems = { - "/" = { - device = "/dev/mmcblk1p1"; - fsType = "btrfs"; - }; - }; - - networking.hostName = "nixturris"; - - i18n.supportedLocales = ["en_US.UTF-8/UTF-8" "cs_CZ.UTF-8/UTF-8"]; - nix = { - package = pkgs.nixFlakes; - extraOptions = "experimental-features = nix-command flakes"; - }; - - programs.vim.defaultEditor = true; - - #services.sentinel.enable = true; - - services.openssh = { - enable = true; - passwordAuthentication = true; - permitRootLogin = "yes"; - }; - - environment.systemPackages = with pkgs; [ - nixos-option - htop - ]; - - users = { - mutableUsers = false; - users.root.password = "nixturris"; - }; - -} diff --git a/medkit.nix b/medkit.nix deleted file mode 100644 index aa93080..0000000 --- a/medkit.nix +++ /dev/null @@ -1,45 +0,0 @@ -board: { config, lib, pkgs, modulesPath, ... }: { - imports = [ - "${toString modulesPath}/installer/cd-dvd/system-tarball.nix" - ]; - - boot.consoleLogLevel = lib.mkDefault 7; - turris.device = "/dev/mmcblk1"; # TODO this is for mox and sd card only - - # Allow access to the root account right after installation - users = { - mutableUsers = false; - users.root.password = "nixturris"; - }; - - # TODO we have to generate the hardware specific configuration on first boot - tarball.contents = [ - { source = pkgs.writeText "default-nixturris-flake" '' - { - inputs.nixturris.url = "git+git://cynerd.cz/nixturris.git"; - outputs = { self, nixturris }: { - nixosConfigurations.nixturris = nixturris.lib.nixturrisSystem { - board = "${board}"; - modules = [({ config, lib, pkgs, ... }: { - # Optionally place your configuration here - })]; - }; - }; - } - ''; - target = "/etc/nixos/flake.nix"; - } - { source = pkgs.writeText "medkit-extlinux" '' - DEFAULT nixos-default - TIMEOUT 0 - LABEL nixos-default - MENU LABEL NixOS - Default - FDTDIR /run/current-system/dtbs - LINUX /run/current-system/kernel - INITRD /run/current-system/initrd - APPEND init=${config.system.build.toplevel}/init ${builtins.toString config.boot.kernelParams} - ''; - target = "/boot/extlinux/extlinux.conf"; - } - ]; -} diff --git a/nixos/default.nix b/nixos/default.nix index 8b20e39..e7c8f00 100644 --- a/nixos/default.nix +++ b/nixos/default.nix @@ -1,3 +1,4 @@ { turris-board = import ./modules/turris-board.nix; + turris-defaults = import ./modules/turris-defaults.nix; } diff --git a/nixos/modules/turris-board.nix b/nixos/modules/turris-board.nix index 4b8aa0d..02b6dae 100644 --- a/nixos/modules/turris-board.nix +++ b/nixos/modules/turris-board.nix @@ -9,12 +9,6 @@ with lib; type = types.enum [ "omnia" "mox" ]; description = "The unique Turris board identifier."; }; - - turris.device = mkOption { - type = types.str; - example = "/dev/mmcblk0"; - description = "The device used to boot the Turris system."; - }; }; config = { @@ -23,73 +17,17 @@ with lib; message = "Turris board has to be specified"; }]; - # We do not need Grub as U-Boot supports boot using extlinux like file - boot.loader.grub.enable = false; - boot.loader.generic-extlinux-compatible.enable = true; - # Use early print to the serial console - boot.kernelParams = [ - "earlyprintk" "console=ttyMV0,115200" "earlycon=ar3700_uart,0xd0012000" - "boot.shell_on_fail" - ]; - - # Use the latest kernel - boot.kernelPackages = pkgs.linuxPackages_latest; - - # The supported deployment is on BTRFS - boot.supportedFilesystems = [ "btrfs" ]; - - # Cover nix memory consumption peaks by compressing the RAM - zramSwap = { - enable = true; - memoryPercent = 100; - }; - # Nix is really memory hungry so we have to sometimes also use swap device. - # We expect that to be the second partition on the root device. - swapDevices = [{ - device = config.turris.device + "p2"; - priority = 0; - }]; - - fileSystems = { - # Root filesystem is expected to be on: - # Mox: SD card - # Omnia: internam MMC storage - "/" = { - device = config.turris.device + "p1"; - fsType = "btrfs"; - }; - }; - - # The default hostname - # TODO set this only if not already set - networking.hostName = "nixturris"; - # Enable flakes for nix as we are using that instead of legacy setup nix = { package = pkgs.nixFlakes; extraOptions = "experimental-features = nix-command flakes"; }; - # Allow root access over SSH - # TODO allow disable as it is nice only for initial setup - services.openssh = { - enable = true; - passwordAuthentication = true; - permitRootLogin = "yes"; - }; - - # Set default editor - # TODO probably switch to nano later on - programs.vim.defaultEditor = true; - - # The additional administration packages environment.systemPackages = with pkgs; [ + # As we override the nix package we have to override nixos-rebuild as well (pkgs.nixos-rebuild.override { nix = config.nix.package.out; }) - git # This is required to access the repository - htop + # The Git is required to access this repository + git ]; - - # No need for installer tools in standard system - system.disableInstallerTools = true; }; } diff --git a/nixos/modules/turris-defaults.nix b/nixos/modules/turris-defaults.nix new file mode 100644 index 0000000..cdf5fbe --- /dev/null +++ b/nixos/modules/turris-defaults.nix @@ -0,0 +1,84 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cnf = config.turris.defaults; + +in { + + options = { + turris.defaults = { + enable = mkOption { + type = types.bool; + default = true; + description = "Use default Turris configuration"; + }; + rootLabel = mkOption { + type = types.str; + default = "NixTurris"; + description = "GPT partition label the root system is stored on"; + }; + swapLabel = mkOption { + type = types.str; + default = "NixTurrisSwap"; + description = "GPT partition label for available swap parition"; + }; + }; + }; + + config = mkIf cnf.enable { + # We do not need Grub as U-Boot supports boot using extlinux like file + boot.loader.grub.enable = false; + boot.loader.generic-extlinux-compatible.enable = true; + # Use early print to the serial console + boot.kernelParams = [ + "earlyprintk" "console=ttyMV0,115200" "earlycon=ar3700_uart,0xd0012000" + "boot.shell_on_fail" + ]; + + # Use the latest kernel + boot.kernelPackages = pkgs.linuxPackages_latest; + + # The supported deployment is on BTRFS + boot.supportedFilesystems = [ "btrfs" ]; + + # Cover nix memory consumption peaks by compressing the RAM + zramSwap = { + enable = true; + memoryPercent = 80; + }; + # Nix is really memory hungry so we have to sometimes also use swap device. + swapDevices = [{ + device = "/dev/disk/by-partlabel/" + cnf.swapLabel; + priority = 0; + }]; + + fileSystems = { + "/" = { + device = "/dev/disk/by-partlabel/" + cnf.rootLabel; + fsType = "btrfs"; + }; + }; + + # The default hostname + networking.hostName = mkDefault "nixturris"; + + # Set default editor + # TODO probably switch to nano later on + programs.vim.defaultEditor = mkDefault true; + + # The additional administration packages + environment.systemPackages = with pkgs; [ + htop + ] ++ optionals (config.turris.board == "mox") [ + libatsha204 + ] ++ optionals (config.turris.board == "omnia") [ + libatsha204 + ]; + + # No need for installer tools in standard system + system.disableInstallerTools = true; + }; +} diff --git a/tarball.nix b/tarball.nix new file mode 100644 index 0000000..9327762 --- /dev/null +++ b/tarball.nix @@ -0,0 +1,57 @@ +board: { config, lib, pkgs, modulesPath, ... }: + +with lib; + +{ + imports = [ + "${toString modulesPath}/installer/cd-dvd/system-tarball.nix" + ]; + + boot.consoleLogLevel = lib.mkDefault 7; + + # Allow access to the root account right after installation + users = { + mutableUsers = false; + users.root.password = mkDefault "nixturris"; + }; + + # Allow root access over SSH + services.openssh = { + enable = true; + passwordAuthentication = true; + permitRootLogin = "yes"; + }; + + # TODO we have to generate the hardware specific configuration on first boot + tarball.contents = [ + { source = pkgs.writeText "default-nixturris-flake" '' + { + inputs.nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-21.11"; + inputs.nixturris.url = "git+https://git.cynerd.cz/nixturris"; + outputs = { self, nixpkgs-stable, nixturris }: { + nixosConfigurations.nixturris = nixturris.lib.nixturrisSystem { + nixpkgs = nixpkgs-stable; + board = "${board}"; + modules = [({ config, lib, pkgs, ... }: { + # Optionally place your configuration here + })]; + }; + }; + } + ''; + target = "/etc/nixos/flake.nix"; + } + { source = pkgs.writeText "medkit-extlinux" '' + DEFAULT nixos-default + TIMEOUT 0 + LABEL nixos-default + MENU LABEL NixOS - Default + LINUX /run/current-system/kernel + FDTDIR /run/current-system/dtbs + INITRD /run/current-system/initrd + APPEND init=${config.system.build.toplevel}/init ${builtins.toString config.boot.kernelParams} + ''; + target = "/boot/extlinux/extlinux.conf"; + } + ]; +} -- cgit v1.2.3