├── .github └── workflows │ ├── build.yml │ └── update.yml ├── .gitignore ├── LICENSE ├── README.md ├── flake.lock └── flake.nix /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: [ push ] 3 | permissions: 4 | id-token: write 5 | pages: write 6 | jobs: 7 | netboot: 8 | runs-on: ubuntu-24.04 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: DeterminateSystems/nix-installer-action@v14 12 | - run: | 13 | nix build -vL 14 | cp -Lr --no-preserve=all result artifact 15 | ln -sr artifact/{ipxe,index.html} 16 | - run: | 17 | sudo apt-get update 18 | sudo apt-get install -y qemu-kvm 19 | 20 | cat < bootfile 21 | #!ipxe 22 | # shutdown now 23 | set cmdline script="https://httpbin.org/base64/c2h1dGRvd24gbm93Cg==" 24 | chain result/ipxe 25 | EOF 26 | 27 | sudo systemd-run --wait --same-dir --collect \ 28 | --property=MemoryAccounting=yes --property=RuntimeMaxSec=120 \ 29 | qemu-system-x86_64 -M q35 -enable-kvm -cpu host -smp 2 -m 2G \ 30 | -boot order=n -nic user,tftp=.,bootfile=bootfile -display none 2>&1 | tee $GITHUB_STEP_SUMMARY 31 | - uses: actions/upload-pages-artifact@v3 32 | with: 33 | path: artifact 34 | - uses: actions/deploy-pages@v4 35 | -------------------------------------------------------------------------------- /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | name: update-flake-lock 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '0 0 * * 0' 6 | 7 | jobs: 8 | lockfile: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout repository 12 | uses: actions/checkout@v4 13 | - name: Install Nix 14 | uses: DeterminateSystems/nix-installer-action@main 15 | - name: Update flake.lock 16 | uses: DeterminateSystems/update-flake-lock@main 17 | with: 18 | pr-title: "Update flake.lock" 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | result* 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Nick Cao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # netboot 2 | boot NixOS from iPXE on machines with only 700M of memory 3 | 4 | ## usage 5 | ```ipxe 6 | #!ipxe 7 | set cmdline sshkey="ssh-ed25519 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 8 | chain http://nickcao.github.io/netboot/ 9 | ``` 10 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "nixpkgs": { 4 | "locked": { 5 | "lastModified": 1749250933, 6 | "narHash": "sha256-mEZPOQeQ+UGAzhMAGnPX/TYq6F2kAvfij6GEMM/smaU=", 7 | "owner": "NickCao", 8 | "repo": "nixpkgs", 9 | "rev": "43db231630b30f4d2b13d1bf48bbc02342e5266a", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "owner": "NickCao", 14 | "repo": "nixpkgs", 15 | "type": "github" 16 | } 17 | }, 18 | "root": { 19 | "inputs": { 20 | "nixpkgs": "nixpkgs" 21 | } 22 | } 23 | }, 24 | "root": "root", 25 | "version": 7 26 | } 27 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NickCao/nixpkgs"; 4 | }; 5 | outputs = 6 | { nixpkgs, ... }: 7 | { 8 | packages.x86_64-linux.default = 9 | (nixpkgs.lib.nixosSystem { 10 | system = "x86_64-linux"; 11 | modules = [ 12 | ( 13 | { 14 | config, 15 | pkgs, 16 | lib, 17 | modulesPath, 18 | ... 19 | }: 20 | let 21 | build = config.system.build; 22 | kernelTarget = pkgs.stdenv.hostPlatform.linux-kernel.target; 23 | in 24 | { 25 | imports = [ 26 | (modulesPath + "/profiles/minimal.nix") 27 | (modulesPath + "/profiles/qemu-guest.nix") 28 | (modulesPath + "/installer/netboot/netboot.nix") 29 | ]; 30 | 31 | systemd.services.nix-daemon.serviceConfig = { 32 | MemoryHigh = "250M"; 33 | MemoryMax = "300M"; 34 | }; 35 | 36 | boot = { 37 | kernelPackages = pkgs.linuxPackages_latest; 38 | initrd.systemd.enable = true; 39 | }; 40 | 41 | networking.useNetworkd = true; 42 | networking.firewall.enable = false; 43 | 44 | services = { 45 | openssh = { 46 | enable = true; 47 | authorizedKeysFiles = [ "/run/authorized_keys" ]; 48 | }; 49 | getty.autologinUser = "root"; 50 | }; 51 | 52 | systemd.services.process-cmdline = { 53 | wantedBy = [ "multi-user.target" ]; 54 | wants = [ "network-online.target" ]; 55 | after = [ "network-online.target" ]; 56 | script = '' 57 | export PATH=/run/current-system/sw/bin:$PATH 58 | xargs -n1 -a /proc/cmdline | while read opt; do 59 | if [[ $opt = sshkey=* ]]; then 60 | echo "''${opt#sshkey=}" >> /run/authorized_keys 61 | fi 62 | if [[ $opt = script=* ]]; then 63 | curl -L "''${opt#script=}" | ${pkgs.runtimeShell} 64 | fi 65 | done 66 | ''; 67 | }; 68 | 69 | system.build.netboot = pkgs.runCommand "netboot" { } '' 70 | mkdir -p $out 71 | 72 | ln -s ${build.kernel}/${kernelTarget} $out/${kernelTarget} 73 | ln -s ${build.netbootRamdisk}/initrd $out/initrd 74 | ln -s ${build.netbootIpxeScript}/netboot.ipxe $out/ipxe 75 | ''; 76 | 77 | zramSwap.enable = true; 78 | 79 | nixpkgs.flake = { 80 | setNixPath = false; 81 | setFlakeRegistry = false; 82 | }; 83 | 84 | system.stateVersion = lib.trivial.release; 85 | } 86 | ) 87 | ]; 88 | }).config.system.build.netboot; 89 | }; 90 | } 91 | --------------------------------------------------------------------------------