From ca8f27bafa6ea4f296acc2b488d23a99b19dd31c Mon Sep 17 00:00:00 2001 From: xinyangli Date: Sun, 24 Nov 2024 17:26:49 +0800 Subject: [PATCH] osmium: added --- flake.nix | 7 ++ home/xin/calcite.nix | 8 +- machines/osmium/default.nix | 111 ++++++++++++++++++ .../sd-image-aarch64-orangepi-r1plus.nix | 44 +++++++ overlays/add-pkgs.nix | 17 ++- scripts/nixos-updater.py | 90 ++++++++++++++ 6 files changed, 271 insertions(+), 6 deletions(-) create mode 100644 machines/osmium/default.nix create mode 100644 machines/osmium/sd-image-aarch64-orangepi-r1plus.nix create mode 100644 scripts/nixos-updater.py diff --git a/flake.nix b/flake.nix index 606276e..5dcb727 100644 --- a/flake.nix +++ b/flake.nix @@ -116,6 +116,9 @@ ./machines/dolomite/lightsail.nix ./machines/dolomite/common.nix ]; + osmium = [ + ./machines/osmium + ]; }; sharedColmenaModules = [ deploymentModule @@ -258,6 +261,10 @@ calcite = mkNixos { hostname = "calcite"; }; + + osmium = mkNixos { + hostname = "osmium"; + }; } // self.colmenaHive.nodes; } diff --git a/home/xin/calcite.nix b/home/xin/calcite.nix index 11dd9ed..69d16d6 100644 --- a/home/xin/calcite.nix +++ b/home/xin/calcite.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ pkgs, lib, ... }: let homeDirectory = "/home/xin"; in @@ -61,6 +61,12 @@ in fcitx5.addons = with pkgs; [ fcitx5-rime ]; }; + # Using wayland + home.sessionVariables = { + GTK_IM_MODULE = lib.mkForce ""; + QT_IM_MODULE = lib.mkForce ""; + }; + custom-hm = { alacritty = { enable = true; diff --git a/machines/osmium/default.nix b/machines/osmium/default.nix new file mode 100644 index 0000000..823d2f0 --- /dev/null +++ b/machines/osmium/default.nix @@ -0,0 +1,111 @@ +{ + pkgs, + lib, + modulesPath, + ... +}: +{ + imports = [ + (modulesPath + "/installer/sd-card/sd-image.nix") + ./sd-image-aarch64-orangepi-r1plus.nix + ]; + + config = { + system.stateVersion = "24.05"; + + nixpkgs.system = "aarch64-linux"; + + boot.tmp.useTmpfs = false; + boot.kernelModules = [ + "br_netfilter" + "bridge" + ]; + boot.kernel.sysctl = { + "net.ipv4.ip_forward" = 1; + "net.ipv4.ip_nonlocal_bind" = 1; + "net.ipv6.conf.all.forwarding" = 1; + "net.ipv6.ip_nonlocal_bind" = 1; + "net.bridge.bridge-nf-call-ip6tables" = 1; + "net.bridge.bridge-nf-call-iptables" = 1; + "net.bridge.bridge-nf-call-arptables" = 1; + "fs.inotify.max_user_watches" = 524288; + "dev.i915.perf_stream_paranoid" = 0; + "net.ipv4.conf.all.rp_filter" = 0; + "vm.max_map_count" = 2000000; + "net.ipv4.conf.all.route_localnet" = 1; + "net.ipv4.conf.all.send_redirects" = 0; + "kernel.msgmnb" = 65536; + "kernel.msgmax" = 65536; + "net.ipv4.tcp_timestamps" = 0; + "net.ipv4.tcp_synack_retries" = 1; + "net.ipv4.tcp_syn_retries" = 1; + "net.ipv4.tcp_tw_recycle" = 1; + "net.ipv4.tcp_tw_reuse" = 1; + "net.ipv4.tcp_fin_timeout" = 15; + "net.ipv4.tcp_keepalive_time" = 1800; + "net.ipv4.tcp_keepalive_probes" = 3; + "net.ipv4.tcp_keepalive_intvl" = 15; + "net.ipv4.ip_local_port_range" = "2048 65535"; + "fs.file-max" = 102400; + "net.ipv4.tcp_max_tw_buckets" = 180000; + }; + + commonSettings = { + nix.enableMirrors = true; + auth.enable = true; + }; + + documentation.enable = false; + + time.timeZone = "Asia/Shanghai"; + i18n = { + defaultLocale = "en_US.UTF-8"; + }; + + environment.systemPackages = with pkgs; [ + lsof + wget + curl + neovim + jq + iptables + ebtables + tcpdump + busybox + ethtool + socat + htop + iftop + lm_sensors + ]; + + programs.command-not-found.enable = false; + + networking = { + useDHCP = false; + hostName = "osmium"; + }; + + systemd.network = { + enable = true; + networks."lan" = { + matchConfig.Name = "enu1"; + networkConfig.DHCP = "no"; + linkConfig.RequiredForOnline = "no"; + }; + networks."wan" = { + matchConfig.Name = "end0"; + networkConfig.DHCP = "yes"; + linkConfig.RequiredForOnline = "yes"; + }; + }; + + services.dae = { + enable = true; + configFile = "/var/lib/dae/config.dae"; + }; + + services.tailscale.enable = true; + + }; +} diff --git a/machines/osmium/sd-image-aarch64-orangepi-r1plus.nix b/machines/osmium/sd-image-aarch64-orangepi-r1plus.nix new file mode 100644 index 0000000..3802760 --- /dev/null +++ b/machines/osmium/sd-image-aarch64-orangepi-r1plus.nix @@ -0,0 +1,44 @@ +{ + config, + modulesPath, + lib, + pkgs, + ... +}: +let +in +{ + imports = [ + (modulesPath + "/profiles/base.nix") + ]; + + boot.loader.grub.enable = false; + boot.loader.generic-extlinux-compatible.enable = true; + boot.kernelPackages = pkgs.linuxPackages_latest; + + boot.kernelParams = [ + "earlycon" + "console=ttyS2,1500000" + "consoleblank=0" + ]; + boot.supportedFilesystems = lib.mkForce [ + "ext4" + "vfat" + "ntfs" + ]; + + sdImage = { + compressImage = false; + imageBaseName = "nixos-sd-image-orange-pi-r1-plus-lts"; + firmwarePartitionOffset = 16; + populateFirmwareCommands = '' + echo "Install U-Boot: ${pkgs.ubootOrangePiR1LtsPackage}" + dd if=${pkgs.ubootOrangePiR1LtsPackage}/idbloader.img of=$img seek=64 conv=notrunc + dd if=${pkgs.ubootOrangePiR1LtsPackage}/u-boot.itb of=$img seek=16384 conv=notrunc + ''; + populateRootCommands = '' + mkdir -p ./files/boot + ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot + ''; + }; +} diff --git a/overlays/add-pkgs.nix b/overlays/add-pkgs.nix index 135a2cb..f1b214e 100644 --- a/overlays/add-pkgs.nix +++ b/overlays/add-pkgs.nix @@ -1,5 +1,12 @@ -( - final: prev: - { - } -) +(final: prev: { + ubootOrangePiR1LtsPackage = prev.buildUBoot { + defconfig = "orangepi-r1-plus-lts-rk3328_defconfig"; + enableParallelBuilding = true; + + BL31 = "${prev.armTrustedFirmwareRK3328}/bl31.elf"; + filesToInstall = [ + "u-boot.itb" + "idbloader.img" + ]; + }; +}) diff --git a/scripts/nixos-updater.py b/scripts/nixos-updater.py new file mode 100644 index 0000000..c859250 --- /dev/null +++ b/scripts/nixos-updater.py @@ -0,0 +1,90 @@ +import requests +import os +import socket +import json +from os import path as osp +from dataclasses import dataclass + +""" +This updater consists of several parts: + +- Update checker: Check an url for update (if outPath is different from /run/current-system or some specified profile) or maybe use timestamp for update +- Nix copy --from: copy from remote. Need to specify remote url. +- Create a symlink: /run/next-system -> +- Listen for POST request to trigger system switch (optional) +""" + + +@dataclass +class GarnixConfig: + token: str + + +@dataclass +class Config: + check_type: str + check_url: str + remote_url: str + garnix: GarnixConfig + hostname: str = socket.gethostname() + + +class Nix: + def __init__(self, args): + self.args = args + + def copy_from_remote(self): + # run nix copy with subprocess + pass + + def eval(self): + + +class Updater: + def __init__(self, config: Config): + self.config = config + + # TODO: Make this configurable + self.current_drv = os.readlink("/run/current-system") + self.next_dev = None + + # checkers take an url and returns the outPath of the latest success build + def garnix_checker(self) -> str: + domain = "garnix.io" + build_endpoint = "/api/build/commit" + + # Latest commit from git + + # Check build status of this commit + resp = requests.get( + f"https://{domain}{build_endpoint}/40b1e9ff23aaa5f555420dd22414c3f137a02cfe" + ) + # Raise error if status code is not valid + + # Fetch outPath from eval endpoint + # TODO: In theory, this could be done by parsing raw log from garnix. + + # Try to evaluate locally if eval endpoint is not configured + + resp = resp.json() + # TODO + return "null" + + def hydra_checker(self) -> str: + # TODO + return "null" + + # Check for update + def poll(self) -> str | None: + cfg = self.config + if cfg.check_type == "garnix": + pass + elif cfg.check_type == "hydra": + pass + else: + pass + pass + + +if __name__ == "__main__": + pass