mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-14 12:53:43 +01:00
komorebi-for-kde/nix/ -> nix/linux/ komorebi-for-mac/nix/ -> nix/macos/ The nix expressions of the platforms (modules, option files, VM test suites, kwin effects, the darwin module) sit next to the existing nix/workspace-src.nix. Renames only (252 files); the flakes that import them are replaced by one root flake later in this stack, so nix does not evaluate at this revision.
232 lines
7.7 KiB
Nix
232 lines
7.7 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
hostPkgs,
|
|
...
|
|
}:
|
|
|
|
# A NixOS Plasma 6 guest to develop and test against a real KWin, with komorebi installed by the
|
|
# flake's module, `services.komorebi`, from the flake's packages. The flake builds it for an Apple
|
|
# silicon Mac, which runs it under QEMU with HVF, and for a Linux machine, which runs it under QEMU
|
|
# with KVM; docs/dev/utm.md says how to build and run it. The system of the guest and the packages
|
|
# of the machine that runs QEMU (`hostPkgs`) come from the flake, so that one file serves them all.
|
|
#
|
|
# The guest mounts the repository at /repo, and keeps its disk in the directory it is started
|
|
# from, which is best .vm (gitignored):
|
|
#
|
|
# nix build .#nixosConfigurations.plasma-vm.config.system.build.vm -o .vm/result-plasma-vm
|
|
# cd .vm && KOMOREBI_REPO=$PWD/.. ./result-plasma-vm/bin/run-plasma-vm-vm
|
|
#
|
|
# The console, in the terminal that runs the guest, is logged in as the user `komorebi`. ssh is
|
|
# forwarded to localhost:2222 (2223 for the session), for the keys in ~/.ssh/authorized_keys of
|
|
# that user, which the guest's disk keeps.
|
|
#
|
|
# The session variant is the one to live in: Plasma logs in by itself, the module's unit runs
|
|
# komorebi in it, and it can be reached over RDP (krdp.nix).
|
|
let
|
|
cfg = config.komorebi.plasmaVm;
|
|
|
|
# The guest's one display, a virtio-gpu, so that KWin has a DRM device to draw on. The machine of
|
|
# an aarch64 guest has no display of its own. The machine of an x86_64 guest has a VGA, which QEMU
|
|
# adds unless it is told not to, and KWin would draw on it as well as on the virtio-gpu: a second
|
|
# head. An x86_64 guest gets `virtio-vga`, a virtio-gpu that is also the VGA, in its place.
|
|
gpu =
|
|
args:
|
|
if pkgs.stdenv.hostPlatform.isx86_64 then
|
|
[
|
|
"-vga none"
|
|
"-device virtio-vga${args}"
|
|
]
|
|
else
|
|
[ "-device virtio-gpu-pci${args}" ];
|
|
in
|
|
{
|
|
imports = [ ./krdp.nix ];
|
|
|
|
options.komorebi.plasmaVm = {
|
|
session = lib.mkEnableOption ''
|
|
a full autologin Plasma Wayland session (sddm + plasmashell), in addition to the headless
|
|
`kwin_wayland --virtual` workflow that is always available from the console and over ssh
|
|
'';
|
|
|
|
display = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = true;
|
|
description = ''
|
|
Whether the runner gives the guest its display device, a virtio-gpu. A guest that sets this
|
|
to false is started with a display device of its own choosing, which can then differ from
|
|
one start to the next: `run-kde` starts the demo guest (run-kde.nix) with a software
|
|
`virtio-vga` or with a `virtio-vga-gl` that renders on the host's GPU, from one closure and
|
|
one disk.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkMerge [
|
|
{
|
|
system.stateVersion = "26.05";
|
|
networking.hostName = "plasma-vm";
|
|
|
|
services.desktopManager.plasma6.enable = true;
|
|
programs.dconf.enable = true;
|
|
# mesa (llvmpipe over the virtio-gpu render node) so kwin can composite with GL
|
|
hardware.graphics.enable = true;
|
|
fonts.enableDefaultPackages = true;
|
|
|
|
# komorebi and komorebic, from the flake's packages; the unit starts with a Plasma session
|
|
services.komorebi.enable = true;
|
|
|
|
services.openssh = {
|
|
enable = true;
|
|
settings = {
|
|
PasswordAuthentication = false;
|
|
PermitRootLogin = "no";
|
|
};
|
|
};
|
|
|
|
# the way in before any key is in ~/.ssh/authorized_keys: there is no password anywhere
|
|
services.getty.autologinUser = "komorebi";
|
|
|
|
users.users.komorebi = {
|
|
isNormalUser = true;
|
|
uid = 1000;
|
|
extraGroups = [
|
|
"wheel"
|
|
"video"
|
|
"render"
|
|
];
|
|
# keep a user manager (and XDG_RUNTIME_DIR) alive across ssh sessions
|
|
linger = true;
|
|
};
|
|
security.sudo.wheelNeedsPassword = false;
|
|
|
|
nix.settings.experimental-features = [
|
|
"nix-command"
|
|
"flakes"
|
|
];
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
# clients to tile: Qt/KDE, GTK3/4 (CSD), Electron-ish via firefox, plain wayland, XWayland
|
|
kdePackages.konsole
|
|
kdePackages.dolphin
|
|
kdePackages.kate
|
|
kdePackages.spectacle
|
|
firefox
|
|
gnome-text-editor
|
|
gnome-calculator
|
|
foot
|
|
xterm
|
|
|
|
# poking at KWin
|
|
kdePackages.qttools # qdbus6
|
|
dbus
|
|
jq
|
|
kdotool
|
|
strace
|
|
|
|
# installing plasma-utm onto a disk image (docs/dev/utm.md)
|
|
nixos-install-tools
|
|
dosfstools
|
|
parted
|
|
e2fsprogs
|
|
|
|
# building komorebi from /repo in the guest
|
|
rustc
|
|
cargo
|
|
gcc
|
|
pkg-config
|
|
git
|
|
rsync
|
|
htop
|
|
];
|
|
|
|
environment.sessionVariables = {
|
|
# kwin refuses to load animating effects (including the stock scripted ones) under software
|
|
# rendering; llvmpipe is all this vm has
|
|
KWIN_EFFECTS_FORCE_ANIMATIONS = "1";
|
|
# always build in guest-local storage; /repo is a 9p mount and is slow for target dirs
|
|
CARGO_TARGET_DIR = "/home/komorebi/target";
|
|
};
|
|
|
|
virtualisation.vmVariant = {
|
|
virtualisation = {
|
|
host.pkgs = hostPkgs;
|
|
qemu.forceAccel = true;
|
|
cores = 6;
|
|
memorySize = 8192;
|
|
diskSize = 20 * 1024;
|
|
graphics = false;
|
|
# no display, but a gpu so there is a drm render node
|
|
qemu.options = lib.mkIf (cfg.display && !cfg.session) (gpu "");
|
|
forwardPorts = [
|
|
{
|
|
from = "host";
|
|
host.address = "127.0.0.1";
|
|
host.port = if cfg.session then 2223 else 2222;
|
|
guest.port = 22;
|
|
}
|
|
];
|
|
sharedDirectories.repo = {
|
|
# the runner says so when it is not set
|
|
source = "\${KOMOREBI_REPO:?set KOMOREBI_REPO to the root of the repository}";
|
|
target = "/repo";
|
|
writable = true;
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|
|
(lib.mkIf cfg.session {
|
|
# a separate disk image (named after the host) and ssh port so both vms can run at once
|
|
networking.hostName = lib.mkForce "plasma-vm-session";
|
|
services.displayManager = {
|
|
sddm = {
|
|
enable = true;
|
|
wayland.enable = true;
|
|
};
|
|
autoLogin = {
|
|
enable = true;
|
|
user = "komorebi";
|
|
};
|
|
defaultSession = "plasma";
|
|
};
|
|
# kwin drives virtio-gpu through drm on the primary node; that is the only place mesa's software
|
|
# rasterizer can allocate buffers (see docs/dev/PLATFORM.md: the headless --virtual backend
|
|
# cannot)
|
|
virtualisation.vmVariant.virtualisation.qemu.options = lib.mkIf cfg.display (
|
|
gpu ",xres=1920,yres=1080"
|
|
);
|
|
# an idle lock screen or dimmed display changes how kwin animates and what screenshots show
|
|
environment.etc."xdg/kscreenlockerrc".text = ''
|
|
[Daemon]
|
|
Autolock=false
|
|
LockOnResume=false
|
|
'';
|
|
# and so does a display that has gone to sleep: with the output off, KWin sends no frame
|
|
# callbacks, so clients stop answering resizes and every window stays where it was while komorebi
|
|
# asks for another place (found on the UTM guest after it sat idle: black screenshots, nothing tiled)
|
|
environment.etc."xdg/powerdevilrc".text = ''
|
|
[AC][Display]
|
|
DimDisplayWhenIdle=false
|
|
TurnOffDisplayWhenIdle=false
|
|
|
|
[AC][SuspendAndShutdown]
|
|
AutoSuspendAction=0
|
|
'';
|
|
|
|
komorebi.krdp.enable = true;
|
|
|
|
# only the host's loopback reaches it
|
|
virtualisation.vmVariant.virtualisation.forwardPorts = [
|
|
{
|
|
from = "host";
|
|
host.address = "127.0.0.1";
|
|
host.port = 3389;
|
|
guest.port = 3389;
|
|
}
|
|
];
|
|
})
|
|
];
|
|
}
|