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.
108 lines
4.3 KiB
Nix
108 lines
4.3 KiB
Nix
# KRDP, Plasma's RDP server, in the Plasma session of every user who logs in. The session guest
|
|
# of plasma-vm.nix enables it, and so does the VM suite `rdp`, which checks that a client can log
|
|
# in and get a picture of the desktop (docs/dev/PLATFORM.md says what it does not check).
|
|
#
|
|
# The password is not in the repository: the unit starts once the user has written one to
|
|
# ~/.config/komorebi-vm/rdp-password, and a client logs in with the user's name and that password.
|
|
# A guest whose password comes from outside, as the demo guest's does (run-kde.nix), names a file
|
|
# of the guest in `passwordFile`, which the unit reads in place of that one when it is there.
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.komorebi.krdp;
|
|
|
|
# KRDP asks for the H.264 Constrained Baseline profile and nothing else. A guest whose VA-API
|
|
# drives the host's encoder (virgl, with the QEMU of run-kde.nix) lists Main and High and no
|
|
# Constrained Baseline, so ffmpeg's h264_vaapi finds no profile it can use and KRDP encodes on
|
|
# the CPUs. Main is in RDP's H.264 mode as well, and the software encoder takes it too.
|
|
krdp = pkgs.kdePackages.krdp.overrideAttrs (old: {
|
|
postPatch = (old.postPatch or "") + ''
|
|
substituteInPlace src/VideoStreamSurface.cpp --replace-fail H264Baseline H264Main
|
|
'';
|
|
});
|
|
|
|
startKrdp = pkgs.writeShellScript "krdp-start" ''
|
|
set -eu
|
|
dir=$HOME/.config/komorebi-vm
|
|
password_file=$dir/rdp-password
|
|
${lib.optionalString (cfg.passwordFile != null) ''
|
|
if [ -r ${lib.escapeShellArg cfg.passwordFile} ]; then
|
|
password_file=${lib.escapeShellArg cfg.passwordFile}
|
|
fi
|
|
''}
|
|
mkdir -p "$dir"
|
|
# krdpserver refuses to run without a TLS certificate and key (its --help promises a temporary
|
|
# one, but it only checks that the files exist), so make a throwaway self-signed pair
|
|
if [ ! -f "$dir/rdp.crt" ] || [ ! -f "$dir/rdp.key" ]; then
|
|
${pkgs.openssl}/bin/openssl req -x509 -newkey rsa:2048 -nodes -days 3650 -subj /CN=komorebi-vm \
|
|
-addext subjectAltName=DNS:localhost,IP:127.0.0.1 -keyout "$dir/rdp.key" -out "$dir/rdp.crt"
|
|
chmod 600 "$dir/rdp.key"
|
|
fi
|
|
# --plasma asks KWin for the screen and for input directly, with no portal prompt to click
|
|
exec ${krdp}/bin/krdpserver --plasma --address 0.0.0.0 --port 3389 \
|
|
--certificate "$dir/rdp.crt" --certificate-key "$dir/rdp.key" \
|
|
--username "$USER" --password "$(cat "$password_file")"
|
|
'';
|
|
in
|
|
{
|
|
options.komorebi.krdp = {
|
|
enable = lib.mkEnableOption "KRDP, an RDP server, in every Plasma session";
|
|
|
|
passwordFile = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.str;
|
|
default = null;
|
|
example = "/run/run-kde-guest/rdp-password";
|
|
description = ''
|
|
The path, in the guest, of a file with the password a client logs in with. It is a path in
|
|
the running guest and not a file of the Nix store, so that no password is part of the
|
|
system. The unit reads it in place of `~/.config/komorebi-vm/rdp-password` when it exists,
|
|
and starts when either exists.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
environment.systemPackages = [
|
|
krdp
|
|
# A client, to try the server from inside the guest. FreeRDP decodes H.264 with OpenH264
|
|
# when it is built with it, and OpenH264 shows nothing of the video KRDP sends; without it,
|
|
# FreeRDP decodes with FFmpeg (the VM suite `rdp`, docs/dev/PLATFORM.md).
|
|
(pkgs.freerdp.override { openh264 = null; })
|
|
];
|
|
|
|
# krdp streams the screen through pipewire
|
|
services.pipewire = {
|
|
enable = true;
|
|
wireplumber.enable = true;
|
|
};
|
|
security.rtkit.enable = true;
|
|
|
|
networking.firewall.allowedTCPPorts = [ 3389 ];
|
|
|
|
systemd.user.services.krdp = {
|
|
description = "RDP into this Plasma session";
|
|
wantedBy = [ "plasma-workspace.target" ];
|
|
after = [ "plasma-core.target" ];
|
|
# with no password the unit is skipped, not failed: `systemctl --user start krdp` once the
|
|
# file is there
|
|
unitConfig.ConditionPathExists =
|
|
if cfg.passwordFile == null then
|
|
"%h/.config/komorebi-vm/rdp-password"
|
|
else
|
|
[
|
|
"|%h/.config/komorebi-vm/rdp-password"
|
|
"|${cfg.passwordFile}"
|
|
];
|
|
serviceConfig = {
|
|
ExecStart = startKrdp;
|
|
Restart = "on-failure";
|
|
RestartSec = 3;
|
|
};
|
|
};
|
|
};
|
|
}
|