diff --git a/.gitignore b/.gitignore index 55f65c2..55a9817 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -result* +result .stfolder flake.lock diff --git a/flake.nix b/flake.nix index 5d1fcde..69aedf5 100644 --- a/flake.nix +++ b/flake.nix @@ -31,6 +31,7 @@ ... }: let + system = "x86_64-linux"; repoLocalPath = let fromEnv = builtins.getEnv "NIXOS_CONFIG_ROOT"; @@ -41,21 +42,26 @@ inputs.nur.overlays.default ]; - mkPkgs = system: import nixpkgs { + pkgs = import nixpkgs { inherit system; config.allowUnfree = true; flake.setFlakeRegistry = true; inherit overlays; }; - mkPkgsUnstable = system: import nixpkgs-unstable { + pkgs-unstable = import nixpkgs-unstable { inherit system; config.allowUnfree = true; flake.setFlakeRegistry = true; inherit overlays; }; - mkSharedModules = pkgs: pkgs-unstable: [ + sharedSpecialArgs = { + inherit repoLocalPath pkgs-unstable; + repoRoot = self; + }; + + sharedModules = [ ./nixos/modules/base.nix inputs.home-manager.nixosModules.home-manager ({ ... }: { @@ -71,32 +77,24 @@ mkHost = { hostName, - system, nixosModules ? [ ], hmModules ? [ ], extraModules ? [ ], }: - let - pkgs = mkPkgs system; - pkgs-unstable = mkPkgsUnstable system; - in nixpkgs.lib.nixosSystem { inherit system pkgs; - specialArgs = { - inherit repoLocalPath pkgs-unstable; - repoRoot = self; - }; + specialArgs = sharedSpecialArgs; modules = - (mkSharedModules pkgs pkgs-unstable) + sharedModules ++ [ (./nixos/hosts + "/${hostName}/configuration.nix") ] ++ nixosModules ++ extraModules ++ [ { home-manager.users.alisceon.imports = - [ + [ inputs.noctalia.homeModules.default - ./home/profiles/base.nix + ./home/profiles/base.nix ] ++ hmModules; home-manager.users.root.imports = [ @@ -127,7 +125,6 @@ nixosConfigurations = { electra = mkHost { hostName = "electra"; - system = "x86_64-linux"; nixosModules = workstationModules; hmModules = workstationHomeModules ++ [ ./home/hosts/alisceon/electra.nix @@ -136,7 +133,6 @@ tower = mkHost { hostName = "tower"; - system = "x86_64-linux"; nixosModules = workstationModules; hmModules = workstationHomeModules ++ [ ./home/hosts/alisceon/tower.nix @@ -145,7 +141,6 @@ tesla-nixos = mkHost { hostName = "tesla-nixos"; - system = "x86_64-linux"; nixosModules = serverModules; hmModules = serverHomeModules; extraModules = [ @@ -156,14 +151,6 @@ nuc = mkHost { hostName = "nuc"; - system = "x86_64-linux"; - nixosModules = serverModules; - hmModules = serverHomeModules; - }; - - alisceon-core = mkHost { - hostName = "alisceon-core"; - system = "aarch64-linux"; nixosModules = serverModules; hmModules = serverHomeModules; }; diff --git a/home/modules/programs/ssh.nix b/home/modules/programs/ssh.nix index 79db2a9..0f44954 100644 --- a/home/modules/programs/ssh.nix +++ b/home/modules/programs/ssh.nix @@ -18,7 +18,7 @@ }; "alisceon-core" = { hostname = "core.alisceon.com"; - user = "alisceon"; + user = "opc"; }; "blogbox-2" = { hostname = "10.1.0.11"; diff --git a/lib/commands.nix b/lib/commands.nix index 476b304..7e766f4 100644 --- a/lib/commands.nix +++ b/lib/commands.nix @@ -1,15 +1,6 @@ { pkgs }: let swaymsg = "${pkgs.sway}/bin/swaymsg"; - systemNotify = pkgs.writeShellApplication { - name = "system-notify"; - runtimeInputs = [ - pkgs.coreutils - pkgs.libnotify - pkgs.util-linux - ]; - text = builtins.readFile ../util/system_notify.sh; - }; in { uwsm = "${pkgs.uwsm}/bin/uwsm-app --"; @@ -18,7 +9,6 @@ in lock = "${pkgs.swaylock}/bin/swaylock --daemonize"; term = "${pkgs.foot}/bin/footclient"; notify = "${pkgs.libnotify}/bin/notify-send"; - "system-notify" = "${systemNotify}/bin/system-notify"; nag = "${pkgs.sway}/bin/swaynag --edge bottom"; dmenu = "${pkgs.rofi-unwrapped}/bin/rofi"; espanso = "${pkgs.espanso-wayland}/bin/espanso cmd"; diff --git a/nixos/hosts/alisceon-core/configuration.nix b/nixos/hosts/alisceon-core/configuration.nix deleted file mode 100644 index 8468905..0000000 --- a/nixos/hosts/alisceon-core/configuration.nix +++ /dev/null @@ -1,297 +0,0 @@ -{ lib, pkgs, modulesPath, ... }: -let - forgejoDomain = "git.alisceon.com"; - forgejoRunnerTokenFile = "/var/lib/forgejo/runner_token"; - - fetchOciAuthorizedKeys = pkgs.writeShellApplication { - name = "fetch-oci-authorized-keys"; - runtimeInputs = [ - pkgs.coreutils - pkgs.curl - ]; - text = '' - install -d -m 0700 -o alisceon -g users /home/alisceon/.ssh - - if [ -s /home/alisceon/.ssh/authorized_keys ]; then - echo "OCI authorized_keys already present for alisceon" - exit 0 - fi - - curl --fail --silent --show-error --location \ - --header "Authorization: Bearer Oracle" \ - --output /home/alisceon/.ssh/authorized_keys \ - http://169.254.169.254/opc/v2/instance/metadata/ssh_authorized_keys - - chown alisceon:users /home/alisceon/.ssh/authorized_keys - chmod 0600 /home/alisceon/.ssh/authorized_keys - ''; - }; - - generateForgejoRunnerToken = pkgs.writeShellApplication { - name = "generate-forgejo-runner-token"; - runtimeInputs = [ - pkgs.coreutils - pkgs.util-linux - ]; - text = '' - token_file=${lib.escapeShellArg forgejoRunnerTokenFile} - - if [ -s "$token_file" ]; then - chmod 0600 "$token_file" - chown root:root "$token_file" - exit 0 - fi - - install -d -m 0750 -o forgejo -g forgejo /var/lib/forgejo - token="$(runuser -u forgejo -- env \ - FORGEJO_WORK_DIR=/var/lib/forgejo \ - FORGEJO_CUSTOM=/var/lib/forgejo/custom \ - ${lib.getExe pkgs.forgejo-lts} actions generate-runner-token)" - - umask 0077 - printf 'TOKEN=%s\n' "$token" > "$token_file" - chown root:root "$token_file" - chmod 0600 "$token_file" - ''; - }; -in -{ - imports = [ - "${modulesPath}/virtualisation/oci-image.nix" - ]; - - nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; - - networking = { - hostName = "alisceon-core"; - networkmanager.enable = lib.mkForce false; - firewall.allowedTCPPorts = [ - 22 - 80 - 443 - 24601 - ]; - }; - - boot = { - initrd.availableKernelModules = [ - "virtio_pci" - "virtio_blk" - "virtio_scsi" - "virtio_net" - "xhci_pci" - ]; - loader.systemd-boot.configurationLimit = lib.mkForce 3; - }; - - nix = { - settings = { - min-free = lib.mkForce (512 * 1024 * 1024); - max-free = lib.mkForce (2 * 1024 * 1024 * 1024); - }; - gc = { - dates = lib.mkForce "daily"; - options = lib.mkForce "--delete-older-than 3d"; - }; - }; - - virtualisation = { - docker.enable = lib.mkForce false; - podman = { - enable = true; - dockerSocket.enable = true; - autoPrune = { - enable = true; - dates = "daily"; - flags = [ "--all" ]; - }; - }; - }; - - users.users.alisceon.extraGroups = [ "systemd-journal" ]; - - security = { - acme = { - acceptTerms = true; - defaults.email = "acme@alisceon.com"; - }; - sudo-rs.wheelNeedsPassword = false; - }; - - services.openssh.settings = { - PasswordAuthentication = false; - PermitRootLogin = lib.mkForce "prohibit-password"; - }; - - services.forgejo = { - enable = true; - package = pkgs.forgejo-lts; - database.type = "sqlite3"; - lfs.enable = true; - settings = { - server = { - DOMAIN = forgejoDomain; - ROOT_URL = "https://${forgejoDomain}/"; - HTTP_ADDR = "127.0.0.1"; - HTTP_PORT = 3000; - SSH_DOMAIN = forgejoDomain; - SSH_PORT = 22; - DISABLE_SSH = false; - }; - session.COOKIE_SECURE = true; - service = { - DISABLE_REGISTRATION = true; - REQUIRE_SIGNIN_VIEW = false; - }; - actions.ENABLED = true; - repository = { - DEFAULT_PRIVATE = "private"; - DISABLE_HTTP_GIT = false; - }; - "cron.archive_cleanup" = { - ENABLED = true; - RUN_AT_START = true; - SCHEDULE = "@every 24h"; - OLDER_THAN = "72h"; - }; - log.LEVEL = "Warn"; - }; - }; - - services.gitea-actions-runner = { - package = pkgs.forgejo-runner; - instances.alisceon-core-podman = { - enable = true; - name = "alisceon-core-podman"; - url = "https://${forgejoDomain}"; - tokenFile = forgejoRunnerTokenFile; - labels = [ - "ubuntu-latest:docker://node:22-bookworm" - "debian-latest:docker://node:22-bookworm" - ]; - settings = { - container = { - network = "host"; - privileged = false; - valid_volumes = [ ]; - }; - cache.enabled = false; - }; - }; - }; - - services.nginx = { - enable = true; - recommendedGzipSettings = true; - recommendedOptimisation = true; - recommendedProxySettings = true; - recommendedTlsSettings = true; - virtualHosts = { - "_" = { - default = true; - rejectSSL = true; - extraConfig = '' - return 421; - ''; - }; - ${forgejoDomain} = { - serverName = forgejoDomain; - forceSSL = true; - enableACME = true; - locations."/" = { - proxyPass = "http://127.0.0.1:3000"; - recommendedProxySettings = true; - }; - }; - }; - }; - - services.tor = { - enable = true; - client.enable = false; - relay = { - enable = true; - role = "relay"; - }; - settings = { - Nickname = "alisceondotcom"; - ORPort = 24601; - DataDirectory = "/var/lib/tor"; - ExitRelay = false; - ExitPolicy = [ "reject *:*" ]; - RelayBandwidthRate = "25 MBytes"; - RelayBandwidthBurst = "25 MBytes"; - BandwidthRate = "25 MBytes"; - BandwidthBurst = "25 MBytes"; - AccountingStart = "month 1 00:00"; - AccountingMax = "8500 GBytes"; - DirCache = true; - AvoidDiskWrites = 1; - Sandbox = false; - }; - }; - - services.cloud-init = { - enable = true; - network.enable = true; - settings = { - datasource_list = [ "Oracle" "ConfigDrive" "NoCloud" ]; - users = [ "default" ]; - system_info.default_user = { - name = "alisceon"; - gecos = "Alisceon"; - groups = [ "wheel" "systemd-journal" ]; - shell = "/run/current-system/sw/bin/xonsh"; - lock_passwd = true; - }; - }; - }; - - systemd.services.fetch-oci-authorized-keys = { - description = "Fetch OCI metadata authorized_keys for alisceon"; - wantedBy = [ "sshd.service" ]; - before = [ "sshd.service" ]; - after = [ "network-online.target" ]; - wants = [ "network-online.target" ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - StandardError = "journal+console"; - StandardOutput = "journal+console"; - }; - script = lib.getExe fetchOciAuthorizedKeys; - }; - - systemd.services.fetch-ssh-keys.enable = false; - - systemd.services.forgejo-runner-token = { - description = "Generate Forgejo runner registration token"; - wantedBy = [ "multi-user.target" ]; - after = [ "forgejo.service" ]; - requires = [ "forgejo.service" ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - StandardError = "journal+console"; - StandardOutput = "journal+console"; - }; - script = lib.getExe generateForgejoRunnerToken; - }; - - systemd.services."gitea-runner-alisceon\\x2dcore\\x2dpodman" = { - after = [ "forgejo-runner-token.service" ]; - requires = [ "forgejo-runner-token.service" ]; - }; - - environment.systemPackages = with pkgs; [ - curl - forgejo-lts - git - htop - jq - vim - wget - ]; - - system.stateVersion = lib.mkForce "25.11"; -} diff --git a/nixos/modules/base.nix b/nixos/modules/base.nix index c4ec01f..4abe5fe 100644 --- a/nixos/modules/base.nix +++ b/nixos/modules/base.nix @@ -2,15 +2,6 @@ let autoUpgradeUser = "alisceon"; flakeRef = "path:${repoLocalPath}"; - devFlakeGarbageCollect = pkgs.writeShellApplication { - name = "dev-flake-garbage-collect"; - runtimeInputs = [ - pkgs.coreutils - pkgs.findutils - pkgs.gnugrep - ]; - text = builtins.readFile ../../util/dev_flake_gc.sh; - }; in { boot = { @@ -43,34 +34,9 @@ in runGarbageCollection = true; }; - systemd = { - services = { - nixos-upgrade.preStart = '' - ${pkgs.util-linux}/bin/runuser -u ${autoUpgradeUser} -- ${lib.getExe config.nix.package} flake update --flake ${lib.escapeShellArg flakeRef} - ''; - - dev-flake-garbage-collect = { - description = "Remove stale development flake caches and build symlinks"; - wants = [ "nix-gc.service" ]; - before = [ "nix-gc.service" ]; - serviceConfig = { - Type = "oneshot"; - ExecStart = lib.getExe devFlakeGarbageCollect; - Nice = 10; - IOSchedulingClass = "idle"; - }; - }; - }; - - timers.dev-flake-garbage-collect = { - wantedBy = [ "timers.target" ]; - timerConfig = { - OnCalendar = "weekly"; - Persistent = true; - RandomizedDelaySec = "3h"; - }; - }; - }; + systemd.services.nixos-upgrade.preStart = '' + ${pkgs.util-linux}/bin/runuser -u ${autoUpgradeUser} -- ${lib.getExe config.nix.package} flake update --flake ${lib.escapeShellArg flakeRef} + ''; nix = { settings = { diff --git a/nixos/modules/profiles/workstation.nix b/nixos/modules/profiles/workstation.nix index d39d714..c8ed2d6 100644 --- a/nixos/modules/profiles/workstation.nix +++ b/nixos/modules/profiles/workstation.nix @@ -1,12 +1,4 @@ -{ pkgs, pkgs-unstable, lib, ... }: -let - commands = import ../../../lib/commands.nix { inherit pkgs; }; - systemNotify = commands."system-notify"; - notify = urgency: title: body: - "${systemNotify} ${lib.escapeShellArgs [ urgency title body ]}"; - notifyFailure = title: service: - "${systemNotify} ${lib.escapeShellArgs [ "critical" title ]} \"${service} ended with: $SERVICE_RESULT\""; -in +{ pkgs, pkgs-unstable, ... }: { boot = { plymouth = { @@ -19,7 +11,6 @@ in "udev.log_level=3" "systemd.show_status=auto" ]; - binfmt.emulatedSystems = [ "aarch64-linux" ]; }; security.sudo.wheelNeedsPassword = false; @@ -62,34 +53,6 @@ in 8888 ]; - systemd.services = { - nixos-upgrade = { - preStart = lib.mkBefore '' - ${notify "normal" "System update started" "Updating flake inputs and preparing the NixOS switch."} - ''; - postStop = '' - if [ "$SERVICE_RESULT" = "success" ]; then - ${notify "normal" "System update finished" "The automated NixOS update completed successfully."} - else - ${notifyFailure "System update failed" "nixos-upgrade.service"} - fi - ''; - }; - - nix-gc = { - preStart = '' - ${notify "normal" "Garbage collection started" "Cleaning old Nix generations and unreferenced store paths."} - ''; - postStop = '' - if [ "$SERVICE_RESULT" = "success" ]; then - ${notify "normal" "Garbage collection finished" "Nix store garbage collection completed successfully."} - else - ${notifyFailure "Garbage collection failed" "nix-gc.service"} - fi - ''; - }; - }; - environment = { systemPackages = [ pkgs-unstable.discord diff --git a/util/dev_flake_gc.sh b/util/dev_flake_gc.sh deleted file mode 100644 index 5942fe1..0000000 --- a/util/dev_flake_gc.sh +++ /dev/null @@ -1,101 +0,0 @@ -set -o pipefail - -retention_days="30" -scan_roots=( - / - /home - /root - /srv - /opt - /tmp - /var/tmp - /var/lib -) - -root_seen() { - local candidate="$1" - local seen - - for seen in "${seen_roots[@]}"; do - [ "$candidate" = "$seen" ] && return 0 - done - - return 1 -} - -has_recent_activity() { - local path="$1" - - find "$path" \ - -xdev \ - \( -name .git -o -name .hg -o -name .svn -o -name node_modules -o -name target \) -prune \ - -o -mindepth 1 -mtime "-$retention_days" -print -quit 2>/dev/null \ - | grep -q . -} - -is_nix_store_symlink() { - local link="$1" - local target - - target="$(readlink "$link" 2>/dev/null || true)" - case "$target" in - /nix/store/*) return 0 ;; - *) return 1 ;; - esac -} - -cleanup_direnv() { - local direnv_dir="$1" - local project_dir - - project_dir="$(dirname "$direnv_dir")" - - if [ ! -e "$project_dir/flake.nix" ] \ - && [ ! -e "$direnv_dir/flake-profile" ] \ - && [ ! -e "$direnv_dir/gcroots" ]; then - return - fi - - if has_recent_activity "$project_dir"; then - return - fi - - echo "Removing stale nix-direnv cache: $direnv_dir" - rm -rf --one-file-system "$direnv_dir" -} - -cleanup_result_link() { - local link="$1" - - if ! is_nix_store_symlink "$link"; then - return - fi - - echo "Removing stale Nix build result symlink: $link" - rm -f "$link" -} - -seen_roots=() - -for root in "${scan_roots[@]}"; do - [ -d "$root" ] || continue - root="$(readlink -f "$root")" - root_seen "$root" && continue - seen_roots+=("$root") - - find "$root" \ - -xdev \ - \( -path /nix -o -path /proc -o -path /sys -o -path /dev -o -path /run -o -path /boot \) -prune \ - -o -type d -name .direnv -mtime "+$retention_days" -print0 2>/dev/null \ - | while IFS= read -r -d "" direnv_dir; do - cleanup_direnv "$direnv_dir" - done - - find "$root" \ - -xdev \ - \( -path /nix -o -path /proc -o -path /sys -o -path /dev -o -path /run -o -path /boot \) -prune \ - -o -type l \( -name result -o -name "result-*" \) -mtime "+$retention_days" -print0 2>/dev/null \ - | while IFS= read -r -d "" link; do - cleanup_result_link "$link" - done -done diff --git a/util/system_notify.sh b/util/system_notify.sh deleted file mode 100644 index 2c307f4..0000000 --- a/util/system_notify.sh +++ /dev/null @@ -1,23 +0,0 @@ -set -o pipefail - -target_user="${SYSTEM_NOTIFY_USER:-alisceon}" -urgency="${1:-normal}" -title="${2:-System task}" -body="${3:-}" - -uid="$(id -u "$target_user" 2>/dev/null || true)" -[ -n "$uid" ] || exit 0 - -runtime_dir="/run/user/$uid" -bus="$runtime_dir/bus" -[ -S "$bus" ] || exit 0 - -runuser -u "$target_user" -- env \ - XDG_RUNTIME_DIR="$runtime_dir" \ - DBUS_SESSION_BUS_ADDRESS="unix:path=$bus" \ - notify-send \ - --app-name="NixOS maintenance" \ - --urgency="$urgency" \ - "$title" \ - "$body" \ - || exit 0