Merge remote-tracking branch 'origin/staging-next' into staging

This commit is contained in:
K900 2024-08-22 13:20:38 +03:00
commit 5c68540f8b
1177 changed files with 27362 additions and 18071 deletions

View File

@ -162,3 +162,6 @@ fc7a83f8b62e90de5679e993d4d49ca014ea013d
# darwin.stdenv: format with nixfmt-rfc-style (#333962)
93c10ac9e561c6594d3baaeaff2341907390d9b8
# nrr: format with nixfmt-rfc-style (#334578)
cffc27daf06c77c0d76bc35d24b929cb9d68c3c9

View File

@ -21,7 +21,7 @@ For new packages please briefly describe the package or provide a link to its ho
- [NixOS test(s)](https://nixos.org/manual/nixos/unstable/index.html#sec-nixos-tests) (look inside [nixos/tests](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests))
- and/or [package tests](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md#package-tests)
- or, for functions and "core" functionality, tests in [lib/tests](https://github.com/NixOS/nixpkgs/blob/master/lib/tests) or [pkgs/test](https://github.com/NixOS/nixpkgs/blob/master/pkgs/test)
- made sure NixOS tests are [linked](https://nixos.org/manual/nixpkgs/unstable/#ssec-nixos-tests-linking) to the relevant packages
- made sure NixOS tests are [linked](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md#linking-nixos-module-tests-to-a-package) to the relevant packages
- [ ] Tested compilation of all packages that depend on this change using `nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"`. Note: all changes have to be committed, also see [nixpkgs-review usage](https://github.com/Mic92/nixpkgs-review#usage)
- [ ] Tested basic functionality of all binary files (usually in `./result/bin/`)
- [24.11 Release Notes](https://github.com/NixOS/nixpkgs/blob/master/nixos/doc/manual/release-notes/rl-2411.section.md) (or backporting [23.11](https://github.com/NixOS/nixpkgs/blob/master/nixos/doc/manual/release-notes/rl-2311.section.md) and [24.05](https://github.com/NixOS/nixpkgs/blob/master/nixos/doc/manual/release-notes/rl-2405.section.md) Release notes)

View File

@ -83,7 +83,7 @@ jobs:
if (( "${#unformattedFiles[@]}" > 0 )); then
echo "Some new/changed Nix files are not properly formatted"
echo "Please run the following in \`nix-shell\`:"
echo "Please go to the Nixpkgs root directory, run \`nix-shell\`, then:"
echo "nixfmt ${unformattedFiles[*]@Q}"
exit 1
fi

View File

@ -3,32 +3,122 @@
Nixpkgs provides a variety of wrapper functions that help build commonly useful derivations.
Like [`stdenv.mkDerivation`](#sec-using-stdenv), each of these build helpers creates a derivation, but the arguments passed are different (usually simpler) from those required by `stdenv.mkDerivation`.
## `runCommand` {#trivial-builder-runCommand}
`runCommand :: String -> AttrSet -> String -> Derivation`
## `runCommandWith` {#trivial-builder-runCommandWith}
The result of `runCommand name drvAttrs buildCommand` is a derivation that is built by running the specified shell commands.
The function `runCommandWith` returns a derivation built using the specified command(s), in a specified environment.
By default `runCommand` runs in a stdenv with no compiler environment, whereas [`runCommandCC`](#trivial-builder-runCommandCC) uses the default stdenv, `pkgs.stdenv`.
It is the underlying base function of all [`runCommand*` variants].
The general behavior is controlled via a single attribute set passed
as the first argument, and allows specifying `stdenv` freely.
`name :: String`
: The name that Nix will append to the store path in the same way that `stdenv.mkDerivation` uses its `name` attribute.
The following [`runCommand*` variants] exist: `runCommand`, `runCommandCC`, and `runCommandLocal`.
`drvAttr :: AttrSet`
: Attributes to pass to the underlying call to [`stdenv.mkDerivation`](#chap-stdenv).
[`runCommand*` variants]: #trivial-builder-runCommand
`buildCommand :: String`
### Type {#trivial-builder-runCommandWith-Type}
```
runCommandWith :: {
name :: name;
stdenv? :: Derivation;
runLocal? :: Bool;
derivationArgs? :: { ... };
} -> String -> Derivation
```
### Inputs {#trivial-builder-runCommandWith-Inputs}
`name` (String)
: The derivation's name, which Nix will append to the store path; see [`mkDerivation`](#sec-using-stdenv).
`runLocal` (Boolean)
: If set to `true` this forces the derivation to be built locally, not using [substitutes] nor remote builds.
This is intended for very cheap commands (<1s execution time) which can be sped up by avoiding the network round-trip(s).
Its effect is to set [`preferLocalBuild = true`][preferLocalBuild] and [`allowSubstitutes = false`][allowSubstitutes].
::: {.note}
This prevents the use of [substituters][substituter], so only set `runLocal` (or use `runCommandLocal`) when certain the user will
always have a builder for the `system` of the derivation. This should be true for most trivial use cases
(e.g., just copying some files to a different location or adding symlinks) because there the `system`
is usually the same as `builtins.currentSystem`.
:::
`stdenv` (Derivation)
: The [standard environment](#chap-stdenv) to use, defaulting to `pkgs.stdenv`
`derivationArgs` (Attribute set)
: Additional arguments for [`mkDerivation`](#sec-using-stdenv).
`buildCommand` (String)
: Shell commands to run in the derivation builder.
::: {.note}
You have to create a file or directory `$out` for Nix to be able to run the builder successfully.
:::
[allowSubstitutes]: https://nixos.org/nix/manual/#adv-attr-allowSubstitutes
[preferLocalBuild]: https://nixos.org/nix/manual/#adv-attr-preferLocalBuild
[substituter]: https://nix.dev/manual/nix/latest/glossary#gloss-substituter
[substitutes]: https://nix.dev/manual/nix/2.23/glossary#gloss-substitute
::: {.example #ex-runcommandwith}
# Invocation of `runCommandWith`
```nix
runCommandWith {
name = "example";
derivationArgs.nativeBuildInputs = [ cowsay ];
} ''
cowsay > $out <<EOMOO
'runCommandWith' is a bit cumbersome,
so we have more ergonomic wrappers.
EOMOO
''
```
:::
## `runCommand` and `runCommandCC` {#trivial-builder-runCommand}
The function `runCommand` returns a derivation built using the specified command(s), in the `stdenvNoCC` environment.
`runCommandCC` is similar but uses the default compiler environment. To minimize dependencies, `runCommandCC`
should only be used when the build command needs a C compiler.
`runCommandLocal` is also similar to `runCommand`, but forces the derivation to be built locally.
See the note on [`runCommandWith`] about `runLocal`.
[`runCommandWith`]: #trivial-builder-runCommandWith
### Type {#trivial-builder-runCommand-Type}
```
runCommand :: String -> AttrSet -> String -> Derivation
runCommandCC :: String -> AttrSet -> String -> Derivation
runCommandLocal :: String -> AttrSet -> String -> Derivation
```
### Input {#trivial-builder-runCommand-Input}
While the type signature(s) differ from [`runCommandWith`], individual arguments with the same name will have the same type and meaning:
`name` (String)
: The derivation's name
`derivationArgs` (Attribute set)
: Additional parameters passed to [`mkDerivation`]
`buildCommand` (String)
: The command(s) run to build the derivation.
::: {.example #ex-runcommand-simple}
# Invocation of `runCommand`
```nix
(import <nixpkgs> {}).runCommand "my-example" {} ''
runCommand "my-example" {} ''
echo My example command is running
mkdir $out
@ -49,18 +139,24 @@ By default `runCommand` runs in a stdenv with no compiler environment, whereas [
```
:::
## `runCommandCC` {#trivial-builder-runCommandCC}
This works just like `runCommand`. The only difference is that it also provides a C compiler in `buildCommand`'s environment. To minimize your dependencies, you should only use this if you are sure you will need a C compiler as part of running your command.
## `runCommandLocal` {#trivial-builder-runCommandLocal}
Variant of `runCommand` that forces the derivation to be built locally, it is not substituted. This is intended for very cheap commands (<1s execution time). It saves on the network round-trip and can speed up a build.
::: {.note}
This sets [`allowSubstitutes` to `false`](https://nixos.org/nix/manual/#adv-attr-allowSubstitutes), so only use `runCommandLocal` if you are certain the user will always have a builder for the `system` of the derivation. This should be true for most trivial use cases (e.g., just copying some files to a different location or adding symlinks) because there the `system` is usually the same as `builtins.currentSystem`.
`runCommand name derivationArgs buildCommand` is equivalent to
```nix
runCommandWith {
inherit name derivationArgs;
stdenv = stdenvNoCC;
} buildCommand
```
Likewise, `runCommandCC name derivationArgs buildCommand` is equivalent to
```nix
runCommandWith {
inherit name derivationArgs;
} buildCommand
```
:::
## Writing text files {#trivial-builder-text-writing}
Nixpkgs provides the following functions for producing derivations which write text files or executable scripts into the Nix store.

View File

@ -232,6 +232,14 @@ To add a new plugin, run `nix-shell -p vimPluginsUpdater --run 'vim-plugins-upda
Finally, there are some plugins that are also packaged in nodePackages because they have Javascript-related build steps, such as running webpack. Those plugins are not listed in `vim-plugin-names` or managed by `vimPluginsUpdater` at all, and are included separately in `overrides.nix`. Currently, all these plugins are related to the `coc.nvim` ecosystem of the Language Server Protocol integration with Vim/Neovim.
### Plugin optional configuration {#vim-plugin-required-snippet}
Some plugins require specific configuration to work. We choose not to
patch those plugins but expose the necessary configuration under
`PLUGIN.passthru.initLua` for neovim plugins. For instance, the `unicode-vim` plugin
needs the path towards a unicode database so we expose the following snippet `vim.g.Unicode_data_directory="${self.unicode-vim}/autoload/unicode"` under `vimPlugins.unicode-vim.passthru.initLua`.
## Updating plugins in nixpkgs {#updating-plugins-in-nixpkgs}
Run the update script with a GitHub API token that has at least `public_repo` access. Running the script without the token is likely to result in rate-limiting (429 errors). For steps on creating an API token, please refer to [GitHub's token documentation](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token).

View File

@ -0,0 +1,102 @@
# Build Support {#sec-build-support}
## `pkgs.substitute` {#pkgs-substitute}
`pkgs.substitute` is a wrapper around [the `substitute` Bash function](#fun-substitute) in the standard environment.
It replaces strings in `src` as specified by the `substitutions` argument.
:::{.example #ex-pkgs-substitute}
# Usage of `pkgs.substitute`
In a build script, the line:
```bash
substitute $infile $outfile --replace-fail @foo@ ${foopkg}/bin/foo
```
is equivalent to:
```nix
{ substitute, foopkg }:
substitute {
src = ./sourcefile.txt;
substitutions = [
"--replace"
"@foo@"
"${foopkg}/bin/foo"
];
}
```
:::
## `pkgs.substituteAll` {#pkgs-substituteall}
`pkgs.substituteAll` substitutes all instances of `@varName@` (`@`s included) in file `src` with the value of the corresponding environment variable.
As this uses the [`substituteAll`] (#fun-substitute) function, its limitations regarding variable names that will or will not be replaced also apply here.
:::{.example #ex-pkgs-substituteAll}
# Usage of `pkgs.substituteAll`
If `say-goodbye.sh` contains the following:
```bash
#! @bash@/bin/bash
echo @unchanged@
@hello@/bin/hello --greeting @greeting@
```
the following derivation will make substitutions to `@bash@`, `@hello@`, and `@greeting@`:
```nix
{
substituteAll,
bash,
hello,
}:
substituteAll {
src = ./say-goodbye.sh;
env = {
inherit bash hello;
greeting = "goodbye";
};
}
```
such that `$out` will result in something like the following:
```
#! /nix/store/s30jrpgav677fpc9yvkqsib70xfmx7xi-bash-5.2p26/bin/bash
echo @unchanged@
/nix/store/566f5isbvw014h7knmzmxa5l6hshx43k-hello-2.12.1/bin/hello --greeting goodbye
```
:::
## `pkgs.substituteAllFiles` {#pkgs-substituteallfiles}
`pkgs.substituteAllFiles` replaces `@varName@` with the value of the environment variable `varName`.
It expects `src` to be a directory and requires a `files` argument that specifies which files will be subject to replacements; only these files will be placed in `$out`.
As it also uses the `substituteAll` function, it is subject to the same limitations on environment variables as discussed in [pkgs.substituteAll](#pkgs-substituteall).
:::{.example #ex-pkgs-substitute-all-files}
# Usage of `pkgs.substituteAllFiles`
If the current directory contains `{foo,bar,baz}.txt` and the following `default.nix`
```nix
{ substituteAllFiles }:
substituteAllFiles {
src = ./.;
files = [
"foo.txt"
"bar.txt"
];
hello = "there";
}
```
in the resulting derivation, every instance of `@hello@` will be replaced with `there` in `$out/foo.txt` and` `$out/bar.txt`; `baz.txt` will not be processed nor will it appear in `$out`.
:::

View File

@ -27,4 +27,5 @@ urxvt.section.md
vcpkg.section.md
weechat.section.md
xorg.section.md
build-support.md
```

View File

@ -219,7 +219,7 @@ rec {
else "(${t.description})";
# When adding new types don't forget to document them in
# nixos/doc/manual/development/option-types.xml!
# nixos/doc/manual/development/option-types.section.md!
types = rec {
raw = mkOptionType {

View File

@ -963,6 +963,12 @@
matrix = "@alexshpilkin:matrix.org";
name = "Alexander Shpilkin";
};
AlexSKaye = {
email = "AlexSKaye@proton.me";
github = "AlexSKaye";
githubId = 3017212;
name = "Alex S. Kaye";
};
alexvorobiev = {
email = "alexander.vorobiev@gmail.com";
github = "alexvorobiev";
@ -2702,6 +2708,14 @@
githubId = 5700358;
name = "Thomas Blank";
};
bleetube = {
email = "git@blee.tube";
matrix = "@blee:satstack.cloud";
name = "Brian Lee";
github = "bleetube";
githubId = 77934086;
keys = [ { fingerprint = "4CA3 48F6 8FE1 1777 8EDA 3860 B9A2 C1B0 25EC 2C55"; } ];
};
blinry = {
name = "blinry";
email = "mail@blinry.org";
@ -3423,6 +3437,12 @@
githubId = 977929;
name = "Cody Allen";
};
Celibistrial = {
email = "ryan80222@gmail.com";
github = "Celibistrial";
githubId = 82810795;
name = "Gaurav Choudhury";
};
centromere = {
email = "nix@centromere.net";
github = "centromere";
@ -5634,7 +5654,7 @@
matrix = "@e1mo:chaos.jetzt";
github = "e1mo";
githubId = 61651268;
name = "Moritz Fromm";
name = "Nina Fromm";
keys = [ { fingerprint = "67BE E563 43B6 420D 550E DF2A 6D61 7FD0 A85B AADA"; } ];
};
eadwu = {
@ -7671,6 +7691,12 @@
githubId = 1621335;
name = "Andrew Trachenko";
};
gordon-bp = {
email = "gordy@hanakano.com";
github = "Gordon-BP";
githubId = 77560236;
name = "Gordon Clark";
};
gotcha = {
email = "gotcha@bubblenet.be";
github = "gotcha";
@ -8687,6 +8713,12 @@
githubId = 7481521;
name = "Balázs Lengyel";
};
ilaumjd = {
email = "ilaumjd@gmail.com";
github = "ilaumjd";
githubId = 16514431;
name = "Ilham AM";
};
ilian = {
email = "ilian@tuta.io";
github = "ilian";
@ -10097,6 +10129,12 @@
githubId = 15893072;
name = "Josh van Leeuwen";
};
jovandeginste = {
email = "jo.vandeginste@gmail.com";
github = "jovandeginste";
githubId = 3170771;
name = "Jo Vandeginste";
};
jpagex = {
name = "Jérémy Pagé";
email = "contact@jeremypage.me";
@ -14429,6 +14467,12 @@
githubId = 2287221;
name = "Andreas Zweili";
};
nebunebu = {
email = "neb.nebuchadnezzar@gmail.com";
github = "nebunebu";
githubId = 87451010;
name = "nebu";
};
Necior = {
email = "adrian@sadlocha.eu";
github = "Necior";
@ -15210,6 +15254,12 @@
githubId = 7397786;
name = "Odysseas Georgoudis";
};
ofalvai = {
email = "ofalvai@gmail.com";
github = "ofalvai";
githubId = 1694986;
name = "Olivér Falvai";
};
ofek = {
email = "oss@ofek.dev";
github = "ofek";
@ -15463,6 +15513,12 @@
github = "OlivierNicole";
githubId = 14031333;
};
ottoblep = {
name = "Severin Lochschmidt";
email = "seviron53@gmail.com";
github = "ottoblep";
githubId = 57066925;
};
otwieracz = {
email = "slawek@otwiera.cz";
github = "otwieracz";
@ -17182,6 +17238,12 @@
githubId = 52847440;
name = "Ryan Burns";
};
rcmlz = {
email = "haguga-nixos@yahoo.com";
github = "rcmlz";
githubId = 19784049;
name = "rcmlz";
};
rcoeurjoly = {
email = "rolandcoeurjoly@gmail.com";
github = "RCoeurjoly";
@ -18545,6 +18607,12 @@
githubId = 17243347;
name = "Sebastian Sellmeier";
};
sedlund = {
email = "scott+nixpkgs@teraton.com";
github = "sedlund";
githubId = 8109138;
name = "Scott Edlund";
};
sefidel = {
name = "sefidel";
email = "contact@sefidel.net";

View File

@ -51,6 +51,8 @@
- [Immersed VR](https://immersed.com/), a closed-source coworking platform. Available as [programs.immersed-vr](#opt-programs.immersed-vr.enable).
- [HomeBox](https://github.com/hay-kot/homebox/): the inventory and organization system built for the Home User. Available as [services.homebox](#opt-services.homebox.enable).
- [Renovate](https://github.com/renovatebot/renovate), a dependency updating tool for various git forges and language ecosystems. Available as [services.renovate](#opt-services.renovate.enable).
- [Music Assistant](https://music-assistant.io/), a music library manager for your offline and online music sources which can easily stream your favourite music to a wide range of supported players. Available as [services.music-assistant](#opt-services.music-assistant.enable).
@ -71,6 +73,8 @@
- [Playerctld](https://github.com/altdesktop/playerctl), a daemon to track media player activity. Available as [services.playerctld](option.html#opt-services.playerctld).
- [MenhirLib](https://gitlab.inria.fr/fpottier/menhir/-/tree/master/coq-menhirlib) A support library for verified Coq parsers produced by Menhir.
- [Glance](https://github.com/glanceapp/glance), a self-hosted dashboard that puts all your feeds in one place. Available as [services.glance](option.html#opt-services.glance).
- [Apache Tika](https://github.com/apache/tika), a toolkit that detects and extracts metadata and text from over a thousand different file types. Available as [services.tika](option.html#opt-services.tika).
@ -85,6 +89,9 @@
- [Proton Mail bridge](https://proton.me/mail/bridge), a desktop application that runs in the background, encrypting and decrypting messages as they enter and leave your computer. It lets you add your Proton Mail account to your favorite email client via IMAP/SMTP by creating a local email server on your computer.
- [chromadb](https://www.trychroma.com/), an open-source AI application
database. Batteries included. Available as [services.chromadb](options.html#opt-services.chromadb.enable).
## Backward Incompatibilities {#sec-release-24.11-incompatibilities}
- `transmission` package has been aliased with a `trace` warning to `transmission_3`. Since [Transmission 4 has been released last year](https://github.com/transmission/transmission/releases/tag/4.0.0), and Transmission 3 will eventually go away, it was decided perform this warning alias to make people aware of the new version. The `services.transmission.package` defaults to `transmission_3` as well because the upgrade can cause data loss in certain specific usage patterns (examples: [#5153](https://github.com/transmission/transmission/issues/5153), [#6796](https://github.com/transmission/transmission/issues/6796)). Please make sure to back up to your data directory per your usage:
@ -184,6 +191,8 @@
- `services.ddclient.use` has been deprecated: `ddclient` now supports separate IPv4 and IPv6 configuration. Use `services.ddclient.usev4` and `services.ddclient.usev6` instead.
- `services.pgbouncer` systemd service is configured with `Type=notify-reload` and allows reloading configuration without process restart. PgBouncer configuration options were moved to the free-form type option named [`services.pgbouncer.settings`](#opt-services.pgbouncer.settings) according to the NixOS RFC 0042.
- `teleport` has been upgraded from major version 15 to major version 16.
Refer to upstream [upgrade instructions](https://goteleport.com/docs/management/operations/upgrading/)
and [release notes for v16](https://goteleport.com/docs/changelog/#1600-061324).
@ -315,6 +324,8 @@
- The `services.trust-dns` module has been renamed to `services.hickory-dns`.
- The `lsh` package and the `services.lshd` module have been removed as they had no maintainer in Nixpkgs and hadnt seen an upstream release in over a decade. It is recommended to migrate to `openssh` and `services.openssh`.
## Other Notable Changes {#sec-release-24.11-notable-changes}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->

View File

@ -458,6 +458,7 @@
./services/continuous-integration/woodpecker/server.nix
./services/databases/aerospike.nix
./services/databases/cassandra.nix
./services/databases/chromadb.nix
./services/databases/clickhouse.nix
./services/databases/cockroachdb.nix
./services/databases/couchdb.nix
@ -1208,7 +1209,6 @@
./services/networking/spacecookie.nix
./services/networking/spiped.nix
./services/networking/squid.nix
./services/networking/ssh/lshd.nix
./services/networking/ssh/sshd.nix
./services/networking/sslh.nix
./services/networking/strongswan-swanctl/module.nix
@ -1418,6 +1418,7 @@
./services/web-apps/healthchecks.nix
./services/web-apps/hedgedoc.nix
./services/web-apps/hledger-web.nix
./services/web-apps/homebox.nix
./services/web-apps/honk.nix
./services/web-apps/icingaweb2/icingaweb2.nix
./services/web-apps/icingaweb2/module-monitoring.nix

View File

@ -70,6 +70,7 @@ in
(mkRemovedOptionModule [ "services" "hydron" ] "The `services.hydron` module has been removed as the project has been archived upstream since 2022 and is affected by a severe remote code execution vulnerability.")
(mkRemovedOptionModule [ "services" "ihatemoney" ] "The ihatemoney module has been removed for lack of downstream maintainer")
(mkRemovedOptionModule [ "services" "kippo" ] "The corresponding package was removed from nixpkgs.")
(mkRemovedOptionModule [ "services" "lshd" ] "The corresponding package was removed from nixpkgs as it had no maintainer in Nixpkgs and hasn't seen an upstream release in over a decades.")
(mkRemovedOptionModule [ "services" "mailpile" ] "The corresponding package was removed from nixpkgs.")
(mkRemovedOptionModule [ "services" "marathon" ] "The corresponding package was removed from nixpkgs.")
(mkRemovedOptionModule [ "services" "mathics" ] "The Mathics module has been removed")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.chromadb;
inherit (lib)
mkEnableOption
mkOption
mkIf
types
literalExpression
;
in
{
meta.maintainers = with lib.maintainers; [ drupol ];
options = {
services.chromadb = {
enable = mkEnableOption "ChromaDB, an open-source AI application database.";
package = mkOption {
type = types.package;
example = literalExpression "pkgs.python3Packages.chromadb";
default = pkgs.python3Packages.chromadb;
defaultText = "pkgs.python3Packages.chromadb";
description = "ChromaDB package to use.";
};
host = mkOption {
type = types.str;
default = "127.0.0.1";
description = ''
Defines the IP address by which ChromaDB will be accessible.
'';
};
port = mkOption {
type = types.port;
default = 8000;
description = ''
Defined the port number to listen.
'';
};
logFile = mkOption {
type = types.path;
default = "/var/log/chromadb/chromadb.log";
description = ''
Specifies the location of file for logging output.
'';
};
dbpath = mkOption {
type = types.str;
default = "/var/lib/chromadb";
description = "Location where ChromaDB stores its files";
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Whether to automatically open the specified TCP port in the firewall.
'';
};
};
};
config = mkIf cfg.enable {
systemd.services.chromadb = {
description = "ChromaDB";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
StateDirectory = "chromadb";
WorkingDirectory = "/var/lib/chromadb";
LogsDirectory = "chromadb";
ExecStart = "${lib.getExe cfg.package} run --path ${cfg.dbpath} --host ${cfg.host} --port ${toString cfg.port} --log-path ${cfg.logFile}";
Restart = "on-failure";
ProtectHome = true;
ProtectSystem = "strict";
PrivateTmp = true;
PrivateDevices = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
NoNewPrivileges = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RemoveIPC = true;
PrivateMounts = true;
DynamicUser = true;
};
};
networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [ cfg.port ];
};
}

View File

@ -1,543 +1,138 @@
{ lib, pkgs, config, ... } :
with lib;
{ config, lib, utils, pkgs, ... }:
let
cfg = config.services.pgbouncer;
confFile = pkgs.writeTextFile {
name = "pgbouncer.ini";
text = ''
[databases]
${concatStringsSep "\n"
(mapAttrsToList (dbname : settings : "${dbname} = ${settings}") cfg.databases)}
[users]
${concatStringsSep "\n"
(mapAttrsToList (username : settings : "${username} = ${settings}") cfg.users)}
[peers]
${concatStringsSep "\n"
(mapAttrsToList (peerid : settings : "${peerid} = ${settings}") cfg.peers)}
[pgbouncer]
# general
${optionalString (cfg.ignoreStartupParameters != null) "ignore_startup_parameters = ${cfg.ignoreStartupParameters}"}
listen_port = ${toString cfg.listenPort}
${optionalString (cfg.listenAddress != null) "listen_addr = ${cfg.listenAddress}"}
pool_mode = ${cfg.poolMode}
max_client_conn = ${toString cfg.maxClientConn}
default_pool_size = ${toString cfg.defaultPoolSize}
max_user_connections = ${toString cfg.maxUserConnections}
max_db_connections = ${toString cfg.maxDbConnections}
#auth
auth_type = ${cfg.authType}
${optionalString (cfg.authHbaFile != null) "auth_hba_file = ${cfg.authHbaFile}"}
${optionalString (cfg.authFile != null) "auth_file = ${cfg.authFile}"}
${optionalString (cfg.authUser != null) "auth_user = ${cfg.authUser}"}
${optionalString (cfg.authQuery != null) "auth_query = ${cfg.authQuery}"}
${optionalString (cfg.authDbname != null) "auth_dbname = ${cfg.authDbname}"}
# TLS
${optionalString (cfg.tls.client != null) ''
client_tls_sslmode = ${cfg.tls.client.sslmode}
client_tls_key_file = ${cfg.tls.client.keyFile}
client_tls_cert_file = ${cfg.tls.client.certFile}
client_tls_ca_file = ${cfg.tls.client.caFile}
''}
${optionalString (cfg.tls.server != null) ''
server_tls_sslmode = ${cfg.tls.server.sslmode}
server_tls_key_file = ${cfg.tls.server.keyFile}
server_tls_cert_file = ${cfg.tls.server.certFile}
server_tls_ca_file = ${cfg.tls.server.caFile}
''}
# log
${optionalString (cfg.logFile != null) "logfile = ${cfg.homeDir}/${cfg.logFile}"}
${optionalString (cfg.syslog != null) ''
syslog = ${if cfg.syslog.enable then "1" else "0"}
syslog_ident = ${cfg.syslog.syslogIdent}
syslog_facility = ${cfg.syslog.syslogFacility}
''}
${optionalString (cfg.verbose != null) "verbose = ${toString cfg.verbose}"}
# console access
${optionalString (cfg.adminUsers != null) "admin_users = ${cfg.adminUsers}"}
${optionalString (cfg.statsUsers != null) "stats_users = ${cfg.statsUsers}"}
# extra
${cfg.extraConfig}
'';
};
in {
settingsFormat = pkgs.formats.ini { };
configFile = settingsFormat.generate "pgbouncer.ini" cfg.settings;
configPath = "pgbouncer/pgbouncer.ini";
in
{
imports = [
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "logFile" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "log_file" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "listenAddress" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "listen_addr" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "listenPort" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "listen_port" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "poolMode" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "pool_mode" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "maxClientConn" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "max_client_conn" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "defaultPoolSize" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "default_pool_size" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "maxDbConnections" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "max_db_connections" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "maxUserConnections" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "max_user_connections" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "ignoreStartupParameters" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "ignore_startup_parameters" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "databases" ]
[ "services" "pgbouncer" "settings" "databases" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "users" ]
[ "services" "pgbouncer" "settings" "users" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "peers" ]
[ "services" "pgbouncer" "settings" "peers" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "authType" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "auth_type" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "authHbaFile" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "auth_hba_file" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "authFile" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "auth_file" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "authUser" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "auth_user" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "authQuery" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "auth_query" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "authDbname" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "auth_dbname" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "adminUsers" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "admin_users" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "statsUsers" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "stats_users" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "verbose" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "verbose" ])
(lib.mkChangedOptionModule
[ "services" "pgbouncer" "syslog" "enable" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "syslog" ]
(config:
let
enable = lib.getAttrFromPath
[ "services" "pgbouncer" "syslog" "enable" ]
config;
in
if enable then 1 else 0))
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "syslog" "syslogIdent" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "syslog_ident" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "syslog" "syslogFacility" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "syslog_facility" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "tls" "client" "sslmode" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "client_tls_sslmode" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "tls" "client" "keyFile" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "client_tls_key_file" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "tls" "client" "certFile" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "client_tls_cert_file" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "tls" "client" "caFile" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "client_tls_ca_file" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "tls" "server" "sslmode" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "server_tls_sslmode" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "tls" "server" "keyFile" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "server_tls_key_file" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "tls" "server" "certFile" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "server_tls_cert_file" ])
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "tls" "server" "caFile" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "server_tls_ca_file" ])
(lib.mkRemovedOptionModule [ "services" "pgbouncer" "extraConfig" ] "Use services.pgbouncer.settings instead.")
];
options.services.pgbouncer = {
enable = lib.mkEnableOption "PostgreSQL connection pooler";
# NixOS settings
package = lib.mkPackageOption pkgs "pgbouncer" { };
enable = mkEnableOption "PostgreSQL connection pooler";
package = mkPackageOption pkgs "pgbouncer" { };
openFirewall = mkOption {
type = types.bool;
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to automatically open the specified TCP port in the firewall.
'';
};
# Generic settings
logFile = mkOption {
type = types.nullOr types.str;
default = null;
settings = lib.mkOption {
type = settingsFormat.type;
default = { };
description = ''
Specifies a log file in addition to journald.
'';
};
listenAddress = mkOption {
type = types.nullOr types.commas;
example = "*";
default = null;
description = ''
Specifies a list (comma-separated) of addresses where to listen for TCP connections.
You may also use * meaning listen on all addresses.
When not set, only Unix socket connections are accepted.
Addresses can be specified numerically (IPv4/IPv6) or by name.
'';
};
listenPort = mkOption {
type = types.port;
default = 6432;
description = ''
Which port to listen on. Applies to both TCP and Unix sockets.
'';
};
poolMode = mkOption {
type = types.enum [ "session" "transaction" "statement" ];
default = "session";
description = ''
Specifies when a server connection can be reused by other clients.
session
Server is released back to pool after client disconnects. Default.
transaction
Server is released back to pool after transaction finishes.
statement
Server is released back to pool after query finishes.
Transactions spanning multiple statements are disallowed in this mode.
'';
};
maxClientConn = mkOption {
type = types.int;
default = 100;
description = ''
Maximum number of client connections allowed.
When this setting is increased, then the file descriptor limits in the operating system
might also have to be increased. Note that the number of file descriptors potentially
used is more than maxClientConn. If each user connects under its own user name to the server,
the theoretical maximum used is:
maxClientConn + (max pool_size * total databases * total users)
If a database user is specified in the connection string (all users connect under the same user name),
the theoretical maximum is:
maxClientConn + (max pool_size * total databases)
The theoretical maximum should never be reached, unless somebody deliberately crafts a special load for it.
Still, it means you should set the number of file descriptors to a safely high number.
'';
};
defaultPoolSize = mkOption {
type = types.int;
default = 20;
description = ''
How many server connections to allow per user/database pair.
Can be overridden in the per-database configuration.
'';
};
maxDbConnections = mkOption {
type = types.int;
default = 0;
description = ''
Do not allow more than this many server connections per database (regardless of user).
This considers the PgBouncer database that the client has connected to,
not the PostgreSQL database of the outgoing connection.
This can also be set per database in the [databases] section.
Note that when you hit the limit, closing a client connection to one pool will
not immediately allow a server connection to be established for another pool,
because the server connection for the first pool is still open.
Once the server connection closes (due to idle timeout),
a new server connection will immediately be opened for the waiting pool.
0 = unlimited
'';
};
maxUserConnections = mkOption {
type = types.int;
default = 0;
description = ''
Do not allow more than this many server connections per user (regardless of database).
This considers the PgBouncer user that is associated with a pool,
which is either the user specified for the server connection
or in absence of that the user the client has connected as.
This can also be set per user in the [users] section.
Note that when you hit the limit, closing a client connection to one pool
will not immediately allow a server connection to be established for another pool,
because the server connection for the first pool is still open.
Once the server connection closes (due to idle timeout), a new server connection
will immediately be opened for the waiting pool.
0 = unlimited
'';
};
ignoreStartupParameters = mkOption {
type = types.nullOr types.commas;
example = "extra_float_digits";
default = null;
description = ''
By default, PgBouncer allows only parameters it can keep track of in startup packets:
client_encoding, datestyle, timezone and standard_conforming_strings.
All others parameters will raise an error.
To allow others parameters, they can be specified here, so that PgBouncer knows that
they are handled by the admin and it can ignore them.
If you need to specify multiple values, use a comma-separated list.
IMPORTANT: When using prometheus-pgbouncer-exporter, you need:
extra_float_digits
<https://github.com/prometheus-community/pgbouncer_exporter#pgbouncer-configuration>
'';
};
# Section [databases]
databases = mkOption {
type = types.attrsOf types.str;
default = {};
example = {
exampledb = "host=/run/postgresql/ port=5432 auth_user=exampleuser dbname=exampledb sslmode=require";
bardb = "host=localhost dbname=bazdb";
foodb = "host=host1.example.com port=5432";
};
description = ''
Detailed information about PostgreSQL database definitions:
<https://www.pgbouncer.org/config.html#section-databases>
'';
};
# Section [users]
users = mkOption {
type = types.attrsOf types.str;
default = {};
example = {
user1 = "pool_mode=session";
};
description = ''
Optional.
Detailed information about PostgreSQL user definitions:
<https://www.pgbouncer.org/config.html#section-users>
'';
};
# Section [peers]
peers = mkOption {
type = types.attrsOf types.str;
default = {};
example = {
"1" = "host=host1.example.com";
"2" = "host=/tmp/pgbouncer-2 port=5555";
};
description = ''
Optional.
Detailed information about PostgreSQL database definitions:
<https://www.pgbouncer.org/config.html#section-peers>
'';
};
# Authentication settings
authType = mkOption {
type = types.enum [ "cert" "md5" "scram-sha-256" "plain" "trust" "any" "hba" "pam" ];
default = "md5";
description = ''
How to authenticate users.
cert
Client must connect over TLS connection with a valid client certificate.
The user name is then taken from the CommonName field from the certificate.
md5
Use MD5-based password check. This is the default authentication method.
authFile may contain both MD5-encrypted and plain-text passwords.
If md5 is configured and a user has a SCRAM secret, then SCRAM authentication is used automatically instead.
scram-sha-256
Use password check with SCRAM-SHA-256. authFile has to contain SCRAM secrets or plain-text passwords.
plain
The clear-text password is sent over the wire. Deprecated.
trust
No authentication is done. The user name must still exist in authFile.
any
Like the trust method, but the user name given is ignored.
Requires that all databases are configured to log in as a specific user.
Additionally, the console database allows any user to log in as admin.
hba
The actual authentication type is loaded from authHbaFile.
This allows different authentication methods for different access paths,
for example: connections over Unix socket use the peer auth method, connections over TCP must use TLS.
pam
PAM is used to authenticate users, authFile is ignored.
This method is not compatible with databases using the authUser option.
The service name reported to PAM is pgbouncer. pam is not supported in the HBA configuration file.
'';
};
authHbaFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/secrets/pgbouncer_hba";
description = ''
HBA configuration file to use when authType is hba.
See HBA file format details:
<https://www.pgbouncer.org/config.html#hba-file-format>
'';
};
authFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/secrets/pgbouncer_authfile";
description = ''
The name of the file to load user names and passwords from.
See section Authentication file format details:
<https://www.pgbouncer.org/config.html#authentication-file-format>
Most authentication types require that either authFile or authUser be set;
otherwise there would be no users defined.
'';
};
authUser = mkOption {
type = types.nullOr types.str;
default = null;
example = "pgbouncer";
description = ''
If authUser is set, then any user not specified in authFile will be queried
through the authQuery query from pg_shadow in the database, using authUser.
The password of authUser will be taken from authFile.
(If the authUser does not require a password then it does not need to be defined in authFile.)
Direct access to pg_shadow requires admin rights.
It's preferable to use a non-superuser that calls a SECURITY DEFINER function instead.
'';
};
authQuery = mkOption {
type = types.nullOr types.str;
default = null;
example = "SELECT usename, passwd FROM pg_shadow WHERE usename=$1";
description = ''
Query to load user's password from database.
Direct access to pg_shadow requires admin rights.
It's preferable to use a non-superuser that calls a SECURITY DEFINER function instead.
Note that the query is run inside the target database.
So if a function is used, it needs to be installed into each database.
'';
};
authDbname = mkOption {
type = types.nullOr types.str;
default = null;
example = "authdb";
description = ''
Database name in the [database] section to be used for authentication purposes.
This option can be either global or overriden in the connection string if this parameter is specified.
'';
};
# TLS settings
tls.client = mkOption {
type = types.nullOr (types.submodule {
options = {
sslmode = mkOption {
type = types.enum [ "disable" "allow" "prefer" "require" "verify-ca" "verify-full" ];
default = "disable";
description = ''
TLS mode to use for connections from clients.
TLS connections are disabled by default.
When enabled, tls.client.keyFile and tls.client.certFile
must be also configured to set up the key and certificate
PgBouncer uses to accept client connections.
disable
Plain TCP. If client requests TLS, it's ignored. Default.
allow
If client requests TLS, it is used. If not, plain TCP is used.
If the client presents a client certificate, it is not validated.
prefer
Same as allow.
require
Client must use TLS. If not, the client connection is rejected.
If the client presents a client certificate, it is not validated.
verify-ca
Client must use TLS with valid client certificate.
verify-full
Same as verify-ca
'';
};
certFile = mkOption {
type = types.path;
example = "/secrets/pgbouncer.key";
description = "Path to certificate for private key. Clients can validate it";
};
keyFile = mkOption {
type = types.path;
example = "/secrets/pgbouncer.crt";
description = "Path to private key for PgBouncer to accept client connections";
};
caFile = mkOption {
type = types.path;
example = "/secrets/pgbouncer.crt";
description = "Path to root certificate file to validate client certificates";
};
};
});
default = null;
description = ''
<https://www.pgbouncer.org/config.html#tls-settings>
'';
};
tls.server = mkOption {
type = types.nullOr (types.submodule {
options = {
sslmode = mkOption {
type = types.enum [ "disable" "allow" "prefer" "require" "verify-ca" "verify-full" ];
default = "disable";
description = ''
TLS mode to use for connections to PostgreSQL servers.
TLS connections are disabled by default.
disable
Plain TCP. TLS is not even requested from the server. Default.
allow
FIXME: if server rejects plain, try TLS?
prefer
TLS connection is always requested first from PostgreSQL.
If refused, the connection will be established over plain TCP.
Server certificate is not validated.
require
Connection must go over TLS. If server rejects it, plain TCP is not attempted.
Server certificate is not validated.
verify-ca
Connection must go over TLS and server certificate must be valid according to tls.server.caFile.
Server host name is not checked against certificate.
verify-full
Connection must go over TLS and server certificate must be valid according to tls.server.caFile.
Server host name must match certificate information.
'';
};
certFile = mkOption {
type = types.path;
example = "/secrets/pgbouncer_server.key";
description = "Certificate for private key. PostgreSQL server can validate it.";
};
keyFile = mkOption {
type = types.path;
example = "/secrets/pgbouncer_server.crt";
description = "Private key for PgBouncer to authenticate against PostgreSQL server.";
};
caFile = mkOption {
type = types.path;
example = "/secrets/pgbouncer_server.crt";
description = "Root certificate file to validate PostgreSQL server certificates.";
};
};
});
default = null;
description = ''
<https://www.pgbouncer.org/config.html#tls-settings>
'';
};
# Log settings
syslog = mkOption {
type = types.nullOr (types.submodule {
options = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Toggles syslog on/off.
'';
};
syslogIdent = mkOption {
type = types.str;
default = "pgbouncer";
description = ''
Under what name to send logs to syslog.
'';
};
syslogFacility = mkOption {
type = types.enum [ "auth" "authpriv" "daemon" "user" "local0" "local1" "local2" "local3" "local4" "local5" "local6" "local7" ];
default = "daemon";
description = ''
Under what facility to send logs to syslog.
'';
};
};
});
default = null;
description = ''
<https://www.pgbouncer.org/config.html#log-settings>
'';
};
verbose = lib.mkOption {
type = lib.types.int;
default = 0;
description = ''
Increase verbosity. Mirrors the -v switch on the command line.
'';
};
# Console access control
adminUsers = mkOption {
type = types.nullOr types.commas;
default = null;
description = ''
Comma-separated list of database users that are allowed to connect and run all commands on the console.
Ignored when authType is any, in which case any user name is allowed in as admin.
'';
};
statsUsers = mkOption {
type = types.nullOr types.commas;
default = null;
description = ''
Comma-separated list of database users that are allowed to connect and run read-only queries on the console.
That means all SHOW commands except SHOW FDS.
Configuration for PgBouncer, see <https://www.pgbouncer.org/config.html>
for supported values.
'';
};
@ -550,42 +145,32 @@ in {
'';
};
user = mkOption {
type = types.str;
user = lib.mkOption {
type = lib.types.str;
default = "pgbouncer";
description = ''
The user pgbouncer is run as.
'';
};
group = mkOption {
type = types.str;
group = lib.mkOption {
type = lib.types.str;
default = "pgbouncer";
description = ''
The group pgbouncer is run as.
'';
};
homeDir = mkOption {
type = types.path;
homeDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/pgbouncer";
description = ''
Specifies the home directory.
'';
};
# Extra settings
extraConfig = mkOption {
type = types.lines;
description = ''
Any additional text to be appended to config.ini
<https://www.pgbouncer.org/config.html>.
'';
default = "";
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
users.groups.${cfg.group} = { };
users.users.${cfg.user} = {
description = "PgBouncer service user";
@ -595,26 +180,36 @@ in {
isSystemUser = true;
};
environment.etc.${configPath}.source = configFile;
# Default to RuntimeDirectory instead of /tmp.
services.pgbouncer.settings.pgbouncer.unix_socket_dir = lib.mkDefault "/run/pgbouncer";
systemd.services.pgbouncer = {
description = "PgBouncer - PostgreSQL connection pooler";
wants = [ "network-online.target" ] ++ lib.optional config.services.postgresql.enable "postgresql.service";
after = [ "network-online.target" ] ++ lib.optional config.services.postgresql.enable "postgresql.service";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
reloadTriggers = [ configFile ];
serviceConfig = {
Type = "notify";
Type = "notify-reload";
User = cfg.user;
Group = cfg.group;
ExecStart = "${lib.getExe pkgs.pgbouncer} ${confFile}";
ExecReload = "${pkgs.coreutils}/bin/kill -SIGHUP $MAINPID";
ExecStart = utils.escapeSystemdExecArgs [
(lib.getExe pkgs.pgbouncer)
"/etc/${configPath}"
];
RuntimeDirectory = "pgbouncer";
LimitNOFILE = cfg.openFilesLimit;
};
};
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.listenPort;
networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [
(cfg.settings.pgbouncer.listen_port or 6432)
];
};
};
meta.maintainers = [ maintainers._1000101 ];
meta.maintainers = [ lib.maintainers._1000101 ];
}

View File

@ -367,18 +367,6 @@ in
message = ''
PgBouncer exporter needs either connectionStringFile or connectionString configured"
'';
} {
assertion = cfg.pgbouncer.enable -> (
config.services.pgbouncer.ignoreStartupParameters != null && builtins.match ".*extra_float_digits.*" config.services.pgbouncer.ignoreStartupParameters != null
);
message = ''
Prometheus PgBouncer exporter requires including `extra_float_digits` in services.pgbouncer.ignoreStartupParameters
Example:
services.pgbouncer.ignoreStartupParameters = extra_float_digits;
See https://github.com/prometheus-community/pgbouncer_exporter#pgbouncer-configuration
'';
} {
assertion = cfg.sql.enable -> (
(cfg.sql.configFile == null) != (cfg.sql.configuration == null)
@ -437,11 +425,6 @@ in
config.services.prometheus.exporters.pgbouncer.connectionString is insecure. Use connectionStringFile instead.
''
)
(mkIf
(cfg.pgbouncer.enable && config.services.pgbouncer.authType != "any") ''
Admin user (with password or passwordless) MUST exist in the services.pgbouncer.authFile if authType other than any is used.
''
)
] ++ config.services.prometheus.exporters.warnings;
}] ++ [(mkIf config.services.prometheus.exporters.rtl_433.enable {
hardware.rtl-sdr.enable = mkDefault true;

View File

@ -4,15 +4,21 @@ let
cfg = config.services.prometheus.exporters.pgbouncer;
inherit (lib)
mkOption
mkPackageOption
types
optionals
optionalString
getExe
getExe'
escapeShellArg
escapeShellArgs
concatStringsSep
;
in
{
port = 9127;
extraOpts = {
package = mkPackageOption pkgs "prometheus-pgbouncer-exporter" { };
telemetryPath = mkOption {
type = types.str;
@ -31,8 +37,10 @@ in
NOTE: You MUST keep pgbouncer as database name (special internal db)!!!
NOTE: Admin user (with password or passwordless) MUST exist
in the services.pgbouncer.authFile if authType other than any is used.
NOTE: ignore_startup_parameters MUST contain "extra_float_digits".
NOTE: Admin user (with password or passwordless) MUST exist in the
auth_file if auth_type other than "any" is used.
WARNING: this secret is stored in the world-readable Nix store!
Use {option}`connectionStringFile` instead.
@ -49,8 +57,10 @@ in
NOTE: You MUST keep pgbouncer as database name (special internal db)!!!
NOTE: Admin user (with password or passwordless) MUST exist
in the services.pgbouncer.authFile if authType other than any is used.
NOTE: ignore_startup_parameters MUST contain "extra_float_digits".
NOTE: Admin user (with password or passwordless) MUST exist in the
auth_file if auth_type other than "any" is used.
{option}`connectionStringFile` takes precedence over {option}`connectionString`
'';
@ -81,7 +91,7 @@ in
};
logLevel = mkOption {
type = types.enum ["debug" "info" "warn" "error" ];
type = types.enum [ "debug" "info" "warn" "error" ];
default = "info";
description = ''
Only log messages with the given severity or above.
@ -89,7 +99,7 @@ in
};
logFormat = mkOption {
type = types.enum ["logfmt" "json"];
type = types.enum [ "logfmt" "json" ];
default = "logfmt";
description = ''
Output format of log messages. One of: [logfmt, json]
@ -116,35 +126,30 @@ in
serviceOpts = {
after = [ "pgbouncer.service" ];
serviceConfig = let
startScript = pkgs.writeShellScriptBin "pgbouncer-start" "${concatStringsSep " " ([
"${pkgs.prometheus-pgbouncer-exporter}/bin/pgbouncer_exporter"
"--web.listen-address ${cfg.listenAddress}:${toString cfg.port}"
"--pgBouncer.connectionString ${if cfg.connectionStringFile != null then
"$(head -n1 ${cfg.connectionStringFile})" else "${escapeShellArg cfg.connectionString}"}"
]
++ optionals (cfg.telemetryPath != null) [
"--web.telemetry-path ${escapeShellArg cfg.telemetryPath}"
]
++ optionals (cfg.pidFile != null) [
"--pgBouncer.pid-file= ${escapeShellArg cfg.pidFile}"
]
++ optionals (cfg.logLevel != null) [
"--log.level ${escapeShellArg cfg.logLevel}"
]
++ optionals (cfg.logFormat != null) [
"--log.format ${escapeShellArg cfg.logFormat}"
]
++ optionals (cfg.webSystemdSocket != false) [
"--web.systemd-socket ${escapeShellArg cfg.webSystemdSocket}"
]
++ optionals (cfg.webConfigFile != null) [
"--web.config.file ${escapeShellArg cfg.webConfigFile}"
]
++ cfg.extraFlags)}";
in
{
ExecStart = "${startScript}/bin/pgbouncer-start";
};
script = optionalString (cfg.connectionStringFile != null) ''
connectionString=$(${escapeShellArgs [
(getExe' pkgs.coreutils "cat") "--" cfg.connectionStringFile
]})
'' + concatStringsSep " " ([
"exec -- ${escapeShellArg (getExe cfg.package)}"
"--web.listen-address ${cfg.listenAddress}:${toString cfg.port}"
"--pgBouncer.connectionString ${if cfg.connectionStringFile != null
then "\"$connectionString\""
else "${escapeShellArg cfg.connectionString}"}"
] ++ optionals (cfg.telemetryPath != null) [
"--web.telemetry-path ${escapeShellArg cfg.telemetryPath}"
] ++ optionals (cfg.pidFile != null) [
"--pgBouncer.pid-file ${escapeShellArg cfg.pidFile}"
] ++ optionals (cfg.logLevel != null) [
"--log.level ${escapeShellArg cfg.logLevel}"
] ++ optionals (cfg.logFormat != null) [
"--log.format ${escapeShellArg cfg.logFormat}"
] ++ optionals (cfg.webSystemdSocket != false) [
"--web.systemd-socket ${escapeShellArg cfg.webSystemdSocket}"
] ++ optionals (cfg.webConfigFile != null) [
"--web.config.file ${escapeShellArg cfg.webConfigFile}"
] ++ cfg.extraFlags);
serviceConfig.RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
};
}

View File

@ -560,6 +560,9 @@ in
};
environment.NUT_CONFPATH = "/etc/nut";
environment.NUT_STATEPATH = "/var/lib/nut";
restartTriggers = [
config.environment.etc."nut/ups.conf".source
];
};
environment.etc = {

View File

@ -6,6 +6,7 @@ let
cfgs = config.services.cgit;
settingType = with types; oneOf [ bool int str ];
repeatedSettingType = with types; oneOf [ settingType (listOf settingType) ];
genAttrs' = names: f: listToAttrs (map f names);
@ -44,12 +45,20 @@ let
toString value
}";
# list value as multiple lines (for "readme" for example)
cgitrcEntry = name: value:
if isList value then
map (cgitrcLine name) value
else
[ (cgitrcLine name value) ];
mkCgitrc = cfg: pkgs.writeText "cgitrc" ''
# global settings
${concatStringsSep "\n" (
mapAttrsToList
cgitrcLine
flatten (mapAttrsToList
cgitrcEntry
({ virtual-root = cfg.nginx.location; } // cfg.settings)
)
)
}
${optionalString (cfg.scanPath != null) (cgitrcLine "scan-path" cfg.scanPath)}
@ -125,7 +134,7 @@ in
settings = mkOption {
description = "cgit configuration, see cgitrc(5)";
type = types.attrsOf settingType;
type = types.attrsOf repeatedSettingType;
default = {};
example = literalExpression ''
{

View File

@ -2,6 +2,12 @@
let
cfg = config.services.harmonia;
format = pkgs.formats.toml { };
signKeyPaths = cfg.signKeyPaths ++ lib.optional (cfg.signKeyPath != null) cfg.signKeyPath;
credentials = lib.imap0 (i: signKeyPath: {
id = "sign-key-${builtins.toString i}";
path = signKeyPath;
}) signKeyPaths;
in
{
options = {
@ -11,7 +17,13 @@ in
signKeyPath = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "Path to the signing key that will be used for signing the cache";
description = "DEPRECATED: Use `services.harmonia.signKeyPaths` instead. Path to the signing key to use for signing the cache";
};
signKeyPaths = lib.mkOption {
type = lib.types.listOf lib.types.path;
default = [ ];
description = "Paths to the signing keys to use for signing the cache";
};
package = lib.mkPackageOption pkgs "harmonia" { };
@ -28,6 +40,8 @@ in
};
config = lib.mkIf cfg.enable {
warnings = lib.optional (cfg.signKeyPath != null)
"`services.harmonia.signKeyPath` is deprecated, use `services.harmonia.signKeyPaths` instead";
nix.settings.extra-allowed-users = [ "harmonia" ];
users.users.harmonia = {
isSystemUser = true;
@ -44,7 +58,9 @@ in
environment = {
CONFIG_FILE = format.generate "harmonia.toml" cfg.settings;
SIGN_KEY_PATH = lib.mkIf (cfg.signKeyPath != null) "%d/sign-key";
SIGN_KEY_PATHS = lib.strings.concatMapStringsSep " " (
credential: "%d/${credential.id}"
) credentials;
# Note: it's important to set this for nix-store, because it wants to use
# $HOME in order to use a temporary cache dir. bizarre failures will occur
# otherwise
@ -60,7 +76,7 @@ in
DeviceAllow = [ "" ];
UMask = "0066";
RuntimeDirectory = "harmonia";
LoadCredential = lib.mkIf (cfg.signKeyPath != null) [ "sign-key:${cfg.signKeyPath}" ];
LoadCredential = builtins.map (credential: "${credential.id}:${credential.path}") credentials;
SystemCallFilter = [
"@system-service"
"~@privileged"

View File

@ -1,187 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
inherit (pkgs) lsh;
cfg = config.services.lshd;
in
{
###### interface
options = {
services.lshd = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable the GNU lshd SSH2 daemon, which allows
secure remote login.
'';
};
portNumber = mkOption {
default = 22;
type = types.port;
description = ''
The port on which to listen for connections.
'';
};
interfaces = mkOption {
default = [];
type = types.listOf types.str;
description = ''
List of network interfaces where listening for connections.
When providing the empty list, `[]`, lshd listens on all
network interfaces.
'';
example = [ "localhost" "1.2.3.4:443" ];
};
hostKey = mkOption {
default = "/etc/lsh/host-key";
type = types.str;
description = ''
Path to the server's private key. Note that this key must
have been created, e.g., using "lsh-keygen --server |
lsh-writekey --server", so that you can run lshd.
'';
};
syslog = mkOption {
type = types.bool;
default = true;
description = "Whether to enable syslog output.";
};
passwordAuthentication = mkOption {
type = types.bool;
default = true;
description = "Whether to enable password authentication.";
};
publicKeyAuthentication = mkOption {
type = types.bool;
default = true;
description = "Whether to enable public key authentication.";
};
rootLogin = mkOption {
type = types.bool;
default = false;
description = "Whether to enable remote root login.";
};
loginShell = mkOption {
default = null;
type = types.nullOr types.str;
description = ''
If non-null, override the default login shell with the
specified value.
'';
example = "/nix/store/xyz-bash-10.0/bin/bash10";
};
srpKeyExchange = mkOption {
default = false;
type = types.bool;
description = ''
Whether to enable SRP key exchange and user authentication.
'';
};
tcpForwarding = mkOption {
type = types.bool;
default = true;
description = "Whether to enable TCP/IP forwarding.";
};
x11Forwarding = mkOption {
type = types.bool;
default = true;
description = "Whether to enable X11 forwarding.";
};
subsystems = mkOption {
type = types.listOf types.path;
description = ''
List of subsystem-path pairs, where the head of the pair
denotes the subsystem name, and the tail denotes the path to
an executable implementing it.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
services.lshd.subsystems = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ];
systemd.services.lshd = {
description = "GNU lshd SSH2 daemon";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment = {
LD_LIBRARY_PATH = config.system.nssModules.path;
};
preStart = ''
test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh
test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh
if ! test -f /var/spool/lsh/yarrow-seed-file
then
# XXX: It would be nice to provide feedback to the
# user when this fails, so that they can retry it
# manually.
${lsh}/bin/lsh-make-seed --sloppy \
-o /var/spool/lsh/yarrow-seed-file
fi
if ! test -f "${cfg.hostKey}"
then
${lsh}/bin/lsh-keygen --server | \
${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}"
fi
'';
script = with cfg; ''
${lsh}/sbin/lshd --daemonic \
--password-helper="${lsh}/sbin/lsh-pam-checkpw" \
-p ${toString portNumber} \
${optionalString (interfaces != []) (concatStrings (map (i: "--interface=\"${i}\"") interfaces))} \
-h "${hostKey}" \
${optionalString (!syslog) "--no-syslog" } \
${if passwordAuthentication then "--password" else "--no-password" } \
${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \
${if rootLogin then "--root-login" else "--no-root-login" } \
${optionalString (loginShell != null) "--login-shell=\"${loginShell}\"" } \
${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \
${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \
${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \
--subsystems=${concatStringsSep ","
(map (pair: (head pair) + "=" +
(head (tail pair)))
subsystems)}
'';
};
security.pam.services.lshd = {};
};
}

View File

@ -0,0 +1,98 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.services.homebox;
inherit (lib)
mkEnableOption
mkPackageOption
mkDefault
types
mkIf
;
in
{
options.services.homebox = {
enable = mkEnableOption "homebox";
package = mkPackageOption pkgs "homebox" { };
settings = lib.mkOption {
type = types.attrsOf types.str;
defaultText = ''
HBOX_STORAGE_DATA = "/var/lib/homebox/data";
HBOX_STORAGE_SQLITE_URL = "/var/lib/homebox/data/homebox.db?_pragma=busy_timeout=999&_pragma=journal_mode=WAL&_fk=1";
HBOX_OPTIONS_ALLOW_REGISTRATION = "false";
HBOX_MODE = "production";
'';
description = ''
The homebox configuration as Environment variables. For definitions and available options see the upstream
[documentation](https://hay-kot.github.io/homebox/quick-start/#env-variables-configuration).
'';
};
};
config = mkIf cfg.enable {
users.users.homebox = {
isSystemUser = true;
group = "homebox";
};
users.groups.homebox = { };
services.homebox.settings = {
HBOX_STORAGE_DATA = mkDefault "/var/lib/homebox/data";
HBOX_STORAGE_SQLITE_URL = mkDefault "/var/lib/homebox/data/homebox.db?_pragma=busy_timeout=999&_pragma=journal_mode=WAL&_fk=1";
HBOX_OPTIONS_ALLOW_REGISTRATION = mkDefault "false";
HBOX_MODE = mkDefault "production";
};
systemd.services.homebox = {
after = [ "network.target" ];
environment = cfg.settings;
serviceConfig = {
User = "homebox";
Group = "homebox";
ExecStart = lib.getExe cfg.package;
StateDirectory = "homebox";
WorkingDirectory = "/var/lib/homebox";
LimitNOFILE = "1048576";
PrivateTmp = true;
PrivateDevices = true;
StateDirectoryMode = "0700";
Restart = "always";
# Hardening
CapabilityBoundingSet = "";
LockPersonality = true;
MemoryDenyWriteExecute = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProcSubset = "pid";
ProtectSystem = "strict";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_NETLINK"
];
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"@pkey"
];
RestrictSUIDSGID = true;
PrivateMounts = true;
UMask = "0077";
};
wantedBy = [ "multi-user.target" ];
};
};
meta.maintainers = with lib.maintainers; [ patrickdag ];
}

View File

@ -775,7 +775,7 @@ in {
'' + lib.optionalString (!databaseActuallyCreateLocally) ''
unset PGPASSWORD
'';
path = [ cfg.package pkgs.postgresql ];
path = [ cfg.package config.services.postgresql.package ];
environment = env // lib.optionalAttrs (!databaseActuallyCreateLocally) {
PGHOST = cfg.database.host;
PGPORT = toString cfg.database.port;

View File

@ -42,9 +42,10 @@ let
SESSION_COOKIE_SECURE = ENABLE_HTTPS
DATA_DIR = "${dataDir}"
CACHE_DIR = f"{DATA_DIR}/cache"
STATIC_ROOT = "${finalPackage.static}/static"
STATIC_ROOT = "${finalPackage.static}"
MEDIA_ROOT = "/var/lib/weblate/media"
COMPRESS_ROOT = "${finalPackage.static}/compressor-cache"
COMPRESS_ROOT = "${finalPackage.static}"
COMPRESS_OFFLINE = True
DEBUG = False
DATABASES = {
@ -86,6 +87,13 @@ let
VCS_BACKENDS = ("weblate.vcs.git.GitRepository",)
SITE_URL = "https://{}".format(SITE_DOMAIN)
# WebAuthn
OTP_WEBAUTHN_RP_NAME = SITE_TITLE
OTP_WEBAUTHN_RP_ID = SITE_DOMAIN.split(":")[0]
OTP_WEBAUTHN_ALLOWED_ORIGINS = [SITE_URL]
''
+ lib.optionalString cfg.smtp.enable ''
ADMINS = (("Weblate Admin", "${cfg.smtp.user}"),)
@ -205,8 +213,7 @@ in
locations = {
"= /favicon.ico".alias = "${finalPackage}/${python.sitePackages}/weblate/static/favicon.ico";
"/static/".alias = "${finalPackage.static}/static/";
"/static/CACHE/".alias = "${finalPackage.static}/compressor-cache/CACHE/";
"/static/".alias = "${finalPackage.static}/";
"/media/".alias = "/var/lib/weblate/media/";
"/".proxyPass = "http://unix:///run/weblate.socket";
};

View File

@ -20,6 +20,7 @@ let
"IPv6PrivacyExtensions"
"IPv4Forwarding"
"IPv6Forwarding"
"UseDomains"
])
(assertValueOneOf "SpeedMeter" boolValues)
(assertInt "SpeedMeterIntervalSec")
@ -28,6 +29,7 @@ let
(assertValueOneOf "IPv6PrivacyExtensions" (boolValues ++ ["prefer-public" "kernel"]))
(assertValueOneOf "IPv4Forwarding" boolValues)
(assertValueOneOf "IPv6Forwarding" boolValues)
(assertValueOneOf "UseDomains" (boolValues ++ ["route"]))
];
sectionDHCPv4 = checkUnitConfig "DHCPv4" [
@ -652,6 +654,7 @@ let
"Address"
"Gateway"
"DNS"
"UseDomains"
"Domains"
"DNSDefaultRoute"
"NTP"
@ -705,6 +708,7 @@ let
(assertValueOneOf "DNSSEC" (boolValues ++ ["allow-downgrade"]))
(assertValueOneOf "LLDP" (boolValues ++ ["routers-only"]))
(assertValueOneOf "EmitLLDP" (boolValues ++ ["nearest-bridge" "non-tpmr-bridge" "customer-bridge"]))
(assertValueOneOf "UseDomains" (boolValues ++ ["route"]))
(assertValueOneOf "DNSDefaultRoute" boolValues)
(assertRemoved "IPForward" "IPv4Forwarding and IPv6Forwarding in systemd.network(5) and networkd.conf(5)")
(assertValueOneOf "IPv4Forwarding" boolValues)

View File

@ -53,7 +53,6 @@ let
"debug-shell.service"
# Udev.
"systemd-tmpfiles-setup-dev-early.service"
"systemd-udevd-control.socket"
"systemd-udevd-kernel.socket"
"systemd-udevd.service"

View File

@ -67,8 +67,6 @@ let
"systemd-poweroff.service"
"systemd-reboot.service"
"systemd-sysctl.service"
"systemd-tmpfiles-setup-dev.service"
"systemd-tmpfiles-setup.service"
"timers.target"
"tpm2.target"
"umount.target"
@ -103,8 +101,17 @@ let
initrdBinEnv = pkgs.buildEnv {
name = "initrd-bin-env";
paths = map getBin cfg.initrdBin;
pathsToLink = ["/bin"];
postBuild = concatStringsSep "\n" (mapAttrsToList (n: v: "ln -sf '${v}' $out/bin/'${n}'") cfg.extraBin);
pathsToLink = ["/bin" "/sbin"];
# Make sure sbin and bin have the same contents, and add extraBin
postBuild = ''
find $out/bin -maxdepth 1 -type l -print0 | xargs --null cp --no-dereference --no-clobber -t $out/sbin/
find $out/sbin -maxdepth 1 -type l -print0 | xargs --null cp --no-dereference --no-clobber -t $out/bin/
${concatStringsSep "\n" (mapAttrsToList (n: v: ''
ln -sf '${v}' $out/bin/'${n}'
ln -sf '${v}' $out/sbin/'${n}'
'') cfg.extraBin)}
'';
};
initialRamdisk = pkgs.makeInitrdNG {
@ -226,8 +233,8 @@ in {
emergencyAccess = mkOption {
type = with types; oneOf [ bool (nullOr (passwdEntry str)) ];
description = ''
Set to true for unauthenticated emergency access, and false for
no emergency access.
Set to true for unauthenticated emergency access, and false or
null for no emergency access.
Can also be set to a hashed super user password to allow
authenticated access to the emergency mode.
@ -408,7 +415,7 @@ in {
fsck = "${cfg.package.util-linux}/bin/fsck";
};
managerEnvironment.PATH = "/bin";
managerEnvironment.PATH = "/bin:/sbin";
contents = {
"/tmp/.keep".text = "systemd requires the /tmp mount point in the initrd cpio archive";
@ -417,7 +424,7 @@ in {
"/etc/systemd/system.conf".text = ''
[Manager]
DefaultEnvironment=PATH=/bin
DefaultEnvironment=PATH=/bin:/sbin
${cfg.extraConfig}
ManagerEnvironment=${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${lib.escapeShellArg v}") cfg.managerEnvironment)}
'';
@ -429,12 +436,17 @@ in {
# We can use either ! or * to lock the root account in the
# console, but some software like OpenSSH won't even allow you
# to log in with an SSH key if you use ! so we use * instead
"/etc/shadow".text = "root:${if isBool cfg.emergencyAccess then optionalString (!cfg.emergencyAccess) "*" else cfg.emergencyAccess}:::::::";
"/etc/shadow".text = let
ea = cfg.emergencyAccess;
access = ea != null && !(isBool ea && !ea);
passwd = if isString ea then ea else "";
in
"root:${if access then passwd else "*"}:::::::";
"/bin".source = "${initrdBinEnv}/bin";
"/sbin".source = "${initrdBinEnv}/bin";
"/sbin".source = "${initrdBinEnv}/sbin";
"/etc/sysctl.d/nixos.conf".text = "kernel.modprobe = /bin/modprobe";
"/etc/sysctl.d/nixos.conf".text = "kernel.modprobe = /sbin/modprobe";
"/etc/modprobe.d/systemd.conf".source = "${cfg.package}/lib/modprobe.d/systemd.conf";
"/etc/modprobe.d/ubuntu.conf".source = pkgs.runCommand "initrd-kmod-blacklist-ubuntu" { } ''
${pkgs.buildPackages.perl}/bin/perl -0pe 's/## file: iwlwifi.conf(.+?)##/##/s;' $src > $out
@ -509,8 +521,6 @@ in {
(v: let n = escapeSystemdPath v.where;
in nameValuePair "${n}.automount" (automountToUnit v)) cfg.automounts);
# make sure all the /dev nodes are set up
services.systemd-tmpfiles-setup-dev.wantedBy = ["sysinit.target"];
services.initrd-nixos-activation = {
after = [ "initrd-fs.target" ];

View File

@ -1,10 +1,121 @@
{ config, lib, pkgs, utils, ... }:
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.systemd.tmpfiles;
initrdCfg = config.boot.initrd.systemd.tmpfiles;
systemd = config.systemd.package;
settingsOption = {
description = ''
Declare systemd-tmpfiles rules to create, delete, and clean up volatile
and temporary files and directories.
Even though the service is called `*tmp*files` you can also create
persistent files.
'';
example = {
"10-mypackage" = {
"/var/lib/my-service/statefolder".d = {
mode = "0755";
user = "root";
group = "root";
};
};
};
default = {};
type = types.attrsOf (types.attrsOf (types.attrsOf (types.submodule ({ name, config, ... }: {
options.type = mkOption {
type = types.str;
default = name;
example = "d";
description = ''
The type of operation to perform on the file.
The type consists of a single letter and optionally one or more
modifier characters.
Please see the upstream documentation for the available types and
more details:
<https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
'';
};
options.mode = mkOption {
type = types.str;
default = "-";
example = "0755";
description = ''
The file access mode to use when creating this file or directory.
'';
};
options.user = mkOption {
type = types.str;
default = "-";
example = "root";
description = ''
The user of the file.
This may either be a numeric ID or a user/group name.
If omitted or when set to `"-"`, the user and group of the user who
invokes systemd-tmpfiles is used.
'';
};
options.group = mkOption {
type = types.str;
default = "-";
example = "root";
description = ''
The group of the file.
This may either be a numeric ID or a user/group name.
If omitted or when set to `"-"`, the user and group of the user who
invokes systemd-tmpfiles is used.
'';
};
options.age = mkOption {
type = types.str;
default = "-";
example = "10d";
description = ''
Delete a file when it reaches a certain age.
If a file or directory is older than the current time minus the age
field, it is deleted.
If set to `"-"` no automatic clean-up is done.
'';
};
options.argument = mkOption {
type = types.str;
default = "";
example = "";
description = ''
An argument whose meaning depends on the type of operation.
Please see the upstream documentation for the meaning of this
parameter in different situations:
<https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
'';
};
}))));
};
# generates a single entry for a tmpfiles.d rule
settingsEntryToRule = path: entry: ''
'${entry.type}' '${path}' '${entry.mode}' '${entry.user}' '${entry.group}' '${entry.age}' ${entry.argument}
'';
# generates a list of tmpfiles.d rules from the attrs (paths) under tmpfiles.settings.<name>
pathsToRules = mapAttrsToList (path: types:
concatStrings (
mapAttrsToList (_type: settingsEntryToRule path) types
)
);
mkRuleFileContent = paths: concatStrings (pathsToRules paths);
in
{
options = {
@ -20,101 +131,16 @@ in
'';
};
systemd.tmpfiles.settings = mkOption {
systemd.tmpfiles.settings = mkOption settingsOption;
boot.initrd.systemd.tmpfiles.settings = mkOption (settingsOption // {
description = ''
Declare systemd-tmpfiles rules to create, delete, and clean up volatile
and temporary files and directories.
Similar to {option}`systemd.tmpfiles.settings` but the rules are
only applied by systemd-tmpfiles before `initrd-switch-root.target`.
Even though the service is called `*tmp*files` you can also create
persistent files.
See {manpage}`bootup(7)`.
'';
example = {
"10-mypackage" = {
"/var/lib/my-service/statefolder".d = {
mode = "0755";
user = "root";
group = "root";
};
};
};
default = {};
type = types.attrsOf (types.attrsOf (types.attrsOf (types.submodule ({ name, config, ... }: {
options.type = mkOption {
type = types.str;
default = name;
example = "d";
description = ''
The type of operation to perform on the file.
The type consists of a single letter and optionally one or more
modifier characters.
Please see the upstream documentation for the available types and
more details:
<https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
'';
};
options.mode = mkOption {
type = types.str;
default = "-";
example = "0755";
description = ''
The file access mode to use when creating this file or directory.
'';
};
options.user = mkOption {
type = types.str;
default = "-";
example = "root";
description = ''
The user of the file.
This may either be a numeric ID or a user/group name.
If omitted or when set to `"-"`, the user and group of the user who
invokes systemd-tmpfiles is used.
'';
};
options.group = mkOption {
type = types.str;
default = "-";
example = "root";
description = ''
The group of the file.
This may either be a numeric ID or a user/group name.
If omitted or when set to `"-"`, the user and group of the user who
invokes systemd-tmpfiles is used.
'';
};
options.age = mkOption {
type = types.str;
default = "-";
example = "10d";
description = ''
Delete a file when it reaches a certain age.
If a file or directory is older than the current time minus the age
field, it is deleted.
If set to `"-"` no automatic clean-up is done.
'';
};
options.argument = mkOption {
type = types.str;
default = "";
example = "";
description = ''
An argument whose meaning depends on the type of operation.
Please see the upstream documentation for the meaning of this
parameter in different situations:
<https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
'';
};
}))));
};
});
systemd.tmpfiles.packages = mkOption {
type = types.listOf types.package;
@ -140,8 +166,9 @@ in
systemd.additionalUpstreamSystemUnits = [
"systemd-tmpfiles-clean.service"
"systemd-tmpfiles-clean.timer"
"systemd-tmpfiles-setup.service"
"systemd-tmpfiles-setup-dev-early.service"
"systemd-tmpfiles-setup-dev.service"
"systemd-tmpfiles-setup.service"
];
systemd.additionalUpstreamUserUnits = [
@ -236,11 +263,7 @@ in
'';
})
] ++ (mapAttrsToList (name: paths:
pkgs.writeTextDir "lib/tmpfiles.d/${name}.conf" (concatStrings (mapAttrsToList (path: types:
concatStrings (mapAttrsToList (_type: entry: ''
'${entry.type}' '${path}' '${entry.mode}' '${entry.user}' '${entry.group}' '${entry.age}' ${entry.argument}
'') types)
) paths ))
pkgs.writeTextDir "lib/tmpfiles.d/${name}.conf" (mkRuleFileContent paths)
) cfg.settings);
systemd.tmpfiles.rules = [
@ -256,5 +279,62 @@ in
"R! /nix/var/nix/gcroots/tmp - - - - -"
"R! /nix/var/nix/temproots - - - - -"
];
boot.initrd.systemd = {
additionalUpstreamUnits = [
"systemd-tmpfiles-setup-dev-early.service"
"systemd-tmpfiles-setup-dev.service"
"systemd-tmpfiles-setup.service"
];
# override to exclude the prefix /sysroot, because it is not necessarily set up when the unit starts
services.systemd-tmpfiles-setup.serviceConfig = {
ExecStart = [
""
"systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev --exclude-prefix=/sysroot"
];
};
# sets up files under the prefix /sysroot, after the hierarchy is available and before nixos activation
services.systemd-tmpfiles-setup-sysroot = {
description = "Create Volatile Files and Directories in the Real Root";
after = [ "initrd-fs.target" ];
before = [
"initrd-nixos-activation.service"
"shutdown.target" "initrd-switch-root.target"
];
conflicts = [ "shutdown.target" "initrd-switch-root.target" ];
wantedBy = [ "initrd.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev --prefix=/sysroot";
SuccessExitStatus = [ "DATAERR CANTCREAT" ];
ImportCredential = [
"tmpfiles.*"
"login.motd"
"login.issue"
"network.hosts"
"ssh.authorized_keys.root"
];
};
unitConfig = {
DefaultDependencies = false;
RefuseManualStop = true;
};
};
contents."/etc/tmpfiles.d" = mkIf (initrdCfg.settings != { }) {
source = pkgs.linkFarm "initrd-tmpfiles.d" (
mapAttrsToList
(name: paths: {
name = "${name}.conf";
path = pkgs.writeText "${name}.conf" (mkRuleFileContent paths);
}
)
initrdCfg.settings);
};
};
};
}

View File

@ -192,6 +192,7 @@ in {
cfssl = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cfssl.nix {};
cgit = handleTest ./cgit.nix {};
charliecloud = handleTest ./charliecloud.nix {};
chromadb = runTest ./chromadb.nix;
chromium = (handleTestOn ["aarch64-linux" "x86_64-linux"] ./chromium.nix {}).stable or {};
chrony = handleTestOn ["aarch64-linux" "x86_64-linux"] ./chrony.nix {};
chrony-ptp = handleTestOn ["aarch64-linux" "x86_64-linux"] ./chrony-ptp.nix {};
@ -421,6 +422,7 @@ in {
hddfancontrol = handleTest ./hddfancontrol.nix {};
hedgedoc = handleTest ./hedgedoc.nix {};
herbstluftwm = handleTest ./herbstluftwm.nix {};
homebox = handleTest ./homebox.nix {};
homepage-dashboard = handleTest ./homepage-dashboard.nix {};
honk = runTest ./honk.nix;
installed-tests = pkgs.recurseIntoAttrs (handleTest ./installed-tests {});
@ -825,7 +827,7 @@ in {
qgis = handleTest ./qgis.nix { qgisPackage = pkgs.qgis; };
qgis-ltr = handleTest ./qgis.nix { qgisPackage = pkgs.qgis-ltr; };
qownnotes = handleTest ./qownnotes.nix {};
qtile = handleTestOn ["x86_64-linux" "aarch64-linux"] ./qtile.nix {};
qtile = handleTestOn ["x86_64-linux" "aarch64-linux"] ./qtile/default.nix {};
quake3 = handleTest ./quake3.nix {};
quicktun = handleTest ./quicktun.nix {};
quickwit = handleTest ./quickwit.nix {};

View File

@ -27,6 +27,12 @@ in {
desc = "some-repo description";
};
};
settings = {
readme = [
":README.md"
":date.txt"
];
};
};
environment.systemPackages = [ pkgs.git ];
@ -56,18 +62,42 @@ in {
git init -b master reference
cd reference
git remote add origin /tmp/git/some-repo
date > date.txt
{ echo -n "cgit NixOS Test at "; date; } > date.txt
git add date.txt
git -c user.name=test -c user.email=test@localhost commit -m 'add date'
git push -u origin master
''}")
# test web download
server.succeed(
"curl -fsS 'http://localhost/%28c%29git/some-repo/plain/date.txt?id=master' | diff -u reference/date.txt -"
)
# test http clone
server.succeed(
"git clone http://localhost/%28c%29git/some-repo && diff -u reference/date.txt some-repo/date.txt"
)
# test list settings by greping for the fallback readme
server.succeed(
"curl -fsS 'http://localhost/%28c%29git/some-repo/about/' | grep -F 'cgit NixOS Test at'"
)
# add real readme
server.succeed("sudo -u cgit ${pkgs.writeShellScript "cgit-commit-readme" ''
set -e
echo '# cgit NixOS test README' > reference/README.md
git -C reference add README.md
git -C reference -c user.name=test -c user.email=test@localhost commit -m 'add readme'
git -C reference push
''}")
# test list settings by greping for the real readme
server.succeed(
"curl -fsS 'http://localhost/%28c%29git/some-repo/about/' | grep -F '# cgit NixOS test README'"
)
server.fail(
"curl -fsS 'http://localhost/%28c%29git/some-repo/about/' | grep -F 'cgit NixOS Test at'"
)
'';
})

26
nixos/tests/chromadb.nix Normal file
View File

@ -0,0 +1,26 @@
{ lib, pkgs, ... }:
let
lib = pkgs.lib;
in
{
name = "chromadb";
meta.maintainers = [ lib.maintainers.drupol ];
nodes = {
machine =
{ pkgs, ... }:
{
services.chromadb = {
enable = true;
};
};
};
testScript = ''
machine.start()
machine.wait_for_unit("chromadb.service")
machine.wait_for_open_port(8000)
'';
}

View File

@ -4,6 +4,9 @@ import ./make-test-python.nix ({ pkgs, ...} :
meta = with pkgs.lib.maintainers; {
maintainers = [ romildo ];
timeout = 600;
# OCR tests are flaky
broken = true;
};
nodes.machine = { ... }:

View File

@ -7,7 +7,7 @@
harmonia = {
services.harmonia = {
enable = true;
signKeyPath = pkgs.writeText "cache-key" "cache.example.com-1:9FhO0w+7HjZrhvmzT1VlAZw4OSAlFGTgC24Seg3tmPl4gZBdwZClzTTHr9cVzJpwsRSYLTu7hEAQe3ljy92CWg==";
signKeyPaths = [(pkgs.writeText "cache-key" "cache.example.com-1:9FhO0w+7HjZrhvmzT1VlAZw4OSAlFGTgC24Seg3tmPl4gZBdwZClzTTHr9cVzJpwsRSYLTu7hEAQe3ljy92CWg==")];
settings.priority = 35;
};

26
nixos/tests/homebox.nix Normal file
View File

@ -0,0 +1,26 @@
import ./make-test-python.nix (
{ pkgs, ... }:
let
port = "7745";
in
{
name = "homebox";
meta = with pkgs.lib.maintainers; {
maintainers = [ patrickdag ];
};
nodes.machine = {
services.homebox = {
enable = true;
settings.HBOX_WEB_PORT = port;
};
};
testScript = ''
machine.wait_for_unit("homebox.service")
machine.wait_for_open_port(${port})
machine.succeed("curl --fail -X GET 'http://localhost:${port}/'")
out = machine.succeed("curl --fail 'http://localhost:${port}/api/v1/status'")
assert '"health":true' in out
'';
}
)

View File

@ -51,8 +51,8 @@ in
with subtest("the backend starts and responds"):
server.wait_for_open_port(${toString backendPort})
# wait until succeeds, it just needs few seconds for migrations, but lets give it 10s max
server.wait_until_succeeds("curl --fail localhost:${toString backendPort}/api/v3/site", 10)
# wait until succeeds, it just needs few seconds for migrations, but lets give it 50s max
server.wait_until_succeeds("curl --fail localhost:${toString backendPort}/api/v3/site", 50)
with subtest("the UI starts and responds"):
server.wait_for_unit("lemmy-ui.service")
@ -77,7 +77,7 @@ in
server.execute("systemctl stop lemmy-ui.service")
def assert_http_code(url, expected_http_code, extra_curl_args=""):
_, http_code = server.execute(f'curl --silent -o /dev/null {extra_curl_args} --fail --write-out "%{{http_code}}" {url}')
_, http_code = server.execute(f'curl --location --silent -o /dev/null {extra_curl_args} --fail --write-out "%{{http_code}}" {url}')
assert http_code == str(expected_http_code), f"expected http code {expected_http_code}, got {http_code}"
# Caddy responds with HTTP code 502 if it cannot handle the requested path

View File

@ -1,20 +1,12 @@
import ./make-test-python.nix ({ pkgs, ... } :
let
testAuthFile = pkgs.writeTextFile {
name = "authFile";
text = ''
"testuser" "testpass"
'';
};
in
{
import ./make-test-python.nix ({ lib, pkgs, ... }: {
name = "pgbouncer";
meta = with pkgs.lib.maintainers; {
meta = with lib.maintainers; {
maintainers = [ _1000101 ];
};
nodes = {
one = { config, pkgs, ... }: {
nodes = {
one = { pkgs, ... }: {
systemd.services.postgresql = {
postStart = ''
${pkgs.postgresql}/bin/psql -U postgres -c "ALTER ROLE testuser WITH LOGIN PASSWORD 'testpass'";
@ -26,10 +18,7 @@ in
postgresql = {
enable = true;
ensureDatabases = [ "testdb" ];
ensureUsers = [
{
name = "testuser";
}];
ensureUsers = [{ name = "testuser"; }];
authentication = ''
local testdb testuser scram-sha-256
'';
@ -37,10 +26,19 @@ in
pgbouncer = {
enable = true;
listenAddress = "localhost";
databases = { test = "host=/run/postgresql/ port=5432 auth_user=testuser dbname=testdb"; };
authType = "scram-sha-256";
authFile = testAuthFile;
openFirewall = true;
settings = {
pgbouncer = {
listen_addr = "localhost";
auth_type = "scram-sha-256";
auth_file = builtins.toFile "pgbouncer-users.txt" ''
"testuser" "testpass"
'';
};
databases = {
test = "host=/run/postgresql port=5432 auth_user=testuser dbname=testdb";
};
};
};
};
};

View File

@ -1001,13 +1001,24 @@ let
metricProvider = {
services.postgresql.enable = true;
services.pgbouncer = {
# https://github.com/prometheus-community/pgbouncer_exporter#pgbouncer-configuration
ignoreStartupParameters = "extra_float_digits";
enable = true;
listenAddress = "*";
databases = { postgres = "host=/run/postgresql/ port=5432 auth_user=postgres dbname=postgres"; };
authType = "any";
maxClientConn = 99;
settings = {
pgbouncer = {
listen_addr = "*";
auth_type = "any";
max_client_conn = 99;
# https://github.com/prometheus-community/pgbouncer_exporter#pgbouncer-configuration
ignore_startup_parameters = "extra_float_digits";
};
databases = {
postgres = concatStringsSep " " [
"host=/run/postgresql"
"port=5432"
"auth_user=postgres"
"dbname=postgres"
];
};
};
};
};
exporterTest = ''

View File

@ -0,0 +1,19 @@
--- a/config.py 2024-05-31 14:49:23.852287845 +0200
+++ b/config.py 2024-05-31 14:51:00.935182266 +0200
@@ -29,6 +29,8 @@
from libqtile.lazy import lazy
from libqtile.utils import guess_terminal
+from qtile_extras import widget
+
mod = "mod4"
terminal = guess_terminal()
@@ -162,6 +164,7 @@
# NB Systray is incompatible with Wayland, consider using StatusNotifier instead
# widget.StatusNotifier(),
widget.Systray(),
+ widget.AnalogueClock(),
widget.Clock(format="%Y-%m-%d %a %I:%M %p"),
widget.QuickExit(),
],

View File

@ -0,0 +1,24 @@
{ stdenvNoCC, fetchurl }:
stdenvNoCC.mkDerivation {
name = "qtile-config";
version = "0.0.1";
src = fetchurl {
url = "https://raw.githubusercontent.com/qtile/qtile/v0.28.1/libqtile/resources/default_config.py";
hash = "sha256-Y5W277CWVNSi4BdgEW/f7Px/MMjnN9W9TDqdOncVwPc=";
};
prePatch = ''
cp $src config.py
'';
patches = [ ./add-widget.patch ];
dontUnpack = true;
dontBuild = true;
installPhase = ''
mkdir -p $out
cp config.py $out/config.py
'';
}

View File

@ -1,15 +1,26 @@
import ./make-test-python.nix ({ lib, ...} : {
import ../make-test-python.nix ({ lib, ...} : {
name = "qtile";
meta = {
maintainers = with lib.maintainers; [ sigmanificient ];
};
nodes.machine = { pkgs, lib, ... }: {
imports = [ ./common/x11.nix ./common/user-account.nix ];
nodes.machine = { pkgs, lib, ... }: let
# We create a custom Qtile configuration file that adds a widget from
# qtile-extras to the bar. This ensure that the qtile-extras package
# also works, and that extraPackages behave as expected.
config-deriv = pkgs.callPackage ./config.nix { };
in {
imports = [ ../common/x11.nix ../common/user-account.nix ];
test-support.displayManager.auto.user = "alice";
services.xserver.windowManager.qtile.enable = true;
services.xserver.windowManager.qtile = {
enable = true;
configFile = "${config-deriv}/config.py";
extraPackages = ps: [ ps.qtile-extras ];
};
services.displayManager.defaultSession = lib.mkForce "qtile";
environment.systemPackages = [ pkgs.kitty ];

View File

@ -269,9 +269,9 @@ in
'';
};
memtest86 = makeTest {
memtest86 = with pkgs.lib; optionalAttrs (meta.availableOn { inherit system; } pkgs.memtest86plus) (makeTest {
name = "systemd-boot-memtest86";
meta.maintainers = with pkgs.lib.maintainers; [ julienmalka ];
meta.maintainers = with maintainers; [ julienmalka ];
nodes.machine = { pkgs, lib, ... }: {
imports = [ common ];
@ -282,7 +282,7 @@ in
machine.succeed("test -e /boot/loader/entries/memtest86.conf")
machine.succeed("test -e /boot/efi/memtest86/memtest.efi")
'';
};
});
netbootxyz = makeTest {
name = "systemd-boot-netbootxyz";

View File

@ -10,6 +10,9 @@ let
192.168.2.103 mastodon.local
'';
postgresqlPassword = "thisisnotasecret";
redisPassword = "thisisnotasecrettoo";
in
{
name = "mastodon-remote-postgresql";
@ -19,9 +22,7 @@ in
databases = { config, ... }: {
environment = {
etc = {
"redis/password-redis-db".text = ''
ogjhJL8ynrP7MazjYOF6
'';
"redis/password-redis-db".text = redisPassword;
};
};
networking = {
@ -46,16 +47,19 @@ in
services.postgresql = {
enable = true;
# TODO remove once https://github.com/NixOS/nixpkgs/pull/266270 is resolved.
package = pkgs.postgresql_14;
enableTCPIP = true;
authentication = ''
hostnossl mastodon_local mastodon_test 192.168.2.201/32 md5
hostnossl mastodon mastodon 192.168.2.201/32 md5
'';
ensureDatabases = [ "mastodon" ];
ensureUsers = [
{
name = "mastodon";
ensureDBOwnership = true;
}
];
initialScript = pkgs.writeText "postgresql_init.sql" ''
CREATE ROLE mastodon_test LOGIN PASSWORD 'SoDTZcISc3f1M1LJsRLT';
CREATE DATABASE mastodon_local TEMPLATE template0 ENCODING UTF8;
GRANT ALL PRIVILEGES ON DATABASE mastodon_local TO mastodon_test;
CREATE ROLE mastodon LOGIN PASSWORD '${postgresqlPassword}';
'';
};
};
@ -100,12 +104,8 @@ in
environment = {
etc = {
"mastodon/password-redis-db".text = ''
ogjhJL8ynrP7MazjYOF6
'';
"mastodon/password-posgressql-db".text = ''
SoDTZcISc3f1M1LJsRLT
'';
"mastodon/password-redis-db".text = redisPassword;
"mastodon/password-posgressql-db".text = postgresqlPassword;
};
};
@ -138,8 +138,8 @@ in
createLocally = false;
host = "192.168.2.102";
port = 5432;
name = "mastodon_local";
user = "mastodon_test";
name = "mastodon";
user = "mastodon";
passwordFile = "/etc/mastodon/password-posgressql-db";
};
smtp = {

View File

@ -34,9 +34,6 @@ in
pki.certificateFiles = [ "${cert pkgs}/cert.pem" ];
};
# TODO remove once https://github.com/NixOS/nixpkgs/pull/266270 is resolved.
services.postgresql.package = pkgs.postgresql_14;
services.mastodon = {
enable = true;
configureNginx = true;

View File

@ -366,9 +366,7 @@ Example: Given a project that has no tags / released versions at all, or applies
Because every version of a package in Nixpkgs creates a potential maintenance burden, old versions of a package should not be kept unless there is a good reason to do so. For instance, Nixpkgs contains several versions of GCC because other packages dont build with the latest version of GCC. Other examples are having both the latest stable and latest pre-release version of a package, or to keep several major releases of an application that differ significantly in functionality.
If there is only one version of a package, its Nix expression should be named `e2fsprogs/default.nix`. If there are multiple versions, this should be reflected in the filename, e.g. `e2fsprogs/1.41.8.nix` and `e2fsprogs/1.41.9.nix`. The version in the filename should leave out unnecessary detail. For instance, if we keep the latest Firefox 2.0.x and 3.5.x versions in Nixpkgs, they should be named `firefox/2.0.nix` and `firefox/3.5.nix`, respectively (which, at a given point, might contain versions `2.0.0.20` and `3.5.4`). If a version requires many auxiliary files, you can use a subdirectory for each version, e.g. `firefox/2.0/default.nix` and `firefox/3.5/default.nix`.
All versions of a package _must_ be included in `all-packages.nix` to make sure that they evaluate correctly.
If there is only one version of a package, its Nix expression should be named (e.g) `pkgs/by-name/xy/xyz/package.nix`. If there are multiple versions, this should be reflected in the attribute name. If you wish to share code between the Nix expressions of each version, you cannot rely upon `pkgs/by-name`'s automatic attribute creation, and must create the attributes yourself in `all-packages.nix`. See also [`pkgs/by-name/README.md`'s section on this topic](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/README.md#recommendation-for-new-packages-with-multiple-versions).
## Meta attributes

View File

@ -23,7 +23,7 @@
stdenv.mkDerivation rec {
pname = "squeekboard";
version = "1.38.0";
version = "1.41.0";
src = fetchFromGitLab {
domain = "gitlab.gnome.org";
@ -31,13 +31,13 @@ stdenv.mkDerivation rec {
owner = "Phosh";
repo = pname;
rev = "v${version}";
hash = "sha256-ZVSnLH2wLPcOHkU2pO0BgIdGmULMNiacIYMRmhN+bZ8=";
hash = "sha256-WHGdA0cEB1nu7vJ+pwjdl8aZzccJ232vsbSGmZohFVo=";
};
cargoDeps = rustPlatform.fetchCargoTarball {
inherit src;
name = "${pname}-${version}";
hash = "sha256-tcn1tRuRlHVTYvc8T/ePfCEPNjih6B9lo/hdX+WwitQ=";
hash = "sha256-CRKaH8cA/EhXQna3zCU0Z06zkB9qu6QxPJ4No3NFcs0=";
};
nativeBuildInputs = [

View File

@ -3,6 +3,7 @@
, fetchgit
, fetchzip
, fetchpatch
, fetchpatch2
, alsa-lib
, aubio
, boost
@ -86,6 +87,12 @@ stdenv.mkDerivation rec {
url = "https://github.com/Ardour/ardour/commit/e995daa37529715214c6c4a2587e4134aaaba02f.patch";
hash = "sha256-EpXOIIObOwwcNgNma0E3nvaBad3930sagDjBpa+78WI=";
})
# Work around itstools bug #9648
(fetchpatch2 {
url = "https://github.com/Ardour/ardour/commit/338cd09a4aa1b36b8095dfc14ab534395f9a4a92.patch?full_index=1";
hash = "sha256-AvV4aLdkfrxPkE4NX2ETSagq4GjEC+sHCEqdcYvL+CY=";
})
];
# Ardour's wscript requires git revision and date to be available.

View File

@ -27,7 +27,7 @@ python311Packages.buildPythonApplication rec {
./disable-autoupdate.patch
];
postPatch = with lib; ''
postPatch = ''
sed -i -re 's,^( *gpodder_dir *= *).*,\1"'"$out"'",' bin/gpodder
'';

View File

@ -14,17 +14,17 @@
rustPlatform.buildRustPackage rec {
pname = "listenbrainz-mpd";
version = "2.3.7";
version = "2.3.8";
src = fetchFromGitea {
domain = "codeberg.org";
owner = "elomatreb";
repo = "listenbrainz-mpd";
rev = "v${version}";
hash = "sha256-xnVhPiHhI7VqkSBBlrKJBpdS6kd51DMlKWVnJIo/OQQ=";
hash = "sha256-QBc0avci232UIxzTKlS0pjL7cCuvwAFgw6dSwdtYAtU=";
};
cargoHash = "sha256-Reglc7UtsFk+VIwg4Q9TIChVrWweuV6yPWxbtTDH6mU=";
cargoHash = "sha256-jnDS9tIJ387A2P9oUSYB3tXrXjwwVmQ26erIIlHBkao=";
nativeBuildInputs = [ pkg-config installShellFiles asciidoctor ];

View File

@ -1,7 +1,5 @@
{ lib
# Python 3.12 demonstrates a peculiar segmentation fault with pyqt5. Using
# pyqt6 with Python 3.12 should work, but this is not released yet.
, python311Packages
, python312Packages
, fetchFromGitHub
, chromaprint
@ -13,7 +11,7 @@
}:
let
pythonPackages = python311Packages;
pythonPackages = python312Packages;
pyqt5 =
if enablePlayback then
pythonPackages.pyqt5-multimedia
@ -23,19 +21,20 @@ in
pythonPackages.buildPythonApplication rec {
pname = "picard";
# nix-update --commit picard --version-regex 'release-(.*)'
version = "2.12";
version = "2.12.1";
format = "setuptools";
src = fetchFromGitHub {
owner = "metabrainz";
repo = "picard";
rev = "refs/tags/release-${version}";
hash = "sha256-+++NDJzXw4tA5eQd24r+l3UK3YS8Jy1t9WNiEU9sH0Q=";
hash = "sha256-wKPE4lj3DIlY+X5A/MqhnwyrhPTXGjmUnLK1VWXUOas=";
};
nativeBuildInputs = [
gettext
qt5.wrapQtAppsHook
pythonPackages.pytestCheckHook
] ++ lib.optionals (pyqt5.multimediaEnabled) [
gst_all_1.gst-libav
gst_all_1.gst-plugins-base
@ -68,6 +67,7 @@ pythonPackages.buildPythonApplication rec {
preCheck = ''
export HOME=$(mktemp -d)
'';
doCheck = true;
# In order to spare double wrapping, we use:
preFixup = ''
@ -76,12 +76,13 @@ pythonPackages.buildPythonApplication rec {
makeWrapperArgs+=(--prefix GST_PLUGIN_SYSTEM_PATH_1_0 : "$GST_PLUGIN_SYSTEM_PATH_1_0")
'';
meta = with lib; {
meta = {
homepage = "https://picard.musicbrainz.org";
changelog = "https://picard.musicbrainz.org/changelog";
description = "Official MusicBrainz tagger";
mainProgram = "picard";
license = licenses.gpl2Plus;
platforms = platforms.all;
license = lib.licenses.gpl2Plus;
platforms = lib.platforms.all;
maintainers = with lib.maintainers; [ doronbehar ];
};
}

View File

@ -16,13 +16,13 @@ let
in
rustPlatform.buildRustPackage rec {
pname = "psst";
version = "unstable-2024-07-29";
version = "unstable-2024-08-19";
src = fetchFromGitHub {
owner = "jpochyla";
repo = pname;
rev = "d895cb94623d320f79b364a8f63ab518fddf697b";
hash = "sha256-LsveuaDmRvC9TUON847QdzqQDUW1zd37++MbtXrfJjk=";
rev = "11bef15e66a3c9b0b991207d09a67c071b3dda02";
hash = "sha256-lKxWIUDouUUul7CpuTy30z/cLJAjFE9e0J1zyZ/PnIo=";
};
cargoLock = {

View File

@ -54,7 +54,7 @@ index fcbd491..8f6e6f0 100644
-pub const GIT_VERSION: &str = git_version!();
-pub const BUILD_TIME: &str = include!(concat!(env!("OUT_DIR"), "/build-time.txt"));
-pub const REMOTE_URL: &str = include!(concat!(env!("OUT_DIR"), "/remote-url.txt"));
+pub const GIT_VERSION: &str = "d895cb94623d320f79b364a8f63ab518fddf697b";
+pub const GIT_VERSION: &str = "11bef15e66a3c9b0b991207d09a67c071b3dda02";
+pub const BUILD_TIME: &str = "1970-01-01 00:00:00";
+pub const REMOTE_URL: &str = "https://github.com/jpochyla/psst";

View File

@ -8,13 +8,13 @@
stdenv.mkDerivation (finalAttrs: {
pname = "pt2-clone";
version = "1.69.2";
version = "1.70";
src = fetchFromGitHub {
owner = "8bitbubsy";
repo = "pt2-clone";
rev = "v${finalAttrs.version}";
sha256 = "sha256-Vy8b9rbYM/bK/mCUW4V4rPeAmoBN/wn7iVBANSboL2Q=";
sha256 = "sha256-oGdgvyVIqM4YVxyr5DFBJ+YLtH95vqbNv0arD9yskdo=";
};
nativeBuildInputs = [ cmake ];

View File

@ -36,8 +36,8 @@ let
pffft-source = fetchFromBitbucket {
owner = "jpommier";
repo = "pffft";
rev = "38946c766c1afecfa4c5945af77913e38b3cec31";
sha256 = "1w6g9v9fy7bavqacb6qw1nxhcik2w36cvl2d7b0bh68w0pd70j5q";
rev = "fbc4058602803f40dc554b8a5d2bcc694c005f2f";
sha256 = "16biji3115232cr1j975hpxw68lfybajlspnhfjcwg8jz2d8ybrf";
};
fuzzysearchdatabase-source = fetchFromBitbucket {
owner = "j_norberg";
@ -64,28 +64,28 @@ let
sha256 = "1d3058x6wgzw7b0wai792flk7s6ffw0z4n9sl016v91yjwv7ds3a";
};
oui-blendish-source = fetchFromGitHub {
owner = "AndrewBelt";
owner = "VCVRack";
repo = "oui-blendish";
rev = "2fc6405883f8451944ed080547d073c8f9f31898";
sha256 = "/QZFZuI5kSsEvSfMJlcqB1HiZ9Vcf3vqLqWIMEgxQK8=";
sha256 = "1bs0654312555vm7nzswsmky4l8759bjdk17pl22p49rw9k4a1px";
};
simde-source = fetchFromGitHub {
owner = "simd-everywhere";
repo = "simde";
rev = "b309d8951997201e493380a2fd09198c09ae1b4e";
sha256 = "1hz8mfbhbiafvim4qrkyvh1yndlhydqkxwhls7cfqa48wkpxfip8";
rev = "416091ebdb9e901b29d026633e73167d6353a0b0";
sha256 = "064ygc6c737yjx04rydwwhkr4n4s4rbvj27swxwyzvp1h8nka6xf";
};
tinyexpr-source = fetchFromGitHub {
owner = "codeplea";
repo = "tinyexpr";
rev = "74804b8c5d296aad0866bbde6c27e2bc1d85e5f2";
sha256 = "0z3r7wfw7p2wwl6wls2nxacirppr2147yz29whxmjaxy89ic1744";
rev = "9907207e5def0fabdb60c443517b0d9e9d521393";
sha256 = "0xbpd09zvrk2ppm1qm1skk6p50mqr9mzjixv3s0biqq6jpabs88l";
};
fundamental-source = fetchFromGitHub {
owner = "VCVRack";
repo = "Fundamental";
rev = "962547d7651260fb6a04f4d8aafd7c27f0221bee"; # tip of branch v2
sha256 = "066gcjkni8ba98vv0di59x3f9piir0vyy5sb53cqrbrl51x853cg";
rev = "5ed79544161e0fa9a55faa7c0a5f299e828e12ab"; # tip of branch v2
sha256 = "0c6qpigyr0ppvra20hcy1fdcmqa212jckb9wkx4f6fgdby7565wv";
};
vcv-rtaudio = stdenv.mkDerivation rec {
pname = "vcv-rtaudio";
@ -112,7 +112,7 @@ let
in
stdenv.mkDerivation rec {
pname = "vcv-rack";
version = "2.4.1";
version = "2.5.1";
desktopItems = [
(makeDesktopItem {
@ -132,7 +132,7 @@ stdenv.mkDerivation rec {
owner = "VCVRack";
repo = "Rack";
rev = "v${version}";
hash = "sha256-Gn/sFltLXX2mLv4dDqmr/UPd+JBXVkIZGwMI6Rm0Ih4=";
sha256 = "1q2bwjfn6crk9lyd6m3py0v754arw1xgpv5kkj6ka1bc2yz839qh";
};
patches = [

View File

@ -6,13 +6,13 @@
stdenv.mkDerivation rec {
pname = "vgmstream";
version = "1917";
version = "1951";
src = fetchFromGitHub {
owner = "vgmstream";
repo = "vgmstream";
rev = "refs/tags/r${version}";
sha256 = "sha256-9HIa5/whdLouUWNFml7tPfXStIkO76dxUl5S4yiat64=";
sha256 = "sha256-Wa0FAUHdJtG+u9y3ZOt8dxRIo78lekFPghiu67KJZ9s=";
};
passthru.updateScript = nix-update-script {

View File

@ -23,16 +23,16 @@
rustPlatform.buildRustPackage rec {
pname = "ludusavi";
version = "0.24.3";
version = "0.25.0";
src = fetchFromGitHub {
owner = "mtkennerly";
repo = "ludusavi";
rev = "v${version}";
hash = "sha256-FtLLj5uFcKuRTCSsSuyj0XGzFMVWQvVk4dTmBCmzfNs=";
hash = "sha256-GjecssOc5xVni73uNRQ/GaZmIdM9r09I8GpPK+jwoAY=";
};
cargoHash = "sha256-xC6HiXt8cfrDtno9IrOe8SP7WBL79paLI223fjxPsbg=";
cargoHash = "sha256-9QaQjb7bdDl4NWKbV+dfu9BgFU8NO3CZEvKSXujMUtI=";
nativeBuildInputs = [
cmake

View File

@ -2,7 +2,7 @@
let
pname = "erigon";
version = "2.60.5";
version = "2.60.6";
in
buildGoModule {
inherit pname version;
@ -11,11 +11,11 @@ buildGoModule {
owner = "ledgerwatch";
repo = pname;
rev = "v${version}";
hash = "sha256-sI5XlPoHjAN3QsNWJXhi+qHDPVpcLqgX1hMa6gN5Iwc=";
hash = "sha256-208gJTLaVEikH92ZDEULPtfnKJyZhZCRCDfCxewABK4=";
fetchSubmodules = true;
};
vendorHash = "sha256-2Gx3ZUq1FDGEPW4qTwK916AGVMwoIDY97rkuEzRXP1U=";
vendorHash = "sha256-TUK7obI1wOXroI1NE1GfIP+NMW909+z92Wpy9B/soY0=";
proxyVendor = true;
# Build errors in mdbx when format hardening is enabled:

View File

@ -10,8 +10,6 @@
name ? "zig-packages",
}:
with lib;
let
unpackZigArtifact =
{ name, artifact }:
@ -39,9 +37,9 @@ let
hash,
}:
let
parts = splitString "#" url;
base = elemAt parts 0;
rev = elemAt parts 1;
parts = lib.splitString "#" url;
base = lib.elemAt parts 0;
rev = lib.elemAt parts 1;
in
fetchgit {
inherit name rev hash;
@ -56,9 +54,9 @@ let
hash,
}:
let
parts = splitString "://" url;
proto = elemAt parts 0;
path = elemAt parts 1;
parts = lib.splitString "://" url;
proto = lib.elemAt parts 0;
path = lib.elemAt parts 1;
fetcher = {
"git+http" = fetchGitZig {
inherit name hash;

View File

@ -210,9 +210,7 @@ in rec {
# Gather up the desired plugins.
pluginEnv = buildEnv {
name = "eclipse-plugins";
paths =
with lib;
filter (x: x ? isEclipsePlugin) (closePropagation plugins);
paths = lib.filter (x: x ? isEclipsePlugin) (lib.closePropagation plugins);
};
# Prepare the JVM arguments to add to the ini file. We here also

View File

@ -23,10 +23,6 @@ lib.packagesFromDirectoryRecursive {
inherit (pkgs) basedpyright git go gopls python3;
};
matrix-client = callPackage ./manual-packages/matrix-client {
_map = self.map;
};
structured-haskell-mode = self.shm;
texpresso = callPackage ./manual-packages/texpresso { inherit (pkgs) texpresso; };
@ -48,5 +44,6 @@ lib.packagesFromDirectoryRecursive {
ess-R-object-popup = throw "emacsPackages.ess-R-object-popup was deleted, since the upstream repo looks abandoned."; # Added 2024-07-15
ghc-mod = throw "emacsPackages.ghc-mod was deleted because it is deprecated, use haskell-language-server instead."; # Added 2024-07-17
haskell-unicode-input-method = throw "emacsPackages.haskell-unicode-input-method is contained in emacsPackages.haskell-mode, please use that instead."; # Added 2024-07-17
matrix-client = throw "emacsPackages.matrix-client is deprecated in favor of emacsPackages.ement."; # Added 2024-08-17
perl-completion = throw "emacsPackages.perl-completion was removed, since it is broken."; # Added 2024-07-19
}

View File

@ -23,6 +23,8 @@ melpaBuild {
popon
];
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
meta = {

View File

@ -15,6 +15,8 @@ melpaBuild {
files = ''("acm/*.el" "acm/icons")'';
ignoreCompilationError = false;
meta = {
description = "Asynchronous Completion Menu";
homepage = "https://github.com/manateelazycat/lsp-bridge";

View File

@ -8,6 +8,8 @@ melpaBuild {
files = ''("src/data/emacs-mode/*.el")'';
ignoreCompilationError = false;
meta = {
inherit (Agda.meta) homepage license;
description = "Agda2-mode for Emacs extracted from Agda package";

View File

@ -25,6 +25,8 @@ melpaBuild {
})
];
ignoreCompilationError = false;
passthru.updateScript = gitUpdater { };
meta = {

View File

@ -13,6 +13,8 @@ melpaBuild {
hash = "sha256-JCrmS3FSGDHSR+eAR0X/uO0nAgd3TUmFxwEVH5+KV+4=";
};
ignoreCompilationError = false;
meta = {
homepage = "https://www.emacswiki.org/emacs/control-lock.el";
description = "Like caps-lock, but for your control key";

View File

@ -30,6 +30,8 @@ melpaBuild {
propagatedUserEnvPkgs = [ nodejs ];
ignoreCompilationError = false;
meta = {
description = "Unofficial copilot plugin for Emacs";
homepage = "https://github.com/copilot-emacs/copilot.el";

View File

@ -13,6 +13,8 @@ melpaBuild rec {
hash = "sha256-GFEDWT88Boz/DxEcmFgf7u2NOoMjAN05yRiYwoYtvXc=";
};
ignoreCompilationError = false;
meta = {
homepage = "https://gitweb.gentoo.org/proj/ebuild-mode.git/";
description = "Major modes for Gentoo package files";

View File

@ -21,6 +21,8 @@ melpaBuild {
files = ''(:defaults "msg")'';
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { tagPrefix = "v"; };
meta = {

View File

@ -27,6 +27,8 @@ melpaBuild {
make
'';
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { };
meta = {

View File

@ -16,6 +16,8 @@ melpaBuild {
hash = "sha256-DIGvnotSQYIgHxGxtyCALHd8ZbrfkmdvjLXlkcqQ6v4=";
};
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
meta = {

View File

@ -23,6 +23,8 @@ melpaBuild {
markdown-mode
];
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
meta = {

View File

@ -17,6 +17,8 @@ melpaBuild {
hash = "sha256-er+knxqAejgKAtOnhqHfsGN286biHFdeMIUlbW7JyYw=";
};
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { };
meta = {

View File

@ -16,6 +16,8 @@ melpaBuild {
hash = "sha256-xwVCAdxnIRHrFNWvtlM3u6CShsUiGgl1CiBTsp2x7IM=";
};
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
meta = {

View File

@ -16,6 +16,8 @@ melpaBuild {
hash = "sha256-3QDw4W3FbFvb2zpkDHAo9BJKxs3LaehyvUVJPKqS9RE=";
};
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
meta = {

View File

@ -22,6 +22,8 @@ melpaBuild {
helm
];
ignoreCompilationError = false;
meta = {
homepage = "https://github.com/emacsmirror/helm-words";
description = "Helm extension for looking up words in dictionaries and thesauri";

View File

@ -16,6 +16,8 @@ melpaBuild {
packageRequires = [ haskell-mode ];
ignoreCompilationError = false;
meta = {
inherit (hsc3.meta) homepage license;
description = "Emacs mode for hsc3";

View File

@ -16,6 +16,8 @@ melpaBuild {
hash = "sha256-Xbt0D9EgmvN1hDTeLbdxq1ARHObj8M4GfH2sbFILRTI=";
};
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
meta = {

View File

@ -24,6 +24,8 @@ melpaBuild {
prop-menu
];
ignoreCompilationError = false;
passthru.updateScript = gitUpdater { };
meta = {

View File

@ -17,6 +17,8 @@ melpaBuild {
hash = "sha256-h/jkIWjkLFbtBp9F+lhA3CulYy2XaeloLmexR0CDm3E=";
};
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { };
meta = {

View File

@ -16,6 +16,8 @@ melpaBuild {
hash = "sha256-Xli7TxBenl5cDMJv3Qz7ZELFpvJKStMploLpf9a+uoA=";
};
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
meta = {

View File

@ -27,6 +27,8 @@ melpaBuild rec {
mv tmp.el jam-mode.el
'';
ignoreCompilationError = false;
meta = {
description = "Emacs major mode for editing Jam files";
license = lib.licenses.gpl2Plus;

View File

@ -19,6 +19,8 @@ melpaBuild {
files = ''("tools/emacs/ligo-mode.el")'';
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { };
meta = {

View File

@ -9,6 +9,8 @@ melpaBuild {
"llvm/utils/emacs/README")
'';
ignoreCompilationError = false;
meta = {
inherit (llvmPackages.llvm.meta) homepage license;
description = "Major mode for the LLVM assembler language";

View File

@ -86,6 +86,8 @@ melpaBuild {
__darwinAllowLocalNetworking = true;
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
meta = {

View File

@ -24,6 +24,8 @@ melpaBuild {
# to compile lspce.el, it needs lspce-module.so
files = ''(:defaults "${lib.getLib lspce-module}/lib/lspce-module.*")'';
ignoreCompilationError = false;
passthru = {
inherit lspce-module;
updateScript = nix-update-script {

View File

@ -1,65 +0,0 @@
{
lib,
melpaBuild,
fetchFromGitHub,
fetchpatch,
# Emacs packages
_map,
a,
anaphora,
cl-lib,
dash,
dash-functional,
esxml,
f,
frame-purpose,
ht,
ov,
rainbow-identifiers,
request,
s,
tracking,
}:
melpaBuild {
pname = "matrix-client";
version = "0.3.0";
src = fetchFromGitHub {
owner = "alphapapa";
repo = "matrix-client.el";
rev = "d2ac55293c96d4c95971ed8e2a3f6f354565c5ed";
hash = "sha256-GLM8oCbm6PdEZPsM0ogMtNJr8mWjCKoX6ed5AUrYjuk=";
};
patches = [
# Fix: avatar loading when imagemagick support is not available
(fetchpatch {
url = "https://github.com/alphapapa/matrix-client.el/commit/5f49e615c7cf2872f48882d3ee5c4a2bff117d07.patch";
hash = "sha256-dXUa/HKDe+UjaXYTvgwPdXDuDcHB2HLPGWHboE+Lex0=";
})
];
packageRequires = [
_map
a
anaphora
cl-lib
dash
dash-functional
esxml
f
frame-purpose
ht
ov
rainbow-identifiers
request
s
tracking
];
meta = {
description = "Chat client and API wrapper for Matrix.org";
license = lib.licenses.gpl3Plus;
};
}

View File

@ -27,6 +27,8 @@ elpaBuild {
popd
'';
ignoreCompilationError = false;
meta = mu.meta // {
description = "Full-featured e-mail client";
};

View File

@ -59,6 +59,8 @@ melpaBuild {
install -D --target-directory=$out/bin source/notdeft-xapian
'';
ignoreCompilationError = false;
passthru = {
updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
};

View File

@ -15,6 +15,8 @@ melpaBuild {
popd
'';
ignoreCompilationError = false;
meta = {
description = "Emacs ott mode (from ott sources)";
inherit (ott.meta) homepage license;

View File

@ -26,6 +26,8 @@ melpaBuild {
install -Dm644 -t ''${!outputDoc}/share/doc/pod-mode/ $sourceRoot/ChangeLog $sourceRoot/README
'';
ignoreCompilationError = false;
meta = {
homepage = "https://metacpan.org/dist/pod-mode";
description = "Major mode for editing .pod-files";

View File

@ -3,13 +3,17 @@
fetchFromGitHub,
melpaBuild,
js2-mode,
lsp-mode,
}:
melpaBuild {
pname = "prisma-mode";
version = "0-unstable-2021-12-07";
packageRequires = [ js2-mode ];
packageRequires = [
js2-mode
lsp-mode
];
src = fetchFromGitHub {
owner = "pimeys";
@ -18,6 +22,8 @@ melpaBuild {
hash = "sha256-DJJfjbu27Gi7Nzsa1cdi8nIQowKH8ZxgQBwfXLB0Q/I=";
};
ignoreCompilationError = false;
meta = {
description = "Major mode for Prisma Schema Language";
license = lib.licenses.gpl2Only;

View File

@ -19,6 +19,8 @@ melpaBuild {
--replace-fail ";; prolog.el ---" ";;; prolog.el ---"
'';
ignoreCompilationError = false;
meta = {
homepage = "https://bruda.ca/emacs/prolog_mode_for_emacs/";
description = "Prolog mode for Emacs";

View File

@ -19,6 +19,8 @@ melpaBuild {
hash = "sha256-/8T1VTYkKUxlNWXuuS54S5jpl4UxJBbgSuWc17a/VyM=";
};
ignoreCompilationError = false;
passthru.updateScript = gitUpdater { };
meta = {

View File

@ -17,6 +17,8 @@ melpaBuild {
hash = "sha256-D36qiRi5OTZrBtJ/bD/javAWizZ8NLlC/YP4rdLCSsw=";
};
ignoreCompilationError = false;
passthru.updateScript = unstableGitUpdater { hardcodeZeroVersion = true; };
meta = {

View File

@ -13,6 +13,8 @@ melpaBuild {
hash = "sha256-VXz3pO6N94XM8FzLSAoYrj3NEh4wp0UiuG6ad8M7nVU=";
};
ignoreCompilationError = false;
meta = {
homepage = "https://www.emacswiki.org/emacs/sv-kalender.el";
description = "Swedish calendar for Emacs";

View File

@ -10,6 +10,8 @@ melpaBuild {
files = ''("emacs/*.el")'';
ignoreCompilationError = false;
meta = {
inherit (texpresso.meta) homepage license;
description = "Emacs mode for TeXpresso";

View File

@ -44,6 +44,8 @@ melpaStablePackages.tree-sitter-langs.overrideAttrs(old: {
fi
'') plugins);
ignoreCompilationError = false;
passthru = old.passthru or {} // {
inherit plugins;
withPlugins = fn: final.tree-sitter-langs.override { plugins = fn tree-sitter-grammars; };

View File

@ -0,0 +1,285 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
[[package]]
name = "cc"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "ctor"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "darling"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "emacs"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6797a940189d353de79bec32abe717aeeecd79a08236e84404c888354e040665"
dependencies = [
"anyhow",
"ctor",
"emacs-macros",
"emacs_module",
"once_cell",
"rustc_version",
"thiserror",
]
[[package]]
name = "emacs-macros"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69656fdfe7c2608b87164964db848b5c3795de7302e3130cce7131552c6be161"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "emacs-tree-sitter"
version = "0.18.0"
dependencies = [
"emacs",
"libloading",
"once_cell",
"tree-sitter",
]
[[package]]
name = "emacs_module"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3067bc974045ed2c6db333bd4fc30d3bdaafa6421a9a889fa7b2826b6f7f2fa"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "libloading"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "once_cell"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "proc-macro2"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "strsim"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
name = "syn"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "thiserror"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tree-sitter"
version = "0.20.0"
source = "git+https://github.com/ubolonton/tree-sitter?branch=improve-text-provider#475b822f47bdc58d832533448b6f6d9818554f37"
dependencies = [
"cc",
"regex",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -1,70 +1,52 @@
{ lib
, symlinkJoin
, melpaBuild
, fetchFromGitHub
, rustPlatform
, runtimeShell
, writeScript
, python3
, nix-prefetch-github
, nix
, stdenv
, nix-update-script
}:
let
libExt = stdenv.hostPlatform.extensions.sharedLibrary;
srcMeta = lib.importJSON ./src.json;
inherit (srcMeta) version;
src = fetchFromGitHub srcMeta.src;
tsc = melpaBuild {
inherit src;
inherit version;
pname = "tsc";
sourceRoot = "${src.name}/core";
};
tsc-dyn = rustPlatform.buildRustPackage {
inherit version;
inherit src;
tsc-dyn = rustPlatform.buildRustPackage rec {
pname = "tsc-dyn";
version = "0.18.0";
src = fetchFromGitHub {
owner = "emacs-tree-sitter";
repo = "emacs-tree-sitter";
rev = version;
hash = "sha256-LrakDpP3ZhRQqz47dPcyoQnu5lROdaNlxGaQfQT6u+k=";
};
cargoLock = {
lockFile = ./Cargo.lock;
outputHashes = {
"tree-sitter-0.20.0" = "sha256-hGiJZFrQpO+xHXosbEKV2k64e2D8auNGEtdrFk2SsOU=";
};
};
nativeBuildInputs = [ rustPlatform.bindgenHook ];
sourceRoot = "${src.name}/core";
postInstall = ''
LIB=($out/lib/libtsc_dyn.*)
TSC_PATH=$out/share/emacs/site-lisp/elpa/tsc-${version}
install -d $TSC_PATH
install -m444 $out/lib/libtsc_dyn.* $TSC_PATH/''${LIB/*libtsc_/tsc-}
echo -n $version > $TSC_PATH/DYN-VERSION
rm -r $out/lib
pushd $out/lib
mv --verbose libtsc_dyn${libExt} tsc-dyn${libExt}
echo -n $version > DYN-VERSION
popd
'';
inherit (srcMeta) cargoHash;
};
in melpaBuild {
pname = "tsc";
inherit (tsc-dyn) version src;
in symlinkJoin {
name = "tsc-${version}";
paths = [ tsc tsc-dyn ];
files = ''("core/*.el" "${tsc-dyn}/lib/*")'';
ignoreCompilationError = false;
passthru = {
updateScript = let
pythonEnv = python3.withPackages(ps: [ ps.requests ]);
in writeScript "tsc-update" ''
#!${runtimeShell}
set -euo pipefail
export PATH=${lib.makeBinPath [
nix-prefetch-github
nix
pythonEnv
]}:$PATH
exec python3 ${builtins.toString ./update.py} ${builtins.toString ./.}
'';
inherit tsc-dyn;
updateScript = nix-update-script { attrPath = "emacsPackages.tsc.tsc-dyn"; };
};
meta = {

View File

@ -1,10 +0,0 @@
{
"src": {
"owner": "emacs-tree-sitter",
"repo": "elisp-tree-sitter",
"rev": "909717c685ff5a2327fa2ca8fb8a25216129361c",
"hash": "sha256-LrakDpP3ZhRQqz47dPcyoQnu5lROdaNlxGaQfQT6u+k="
},
"version": "0.18.0",
"cargoHash": "sha256-IRCZqszBkGF8anF/kpcPOzHdOP4lAtJBAp6FS5tAOx8="
}

View File

@ -1,123 +0,0 @@
#!/usr/bin/env python3
from textwrap import dedent
from os.path import (
abspath,
dirname,
join,
)
from typing import (
Dict,
Any,
)
import subprocess
import tempfile
import json
import sys
import re
import requests
def eval_drv(nixpkgs: str, expr: str) -> Any:
expr = "\n".join(
(
"with (import %s {});" % nixpkgs,
expr,
)
)
with tempfile.NamedTemporaryFile(mode="w") as f:
f.write(dedent(expr))
f.flush()
p = subprocess.run(
["nix-instantiate", "--json", f.name], stdout=subprocess.PIPE, check=True
)
return p.stdout.decode().strip()
def get_src(tag_name: str) -> Dict[str, str]:
p = subprocess.run(
[
"nix-prefetch-github",
"--rev",
tag_name,
"--json",
"emacs-tree-sitter",
"elisp-tree-sitter",
],
stdout=subprocess.PIPE,
check=True,
)
src = json.loads(p.stdout)
fields = ["owner", "repo", "rev", "hash"]
return {f: src[f] for f in fields}
def get_cargo_hash(drv_path: str):
# Note: No check=True since we expect this command to fail
p = subprocess.run(["nix-store", "-r", drv_path], stderr=subprocess.PIPE)
stderr = p.stderr.decode()
lines = iter(stderr.split("\n"))
for l in lines:
if l.startswith("error: hash mismatch in fixed-output derivation"):
break
else:
raise ValueError("Did not find expected hash mismatch message")
for l in lines:
m = re.match(r"\s+got:\s+(.+)$", l)
if m:
return m.group(1)
raise ValueError("Could not extract actual hash: ", stderr)
if __name__ == "__main__":
cwd = sys.argv[1]
# This should point to the root default.nix of Nixpkgs tree
nixpkgs = abspath(join(cwd, "../../../../../../.."))
tag_name = requests.get(
"https://api.github.com/repos/emacs-tree-sitter/elisp-tree-sitter/releases/latest"
).json()["tag_name"]
src = get_src(tag_name)
with tempfile.NamedTemporaryFile(mode="w") as f:
json.dump(src, f)
f.flush()
drv_path = eval_drv(
nixpkgs,
"""
rustPlatform.buildRustPackage rec {
pname = "tsc-dyn";
version = "%s";
nativeBuildInputs = [ clang ];
src = fetchFromGitHub (lib.importJSON %s);
sourceRoot = "${src.name}/core";
cargoHash = lib.fakeHash;
}
"""
% (tag_name, f.name),
)
cargo_hash = get_cargo_hash(drv_path)
with open(join(cwd, "src.json"), mode="w") as f:
json.dump(
{
"src": src,
"version": tag_name,
"cargoHash": cargo_hash,
},
f,
indent=2,
)
f.write("\n")

Some files were not shown because too many files have changed in this diff Show More