init: public
This commit is contained in:
228
modules/virt/default.nix
Normal file
228
modules/virt/default.nix
Normal file
@@ -0,0 +1,228 @@
|
||||
{
|
||||
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"
|
||||
];
|
||||
})
|
||||
];
|
||||
|
||||
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.verbatimConfig = ''
|
||||
dynamic_ownership = 0
|
||||
remember_owner = 0
|
||||
'';
|
||||
};
|
||||
programs.virt-manager.enable = true;
|
||||
users.users.${username}.extraGroups = [ "libvirtd" ];
|
||||
environment.systemPackages = with pkgs; [ virglrenderer ];
|
||||
})
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user