237 lines
7.5 KiB
Nix
237 lines
7.5 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
username,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.my.virt;
|
|
generateConfig =
|
|
settings:
|
|
lib.generators.toINI {
|
|
mkKeyValue = lib.generators.mkKeyValueDefault {
|
|
mkValueString =
|
|
v:
|
|
if (true == v) then
|
|
"yes"
|
|
else if (false == v) then
|
|
"no"
|
|
else
|
|
(lib.generators.mkValueStringDefault { } v);
|
|
} "=";
|
|
} settings;
|
|
in
|
|
{
|
|
imports = [
|
|
(lib.my.makeHomePackageConfig {
|
|
inherit config pkgs;
|
|
packageName = "moonlight-qt";
|
|
packagePath = [ "moonlight-qt" ];
|
|
optionPath = [
|
|
"virt"
|
|
"moonlight"
|
|
];
|
|
extraConfig = {
|
|
my.persist.homeDirs = [
|
|
".config/Moonlight Game Streaming Project"
|
|
];
|
|
};
|
|
})
|
|
];
|
|
|
|
options.my.virt = {
|
|
enable = lib.mkEnableOption "virtualization";
|
|
looking-glass = {
|
|
enable = lib.mkEnableOption "looking-glass";
|
|
package = lib.mkPackageOption pkgs "looking-glass-client" { };
|
|
kvmfr = {
|
|
enable = lib.mkEnableOption "KVM Frame Relay (kvmfr)";
|
|
|
|
package = lib.mkPackageOption config.boot.kernelPackages "kvmfr" {
|
|
pkgsText = "config.boot.kernelPackages";
|
|
};
|
|
|
|
owner = lib.mkOption {
|
|
description = "Owner of the kvmfr device file(s). You probably want to set this to the name of the user who will run looking-glass-client.";
|
|
default = "kvm";
|
|
example = "your-user-name";
|
|
type = lib.types.str;
|
|
};
|
|
|
|
group = lib.mkOption {
|
|
description = "Group of the kvmfr device file(s)";
|
|
default = "kvm";
|
|
example = "kvm";
|
|
type = lib.types.str;
|
|
};
|
|
|
|
sizeMB = lib.mkOption {
|
|
description = "Size (in megabytes) of the kvmfr device";
|
|
default = 32;
|
|
example = 128;
|
|
type = lib.types.ints.positive;
|
|
};
|
|
|
|
configureDeviceACLs = lib.mkOption {
|
|
description = ''
|
|
Configure libvirtd's qemu.conf to include the kvmfr device in the
|
|
cgroup_device_acl setting. When enabled, this module adds a block
|
|
to the 'virtualisation.libvirtd.qemu.verbatimConfig' option which
|
|
sets cgroup_device_acl to the default list of devices along with
|
|
the kvmfr0 device. You probably want this enabled unless you
|
|
explicitly set the 'verbatimConfig' option elsewhere.
|
|
If you already set a custom value for cgroup_device_acl, you should
|
|
not enable this option. Instead, add '/dev/kvmfr0' to the setting
|
|
yourself.
|
|
If you do not add '/dev/kvmfr0' to the list or enable this option,
|
|
any VMs attempting to utilize kvmfr will fail to start, and libvirt
|
|
will report a Permission Denied error.
|
|
'';
|
|
default = false;
|
|
example = true;
|
|
type = lib.types.bool;
|
|
};
|
|
};
|
|
|
|
# Options for creating the /dev/shm shared memory file
|
|
shm = {
|
|
enable = lib.mkEnableOption "Shared Memory Frame Relay";
|
|
|
|
owner = lib.mkOption {
|
|
description = "Owner of the shared memory file";
|
|
default = "kvm";
|
|
example = "your-user-name";
|
|
type = lib.types.str;
|
|
};
|
|
|
|
name = lib.mkOption {
|
|
description = "Name of the shared memory file under /dev/shm";
|
|
default = "looking-glass";
|
|
example = "looking-glass";
|
|
};
|
|
};
|
|
|
|
# Client configuration (written to /etc/looking-glass-client.ini)
|
|
settings = lib.mkOption {
|
|
description = "Looking Glass client configuration";
|
|
default = { };
|
|
type = lib.types.submodule ./types;
|
|
|
|
example = {
|
|
app.shmFile = "/dev/kvmfr0";
|
|
input.escapeKey = "KEY_RIGHTCTRL";
|
|
|
|
win = {
|
|
fullScreen = true;
|
|
noScreensaver = true;
|
|
showFPS = true;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
config = lib.mkMerge [
|
|
(lib.mkIf cfg.looking-glass.enable (
|
|
let
|
|
cfg' = cfg.looking-glass;
|
|
in
|
|
{
|
|
warnings = lib.lists.optional (!cfg'.kvmfr.enable && !cfg'.shm.enable) ''
|
|
Neither the shared memory nor kvmfr kernel module are enabled.
|
|
You must configure one of these manually or set one of programs.looking-glass.kvmfr.enable
|
|
or programs.looking-glass.shm.enable to have them automatically configured.
|
|
'';
|
|
|
|
# Install looking glass
|
|
environment.systemPackages = [ cfg'.package ];
|
|
|
|
# Optionally install the kvmfr kernel module
|
|
boot.extraModulePackages = lib.lists.optional cfg'.kvmfr.enable cfg'.kvmfr.package;
|
|
|
|
# Create the configuration file if requested
|
|
environment.etc = {
|
|
# Write the looking glass configuration
|
|
"looking-glass-client.ini".text = generateConfig cfg'.settings;
|
|
|
|
# Set the frame size if kvmfr is enabled
|
|
"modprobe.d/kvmfr.conf" = {
|
|
enable = cfg'.kvmfr.enable;
|
|
text = ''
|
|
options kvmfr static_size_mb=${toString cfg'.kvmfr.sizeMB}
|
|
'';
|
|
};
|
|
|
|
# Load the kvmfr module at boot if enabled
|
|
"modules-load.d/kvmfr.conf" = {
|
|
enable = cfg'.kvmfr.enable;
|
|
text = ''
|
|
# KVMFR Looking Glass Module
|
|
kvmfr
|
|
'';
|
|
};
|
|
};
|
|
|
|
# Automatically apply permissions to the kvmfr device as requested
|
|
services.udev.packages = lib.lists.optional cfg'.kvmfr.enable (
|
|
pkgs.writeTextFile {
|
|
name = "99-looking-glass-kvmfr.rules";
|
|
destination = "/etc/udev/rules.d/99-looking-glass-kvmfr.rules";
|
|
text = ''
|
|
SUBSYSTEM=="kvmfr", OWNER="${cfg'.kvmfr.owner}", GROUP="${cfg'.kvmfr.group}", MODE="0660"
|
|
'';
|
|
}
|
|
);
|
|
|
|
# Create the /dev/shm file if requested
|
|
systemd.tmpfiles.rules = lib.lists.optional cfg'.shm.enable ''
|
|
f /dev/shm/${cfg'.shm.name} 0660 ${cfg'.shm.owner} qemu-libvirtd -
|
|
'';
|
|
|
|
# Allow access to the kvmfr device from the libvirt cgroups
|
|
virtualisation.libvirtd.qemu.verbatimConfig =
|
|
lib.strings.optionalString (cfg'.kvmfr.enable && cfg'.kvmfr.configureDeviceACLs)
|
|
''
|
|
cgroup_device_acl = [
|
|
"/dev/null", "/dev/full", "/dev/zero",
|
|
"/dev/random", "/dev/urandom",
|
|
"/dev/ptmx", "/dev/kvm", "/dev/kqemu",
|
|
"/dev/rtc","/dev/hpet", "/dev/vfio/vfio",
|
|
"/dev/kvmfr0"
|
|
]
|
|
'';
|
|
|
|
# Add libvirt-qemu apparmor policy allowing rw access to kvmfr device if apparmor is enabled
|
|
security.apparmor.packages =
|
|
lib.lists.optional (cfg'.kvmfr.enable && config.security.apparmor.enable)
|
|
(
|
|
pkgs.writeTextFile {
|
|
name = "looking-glass-kvmfr-apparmor-policy";
|
|
destination = "/etc/apparmor.d/local/abstractions/libvirt-qemu";
|
|
text = ''
|
|
# Looking Glass
|
|
/dev/kvmfr0 rw,
|
|
'';
|
|
}
|
|
);
|
|
}
|
|
))
|
|
(lib.mkIf cfg.enable {
|
|
virtualisation.libvirtd = {
|
|
enable = true;
|
|
qemu = {
|
|
package = pkgs.qemu_kvm;
|
|
verbatimConfig = ''
|
|
dynamic_ownership = 0
|
|
remember_owner = 0
|
|
'';
|
|
};
|
|
};
|
|
programs.virt-manager.enable = true;
|
|
users.users.${username}.extraGroups = [ "libvirtd" ];
|
|
environment.systemPackages = with pkgs; [ virglrenderer ];
|
|
})
|
|
];
|
|
}
|