Compare commits
3 Commits
5d05aa3db9
...
b252af1270
Author | SHA1 | Date | |
---|---|---|---|
b252af1270 | |||
f3dac6ebf3 | |||
5183f69b39 |
6
flake.lock
generated
6
flake.lock
generated
@ -972,11 +972,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710743555,
|
||||
"narHash": "sha256-e8iXy4hCLYegNTeyB/GB8hj+gj1wPD+b+XOsEcdfEJY=",
|
||||
"lastModified": 1734507658,
|
||||
"narHash": "sha256-Ooz0UCrq+WYQp6ekYfqeAP2gazprWBvobXaIV38Btks=",
|
||||
"owner": "Silveere",
|
||||
"repo": "nixfiles-assets",
|
||||
"rev": "4ee66c3036eda78fe0ddada0e289a4f672ac4f57",
|
||||
"rev": "5612da9d6619ca3661abf08055d9b6d76e17d3bf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -65,6 +65,19 @@
|
||||
};
|
||||
};
|
||||
common.remoteAccess.enable = true;
|
||||
common.bootnext = {
|
||||
enable = true;
|
||||
entries = {
|
||||
windows = {
|
||||
name = "Windows Boot Manager";
|
||||
efiPartUUID = "6fc437f5-b917-42b2-9d5d-1439a14e105b";
|
||||
desktopEntry = {
|
||||
name = "Windows";
|
||||
icon = "microsoft-windows";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
# session = lib.mkDefault "hyprland";
|
||||
session = lib.mkDefault "plasma";
|
||||
hardware.nvidia.modesetting.enable = true;
|
||||
|
138
system/common/bootnext.nix
Normal file
138
system/common/bootnext.nix
Normal file
@ -0,0 +1,138 @@
|
||||
{ config, lib, pkgs, options, ... }:
|
||||
let
|
||||
inherit (lib) types escapeShellArg;
|
||||
cfg = config.nixfiles.common.bootnext;
|
||||
bootNextScriptMain = pkgs.writeShellScript "bootnext-wrapped" ''
|
||||
set -Eeuxo pipefail
|
||||
|
||||
PATH=${lib.escapeShellArg (with pkgs; lib.makeBinPath [ gnugrep coreutils efibootmgr ])}
|
||||
export PATH
|
||||
|
||||
function do_bootnext() {
|
||||
uuid="$1"
|
||||
shift
|
||||
entryName="$1"
|
||||
shift
|
||||
|
||||
efibootmgr -n "$(efibootmgr | grep -Fi "$uuid" | grep -F "$entryName" | cut -d' ' -f1 | tr -dc '[:digit:]')"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
${lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList (name: value:
|
||||
" ${escapeShellArg name}) do_bootnext ${escapeShellArg value.efiPartUUID} ${escapeShellArg value.name} ;;"
|
||||
) cfg.entries
|
||||
)}
|
||||
*) echo "Boot entry \"$1\" not configured."; exit 1;;
|
||||
esac
|
||||
'';
|
||||
|
||||
bootNextScript = pkgs.writeShellScriptBin "bootnext" ''
|
||||
# this wrapper is needed because the sudoers config needs the path to the
|
||||
# actual script and self referencing is a pain. this way we can guarantee
|
||||
# that the script passed is exactly the same as the one in the sudoers
|
||||
# config. i could use realpath but this is probably safer since it is not
|
||||
# evaluated at runtime. who knows.
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
exec sudo ${escapeShellArg bootNextScriptMain} "$@"
|
||||
else
|
||||
exec ${escapeShellArg bootNextScriptMain} "$@"
|
||||
fi
|
||||
'';
|
||||
|
||||
desktopWrapper = pkgs.writeShellScript "bootnext-desktop-wrapper" ''
|
||||
if ${pkgs.libsForQt5.kdialog}/bin/kdialog --warningyesno "Are you sure you want to reboot?" ; then
|
||||
${bootNextScript}/bin/bootnext "$@"
|
||||
reboot
|
||||
fi
|
||||
'';
|
||||
|
||||
bootnextDesktopEntries = pkgs.symlinkJoin {
|
||||
name = "bootnext-desktop-entries";
|
||||
paths = lib.mapAttrsToList (name: value: pkgs.makeDesktopItem {
|
||||
name = "bootnext-reboot-${name}";
|
||||
desktopName = "Reboot into ${value.desktopEntry.name}";
|
||||
comment = "Select the entry defined by the `${name}` configuration in the bootnext script and then reboot.";
|
||||
icon = "${value.desktopEntry.icon}";
|
||||
keywords = [ "bootnext" "reboot" "${name}" "${value.desktopEntry.name}" ];
|
||||
exec = "${desktopWrapper} ${name}";
|
||||
}) (lib.filterAttrs (_: value: value.desktopEntry.enable) cfg.entries);
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
options = {
|
||||
nixfiles.common.bootnext = {
|
||||
enable = lib.mkOption {
|
||||
description = ''
|
||||
Whether to enable the bootnext wrapper command for controlling boot order
|
||||
'';
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
};
|
||||
enableDesktopEntries = lib.mkEnableOption "generation of bootnext Desktop entries" // { default = true; };
|
||||
entries = let
|
||||
entryModule = {name, config, ... }: {
|
||||
options = let
|
||||
uuidType = with types; lib.mkOptionType {
|
||||
name = "uuid";
|
||||
description = "UUID";
|
||||
descriptionClass = "noun";
|
||||
check = let
|
||||
uuidRegex = "^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$";
|
||||
in x: str.check x && (builtins.match uuidRegex x) != null;
|
||||
inherit (str) merge;
|
||||
};
|
||||
in {
|
||||
efiPartUUID = lib.mkOption {
|
||||
description = "UUID of EFI partition containing boot entry";
|
||||
type = uuidType;
|
||||
apply = lib.strings.toLower;
|
||||
};
|
||||
name = lib.mkOption {
|
||||
description = "Name of boot entry as it appears in efibootmgr";
|
||||
type = types.str;
|
||||
example = "Windows Boot Manager";
|
||||
};
|
||||
desktopEntry = {
|
||||
enable = lib.mkOption {
|
||||
description = "Whether to generate this desktop entry.";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
example = false;
|
||||
};
|
||||
name = lib.mkOption {
|
||||
description = "Display name of boot entry for desktop entry.";
|
||||
type = types.str;
|
||||
default = config.name;
|
||||
example = "Windows";
|
||||
};
|
||||
icon = lib.mkOption {
|
||||
description = "Path or name of icon to use for desktop entry";
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in lib.mkOption {
|
||||
description = "bootnext entry";
|
||||
type = with types; attrsOf (submodule entryModule);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ bootNextScript ] ++ lib.optional cfg.enableDesktopEntries bootnextDesktopEntries;
|
||||
|
||||
security.sudo.extraRules = lib.mkAfter [
|
||||
{
|
||||
commands = [
|
||||
{ command = "${bootNextScriptMain}"; options = [ "NOPASSWD" ]; }
|
||||
];
|
||||
groups = [ "wheel" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
@ -5,5 +5,6 @@
|
||||
./remote.nix
|
||||
./wm.nix
|
||||
./nix.nix
|
||||
./bootnext.nix
|
||||
];
|
||||
}
|
||||
|
@ -24,6 +24,12 @@ in
|
||||
# FIXME find somewhere else to put this
|
||||
networking.networkmanager.enable = lib.mkDefault true; # Easiest to use and most distros use this by default.
|
||||
|
||||
# contains icons for bootnext desktop entries (the Windows icon); there's
|
||||
# probably no reason to *not* include this.
|
||||
environment.systemPackages = with pkgs; [
|
||||
nixfiles-assets
|
||||
];
|
||||
|
||||
# enable option sets
|
||||
nixfiles = {
|
||||
hardware = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user