Unverified Commit 61353634 authored by Sandro Jäckel's avatar Sandro Jäckel Committed by GitHub
Browse files

reframe: init at 1.15.1, nixos/reframe: init (#512159)

parents 91cbfc39 98831cfb
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -129,6 +129,8 @@

- [RSSHub](https://github.com/DIYgod/RSSHub), a service to convert many sources into rss. Available as `services.rsshub`.

- [ReFrame](https://github.com/AlynxZhou/reframe), a DRM/KMS based remote desktop for Linux that supports Wayland/NVIDIA/headless/login.

- [Komodo Periphery](https://github.com/moghtech/komodo), a multi-server Docker and Git deployment agent by Komodo. Available as [services.komodo-periphery](#opt-services.komodo-periphery.enable).

- [Shoko](https://shokoanime.com), an anime management system. Available as [services.shoko](#opt-services.shoko.enable).
+190 −0
Original line number Diff line number Diff line
{
  lib,
  pkgs,
  config,
  ...
}:
let
  cfg = config.services.reframe;
  iniFmt = pkgs.formats.ini { };
in
{
  options.programs.reframe = {
    enable = lib.mkEnableOption "DRM/KMS based remote desktop for Linux that supports Wayland/NVIDIA/headless/login…";
    package = lib.mkPackageOption pkgs "reframe" { };
    configs = lib.mkOption {
      type = lib.types.attrsOf (
        lib.types.submodule {
          options = {
            reframe = {
              card = lib.mkOption {
                type = lib.types.str;
                default = "";
                description = "Select monitor via DRM card. All available cards and connectors can be found in `/sys/class/drm/`.";
                example = "card0";
              };
              connector = lib.mkOption {
                type = lib.types.str;
                default = "";
                description = "Select monitor via connector. All available cards and connectors can be found in `/sys/class/drm/`.";
                example = "eDP-1";
              };
              rotation = lib.mkOption {
                type = lib.types.enum [
                  0
                  90
                  180
                  270
                ];
                default = 0;
                description = ''
                  This is the angle you rotate the monitor, not the angle of display content relative to the monitor!
                  Valid angles are clockwise `0`, `90`, `180`, `270`.
                '';
              };
              desktop-width = lib.mkOption {
                type = lib.types.int;
                default = 0;
                description = ''
                  If you have more than 1 monitor, set those values to the logical size of the whole virtual desktop.
                  You can get those value by finding the pointer position of the right most and bottom most border of your monitors.
                '';
              };
              desktop-height = lib.mkOption {
                type = lib.types.int;
                default = 0;
                description = ''
                  If you have more than 1 monitor, set those values to the logical size of the whole virtual desktop.
                  You can get those value by finding the pointer position of the right most and bottom most border of your monitors.
                '';
              };
              monitor-x = lib.mkOption {
                type = lib.types.int;
                default = 0;
                description = ''
                  If you have more than 1 monitor, set those values to the logical position of the top left corner of your selected monitor.
                '';
              };
              monitor-y = lib.mkOption {
                type = lib.types.int;
                default = 0;
                description = ''
                  If you have more than 1 monitor, set those values to the logical position of the top left corner of your selected monitor.
                '';
              };
              default-width = lib.mkOption {
                type = lib.types.int;
                default = 0;
                description = ''
                  If your client does not support resizing, use those to force a size. Empty or `0` means monitor size.
                '';
              };
              default-height = lib.mkOption {
                type = lib.types.int;
                default = 0;
                description = ''
                  If your client does not support resizing, use those to force a size. Empty or `0` means monitor size.
                '';
              };
              resize = lib.mkOption {
                type = lib.types.bool;
                default = true;
                description = ''
                  Set to `false` to prohibit client resizing.
                '';
              };
              cursor = lib.mkOption {
                type = lib.types.bool;
                default = true;
                description = ''
                  Set to `false` to ignore DRM cursor plane.
                '';
              };
              wakeup = lib.mkOption {
                type = lib.types.bool;
                default = true;
                description = ''
                  Set to `false` if you already disabled automatic screen blank.
                '';
              };
              damage = lib.mkOption {
                type = lib.types.enum [
                  ""
                  "cpu"
                  "gpu"
                ];
                default = true;
                description = ''
                  Set to `gpu` to use GPU damage region detection, which may be more efficiency but may cause artifacts depending on GPU vendors.
                  Set to `cpu` to use CPU damage region detection if you get bugs with `gpu`.
                  Empty to disable damage region detection, which may require higher network bandwidth.
                '';
              };
              fps = lib.mkOption {
                type = lib.types.int;
                default = 30;
              };
            };
            vnc = {
              ip = lib.mkOption {
                type = lib.types.str;
                default = "";
                description = ''
                  Empty means accept all incoming connections.
                '';
              };
              port = lib.mkOption {
                type = lib.types.port;
                default = 5933;
              };
              password = lib.mkOption {
                type = lib.types.str;
                default = "";
                description = ''
                  Empty means no password.
                '';
              };
              type = lib.mkOption {
                type = lib.types.enum [
                  "libvncserver"
                  "neatvnc"
                ];
                default = "libvncserver";
                description = ''
                  Set to `neatvnc` to prefer neatvnc, which provides more efficient encoding methods but maybe more unstable.
                '';
              };
            };
          };
        }
      );
      default = { };
      description = "Configurations for ReFrame";
    };
  };

  config = lib.mkIf cfg.enable {
    environment.systemPackages = [ cfg.package ];
    systemd.packages = [ cfg.package ];
    systemd.tmpfiles.packages = [ cfg.package ];
    users.users.reframe = {
      isSystemUser = true;
      group = "reframe";
      description = "ReFrame Remote Desktop";
    };
    users.groups.reframe = { };
    environment.etc = builtins.mapAttrs' (
      name: value:
      lib.nameValuePair "reframe/${name}.conf" {
        mode = "0644";
        user = "root";
        group = "root";
        source = iniFmt.generate "${name}.conf" value;
      }
    ) cfg.configs;
  };

  meta.maintainers = with lib.maintainers; [
    bitbloxhub
  ];
}
+93 −0
Original line number Diff line number Diff line
{
  lib,
  stdenv,
  fetchFromGitHub,
  pkg-config,
  meson,
  ninja,
  cmake,
  systemd,
  glib,
  gtk4,
  libdrm,
  libepoxy,
  libxkbcommon,
  libvncserver,
  neatvnc,
  aml,
  pixman,
  zlib,
  ffmpeg,
  nix-update-script,

  withNeatVNC ? true,
}:

stdenv.mkDerivation (finalAttrs: {
  pname = "reframe";
  version = "1.15.1";

  src = fetchFromGitHub {
    owner = "AlynxZhou";
    repo = "reframe";
    tag = "v${finalAttrs.version}";
    hash = "sha256-3ZCLnmu5Idn4RsypJr+JNqIhT13/pq1Xi4wTidUgCqQ=";
    fetchSubmodules = true;
  };

  nativeBuildInputs = [
    meson
    ninja
    cmake
    pkg-config
  ];

  buildInputs = [
    systemd
    glib
    gtk4
    libdrm
    libepoxy
    libxkbcommon
    libvncserver
  ]
  ++ lib.optionals withNeatVNC [
    neatvnc
    aml
    pixman
    zlib
    ffmpeg
  ];

  passthru = {
    updateScript = nix-update-script { };
  };

  mesonFlags = [
    (lib.mesonOption "systemunitdir" "${placeholder "out"}/lib/systemd/system")
    (lib.mesonOption "sysusersdir" "${placeholder "out"}/lib/sysusers.d")
    (lib.mesonOption "tmpfilesdir" "${placeholder "out"}/lib/tmpfiles.d")
  ]
  ++ lib.optionals withNeatVNC [ (lib.mesonOption "neatvnc" "true") ];

  postPatch = ''
    chmod +x meson_post_install.sh
    patchShebangs meson_post_install.sh

    # Comment out all commands, all systemd reloading
    sed -i '1,2! s/^/# /' meson_post_install.sh
  '';

  strictDeps = true;
  __structuredAttrs = true;

  meta = {
    homepage = "https://reframe.alynx.one/";
    description = "DRM/KMS based remote desktop for Linux that supports Wayland/NVIDIA/headless/login…";
    license = lib.licenses.asl20;
    maintainers = with lib.maintainers; [
      bitbloxhub
    ];
    platforms = lib.platforms.linux;
  };
})