A new start

This commit is contained in:
Harald Hoyer 2024-03-21 15:00:36 +01:00
commit f4e2368893
93 changed files with 7621 additions and 0 deletions

65
lib/audio/default.nix Normal file
View file

@ -0,0 +1,65 @@
{ lib }:
rec {
## Renames an alsa device from a given `name` using the new `description`.
##
#@ { name: String, description: String } -> { matches: List, apply_properties: Attrs }
mkAlsaRename = { name, description }: {
matches = [
[
[ "device.name" "matches" name ]
]
];
# actions = { "update-props" = { "node.description" = description; }; };
apply_properties = {
"device.description" = description;
};
};
## Create a pipewire audio node.
##
#@ { name: String, factory: String ? "adapter", ... } -> { factory: String, args: Attrs }
mkAudioNode = args@{ name, factory ? "adapter", ... }: {
inherit factory;
args = (builtins.removeAttrs args [ "name" "description" ]) // {
"node.name" = name;
"node.description" = args.description or args."node.description";
"factory.name" = args."factory.name" or "support.null-audio-sink";
};
};
## Create a virtual pipewire audio node.
##
#@ { name: String, ... } -> { factory: "adapter", args: Attrs }
mkVirtualAudioNode = args@{ name, ... }:
mkAudioNode (args // {
name = "virtual-${lib.toLower name}-audio";
description = "${name} (Virtual)";
"media.class" = args.class or args."media.class" or "Audio/Duplex";
"object.linger" = args."object.linger" or true;
"audio.position" = args."audio.position" or [ "FL" "FR" ];
"monitor.channel-volumes" = args."monitor.channel-volumes" or true;
});
## Connect two pipewire audio nodes
##
#@ { name: String?, from: String, to: String, ... } -> { name: "libpipewire-module-loopback", args: Attrs }
mkBridgeAudioModule = args@{ from, to, ... }: {
name = "libpipewire-module-loopback";
args = (builtins.removeAttrs args [ "from" "to" "name" ]) // {
"node.name" =
if args ? name then
"${args.name}-bridge"
else
"${lib.toLower from}-to-${lib.toLower to}-bridge";
"audio.position" = args."audio.position" or [ "FL" "FR" ];
"capture.props" = {
"node.target" = from;
} // (args."capture.props" or { });
"playback.props" = {
"node.target" = to;
"monitor.channel-volumes" = true;
} // (args."playback.props" or { });
};
};
}

20
lib/default.nix Normal file
View file

@ -0,0 +1,20 @@
{ lib, inputs, snowfall-inputs }:
rec {
## Override a package's metadata
##
## ```nix
## let
## new-meta = {
## description = "My new description";
## };
## in
## lib.override-meta new-meta pkgs.hello
## ```
##
#@ Attrs -> Package -> Package
override-meta = meta: package:
package.overrideAttrs (attrs: {
meta = (attrs.meta or { }) // meta;
});
}

51
lib/deploy/default.nix Normal file
View file

@ -0,0 +1,51 @@
{ lib, inputs }:
let
inherit (inputs) deploy-rs;
in
rec {
## Create deployment configuration for use with deploy-rs.
##
## ```nix
## mkDeploy {
## inherit self;
## overrides = {
## my-host.system.sudo = "doas -u";
## };
## }
## ```
##
#@ { self: Flake, overrides: Attrs ? {} } -> Attrs
mkDeploy = { self, overrides ? { } }:
let
hosts = self.nixosConfigurations or { };
names = builtins.attrNames hosts;
nodes = lib.foldl
(result: name:
let
host = hosts.${name};
user = host.config.metacfg.user.name or null;
inherit (host.pkgs) system;
in
result // {
${name} = (overrides.${name} or { }) // {
hostname = overrides.${name}.hostname or "${name}";
profiles = (overrides.${name}.profiles or { }) // {
system = (overrides.${name}.profiles.system or { }) // {
path = deploy-rs.lib.${system}.activate.nixos host;
} // lib.optionalAttrs (user != null) {
user = "root";
sshUser = user;
} // lib.optionalAttrs
(host.config.metacfg.security.doas.enable or false)
{
sudo = "doas -u";
};
};
};
})
{ }
names;
in
{ inherit nodes; };
}

25
lib/file/default.nix Normal file
View file

@ -0,0 +1,25 @@
{ lib, ... }:
rec {
## Append text to the contents of a file
##
## ```nix
## fileWithText ./some.txt "appended text"
## ```
##
#@ Path -> String -> String
fileWithText = file: text: ''
${builtins.readFile file}
${text}'';
## Prepend text to the contents of a file
##
## ```nix
## fileWithText' ./some.txt "prepended text"
## ```
##
#@ Path -> String -> String
fileWithText' = file: text: ''
${text}
${builtins.readFile file}'';
}

62
lib/module/default.nix Normal file
View file

@ -0,0 +1,62 @@
{ lib, ... }:
with lib; rec {
## Create a NixOS module option.
##
## ```nix
## lib.mkOpt nixpkgs.lib.types.str "My default" "Description of my option."
## ```
##
#@ Type -> Any -> String
mkOpt = type: default: description:
mkOption { inherit type default description; };
## Create a NixOS module option without a description.
##
## ```nix
## lib.mkOpt' nixpkgs.lib.types.str "My default"
## ```
##
#@ Type -> Any -> String
mkOpt' = type: default: mkOpt type default null;
## Create a boolean NixOS module option.
##
## ```nix
## lib.mkBoolOpt true "Description of my option."
## ```
##
#@ Type -> Any -> String
mkBoolOpt = mkOpt types.bool;
## Create a boolean NixOS module option without a description.
##
## ```nix
## lib.mkBoolOpt true
## ```
##
#@ Type -> Any -> String
mkBoolOpt' = mkOpt' types.bool;
enabled = {
## Quickly enable an option.
##
## ```nix
## services.nginx = enabled;
## ```
##
#@ true
enable = true;
};
disabled = {
## Quickly disable an option.
##
## ```nix
## services.nginx = enabled;
## ```
##
#@ false
enable = false;
};
}

54
lib/network/default.nix Normal file
View file

@ -0,0 +1,54 @@
{ lib, inputs, snowfall-inputs }:
let
inherit (inputs.nixpkgs.lib) assertMsg last;
in
{
network = {
# Split an address to get its host name or ip and its port.
# Type: String -> Attrs
# Usage: get-address-parts "bismuth:3000"
# result: { host = "bismuth"; port = "3000"; }
get-address-parts = address:
let
address-parts = builtins.split ":" address;
ip = builtins.head address-parts;
host = if ip == "" then "127.0.0.1" else ip;
port = if builtins.length address-parts != 3 then "" else last address-parts;
in
{ inherit host port; };
## Create proxy configuration for NGINX virtual hosts.
##
## ```nix
## services.nginx.virtualHosts."example.com" = lib.network.create-proxy {
## port = 3000;
## host = "0.0.0.0";
## proxy-web-sockets = true;
## extra-config = {
## forceSSL = true;
## };
## }
## ``
##
#@ { port: Int ? null, host: String ? "127.0.0.1", proxy-web-sockets: Bool ? false, extra-config: Attrs ? { } } -> Attrs
create-proxy =
{ port ? null
, host ? "127.0.0.1"
, proxy-web-sockets ? false
, extra-config ? { }
}:
assert assertMsg (port != "" && port != null) "port cannot be empty";
assert assertMsg (host != "") "host cannot be empty";
extra-config // {
locations = (extra-config.locations or { }) // {
"/" = (extra-config.locations."/" or { }) // {
proxyPass =
"http://${host}${if port != null then ":${builtins.toString port}" else ""}";
proxyWebsockets = proxy-web-sockets;
};
};
};
};
}