dragnpkgs/README.md

20 KiB

Table of Contents

dragnpkgs

this is my personal nixos modules and packages repository. while it was designed for my own use, it's also intended to be flexible and reusable enough for general purpose usage

dragnpkgs provides the following

  • a set of package definitions, in pkgs/, which provide packages not in nixpkgs, some of my own libraries and utilities, and rewrites/patches of upstream packages to suit my needs
    • the top level overlay is located in overlay.nix, in a similar style as nixpkgs all-packages.nix
  • a set of nixos modules, in modules/
    • a module including all of the other modules is located at module.nix
  • utilities, in lib/ and contained within flake.nix
  • flake templates, in templates/
  • a full wrapper around nixpkgs which includes the package set and nixos modules by default, and changes the default nix implementation to lix, so this repo can be used in place of the nixpkgs flake

licensing

this repository is NOT licensed under a "standard" FOSS license. instead, it uses CC-BY-NC-SA 4.0. this means, in particular that commercial use is forbidden. if you are, for whatever reason, interested in using this code commercially, please contact me

additionally, several package definitions included in this repo point to packages which have their own noteworthy licensing (including, for example, unfree and non-redistributable game server software). make sure you are following the license requirements, which can be found in meta.license for each package

usage

since i use flakes now (sigh!!!) i'm not supporting non-flake usage anymore. if you read the files in the repo there's a way to do it probably

for flake usage, add this repo as an input and don't input nixpkgs at all, since we fully wrap it

{
  inputs = {
    # for nixos-25.05
    dragnpkgs.url = "git+https://git.lain.faith/haskal/dragnpkgs.git?ref=nixos-25.05";

    # for nixos-unstable
    dragnpkgs.url = "git+https://git.lain.faith/haskal/dragnpkgs.git?ref=main";
  };

  outputs = { self, dragnpkgs, ... }: {
    nixosConfigurations.mycomputer = dragnpkgs.lib.nixosSystem {
      ...
    };
  };
}

note that the dragnpkgs module sets a couple defaults -- see module.nix and the inline modules in flake.nix for details

  • disables nixpkgs self-registration in the flake registry and nix path and enables a dragnpkgs-specific registration mechanism for these that is enabled by default, see options.dragnpkgs
  • in flake.nix but not in module.nix: disable channels
  • enable experimental features nix-command flakes repl-flake
  • disable the default flake registry. i think it's cringe
  • add a repl overlay that adds some useful utilities to nix repl -- see repl-overlay.nix for details
  • provides a flake pure eval mode bypass via a lix plugin for allowlisting certain unfree licenses that can be enabled when the user has permission to use packages with those licenses. this allows usage of those packages without needing to set NIXPKGS_ALLOW_UNFREE=1 and passing --impure, which i find very clunky

also note that overriding inputs to the flake won't necessarily work because of the way nixpkgs registers itself with the system. this requires really annoying hacks to get working at all. if you want to depend on dragnpkgs with a different version of nixpkgs (ie not 24.11 or unstable), clone the repo and recreate flake.lock. aren't flakes so cool and fun!!!!

flake lib documentation

These utilities are provided by the dragnpkgs flake.

dragnpkgs.lib.mkFlake attrs

This provides a small utility for defining flakes in a way that avoids some of the pain related to flake attributes being keyed by system. attrs is an attribute set similar to what would normally be returned for outputs, but the keys packages, legacyPackages, devShells, and apps are written in callPackage style

For example:

outputs = { self, dragnpkgs }: dragnpkgs.lib.mkFlake {
  devShells.default = {
    mkShell,
    hello,
  }: mkShell {
    packages = [
      hello
    ];
  };
};

Currently there is no mechanism to access system-keyed attributes from another system-keyed attribute, so it must be done manually using system in the arguments to the callPackage-style function. For example:

outputs = { self, dragnpkgs }: dragnpkgs.lib.mkFlake {
  packages.default = {
    stdenv,
    mydependency,
  }: stdenv.mkDerivation {
    pname = "mypackage";
    version = "DEV";

    src = ./.;

    buildInputs = [ mydependency ];
  };

  devShells.default = {
    mkShell,
    system,
  }: mkShell {
    packages = [
      self.packages.${system}.default
    ];
  };
};

Future work is planned to make this easier.

lib documentation

These utilities are provided by the dragnpkgs overlay

fetchFromSteam

a fetcher that downloads binaries from Steam using DepotDownloader. this is intended for game servers that are distributed via Steam. use SteamDB to get the needed IDs.

Usage:

pkgs.fetchFromSteam {
  name = "..."; # optional
  appId = "...";
  depot = {
    depotId = "...";
    manifestId = "...";
    beta = "..."; # optional
  };

  additionalDepots = [
    # same format as the main `depot`
    # use this to include eg the steamworks redistributable depot
  ];

  hash = pkgs.lib.fakeHash;
}

fetchb4

A fetcher that uses b4 to download patchsets from https://lore.kernel.org so that they can be applied in boot.kernelPatches

Usage:

pkgs.fetchb4 {
  msgid = "2024042069.1337-example@example";
  hash = pkgs.lib.fakeHash;

  # optional args
  version = "3"; # default: latest
  single_message = true; # default: false
}

note that not specifying a version may make cause future invocations to return different output if a newer version is sent to the thread

mkNginxServer

creates a shell script that launches nginx in the foreground as the current user. the nginx is configured to run an http server on localhost:8080 with the given siteConfig

example:

pkgs.mkNginxServer {
  siteConfig = ''
    location / {
      root path/to/development_site_root;
      error_page 404 /404.html;
    }
  '';
}

makeSquashFs

builds a squashfs image from the given derivations

example

makeSquashFs {
  filename = "my-image"; # optional
  storeContents = [ foo bar ];
}

makeHpcDist

create a packaged nix distribution with the given packages in it for weird HPC systems. go read the source to find out what it does; i don't recommend using this if you're not me

lib.licenses.fyptl

The "Fuck You, Pirate This License" (FYPTL) is the author's version of a software non-license, which explicitly does not grant any rights to use, modify, or redistribute a given piece of software, but does disclaim warranty.

nixos options documentation

documentation for nixos options provided by dragnpkgs

dragnpkgs

options for configuring dragnpkgs

dragnpkgs.setFlakeRegistry (true)

Set flake registry option pointing to self

dragnpkgs.setNixPath (true)

Set nix path entry pointing to self

dragnpkgs.setNixpkgsFlakeAlias (true)

Set flake registry entry for nixpkgs to self

dragnpkgs.setTemplatesFlakeAlias (true)

Set flake registry entry for templates to self

dragnpkgs.possiblyCommitCrimes (false)

Globally enable usage of packages marked as FYPTL. This installs a nix plugin, which is widely considered to be a nix crime, and it also might be an actual crime to use these packages depending on you jurisdiction. Use at your own risk

services.ghidra-server

the shared project server for ghidra

example usage:

services.ghidra-server = {
  enable = true;
  host = "your.domain.or.ip";
};
development notes

the module does the following:

  • sets up unix permissions on the ghidra repositories location that allows anyone in the ghidra group to run ghidra-svrAdmin to perform admin tasks
  • only supports basic username/password authentication for the time being
  • parses the classpath file for the ghidra server which is normally read by the launcher, and uses it to launch the server directly, without using the launcher. this was done because the launcher was doing several things that were unwanted / could be better handled by systemd and journald, and it was complicated to turn them off. this also allows us to customize the jvm args more easily
  • provides a log4j configuration that causes all logs to be sent to the system journal. this effectively disables any ghidra-server-specific logfile management
  • sets the most basic isolation parameters (PrivateTmp=true and NoNewPrivileges=true), but more work could be done to secure the ghidra server service

services.ghidra-server.enable

enables the ghidra server service

services.ghidra-server.enableAdminCli (true)

adds a system package for the CLI tool ghidra-svrAdmin, which allows anyone in the ghidra group to administer the server (this corresponds to the server/svrAdmin tool in the stock ghidra distribution)

services.ghidra-server.{package, jdkPackage} (ghidra_headless, openjdk21_headless)

allows overriding the ghidra package and jdk package used for the server

services.ghidra-server.host

the server hostname or IP; this is typically required (by java RMI) for correct operation

services.ghidra-server.basePort (13100)

the server will use 3 consecutive TCP ports starting from this port

services.ghidra-server.directory (ghidra-server)

the root directory for server files, as a subdirectory of /var/lib. this is needed because this option is passed to systemd StateDirectory=

services.ghidra-server.{user,group} (ghidra)

the service user and group

environment.machineInfo

provides options to customize the /etc/machine-info file on a NixOS system. See the module itself and https://www.freedesktop.org/software/systemd/man/latest/machine-info.html for more info

services.satisfactory

The dedicated server for the game Satisfactory

This module provides the needed runtime environment for the dedicated server to run on NixOS, as well as settings which can be automatically applied to provision the server on the first start (eg server name, admin password). This provisioning needs to be done at runtime, due to the way the server works, but it will be performed securely, before the server is exposed to the network for the first time. This means you can safely deploy the server to the public internet without worrying about exposing the "unclaimed" initial server mode, where any user could gain full privileges.

development notes

this module does the following:

  • sets up satisfactory.service with some systemd isolation options and notably, a private mount namespace in which the nix store path for the server is mounted together with some overmounts for read-write directories within the installation. this allows the software to "write to its own install directory" which is required for operation. the real location of the written files is in /var/lib/satisfactory
  • if certs are provided, the systemd credentials mechanism is used to make them available to the server process. another bind overmount is used to put the credentials dir in the place that the server binary expects. additionally, satisfactory-restart-certs.service is configured to restart the dedicated server whenever the cert is renewed
  • when the first-run options are specified, satisfactory-first-time-setup.service is configured as a dependency with a condition on the data file the server uses to store its settings. if the file exists, the first-run setup is skipped. in this service, PrivateNetwork=true is used to isolate the service from the network while a bash script executes HTTP API calls to perform the requested setup. once this is done, the server is shut down and execution will proceed to the main satisfactory.service

this is mostly still in line with a blog post i wrote on the topic but there have been some changes since then that are not reflected in the post

services.satisfactory.enable

enables the satisfactory dedicated server service

services.satisfactory.package (pkgs.satisfactory-dedicated-server)

the package to use for the service

services.satisfactory.directory ("/var/lib/satisfactory")

Directory where Satisfactory Dedicated Server data will be stored

services.satisfactory.{user,group} ("satisfactory")

User account and group under which Satisfactory Dedicated Server runs

services.satisfactory.useACMEHost (null)

If set, the server will use the ACME-provided TLS certificate for the given host.

Note that this module does not actually provision the specified certificate; you must use additional config (e.g., services.nginx.virtualHosts.<name>.enableACME = true) to provision the certificate using a supported ACME method.

services.satisfactory.port (7777)

Server port number (TCP/UDP)

This corresponds to the -Port command line option.

services.satisfactory.reliablePort (8888)

Server reliable port number

This corresponds to the -ReliablePort command line option.

services.satisfactory.externalReliablePort (null)

Server reliable port number as seen outside NAT.

This corresponds to the -ExternalReliablePort command line option.

services.satisfactory.disableSeasonalEvents (false)

Whether to run the server with seasonal events disabled.

This corresponds to the -DisableSeasonalEvents command line option.

services.satisfactory.extraIniOptions ({})

Run the server with additional ini configuration values.

This is a nested attribute set of values.

  • The top level attribute specifies the ini file containing the value to set (i.e., the first component of the -ini command line option), for example Game or Engine.
  • The secondary level attribute specifies the ini file category, without brackets, for example /Script/Engine.GameSession.
  • The final level attribute specifies the option name to set, for example MaxPlayers. The value of the attribute is the value to set on the command line.

This corresponds to the -ini command line option.

services.satisfactory.initialSettings

Settings to apply to the server via the server API on the first run.

services.satisfactory.initialSettings.serverName (null)

The name of the server.

If this is provided, adminPasswordFile must also be set.

services.satisfactory.initialSettings.adminPasswordFile (null)

Path to a file containing the initial admin password.

If this is provided, serverName must also be set.

services.satisfactory.initialSettings.clientPasswordFile (null)

Path to a file containing the initial client password. If not set, the server will not be configured with a client password and will be accessible to any client.

hardware.wirelessRegulatoryDomain

The wireless regulatory domain to set in the kernel cfg80211 module. This defaults to "00" (international), but more bands (such as 6GHz, on supported hardware) can be enabled by setting this to the jurisdiction in which the machine is located, for example "US".

packages documentation

ghidra

a version of ghidra that uses a split derivation, lib contains the core ghidra distribution, doc contains all the documentation elements, and out contains the bin folder, icons, and desktop file. only out has a dependency on the build jdk, so lib and doc can be used with reduced closure size

ghidra_headless

a variant of ghidra which does not have a dependency on any jdk, intended to reduce closure size for server operation with a headless jdk (in particular, the ghidra-server nixos module uses ghidra_headless with openjdk21_headless by default

this is equivalent to the lib output of the split ghidra package

ocamlPackages.ppx_unicode

opinionated ppx for string literals: https://git.lain.faith/haskal/ppx_unicode

ocamlPackages.xlog

logging for cats, in ocaml: https://git.lain.faith/haskal/xlog

ocamlPackages.systemd-ml

libsystemd implementation in native ocaml: https://git.lain.faith/haskal/systemd-ml

ocamlPackages.ocaml-manual

the ocaml html docs package from opam

python312Packages.feedvalidator or feedvalidator

the W3C atom/RSS feed validator library, https://github.com/w3c/feedvalidator

this package comes with an additional CLI bin, feedvalidator, which is a simple wrapper around the library that enables CLI usage

usage

usage: feedvalidator [-h] [-b BASE] file

W3C feedvalidator

positional arguments:
  file                  File to validate

options:
  -h, --help            show this help message and exit
  -b BASE, --base BASE  Base URL of document

example

feedvalidator --base "https://my-base-url/atom.xml" path/to/atom.xml

python312Packages.megacom or megacom

a python utility to access serial ports from the command line

outer-wilds-text-adventure

nix packaging for the Outer Wilds text adventure game. it should work by default on NixOS. if using the nix package manager on a non-NixOS computer, you also need the following when using pipewire or another ALSA plugin that lives in a separate package

export ALSA_PLUGIN_DIR=$(nix eval -f '<nixpkgs>' --raw pipewire)/lib/alsa-lib

satisfactory-dedicated-server

The dedicated server for Satisfactory, with packaging steps to make it run correctly on NixOS. This must be used together with the NixOS module (services.satisfactory), which sets up the environment needed for the server to execute.

See services.satisfactory for further info and development notes

eta

Generic tool for monitoring ETA and progress of an arbitrary process.

https://github.com/aioobe/eta

zbasefind

Command line tool to guess the base address of a raw firmware binary (zoomer edition).

https://git.lain.faith/haskal/zbasefind.git

cado-nfs

Cado-NFS, An Implementation of the Number Field Sieve Algorithm

https://gitlab.inria.fr/cado-nfs/cado-nfs

lix-plugins

A plugin module for lix which provides the flake pure eval bypass which can be enabled using the dragnpkgs flake.

zfs_2_3

A version of ZFS with a patch for the zed userspace daemon to enable desktop notifications on ZFS errors. This makes ZFS a bit more reasonable to run on GUI systems

pympress

A version of pympress with a patch to fix the window icon on KDE

texliveDragonPackages.moloch

A version of the moloch beamer theme with some patches to make it easier to use with pympress and fix an issue with appendix slide numbering