92 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, lib, libS, pkgs, ... }:
 | 
						|
 | 
						|
let
 | 
						|
  cfg = config.nix;
 | 
						|
in
 | 
						|
{
 | 
						|
  options.nix = {
 | 
						|
    deleteChannels = lib.mkEnableOption "" // { description = "Whether to delete all channels on a system switch."; };
 | 
						|
 | 
						|
    deleteUserProfiles = lib.mkEnableOption "" // { description = "Whether to delete all user profiles on a system switch."; };
 | 
						|
 | 
						|
    diffSystem = libS.mkOpinionatedOption "system closure diffing on updates";
 | 
						|
 | 
						|
    recommendedDefaults = libS.mkOpinionatedOption "set recommended default settings";
 | 
						|
 | 
						|
    remoteBuilder = {
 | 
						|
      enable = lib.mkEnableOption "restricted nix remote builder";
 | 
						|
 | 
						|
      sshPublicKeys = lib.mkOption {
 | 
						|
        description = "SSH public keys accepted by the remote build user.";
 | 
						|
        type = lib.types.listOf lib.types.str;
 | 
						|
      };
 | 
						|
 | 
						|
      name = lib.mkOption {
 | 
						|
        description = "Name of the user used for remote building.";
 | 
						|
        type = lib.types.str;
 | 
						|
        readOnly = true;
 | 
						|
        default = "nix-remote-builder";
 | 
						|
      };
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  config = {
 | 
						|
    # based on https://github.com/numtide/srvos/blob/main/nixos/roles/nix-remote-builder.nix
 | 
						|
    # and https://discourse.nixos.org/t/wrapper-to-restrict-builder-access-through-ssh-worth-upstreaming/25834
 | 
						|
    nix.settings = {
 | 
						|
      builders-use-substitutes = lib.mkIf cfg.recommendedDefaults true;
 | 
						|
      connect-timeout = lib.mkIf cfg.recommendedDefaults 20;
 | 
						|
      experimental-features = lib.mkIf cfg.recommendedDefaults [ "nix-command" "flakes" ];
 | 
						|
      trusted-users = lib.mkIf cfg.remoteBuilder.enable [ cfg.remoteBuilder.name ];
 | 
						|
    };
 | 
						|
 | 
						|
    users.users.${cfg.remoteBuilder.name} = lib.mkIf cfg.remoteBuilder.enable {
 | 
						|
      group = "nogroup";
 | 
						|
      isNormalUser = true;
 | 
						|
      openssh.authorizedKeys.keys = map
 | 
						|
        (key:
 | 
						|
          let
 | 
						|
            wrapper-dispatch-ssh-nix = pkgs.writeShellScriptBin "wrapper-dispatch-ssh-nix" /* bash */ ''
 | 
						|
              case $SSH_ORIGINAL_COMMAND in
 | 
						|
                "nix-daemon --stdio")
 | 
						|
                  exec ${config.nix.package}/bin/nix-daemon --stdio
 | 
						|
                  ;;
 | 
						|
                "nix-store --serve --write")
 | 
						|
                  exec ${config.nix.package}/bin/nix-store --serve --write
 | 
						|
                  ;;
 | 
						|
                *)
 | 
						|
                  echo "Access is only allowed for the nix remote builder" 1>&2
 | 
						|
                  exit 1
 | 
						|
              esac
 | 
						|
            '';
 | 
						|
 | 
						|
          in
 | 
						|
          "restrict,pty,command=\"${wrapper-dispatch-ssh-nix}/bin/wrapper-dispatch-ssh-nix\" ${key}"
 | 
						|
        )
 | 
						|
        config.nix.remoteBuilder.sshPublicKeys;
 | 
						|
    };
 | 
						|
 | 
						|
    system.activationScripts = {
 | 
						|
      deleteChannels = lib.mkIf cfg.deleteChannels ''
 | 
						|
        echo "Deleting all channels..."
 | 
						|
        rm -rf /root/.nix-channels /home/*/.nix-channels /nix/var/nix/profiles/per-user/*/channels* || true
 | 
						|
      '';
 | 
						|
 | 
						|
      deleteUserProfiles = lib.mkIf cfg.deleteUserProfiles ''
 | 
						|
        echo "Deleting all user profiles..."
 | 
						|
        rm -rf /root/.nix-profile /home/*/.nix-profile /nix/var/nix/profiles/per-user/*/profile* || true
 | 
						|
      '';
 | 
						|
 | 
						|
      diff-system = lib.mkIf cfg.diffSystem {
 | 
						|
        supportsDryActivation = true;
 | 
						|
        text = ''
 | 
						|
          if [[ -e /run/current-system && -e $systemConfig ]]; then
 | 
						|
            echo System package diff:
 | 
						|
            ${lib.getExe config.nix.package} --extra-experimental-features nix-command store diff-closures /run/current-system $systemConfig || true
 | 
						|
          fi
 | 
						|
        '';
 | 
						|
      };
 | 
						|
    };
 | 
						|
  };
 | 
						|
}
 |