wivrn: init at 0.19 (#316975)
This commit is contained in:
commit
d249539594
@ -201,6 +201,8 @@ The pre-existing `services.ankisyncd` has been marked deprecated and will be dro
|
|||||||
|
|
||||||
- [watchdogd](https://troglobit.com/projects/watchdogd/), a system and process supervisor using watchdog timers. Available as [services.watchdogd](#opt-services.watchdogd.enable).
|
- [watchdogd](https://troglobit.com/projects/watchdogd/), a system and process supervisor using watchdog timers. Available as [services.watchdogd](#opt-services.watchdogd.enable).
|
||||||
|
|
||||||
|
- [WiVRn](https://github.com/Meumeu/WiVRn), an OpenXR streaming application. Available as [services.wivrn](#opt-services.wivrn.enable).
|
||||||
|
|
||||||
- [Workout-tracker](https://github.com/jovandeginste/workout-tracker), a workout tracking web application for personal use.
|
- [Workout-tracker](https://github.com/jovandeginste/workout-tracker), a workout tracking web application for personal use.
|
||||||
|
|
||||||
- [wyoming-satellite](https://github.com/rhasspy/wyoming-satellite), a voice assistant satellite for Home Assistant using the Wyoming protocol. Available as [services.wyoming.satellite](#opt-services.wyoming.satellite.enable).
|
- [wyoming-satellite](https://github.com/rhasspy/wyoming-satellite), a voice assistant satellite for Home Assistant using the Wyoming protocol. Available as [services.wyoming.satellite](#opt-services.wyoming.satellite.enable).
|
||||||
|
|||||||
@ -1380,6 +1380,7 @@
|
|||||||
./services/video/photonvision.nix
|
./services/video/photonvision.nix
|
||||||
./services/video/mediamtx.nix
|
./services/video/mediamtx.nix
|
||||||
./services/video/v4l2-relayd.nix
|
./services/video/v4l2-relayd.nix
|
||||||
|
./services/video/wivrn.nix
|
||||||
./services/wayland/cage.nix
|
./services/wayland/cage.nix
|
||||||
./services/wayland/hypridle.nix
|
./services/wayland/hypridle.nix
|
||||||
./services/web-apps/akkoma.nix
|
./services/web-apps/akkoma.nix
|
||||||
|
|||||||
226
nixos/modules/services/video/wivrn.nix
Normal file
226
nixos/modules/services/video/wivrn.nix
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
mkIf
|
||||||
|
mkEnableOption
|
||||||
|
mkPackageOption
|
||||||
|
mkOption
|
||||||
|
optionalString
|
||||||
|
optionalAttrs
|
||||||
|
isDerivation
|
||||||
|
recursiveUpdate
|
||||||
|
getExe
|
||||||
|
literalExpression
|
||||||
|
types
|
||||||
|
maintainers
|
||||||
|
;
|
||||||
|
cfg = config.services.wivrn;
|
||||||
|
configFormat = pkgs.formats.json { };
|
||||||
|
|
||||||
|
# For the application option to work with systemd PATH, we find the store binary path of
|
||||||
|
# the package, concat all of the following strings, and then update the application attribute.
|
||||||
|
# Application can either be a package or a list that has a package as the first element.
|
||||||
|
applicationExists = builtins.hasAttr "application" cfg.config.json;
|
||||||
|
applicationListNotEmpty = (
|
||||||
|
if builtins.isList cfg.config.json.application then
|
||||||
|
(builtins.length cfg.config.json.application) != 0
|
||||||
|
else
|
||||||
|
true
|
||||||
|
);
|
||||||
|
applicationCheck = applicationExists && applicationListNotEmpty;
|
||||||
|
|
||||||
|
applicationBinary = (
|
||||||
|
if builtins.isList cfg.config.json.application then
|
||||||
|
builtins.head cfg.config.json.application
|
||||||
|
else
|
||||||
|
cfg.config.json.application
|
||||||
|
);
|
||||||
|
applicationStrings = builtins.tail cfg.config.json.application;
|
||||||
|
|
||||||
|
applicationPath = mkIf applicationCheck applicationBinary;
|
||||||
|
|
||||||
|
applicationConcat = (
|
||||||
|
if builtins.isList cfg.config.json.application then
|
||||||
|
builtins.concatStringsSep " " ([ (getExe applicationBinary) ] ++ applicationStrings)
|
||||||
|
else
|
||||||
|
(getExe applicationBinary)
|
||||||
|
);
|
||||||
|
applicationUpdate = recursiveUpdate cfg.config.json (
|
||||||
|
optionalAttrs applicationCheck { application = applicationConcat; }
|
||||||
|
);
|
||||||
|
configFile = configFormat.generate "config.json" applicationUpdate;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
services.wivrn = {
|
||||||
|
enable = mkEnableOption "WiVRn, an OpenXR streaming application";
|
||||||
|
|
||||||
|
package = mkPackageOption pkgs "wivrn" { };
|
||||||
|
|
||||||
|
openFirewall = mkEnableOption "the default ports in the firewall for the WiVRn server";
|
||||||
|
|
||||||
|
defaultRuntime = mkEnableOption ''
|
||||||
|
WiVRn Monado as the default OpenXR runtime on the system.
|
||||||
|
The config can be found at `/etc/xdg/openxr/1/active_runtime.json`.
|
||||||
|
|
||||||
|
Note that applications can bypass this option by setting an active
|
||||||
|
runtime in a writable XDG_CONFIG_DIRS location like `~/.config`
|
||||||
|
'';
|
||||||
|
|
||||||
|
autoStart = mkEnableOption "starting the service by default";
|
||||||
|
|
||||||
|
monadoEnvironment = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
description = "Environment variables to be passed to the Monado environment.";
|
||||||
|
default = {
|
||||||
|
XRT_COMPOSITOR_LOG = "debug";
|
||||||
|
XRT_PRINT_OPTIONS = "on";
|
||||||
|
IPC_EXIT_ON_DISCONNECT = "off";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraPackages = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
description = "Packages to add to the wivrn-application service $PATH.";
|
||||||
|
default = [ ];
|
||||||
|
example = literalExpression "[ pkgs.bash pkgs.procps ]";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
enable = mkEnableOption "configuration for WiVRn";
|
||||||
|
json = mkOption {
|
||||||
|
type = configFormat.type;
|
||||||
|
description = ''
|
||||||
|
Configuration for WiVRn. The attributes are serialized to JSON in config.json.
|
||||||
|
|
||||||
|
Note that the application option must be either a package or a
|
||||||
|
list with package as the first element.
|
||||||
|
|
||||||
|
See https://github.com/Meumeu/WiVRn/blob/master/docs/configuration.md
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
scale = 0.8;
|
||||||
|
bitrate = 100000000;
|
||||||
|
encoders = [
|
||||||
|
{
|
||||||
|
encoder = "nvenc";
|
||||||
|
codec = "h264";
|
||||||
|
width = 1.0;
|
||||||
|
height = 1.0;
|
||||||
|
offset_x = 0.0;
|
||||||
|
offset_y = 0.0;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
application = [ pkgs.wlx-overlay-s ];
|
||||||
|
tcp_only = true;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = !applicationCheck || isDerivation applicationBinary;
|
||||||
|
message = "The application in WiVRn configuration is not a package. Please ensure that the application is a package or that a package is the first element in the list.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.user = {
|
||||||
|
services = {
|
||||||
|
# The WiVRn server runs in a hardened service and starts the applications in a different service
|
||||||
|
wivrn = {
|
||||||
|
description = "WiVRn XR runtime service";
|
||||||
|
environment = {
|
||||||
|
# Default options
|
||||||
|
# https://gitlab.freedesktop.org/monado/monado/-/blob/598080453545c6bf313829e5780ffb7dde9b79dc/src/xrt/targets/service/monado.in.service#L12
|
||||||
|
XRT_COMPOSITOR_LOG = "debug";
|
||||||
|
XRT_PRINT_OPTIONS = "on";
|
||||||
|
IPC_EXIT_ON_DISCONNECT = "off";
|
||||||
|
} // cfg.monadoEnvironment;
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = (
|
||||||
|
(getExe cfg.package) + " --systemd" + optionalString cfg.config.enable " -f ${configFile}"
|
||||||
|
);
|
||||||
|
# Hardening options
|
||||||
|
CapabilityBoundingSet = [ "CAP_SYS_NICE" ];
|
||||||
|
AmbientCapabilities = [ "CAP_SYS_NICE" ];
|
||||||
|
LockPersonality = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
RemoveIPC = true;
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
};
|
||||||
|
wantedBy = mkIf cfg.autoStart [ "default.target" ];
|
||||||
|
restartTriggers = [
|
||||||
|
cfg.package
|
||||||
|
configFile
|
||||||
|
];
|
||||||
|
};
|
||||||
|
wivrn-application = mkIf applicationCheck {
|
||||||
|
description = "WiVRn application service";
|
||||||
|
requires = [ "wivrn.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = (
|
||||||
|
(getExe cfg.package) + " --application" + optionalString cfg.config.enable " -f ${configFile}"
|
||||||
|
);
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 0;
|
||||||
|
PrivateTmp = true;
|
||||||
|
};
|
||||||
|
# We need to add the application to PATH so WiVRn can find it
|
||||||
|
path = [ applicationPath ] ++ cfg.extraPackages;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
# WiVRn can be used with some wired headsets so we include xr-hardware
|
||||||
|
udev.packages = with pkgs; [
|
||||||
|
android-udev-rules
|
||||||
|
xr-hardware
|
||||||
|
];
|
||||||
|
avahi = {
|
||||||
|
enable = true;
|
||||||
|
publish = {
|
||||||
|
enable = true;
|
||||||
|
userServices = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = mkIf cfg.openFirewall {
|
||||||
|
allowedTCPPorts = [ 9757 ];
|
||||||
|
allowedUDPPorts = [ 9757 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
systemPackages = [
|
||||||
|
cfg.package
|
||||||
|
applicationPath
|
||||||
|
];
|
||||||
|
pathsToLink = [ "/share/openxr" ];
|
||||||
|
etc."xdg/openxr/1/active_runtime.json" = mkIf cfg.defaultRuntime {
|
||||||
|
source = "${cfg.package}/share/openxr/1/openxr_wivrn.json";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
meta.maintainers = with maintainers; [ passivelemon ];
|
||||||
|
}
|
||||||
149
pkgs/by-name/wi/wivrn/package.nix
Normal file
149
pkgs/by-name/wi/wivrn/package.nix
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
fetchFromGitHub,
|
||||||
|
fetchFromGitLab,
|
||||||
|
applyPatches,
|
||||||
|
autoAddDriverRunpath,
|
||||||
|
avahi,
|
||||||
|
boost,
|
||||||
|
cli11,
|
||||||
|
cmake,
|
||||||
|
cudaPackages ? { },
|
||||||
|
cudaSupport ? config.cudaSupport,
|
||||||
|
eigen,
|
||||||
|
ffmpeg,
|
||||||
|
freetype,
|
||||||
|
git,
|
||||||
|
glm,
|
||||||
|
glslang,
|
||||||
|
harfbuzz,
|
||||||
|
libdrm,
|
||||||
|
libGL,
|
||||||
|
libva,
|
||||||
|
libpulseaudio,
|
||||||
|
libX11,
|
||||||
|
libXrandr,
|
||||||
|
nix-update-script,
|
||||||
|
nlohmann_json,
|
||||||
|
onnxruntime,
|
||||||
|
openxr-loader,
|
||||||
|
pipewire,
|
||||||
|
pkg-config,
|
||||||
|
python3,
|
||||||
|
shaderc,
|
||||||
|
spdlog,
|
||||||
|
systemd,
|
||||||
|
udev,
|
||||||
|
vulkan-headers,
|
||||||
|
vulkan-loader,
|
||||||
|
vulkan-tools,
|
||||||
|
x264,
|
||||||
|
}:
|
||||||
|
stdenv.mkDerivation (finalAttrs: {
|
||||||
|
pname = "wivrn";
|
||||||
|
version = "0.19";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "wivrn";
|
||||||
|
repo = "wivrn";
|
||||||
|
rev = "v${finalAttrs.version}";
|
||||||
|
hash = "sha256-DYV+JUWjjhLZLq+4Hv7jxOyxDqQut/mU1X0ZFMoNkDI=";
|
||||||
|
};
|
||||||
|
|
||||||
|
monado = applyPatches {
|
||||||
|
src = fetchFromGitLab {
|
||||||
|
domain = "gitlab.freedesktop.org";
|
||||||
|
owner = "monado";
|
||||||
|
repo = "monado";
|
||||||
|
rev = "bcbe19ddd795f182df42051e5495e9727db36c1c";
|
||||||
|
hash = "sha256-sh5slHROcuC3Dgenu1+hm8U5lUOW48JUbiluYvc3NiQ=";
|
||||||
|
};
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
"${finalAttrs.src}/patches/monado/0001-c-multi-disable-dropping-of-old-frames.patch"
|
||||||
|
"${finalAttrs.src}/patches/monado/0002-ipc-server-Always-listen-to-stdin.patch"
|
||||||
|
"${finalAttrs.src}/patches/monado/0003-c-multi-Don-t-log-frame-time-diff.patch"
|
||||||
|
"${finalAttrs.src}/patches/monado/0005-distortion-images.patch"
|
||||||
|
"${finalAttrs.src}/patches/monado/0008-Use-mipmaps-for-distortion-shader.patch"
|
||||||
|
"${finalAttrs.src}/patches/monado/0009-convert-to-YCbCr-in-monado.patch"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
strictDeps = true;
|
||||||
|
|
||||||
|
postUnpack = ''
|
||||||
|
# Let's make sure our monado source revision matches what is used by WiVRn upstream
|
||||||
|
ourMonadoRev="${finalAttrs.monado.src.rev}"
|
||||||
|
theirMonadoRev=$(grep "GIT_TAG" ${finalAttrs.src.name}/CMakeLists.txt | awk '{print $2}')
|
||||||
|
if [ ! "$theirMonadoRev" == "$ourMonadoRev" ]; then
|
||||||
|
echo "Our Monado source revision doesn't match CMakeLists.txt." >&2
|
||||||
|
echo " theirs: $theirMonadoRev" >&2
|
||||||
|
echo " ours: $ourMonadoRev" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
cmake
|
||||||
|
git
|
||||||
|
glslang
|
||||||
|
pkg-config
|
||||||
|
python3
|
||||||
|
] ++ lib.optionals cudaSupport [ autoAddDriverRunpath ];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
avahi
|
||||||
|
boost
|
||||||
|
cli11
|
||||||
|
eigen
|
||||||
|
ffmpeg
|
||||||
|
freetype
|
||||||
|
glm
|
||||||
|
harfbuzz
|
||||||
|
libdrm
|
||||||
|
libGL
|
||||||
|
libva
|
||||||
|
libX11
|
||||||
|
libXrandr
|
||||||
|
libpulseaudio
|
||||||
|
nlohmann_json
|
||||||
|
onnxruntime
|
||||||
|
openxr-loader
|
||||||
|
pipewire
|
||||||
|
shaderc
|
||||||
|
spdlog
|
||||||
|
systemd
|
||||||
|
udev
|
||||||
|
vulkan-headers
|
||||||
|
vulkan-loader
|
||||||
|
vulkan-tools
|
||||||
|
x264
|
||||||
|
] ++ lib.optionals cudaSupport [ cudaPackages.cudatoolkit ];
|
||||||
|
|
||||||
|
cmakeFlags = [
|
||||||
|
(lib.cmakeBool "WIVRN_USE_VAAPI" true)
|
||||||
|
(lib.cmakeBool "WIVRN_USE_X264" true)
|
||||||
|
(lib.cmakeBool "WIVRN_USE_NVENC" cudaSupport)
|
||||||
|
(lib.cmakeBool "WIVRN_USE_SYSTEMD" true)
|
||||||
|
(lib.cmakeBool "WIVRN_USE_PIPEWIRE" true)
|
||||||
|
(lib.cmakeBool "WIVRN_USE_PULSEAUDIO" true)
|
||||||
|
(lib.cmakeBool "WIVRN_BUILD_CLIENT" false)
|
||||||
|
(lib.cmakeBool "WIVRN_OPENXR_INSTALL_ABSOLUTE_RUNTIME_PATH" true)
|
||||||
|
(lib.cmakeBool "FETCHCONTENT_FULLY_DISCONNECTED" true)
|
||||||
|
(lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_MONADO" "${finalAttrs.monado}")
|
||||||
|
];
|
||||||
|
|
||||||
|
passthru.updateScript = nix-update-script { };
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "An OpenXR streaming application to a standalone headset";
|
||||||
|
homepage = "https://github.com/Meumeu/WiVRn/";
|
||||||
|
changelog = "https://github.com/Meumeu/WiVRn/releases/";
|
||||||
|
license = licenses.gpl3Only;
|
||||||
|
maintainers = with maintainers; [ passivelemon ];
|
||||||
|
platforms = platforms.linux;
|
||||||
|
mainProgram = "wivrn-server";
|
||||||
|
};
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user