Merge master into staging-next

This commit is contained in:
nixpkgs-ci[bot]
2025-01-20 12:06:03 +00:00
committed by GitHub
68 changed files with 2270 additions and 575 deletions
+6 -5
View File
@@ -3241,6 +3241,12 @@
matrix = "@boozedog:matrix.org";
name = "David A. Buser";
};
boralg = {
name = "boralg";
github = "boralg";
githubId = 144260188;
matrix = "@boralg:matrix.org";
};
borisbabic = {
email = "boris.ivan.babic@gmail.com";
github = "borisbabic";
@@ -22970,11 +22976,6 @@
github = "thilobillerbeck";
githubId = 7442383;
};
thinnerthinker = {
name = "thinnerthinker";
github = "thinnerthinker";
githubId = 144260188;
};
thled = {
name = "Thomas Le Duc";
email = "dev@tleduc.de";
@@ -22,6 +22,7 @@ subversion.chapter.md
```{=include=} chapters
profiles.chapter.md
mattermost.chapter.md
kubernetes.chapter.md
```
<!-- Apache; libvirtd virtualisation -->
@@ -0,0 +1,134 @@
# Mattermost {#sec-mattermost}
The NixOS Mattermost module lets you build [Mattermost](https://mattermost.com)
instances for collaboration over chat, optionally with custom builds of plugins
specific to your instance.
To enable Mattermost using Postgres, use a config like this:
```nix
{
services.mattermost = {
enable = true;
# You can change this if you are reverse proxying.
host = "0.0.0.0";
port = 8065;
# Allow modifications to the config from Mattermost.
mutableConfig = true;
# Override modifications to the config with your NixOS config.
preferNixConfig = true;
socket = {
# Enable control with the `mmctl` socket.
enable = true;
# Exporting the control socket will add `mmctl` to your PATH, and export
# MMCTL_LOCAL_SOCKET_PATH systemwide. Otherwise, you can get the socket
# path out of `config.mattermost.socket.path` and set it manually.
export = true;
};
# For example, to disable auto-installation of prepackaged plugins.
settings.PluginSettings.AutomaticPrepackagedPlugins = false;
}
}
```
As of NixOS 25.05, Mattermost uses peer authentication with Postgres or
MySQL by default. If you previously used password auth on localhost,
this will automatically be configured if your `stateVersion` is set to at least
`25.05`.
## Using the Mattermost derivation {#sec-mattermost-derivation}
The nixpkgs `mattermost` derivation runs the entire test suite during the
`checkPhase`. This test suite is run with a live MySQL and Postgres database
instance in the sandbox. If you are building Mattermost, this can take a while,
especially if it is building on a resource-constrained system.
The following passthrus are designed to assist with enabling or disabling
the `checkPhase`:
- `mattermost.withTests`
- `mattermost.withoutTests`
The default (`mattermost`) is an alias for `mattermost.withTests`.
## Using Mattermost plugins {#sec-mattermost-plugins}
You can configure Mattermost plugins by either using prebuilt binaries or by
building your own. We test building and using plugins in the NixOS test suite.
Mattermost plugins are tarballs containing a system-specific statically linked
Go binary and webapp resources.
Here is an example with a prebuilt plugin tarball:
```nix
{
services.mattermost = {
plugins = with pkgs; [
/*
* todo
* 0.7.1
* https://github.com/mattermost/mattermost-plugin-todo/releases/tag/v0.7.1
*/
(fetchurl {
# Note: Don't unpack the tarball; the NixOS module will repack it for you.
url = "https://github.com/mattermost-community/mattermost-plugin-todo/releases/download/v0.7.1/com.mattermost.plugin-todo-0.7.1.tar.gz";
hash = "sha256-P+Z66vqE7FRmc2kTZw9FyU5YdLLbVlcJf11QCbfeJ84=";
})
];
};
}
```
Once the plugin is installed and the config rebuilt, you can enable this plugin
in the System Console.
## Building Mattermost plugins {#sec-mattermost-plugins-build}
The `mattermost` derivation includes the `buildPlugin` passthru for building
plugins that use the "standard" Mattermost plugin build template at
[mattermost-plugin-demo](https://github.com/mattermost/mattermost-plugin-demo).
Since this is a "de facto" standard for building Mattermost plugins that makes
assumptions about the build environment, the `buildPlugin` helper tries to fit
these assumptions the best it can.
Here is how to build the above Todo plugin. Note that we rely on
package-lock.json being assembled correctly, so must use a version where it is!
If there is no lockfile or the lockfile is incorrect, Nix cannot fetch NPM build
and runtime dependencies for a sandbox build.
```nix
{
services.mattermost = {
plugins = with pkgs; [
(mattermost.buildPlugin {
pname = "mattermost-plugin-todo";
version = "0.8-pre";
src = fetchFromGitHub {
owner = "mattermost-community";
repo = "mattermost-plugin-todo";
# 0.7.1 didn't work, seems to use an older set of node dependencies.
rev = "f25dc91ea401c9f0dcd4abcebaff10eb8b9836e5";
hash = "sha256-OM+m4rTqVtolvL5tUE8RKfclqzoe0Y38jLU60Pz7+HI=";
};
vendorHash = "sha256-5KpechSp3z/Nq713PXYruyNxveo6CwrCSKf2JaErbgg=";
npmDepsHash = "sha256-o2UOEkwb8Vx2lDWayNYgng0GXvmS6lp/ExfOq3peyMY=";
extraGoModuleAttrs = {
npmFlags = [ "--legacy-peer-deps" ];
};
})
];
};
}
```
See `pkgs/by-name/ma/mattermost/build-plugin.nix` for all the options.
As in the previous example, once the plugin is installed and the config rebuilt,
you can enable this plugin in the System Console.
+12
View File
@@ -47,6 +47,18 @@
"ch-installation": [
"index.html#ch-installation"
],
"sec-mattermost": [
"index.html#sec-mattermost"
],
"sec-mattermost-derivation": [
"index.html#sec-mattermost-derivation"
],
"sec-mattermost-plugins": [
"index.html#sec-mattermost-plugins"
],
"sec-mattermost-plugins-build": [
"index.html#sec-mattermost-plugins-build"
],
"sec-obtaining": [
"index.html#sec-obtaining"
],
@@ -10,6 +10,8 @@
Users on old macOS versions should consider upgrading to a supported version (potentially using [OpenCore Legacy Patcher](https://dortania.github.io/OpenCore-Legacy-Patcher/) for old hardware) or installing NixOS.
If neither of those options are viable and you require new versions of software, [MacPorts](https://www.macports.org/) supports versions back to Mac OS X Snow Leopard 10.6.
- The default kernel package has been updated from 6.6 to 6.12. All supported kernels remain available.
- GCC has been updated from GCC 13 to GCC 14.
This introduces some backwardsincompatible changes; see the [upstream porting guide](https://gcc.gnu.org/gcc-14/porting_to.html) for details.
@@ -31,6 +33,18 @@
- `nixos-option` has been rewritten to a Nix expression called by a simple bash script. This lowers our maintenance threshold, makes eval errors less verbose, adds support for flake-based configurations, descending into `attrsOf` and `listOf` submodule options, and `--show-trace`.
- The Mattermost module ({option}`services.mattermost`) and packages (`mattermost` and `mmctl`) have been substantially updated:
- `pkgs.mattermostLatest` is now an option to track the latest (non-prerelease) Mattermost release. We test upgrade migrations from ESR releases (`pkgs.mattermost`) to `pkgs.mattermostLatest`.
- The Mattermost frontend is now built from source and can be overridden.
- Note that the Mattermost derivation containing both the webapp and server is now wrapped to allow them to be built independently, so overrides to both webapp and server look like `mattermost.overrideAttrs (prev: { webapp = prev.webapp.override { ... }; server = prev.server.override { ... }; })` now.
- `services.mattermost.listenAddress` has been split into {option}`services.mattermost.host` and {option}`services.mattermost.port`. If your `listenAddress` contained a port, you will need to edit your configuration.
- Mattermost now supports peer authentication on both MySQL and Postgres database backends. Updating {option}`system.stateVersion` to 25.05 or later will result in peer authentication being used by default if the Mattermost server would otherwise be connecting to localhost. This is the recommended configuration.
- The Mattermost module will produce eval warnings if a database password would end up in the Nix store, and recommend alternatives such as peer authentication or using the environment file.
- Mattermost's entire test suite is now enabled by default, which will extend build time from sources by up to an hour. A `withoutTests` passthru has been added in case you want to skip it.
- We now support `mmctl` for Mattermost administration if both {option}`services.mattermost.socket.enable` and {option}`services.mattermost.socket.export` are set, which export the Mattermost control socket path into the system environment.
- A new `pkgs.mattermost.buildPlugin` function has been added, which allows plugins to be built from source, including webapp frontends with a supported package-lock.json. See the Mattermost NixOS test and [manual](https://nixos.org/manual/nixpkgs/unstable/#sec-mattermost-plugins-build) for an example.
- Note that the Mattermost module will create an account _without_ a well-known UID if the username differs from the default (`mattermost`). If you used Mattermost with a nonstandard username, you may want to review the module changes before upgrading.
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
## New Modules {#sec-release-25.05-new-modules}
+710 -153
View File
@@ -5,35 +5,147 @@
...
}:
with lib;
let
inherit (lib.strings)
hasInfix
hasSuffix
escapeURL
concatStringsSep
escapeShellArg
escapeShellArgs
versionAtLeast
optionalString
;
inherit (lib.meta) getExe;
inherit (lib.lists) singleton;
inherit (lib.attrsets) mapAttrsToList recursiveUpdate optionalAttrs;
inherit (lib.options) mkOption mkPackageOption mkEnableOption;
inherit (lib.modules)
mkRenamedOptionModule
mkMerge
mkIf
mkDefault
;
inherit (lib.trivial) warnIf throwIf;
inherit (lib) types;
cfg = config.services.mattermost;
database = "postgres://${cfg.localDatabaseUser}:${cfg.localDatabasePassword}@localhost:5432/${cfg.localDatabaseName}?sslmode=disable&connect_timeout=10";
# The directory to store mutable data within dataDir.
mutableDataDir = "${cfg.dataDir}/data";
postgresPackage = config.services.postgresql.package;
# The plugin directory. Note that this is the *post-unpack* plugin directory,
# since Mattermost unpacks plugins to put them there. (Hence, mutable data.)
pluginDir = "${mutableDataDir}/plugins";
createDb =
# Mattermost uses this as a staging directory to unpack plugins, among possibly other things.
# Ensure that it's inside mutableDataDir since it can get rather large.
tempDir = "${mutableDataDir}/tmp";
# Creates a database URI.
mkDatabaseUri =
{
statePath ? cfg.statePath,
localDatabaseUser ? cfg.localDatabaseUser,
localDatabasePassword ? cfg.localDatabasePassword,
localDatabaseName ? cfg.localDatabaseName,
useSudo ? true,
scheme,
user ? null,
password ? null,
escapeUserAndPassword ? true,
host ? null,
escapeHost ? true,
port ? null,
path ? null,
query ? { },
}:
''
if ! test -e ${escapeShellArg "${statePath}/.db-created"}; then
${lib.optionalString useSudo "${pkgs.sudo}/bin/sudo -u ${escapeShellArg config.services.postgresql.superUser} \\"}
${postgresPackage}/bin/psql postgres -c \
"CREATE ROLE ${localDatabaseUser} WITH LOGIN NOCREATEDB NOCREATEROLE ENCRYPTED PASSWORD '${localDatabasePassword}'"
${lib.optionalString useSudo "${pkgs.sudo}/bin/sudo -u ${escapeShellArg config.services.postgresql.superUser} \\"}
${postgresPackage}/bin/createdb \
--owner ${escapeShellArg localDatabaseUser} ${escapeShellArg localDatabaseName}
touch ${escapeShellArg "${statePath}/.db-created"}
fi
'';
let
nullToEmpty = val: if val == null then "" else toString val;
# Converts a list of URI attrs to a query string.
toQuery = mapAttrsToList (
name: value: if value == null then null else (escapeURL name) + "=" + (escapeURL (toString value))
);
schemePart = if scheme == null then "" else "${escapeURL scheme}://";
userPart =
let
realUser = if escapeUserAndPassword then escapeURL user else user;
realPassword = if escapeUserAndPassword then escapeURL password else password;
in
if user == null && password == null then
""
else if user != null && password != null then
"${realUser}:${realPassword}"
else if user != null then
realUser
else
throw "Either user or username and password must be provided";
hostPart =
let
realHost = if escapeHost then escapeURL (nullToEmpty host) else nullToEmpty host;
in
if userPart == "" then realHost else "@" + realHost;
portPart = if port == null then "" else ":" + (toString port);
pathPart = if path == null then "" else "/" + path;
queryPart = if query == { } then "" else "?" + concatStringsSep "&" (toQuery query);
in
schemePart + userPart + hostPart + portPart + pathPart + queryPart;
database =
let
hostIsPath = hasInfix "/" cfg.database.host;
in
if cfg.database.driver == "postgres" then
if cfg.database.peerAuth then
mkDatabaseUri {
scheme = cfg.database.driver;
inherit (cfg.database) user;
path = escapeURL cfg.database.name;
query = {
host = cfg.database.socketPath;
} // cfg.database.extraConnectionOptions;
}
else
mkDatabaseUri {
scheme = cfg.database.driver;
inherit (cfg.database) user password;
host = if hostIsPath then null else cfg.database.host;
port = if hostIsPath then null else cfg.database.port;
path = escapeURL cfg.database.name;
query =
optionalAttrs hostIsPath { host = cfg.database.host; } // cfg.database.extraConnectionOptions;
}
else if cfg.database.driver == "mysql" then
if cfg.database.peerAuth then
mkDatabaseUri {
scheme = null;
inherit (cfg.database) user;
escapeUserAndPassword = false;
host = "unix(${cfg.database.socketPath})";
escapeHost = false;
path = escapeURL cfg.database.name;
query = cfg.database.extraConnectionOptions;
}
else
mkDatabaseUri {
scheme = null;
inherit (cfg.database) user password;
escapeUserAndPassword = false;
host =
if hostIsPath then
"unix(${cfg.database.host})"
else
"tcp(${cfg.database.host}:${toString cfg.database.port})";
escapeHost = false;
path = escapeURL cfg.database.name;
query = cfg.database.extraConnectionOptions;
}
else
throw "Invalid database driver: ${cfg.database.driver}";
mattermostPluginDerivations =
with pkgs;
@@ -60,23 +172,19 @@ let
else
stdenv.mkDerivation {
name = "${cfg.package.name}-plugins";
nativeBuildInputs = [
autoPatchelfHook
] ++ mattermostPluginDerivations;
buildInputs = [
cfg.package
];
nativeBuildInputs = [ autoPatchelfHook ] ++ mattermostPluginDerivations;
buildInputs = [ cfg.package ];
installPhase = ''
mkdir -p $out/data/plugins
mkdir -p $out
plugins=(${
escapeShellArgs (map (plugin: "${plugin}/share/plugin.tar.gz") mattermostPluginDerivations)
})
for plugin in "''${plugins[@]}"; do
hash="$(sha256sum "$plugin" | cut -d' ' -f1)"
hash="$(sha256sum "$plugin" | awk '{print $1}')"
mkdir -p "$hash"
tar -C "$hash" -xzf "$plugin"
autoPatchelf "$hash"
GZIP_OPT=-9 tar -C "$hash" -cvzf "$out/data/plugins/$hash.tar.gz" .
GZIP_OPT=-9 tar -C "$hash" -cvzf "$out/$hash.tar.gz" .
rm -rf "$hash"
done
'';
@@ -89,40 +197,157 @@ let
};
mattermostConfWithoutPlugins = recursiveUpdate {
ServiceSettings.SiteURL = cfg.siteUrl;
ServiceSettings.ListenAddress = cfg.listenAddress;
ServiceSettings = {
SiteURL = cfg.siteUrl;
ListenAddress = "${cfg.host}:${toString cfg.port}";
LocalModeSocketLocation = cfg.socket.path;
EnableLocalMode = cfg.socket.enable;
};
TeamSettings.SiteName = cfg.siteName;
SqlSettings.DriverName = "postgres";
SqlSettings.DataSource = database;
PluginSettings.Directory = "${cfg.statePath}/plugins/server";
PluginSettings.ClientDirectory = "${cfg.statePath}/plugins/client";
} cfg.extraConfig;
SqlSettings.DriverName = cfg.database.driver;
SqlSettings.DataSource =
if cfg.database.fromEnvironment then
null
else
warnIf (!cfg.database.peerAuth && cfg.database.password != null) ''
Database password is set in Mattermost config! This password will end up in the Nix store.
You may be able to simply set the following, if the database is on the same host
and peer authentication is enabled:
services.mattermost.database.peerAuth = true;
Note that this is the default if you set system.stateVersion to 25.05 or later
and the database host is localhost.
Alternatively, you can write the following to ${
if cfg.environmentFile == null then "your environment file" else cfg.environmentFile
}:
MM_SQLSETTINGS_DATASOURCE=${database}
Then set the following options:
services.mattermost.environmentFile = "<your environment file>";
services.mattermost.database.fromEnvironment = true;
'' database;
FileSettings.Directory = cfg.dataDir;
PluginSettings.Directory = "${pluginDir}/server";
PluginSettings.ClientDirectory = "${pluginDir}/client";
LogSettings.FileLocation = cfg.logDir;
} cfg.settings;
mattermostConf = recursiveUpdate mattermostConfWithoutPlugins (
lib.optionalAttrs (mattermostPlugins != null) {
PluginSettings = {
Enable = true;
};
}
if mattermostPlugins == null then
{ }
else
{
PluginSettings = {
Enable = true;
};
}
);
mattermostConfJSON = pkgs.writeText "mattermost-config.json" (builtins.toJSON mattermostConf);
in
{
imports = [
(mkRenamedOptionModule
[
"services"
"mattermost"
"listenAddress"
]
[
"services"
"mattermost"
"host"
]
)
(mkRenamedOptionModule
[
"services"
"mattermost"
"localDatabaseCreate"
]
[
"services"
"mattermost"
"database"
"create"
]
)
(mkRenamedOptionModule
[
"services"
"mattermost"
"localDatabasePassword"
]
[
"services"
"mattermost"
"database"
"password"
]
)
(mkRenamedOptionModule
[
"services"
"mattermost"
"localDatabaseUser"
]
[
"services"
"mattermost"
"database"
"user"
]
)
(mkRenamedOptionModule
[
"services"
"mattermost"
"localDatabaseName"
]
[
"services"
"mattermost"
"database"
"name"
]
)
(mkRenamedOptionModule
[
"services"
"mattermost"
"extraConfig"
]
[
"services"
"mattermost"
"settings"
]
)
(mkRenamedOptionModule
[
"services"
"mattermost"
"statePath"
]
[
"services"
"mattermost"
"dataDir"
]
)
];
options = {
services.mattermost = {
enable = mkEnableOption "Mattermost chat server";
package = mkPackageOption pkgs "mattermost" { };
statePath = mkOption {
type = types.str;
default = "/var/lib/mattermost";
description = "Mattermost working directory";
};
siteUrl = mkOption {
type = types.str;
example = "https://chat.example.com";
@@ -137,12 +362,77 @@ in
description = "Name of this Mattermost site.";
};
listenAddress = mkOption {
host = mkOption {
type = types.str;
default = ":8065";
example = "[::1]:8065";
default = "127.0.0.1";
example = "0.0.0.0";
description = ''
Address and port this Mattermost instance listens to.
Host or address that this Mattermost instance listens on.
'';
};
port = mkOption {
type = types.port;
default = 8065;
description = ''
Port for Mattermost server to listen on.
'';
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/mattermost";
description = ''
Mattermost working directory.
'';
};
socket = {
enable = mkEnableOption "Mattermost control socket";
path = mkOption {
type = types.path;
default = "${cfg.dataDir}/mattermost.sock";
defaultText = ''''${config.mattermost.dataDir}/mattermost.sock'';
description = ''
Default location for the Mattermost control socket used by `mmctl`.
'';
};
export = mkEnableOption "Export socket control to system environment variables";
};
logDir = mkOption {
type = types.path;
default =
if versionAtLeast config.system.stateVersion "25.05" then
"/var/log/mattermost"
else
"${cfg.dataDir}/logs";
defaultText = ''
if versionAtLeast config.system.stateVersion "25.05" then "/var/log/mattermost"
else "''${config.services.mattermost.dataDir}/logs";
'';
description = ''
Mattermost log directory.
'';
};
configDir = mkOption {
type = types.path;
default =
if versionAtLeast config.system.stateVersion "25.05" then
"/etc/mattermost"
else
"${cfg.dataDir}/config";
defaultText = ''
if versionAtLeast config.system.stateVersion "25.05" then
"/etc/mattermost"
else
"''${config.services.mattermost.dataDir}/config";
'';
description = ''
Mattermost config directory.
'';
};
@@ -173,21 +463,8 @@ in
'';
};
extraConfig = mkOption {
type = types.attrs;
default = { };
description = ''
Additional configuration options as Nix attribute set in config.json schema.
'';
};
plugins = mkOption {
type = types.listOf (
types.oneOf [
types.path
types.package
]
);
type = with types; listOf (either path package);
default = [ ];
example = "[ ./com.github.moussetc.mattermost.plugin.giphy-2.0.0.tar.gz ]";
description = ''
@@ -196,13 +473,25 @@ in
.tar.gz files.
'';
};
environment = mkOption {
type = with types; attrsOf (either int str);
default = { };
description = ''
Extra environment variables to export to the Mattermost process, in the systemd unit.
'';
example = {
MM_SERVICESETTINGS_SITEURL = "http://example.com";
};
};
environmentFile = mkOption {
type = types.nullOr types.path;
type = with types; nullOr path;
default = null;
description = ''
Environment file (see {manpage}`systemd.exec(5)`
"EnvironmentFile=" section for the syntax) which sets config options
for mattermost (see [the mattermost documentation](https://docs.mattermost.com/configure/configuration-settings.html#environment-variables)).
for mattermost (see [the Mattermost documentation](https://docs.mattermost.com/configure/configuration-settings.html#environment-variables)).
Settings defined in the environment file will overwrite settings
set via nix or via the {option}`services.mattermost.extraConfig`
@@ -213,36 +502,142 @@ in
'';
};
localDatabaseCreate = mkOption {
type = types.bool;
default = true;
description = ''
Create a local PostgreSQL database for Mattermost automatically.
'';
};
database = {
driver = mkOption {
type = types.enum [
"postgres"
"mysql"
];
default = "postgres";
description = ''
The database driver to use (Postgres or MySQL).
'';
};
localDatabaseName = mkOption {
type = types.str;
default = "mattermost";
description = ''
Local Mattermost database name.
'';
};
create = mkOption {
type = types.bool;
default = true;
description = ''
Create a local PostgreSQL or MySQL database for Mattermost automatically.
'';
};
localDatabaseUser = mkOption {
type = types.str;
default = "mattermost";
description = ''
Local Mattermost database username.
'';
};
peerAuth = mkOption {
type = types.bool;
default = versionAtLeast config.system.stateVersion "25.05" && cfg.database.host == "localhost";
defaultText = ''
versionAtLeast config.system.stateVersion "25.05" && config.services.mattermost.database.host == "localhost"
'';
description = ''
If set, will use peer auth instead of connecting to a Postgres server.
Use services.mattermost.database.socketPath to configure the socket path.
'';
};
localDatabasePassword = mkOption {
type = types.str;
default = "mmpgsecret";
description = ''
Password for local Mattermost database user.
'';
socketPath = mkOption {
type = types.path;
default =
if cfg.database.driver == "postgres" then "/run/postgresql" else "/run/mysqld/mysqld.sock";
defaultText = ''
if config.services.mattermost.database.driver == "postgres" then "/run/postgresql" else "/run/mysqld/mysqld.sock";
'';
description = ''
The database (Postgres or MySQL) socket path.
'';
};
fromEnvironment = mkOption {
type = types.bool;
default = false;
description = ''
Use services.mattermost.environmentFile to configure the database instead of writing the database URI
to the Nix store. Useful if you use password authentication with peerAuth set to false.
'';
};
name = mkOption {
type = types.str;
default = "mattermost";
description = ''
Local Mattermost database name.
'';
};
host = mkOption {
type = types.str;
default = "localhost";
example = "127.0.0.1";
description = ''
Host to use for the database. Can also be set to a path if you'd like to connect
to a socket using a username and password.
'';
};
port = mkOption {
type = types.port;
default = if cfg.database.driver == "postgres" then 5432 else 3306;
defaultText = ''
if config.services.mattermost.database.type == "postgres" then 5432 else 3306
'';
example = 3306;
description = ''
Port to use for the database.
'';
};
user = mkOption {
type = types.str;
default = "mattermost";
description = ''
Local Mattermost database username.
'';
};
password = mkOption {
type = types.str;
default = "mmpgsecret";
description = ''
Password for local Mattermost database user. If set and peerAuth is not true,
will cause a warning nagging you to use environmentFile instead since it will
end up in the Nix store.
'';
};
extraConnectionOptions = mkOption {
type = with types; attrsOf (either int str);
default =
if cfg.database.driver == "postgres" then
{
sslmode = "disable";
connect_timeout = 30;
}
else if cfg.database.driver == "mysql" then
{
charset = "utf8mb4,utf8";
writeTimeout = "30s";
readTimeout = "30s";
}
else
throw "Invalid database driver ${cfg.database.driver}";
defaultText = ''
if config.mattermost.database.driver == "postgres" then
{
sslmode = "disable";
connect_timeout = 30;
}
else if config.mattermost.database.driver == "mysql" then
{
charset = "utf8mb4,utf8";
writeTimeout = "30s";
readTimeout = "30s";
}
else
throw "Invalid database driver";
'';
description = ''
Extra options that are placed in the connection URI's query parameters.
'';
};
};
user = mkOption {
@@ -261,6 +656,14 @@ in
'';
};
settings = mkOption {
type = types.attrs;
default = { };
description = ''
Additional configuration options as Nix attribute set in config.json schema.
'';
};
matterircd = {
enable = mkEnableOption "Mattermost IRC bridge";
package = mkPackageOption pkgs "matterircd" { };
@@ -282,83 +685,235 @@ in
config = mkMerge [
(mkIf cfg.enable {
users.users = optionalAttrs (cfg.user == "mattermost") {
mattermost = {
users.users = {
${cfg.user} = {
group = cfg.group;
uid = config.ids.uids.mattermost;
home = cfg.statePath;
uid = mkIf (cfg.user == "mattermost") config.ids.uids.mattermost;
home = cfg.dataDir;
isSystemUser = true;
packages = [ cfg.package ];
};
};
users.groups = optionalAttrs (cfg.group == "mattermost") {
mattermost.gid = config.ids.gids.mattermost;
users.groups = {
${cfg.group} = {
gid = mkIf (cfg.group == "mattermost") config.ids.gids.mattermost;
};
};
services.postgresql.enable = cfg.localDatabaseCreate;
services.postgresql = mkIf (cfg.database.driver == "postgres" && cfg.database.create) {
enable = true;
ensureDatabases = singleton cfg.database.name;
ensureUsers = singleton {
name =
throwIf
(cfg.database.peerAuth && (cfg.database.user != cfg.user || cfg.database.name != cfg.database.user))
''
Mattermost database peer auth is enabled and the user, database user, or database name mismatch.
Peer authentication will not work.
''
cfg.database.user;
ensureDBOwnership = true;
};
};
# The systemd service will fail to execute the preStart hook
# if the WorkingDirectory does not exist
systemd.tmpfiles.settings."10-mattermost".${cfg.statePath}.d = { };
services.mysql = mkIf (cfg.database.driver == "mysql" && cfg.database.create) {
enable = true;
package = mkDefault pkgs.mariadb;
ensureDatabases = singleton cfg.database.name;
ensureUsers = singleton {
name = cfg.database.user;
ensurePermissions = {
"${cfg.database.name}.*" = "ALL PRIVILEGES";
};
};
settings = rec {
mysqld = {
collation-server = mkDefault "utf8mb4_general_ci";
init-connect = mkDefault "SET NAMES utf8mb4";
character-set-server = mkDefault "utf8mb4";
};
mysqld_safe = mysqld;
};
};
systemd.services.mattermost = {
environment = {
variables = mkIf cfg.socket.export {
MMCTL_LOCAL = "true";
MMCTL_LOCAL_SOCKET_PATH = cfg.socket.path;
};
};
systemd.tmpfiles.rules =
[
"d ${cfg.dataDir} 0750 ${cfg.user} ${cfg.group} - -"
"d ${cfg.logDir} 0750 ${cfg.user} ${cfg.group} - -"
"d ${cfg.configDir} 0750 ${cfg.user} ${cfg.group} - -"
"d ${mutableDataDir} 0750 ${cfg.user} ${cfg.group} - -"
# Make sure tempDir exists and is not a symlink.
"R- ${tempDir} - - - - -"
"d= ${tempDir} 0750 ${cfg.user} ${cfg.group} - -"
# Ensure that pluginDir is a directory, as it could be a symlink on prior versions.
"r- ${pluginDir} - - - - -"
"d= ${pluginDir} 0750 ${cfg.user} ${cfg.group} - -"
# Ensure that the plugin directories exist.
"d= ${mattermostConf.PluginSettings.Directory} 0750 ${cfg.user} ${cfg.group} - -"
"d= ${mattermostConf.PluginSettings.ClientDirectory} 0750 ${cfg.user} ${cfg.group} - -"
# Link in some of the immutable data directories.
"L+ ${cfg.dataDir}/bin - - - - ${cfg.package}/bin"
"L+ ${cfg.dataDir}/fonts - - - - ${cfg.package}/fonts"
"L+ ${cfg.dataDir}/i18n - - - - ${cfg.package}/i18n"
"L+ ${cfg.dataDir}/templates - - - - ${cfg.package}/templates"
"L+ ${cfg.dataDir}/client - - - - ${cfg.package}/client"
]
++ (
if mattermostPlugins == null then
# Create the plugin tarball directory if it's a symlink.
[
"r- ${cfg.dataDir}/plugins - - - - -"
"d= ${cfg.dataDir}/plugins 0750 ${cfg.user} ${cfg.group} - -"
]
else
# Symlink the plugin tarball directory, removing anything existing.
[ "L+ ${cfg.dataDir}/plugins - - - - ${mattermostPlugins}" ]
);
systemd.services.mattermost = rec {
description = "Mattermost chat service";
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"postgresql.service"
after = mkMerge [
[ "network.target" ]
(mkIf (cfg.database.driver == "postgres" && cfg.database.create) [ "postgresql.service" ])
(mkIf (cfg.database.driver == "mysql" && cfg.database.create) [ "mysql.service" ])
];
requires = after;
environment = mkMerge [
{
# Use tempDir as this can get rather large, especially if Mattermost unpacks a large number of plugins.
TMPDIR = tempDir;
}
cfg.environment
];
preStart =
''
mkdir -p "${cfg.statePath}"/{data,config,logs,plugins}
mkdir -p "${cfg.statePath}/plugins"/{client,server}
ln -sf ${cfg.package}/{bin,fonts,i18n,templates,client} "${cfg.statePath}"
dataDir=${escapeShellArg cfg.dataDir}
configDir=${escapeShellArg cfg.configDir}
logDir=${escapeShellArg cfg.logDir}
package=${escapeShellArg cfg.package}
nixConfig=${escapeShellArg mattermostConfJSON}
''
+ lib.optionalString (mattermostPlugins != null) ''
rm -rf "${cfg.statePath}/data/plugins"
ln -sf ${mattermostPlugins}/data/plugins "${cfg.statePath}/data"
''
+ lib.optionalString (!cfg.mutableConfig) ''
rm -f "${cfg.statePath}/config/config.json"
${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${cfg.package}/config/config.json ${mattermostConfJSON} > "${cfg.statePath}/config/config.json"
''
+ lib.optionalString cfg.mutableConfig ''
if ! test -e "${cfg.statePath}/config/.initial-created"; then
rm -f ${cfg.statePath}/config/config.json
${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${cfg.package}/config/config.json ${mattermostConfJSON} > "${cfg.statePath}/config/config.json"
touch "${cfg.statePath}/config/.initial-created"
+ optionalString (versionAtLeast config.system.stateVersion "25.05") ''
# Migrate configs in the pre-25.05 directory structure.
oldConfig="$dataDir/config/config.json"
newConfig="$configDir/config.json"
if [ "$oldConfig" != "$newConfig" ] && [ -f "$oldConfig" ] && [ ! -f "$newConfig" ]; then
# Migrate the legacy config location to the new config location
echo "Moving legacy config at $oldConfig to $newConfig" >&2
mkdir -p "$configDir"
mv "$oldConfig" "$newConfig"
touch "$configDir/.initial-created"
fi
# Logs too.
oldLogs="$dataDir/logs"
newLogs="$logDir"
if [ "$oldLogs" != "$newLogs" ] && [ -d "$oldLogs" ]; then
# Migrate the legacy log location to the new log location.
# Allow this to fail if there aren't any logs to move.
echo "Moving legacy logs at $oldLogs to $newLogs" >&2
mkdir -p "$newLogs"
mv "$oldLogs"/* "$newLogs" || true
fi
''
+ lib.optionalString (cfg.mutableConfig && cfg.preferNixConfig) ''
new_config="$(${pkgs.jq}/bin/jq -s '.[0] * .[1]' "${cfg.statePath}/config/config.json" ${mattermostConfJSON})"
rm -f "${cfg.statePath}/config/config.json"
echo "$new_config" > "${cfg.statePath}/config/config.json"
+ optionalString (!cfg.mutableConfig) ''
${getExe pkgs.jq} -s '.[0] * .[1]' "$package/config/config.json" "$nixConfig" > "$configDir/config.json"
''
+ lib.optionalString cfg.localDatabaseCreate (createDb { })
+ ''
# Don't change permissions recursively on the data, current, and symlinked directories (see ln -sf command above).
# This dramatically decreases startup times for installations with a lot of files.
find . -maxdepth 1 -not -name data -not -name client -not -name templates -not -name i18n -not -name fonts -not -name bin -not -name . \
-exec chown "${cfg.user}:${cfg.group}" -R {} \; -exec chmod u+rw,g+r,o-rwx -R {} \;
chown "${cfg.user}:${cfg.group}" "${cfg.statePath}/data" .
chmod u+rw,g+r,o-rwx "${cfg.statePath}/data" .
+ optionalString cfg.mutableConfig ''
if [ ! -e "$configDir/.initial-created" ]; then
${getExe pkgs.jq} -s '.[0] * .[1]' "$package/config/config.json" "$nixConfig" > "$configDir/config.json"
touch "$configDir/.initial-created"
fi
''
+ optionalString (cfg.mutableConfig && cfg.preferNixConfig) ''
echo "$(${getExe pkgs.jq} -s '.[0] * .[1]' "$configDir/config.json" "$nixConfig")" > "$configDir/config.json"
'';
serviceConfig = {
PermissionsStartOnly = true;
User = cfg.user;
Group = cfg.group;
ExecStart = "${cfg.package}/bin/mattermost";
WorkingDirectory = "${cfg.statePath}";
Restart = "always";
RestartSec = "10";
LimitNOFILE = "49152";
EnvironmentFile = cfg.environmentFile;
};
unitConfig.JoinsNamespaceOf = mkIf cfg.localDatabaseCreate "postgresql.service";
serviceConfig = mkMerge [
{
User = cfg.user;
Group = cfg.group;
ExecStart = "${getExe cfg.package} --config ${cfg.configDir}/config.json";
ReadWritePaths = [
cfg.dataDir
cfg.logDir
cfg.configDir
];
UMask = "0027";
Restart = "always";
RestartSec = 10;
LimitNOFILE = 49152;
LockPersonality = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RestrictNamespaces = true;
RestrictSUIDSGID = true;
EnvironmentFile = cfg.environmentFile;
WorkingDirectory = cfg.dataDir;
}
(mkIf (cfg.dataDir == "/var/lib/mattermost") {
StateDirectory = baseNameOf cfg.dataDir;
StateDirectoryMode = "0750";
})
(mkIf (cfg.logDir == "/var/log/mattermost") {
LogsDirectory = baseNameOf cfg.logDir;
LogsDirectoryMode = "0750";
})
(mkIf (cfg.configDir == "/etc/mattermost") {
ConfigurationDirectory = baseNameOf cfg.configDir;
ConfigurationDirectoryMode = "0750";
})
];
unitConfig.JoinsNamespaceOf = mkMerge [
(mkIf (cfg.database.driver == "postgres" && cfg.database.create) [ "postgresql.service" ])
(mkIf (cfg.database.driver == "mysql" && cfg.database.create) [ "mysql.service" ])
];
};
assertions = [
{
# Make sure the URL doesn't have a trailing slash
assertion = !(hasSuffix "/" cfg.siteUrl);
message = ''
services.mattermost.siteUrl should not have a trailing "/".
'';
}
{
# Make sure this isn't a host/port pair
assertion = !(hasInfix ":" cfg.host && !(hasInfix "[" cfg.host) && !(hasInfix "]" cfg.host));
message = ''
services.mattermost.host should not include a port. Use services.mattermost.host for the address
or hostname, and services.mattermost.port to specify the port separately.
'';
}
];
})
(mkIf cfg.matterircd.enable {
systemd.services.matterircd = {
@@ -367,7 +922,7 @@ in
serviceConfig = {
User = "nobody";
Group = "nogroup";
ExecStart = "${cfg.matterircd.package}/bin/matterircd ${escapeShellArgs cfg.matterircd.parameters}";
ExecStart = "${getExe cfg.matterircd.package} ${escapeShellArgs cfg.matterircd.parameters}";
WorkingDirectory = "/tmp";
PrivateTmp = true;
Restart = "always";
@@ -376,4 +931,6 @@ in
};
})
];
meta.maintainers = with lib.maintainers; [ numinit ];
}
@@ -27,9 +27,6 @@ tmpOther="$targetOther.tmp"
configurationCounter=0
numAlienEntries=`cat <<EOF | egrep '^[[:space:]]*title' | wc -l
@extraEntries@
EOF`
+6
View File
@@ -64,6 +64,11 @@ rec {
proxy
simple
;
latestKernel = {
inherit (nixos'.tests.latestKernel)
login
;
};
installer = {
inherit (nixos'.tests.installer)
lvm
@@ -137,6 +142,7 @@ rec {
"nixos.tests.ipv6"
"nixos.tests.installer.simpleUefiSystemdBoot"
"nixos.tests.login"
"nixos.tests.latestKernel.login"
"nixos.tests.misc"
"nixos.tests.nat.firewall"
"nixos.tests.nat.standalone"
+1 -1
View File
@@ -593,7 +593,7 @@ in {
matrix-synapse-workers = handleTest ./matrix/synapse-workers.nix {};
mautrix-meta-postgres = handleTest ./matrix/mautrix-meta-postgres.nix {};
mautrix-meta-sqlite = handleTest ./matrix/mautrix-meta-sqlite.nix {};
mattermost = handleTest ./mattermost.nix {};
mattermost = handleTest ./mattermost {};
mealie = handleTest ./mealie.nix {};
mediamtx = handleTest ./mediamtx.nix {};
mediatomb = handleTest ./mediatomb.nix {};
-169
View File
@@ -1,169 +0,0 @@
import ./make-test-python.nix (
{ pkgs, lib, ... }:
let
host = "smoke.test";
port = "8065";
url = "http://${host}:${port}";
siteName = "NixOS Smoke Tests, Inc.";
makeMattermost =
mattermostConfig:
{ config, ... }:
{
environment.systemPackages = [
pkgs.mattermost
pkgs.curl
pkgs.jq
];
networking.hosts = {
"127.0.0.1" = [ host ];
};
services.mattermost = lib.recursiveUpdate {
enable = true;
inherit siteName;
listenAddress = "0.0.0.0:${port}";
siteUrl = url;
extraConfig = {
SupportSettings.AboutLink = "https://nixos.org";
};
} mattermostConfig;
};
in
{
name = "mattermost";
nodes = {
mutable = makeMattermost {
mutableConfig = true;
extraConfig.SupportSettings.HelpLink = "https://search.nixos.org";
};
mostlyMutable = makeMattermost {
mutableConfig = true;
preferNixConfig = true;
plugins =
let
mattermostDemoPlugin = pkgs.fetchurl {
url = "https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.9.0/com.mattermost.demo-plugin-0.9.0.tar.gz";
sha256 = "1h4qi34gcxcx63z8wiqcf2aaywmvv8lys5g8gvsk13kkqhlmag25";
};
in
[
mattermostDemoPlugin
];
};
immutable = makeMattermost {
package = pkgs.mattermost.overrideAttrs (prev: {
webapp = prev.webapp.overrideAttrs (prevWebapp: {
# Ensure that users can add patches.
postPatch =
prevWebapp.postPatch or ""
+ ''
substituteInPlace channels/src/root.html --replace-fail "Mattermost" "Patched Mattermost"
'';
});
});
mutableConfig = false;
extraConfig.SupportSettings.HelpLink = "https://search.nixos.org";
};
environmentFile = makeMattermost {
mutableConfig = false;
extraConfig.SupportSettings.AboutLink = "https://example.org";
environmentFile = pkgs.writeText "mattermost-env" ''
MM_SUPPORTSETTINGS_ABOUTLINK=https://nixos.org
'';
};
};
testScript =
let
expectConfig =
jqExpression:
pkgs.writeShellScript "expect-config" ''
set -euo pipefail
echo "Expecting config to match: "${lib.escapeShellArg jqExpression} >&2
curl ${lib.escapeShellArg url} >/dev/null
config="$(curl ${lib.escapeShellArg "${url}/api/v4/config/client?format=old"})"
echo "Config: $(echo "$config" | ${pkgs.jq}/bin/jq)" >&2
[[ "$(echo "$config" | ${pkgs.jq}/bin/jq -r ${lib.escapeShellArg ".SiteName == $siteName and .Version == ($mattermostName / $sep)[-1] and (${jqExpression})"} --arg siteName ${lib.escapeShellArg siteName} --arg mattermostName ${lib.escapeShellArg pkgs.mattermost.name} --arg sep '-')" = "true" ]]
'';
setConfig =
jqExpression:
pkgs.writeShellScript "set-config" ''
set -euo pipefail
mattermostConfig=/var/lib/mattermost/config/config.json
newConfig="$(${pkgs.jq}/bin/jq -r ${lib.escapeShellArg jqExpression} $mattermostConfig)"
rm -f $mattermostConfig
echo "$newConfig" > "$mattermostConfig"
'';
in
''
start_all()
## Mutable node tests ##
mutable.wait_for_unit("mattermost.service")
mutable.wait_for_open_port(8065)
mutable.succeed("curl -L http://localhost:8065/index.html | grep '${siteName}'")
mutable.succeed("curl -L http://localhost:8065/index.html | grep 'Mattermost'")
# Get the initial config
mutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"''}")
# Edit the config
mutable.succeed("${setConfig ''.SupportSettings.AboutLink = "https://mattermost.com"''}")
mutable.succeed("${setConfig ''.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"''}")
mutable.systemctl("restart mattermost.service")
mutable.wait_for_open_port(8065)
# AboutLink and HelpLink should be changed
mutable.succeed("${expectConfig ''.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"''}")
## Mostly mutable node tests ##
mostlyMutable.wait_for_unit("mattermost.service")
mostlyMutable.wait_for_open_port(8065)
mostlyMutable.succeed("curl -L http://localhost:8065/index.html | grep '${siteName}'")
mostlyMutable.succeed("curl -L http://localhost:8065/index.html | grep 'Mattermost'")
# Get the initial config
mostlyMutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org"''}")
# Edit the config
mostlyMutable.succeed("${setConfig ''.SupportSettings.AboutLink = "https://mattermost.com"''}")
mostlyMutable.succeed("${setConfig ''.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"''}")
mostlyMutable.systemctl("restart mattermost.service")
mostlyMutable.wait_for_open_port(8065)
# AboutLink should be overridden by NixOS configuration; HelpLink should be what we set above
mostlyMutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"''}")
## Immutable node tests ##
immutable.wait_for_unit("mattermost.service")
immutable.wait_for_open_port(8065)
# Since we patched it, it doesn't replace the site name at runtime anymore
immutable.succeed("curl -L http://localhost:8065/index.html | grep 'Patched Mattermost'")
# Get the initial config
immutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"''}")
# Edit the config
immutable.succeed("${setConfig ''.SupportSettings.AboutLink = "https://mattermost.com"''}")
immutable.succeed("${setConfig ''.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"''}")
immutable.systemctl("restart mattermost.service")
immutable.wait_for_open_port(8065)
# Our edits should be ignored on restart
immutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"''}")
## Environment File node tests ##
environmentFile.wait_for_unit("mattermost.service")
environmentFile.wait_for_open_port(8065)
environmentFile.succeed("curl -L http://localhost:8065/index.html | grep '${siteName}'")
environmentFile.succeed("curl -L http://localhost:8065/index.html | grep 'Mattermost'")
# Settings in the environment file should override settings set otherwise
environmentFile.succeed("${expectConfig ''.AboutLink == "https://nixos.org"''}")
'';
}
)
+537
View File
@@ -0,0 +1,537 @@
import ../make-test-python.nix (
{ pkgs, lib, ... }:
let
host = "smoke.test";
port = 8065;
url = "http://${host}:${toString port}";
siteName = "NixOS Smoke Tests, Inc.";
makeMattermost =
mattermostConfig: extraConfig:
lib.mkMerge [
(
{ config, ... }:
{
environment = {
systemPackages = [
pkgs.mattermost
pkgs.curl
pkgs.jq
];
};
networking.hosts = {
"127.0.0.1" = [ host ];
};
# Assume that Postgres won't update across stateVersion.
services.postgresql = {
package = lib.mkForce pkgs.postgresql;
initialScript = lib.mkIf (!config.services.mattermost.database.peerAuth) (
pkgs.writeText "init.sql" ''
create role ${config.services.mattermost.database.user} with login nocreatedb nocreaterole encrypted password '${config.services.mattermost.database.password}';
''
);
};
system.stateVersion = lib.mkDefault "25.05";
services.mattermost = lib.recursiveUpdate {
enable = true;
inherit siteName;
host = "0.0.0.0";
inherit port;
siteUrl = url;
socket = {
enable = true;
export = true;
};
database = {
peerAuth = lib.mkDefault true;
};
settings = {
SupportSettings.AboutLink = "https://nixos.org";
PluginSettings.AutomaticPrepackagedPlugins = false;
AnnouncementSettings = {
# Disable this since it doesn't work in the sandbox and causes a timeout.
AdminNoticesEnabled = false;
UserNoticesEnabled = false;
};
};
} mattermostConfig;
# Upgrade to the latest Mattermost.
specialisation.latest.configuration = {
services.mattermost.package = lib.mkForce pkgs.mattermostLatest;
system.stateVersion = lib.mkVMOverride "25.05";
};
}
)
extraConfig
];
makeMysql =
mattermostConfig: extraConfig:
lib.mkMerge [
mattermostConfig
(
{ pkgs, config, ... }:
{
services.mattermost.database = {
driver = lib.mkForce "mysql";
peerAuth = lib.mkForce true;
};
}
)
extraConfig
];
in
{
name = "mattermost";
nodes = rec {
postgresMutable =
makeMattermost
{
mutableConfig = true;
settings.SupportSettings.HelpLink = "https://search.nixos.org";
}
{
# Last version to support the "old" config layout.
system.stateVersion = lib.mkForce "24.11";
# First version to support the "new" config layout.
specialisation.upgrade.configuration.system.stateVersion = lib.mkVMOverride "25.05";
};
postgresMostlyMutable = makeMattermost {
mutableConfig = true;
preferNixConfig = true;
plugins = with pkgs; [
# Build the demo plugin.
(mattermost.buildPlugin {
pname = "mattermost-plugin-starter-template";
version = "0.1.0";
src = fetchFromGitHub {
owner = "mattermost";
repo = "mattermost-plugin-starter-template";
# Newer versions have issues with their dependency lockfile.
rev = "7c98e89ac1a268ce8614bc665571b7bbc9a70df2";
hash = "sha256-uyfxB0GZ45qL9ssWUord0eKQC6S0TlCTtjTOXWtK4H0=";
};
vendorHash = "sha256-Jl4F9YkHNqiFP9/yeyi4vTntqxMk/J1zhEP6QLSvJQA=";
npmDepsHash = "sha256-z08nc4XwT+uQjQlZiUydJyh8mqeJoYdPFWuZpw9k99s=";
})
# Build the todos plugin.
(mattermost.buildPlugin {
pname = "mattermost-plugin-todo";
version = "0.8-pre";
src = fetchFromGitHub {
owner = "mattermost-community";
repo = "mattermost-plugin-todo";
# 0.7.1 didn't work, seems to use an older set of node dependencies.
rev = "f25dc91ea401c9f0dcd4abcebaff10eb8b9836e5";
hash = "sha256-OM+m4rTqVtolvL5tUE8RKfclqzoe0Y38jLU60Pz7+HI=";
};
vendorHash = "sha256-5KpechSp3z/Nq713PXYruyNxveo6CwrCSKf2JaErbgg=";
npmDepsHash = "sha256-o2UOEkwb8Vx2lDWayNYgng0GXvmS6lp/ExfOq3peyMY=";
extraGoModuleAttrs = {
npmFlags = [ "--legacy-peer-deps" ];
};
})
];
} { };
postgresImmutable = makeMattermost {
package = pkgs.mattermost.overrideAttrs (prev: {
webapp = prev.webapp.overrideAttrs (prevWebapp: {
# Ensure that users can add patches.
postPatch =
prevWebapp.postPatch or ""
+ ''
substituteInPlace channels/src/root.html --replace-fail "Mattermost" "Patched Mattermost"
'';
});
});
mutableConfig = false;
# Make sure something other than the default works.
user = "mmuser";
group = "mmgroup";
database = {
# Ensure that this gets tested on Postgres.
peerAuth = false;
};
settings.SupportSettings.HelpLink = "https://search.nixos.org";
} { };
postgresEnvironmentFile = makeMattermost {
mutableConfig = false;
database.fromEnvironment = true;
settings.SupportSettings.AboutLink = "https://example.org";
environmentFile = pkgs.writeText "mattermost-env" ''
MM_SQLSETTINGS_DATASOURCE=postgres:///mattermost?host=/run/postgresql
MM_SUPPORTSETTINGS_ABOUTLINK=https://nixos.org
'';
} { };
mysqlMutable = makeMysql postgresMutable { };
mysqlMostlyMutable = makeMysql postgresMostlyMutable { };
mysqlImmutable = makeMysql postgresImmutable {
# Let's try to use this on MySQL.
services.mattermost.database = {
peerAuth = lib.mkForce true;
user = lib.mkForce "mmuser";
name = lib.mkForce "mmuser";
};
};
mysqlEnvironmentFile = makeMysql postgresEnvironmentFile {
services.mattermost.environmentFile = lib.mkForce (
pkgs.writeText "mattermost-env" ''
MM_SQLSETTINGS_DATASOURCE=mattermost@unix(/run/mysqld/mysqld.sock)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s
MM_SUPPORTSETTINGS_ABOUTLINK=https://nixos.org
''
);
};
};
testScript =
{ nodes, ... }:
let
expectConfig = pkgs.writeShellScript "expect-config" ''
set -euo pipefail
config="$(curl ${lib.escapeShellArg "${url}/api/v4/config/client?format=old"})"
echo "Config: $(echo "$config" | ${pkgs.jq}/bin/jq)" >&2
[[ "$(echo "$config" | ${pkgs.jq}/bin/jq -r ${lib.escapeShellArg ".SiteName == $siteName and .Version == $mattermostVersion and "}"($1)" --arg siteName ${lib.escapeShellArg siteName} --arg mattermostVersion "$2" --arg sep '-')" = "true" ]]
'';
setConfig = pkgs.writeShellScript "set-config" ''
set -eo pipefail
mattermostConfig=/etc/mattermost/config.json
nixosVersion="$2"
if [ -z "$nixosVersion" ]; then
nixosVersion="$(nixos-version)"
fi
nixosVersion="$(echo "$nixosVersion" | sed -nr 's/^([0-9]{2})\.([0-9]{2}).*/\1\2/p')"
echo "NixOS version: $nixosVersion" >&2
if [ "$nixosVersion" -lt 2505 ]; then
mattermostConfig=/var/lib/mattermost/config/config.json
fi
newConfig="$(${pkgs.jq}/bin/jq -r "$1" "$mattermostConfig")"
echo "New config @ $mattermostConfig: $(echo "$newConfig" | ${pkgs.jq}/bin/jq)" >&2
truncate -s 0 "$mattermostConfig"
echo "$newConfig" >> "$mattermostConfig"
'';
expectPlugins = pkgs.writeShellScript "expect-plugins" ''
set -euo pipefail
case "$1" in
""|*[!0-9]*)
plugins="$(curl ${lib.escapeShellArg "${url}/api/v4/plugins/webapp"})"
echo "Plugins: $(echo "$plugins" | ${pkgs.jq}/bin/jq)" >&2
[[ "$(echo "$plugins" | ${pkgs.jq}/bin/jq -r "$1")" == "true" ]]
;;
*)
code="$(curl -s -o /dev/null -w "%{http_code}" ${lib.escapeShellArg "${url}/api/v4/plugins/webapp"})"
[[ "$code" == "$1" ]]
;;
esac
'';
ensurePost = pkgs.writeShellScript "ensure-post" ''
set -euo pipefail
url="$1"
failIfNotFound="$2"
# Make sure the user exists
thingExists='(type == "array" and length > 0)'
userExists="($thingExists and ("'.[0].username == "nixos"))'
if mmctl user list --json | jq | tee /dev/stderr | jq -e "$userExists | not"; then
if [ "$failIfNotFound" -ne 0 ]; then
echo "User didn't exist!" >&2
exit 1
else
mmctl user create \
--email tests@nixos.org \
--username nixos --password nixosrules --system-admin --email-verified >&2
# Make sure the user exists.
while mmctl user list --json | jq | tee /dev/stderr | jq -e "$userExists | not"; do
sleep 1
done
fi
fi
# Auth.
mmctl auth login "$url" --name nixos --username nixos --password nixosrules
# Make sure the team exists
teamExists="($thingExists and ("'.[0].display_name == "NixOS Smoke Tests, Inc."))'
if mmctl team list --json | jq | tee /dev/stderr | jq -e "$teamExists | not"; then
if [ "$failIfNotFound" -ne 0 ]; then
echo "Team didn't exist!" >&2
exit 1
else
mmctl team create \
--name nixos \
--display-name "NixOS Smoke Tests, Inc."
# Teams take a second to create.
while mmctl team list --json | jq | tee /dev/stderr | jq -e "$teamExists | not"; do
sleep 1
done
# Add the user.
mmctl team users add nixos tests@nixos.org
fi
fi
authToken="$(cat ~/.config/mmctl/config | jq -r '.nixos.authToken')"
authHeader="Authorization: Bearer $authToken"
acceptHeader="Accept: application/json; charset=UTF-8"
# Make sure the test post exists.
postContents="pls enjoy this NixOS meme I made"
postAttachment=${./test.jpg}
postAttachmentSize="$(stat -c%s $postAttachment)"
postAttachmentHash="$(sha256sum $postAttachment | awk '{print $1}')"
postAttachmentId=""
postPredicate='select(.message == $message and (.file_ids | length) > 0 and (.metadata.files[0].size | tonumber) == ($size | tonumber))'
postExists="($thingExists and ("'(.[] | '"$postPredicate"' | length) > 0))'
if mmctl post list nixos:off-topic --json | jq | tee /dev/stderr | jq --arg message "$postContents" --arg size "$postAttachmentSize" -e "$postExists | not"; then
if [ "$failIfNotFound" -ne 0 ]; then
echo "Post didn't exist!" >&2
exit 1
else
# Can't use mmcli for this seemingly.
channelId="$(mmctl channel list nixos --json | jq | tee /dev/stderr | jq -r '.[] | select(.name == "off-topic") | .id')"
echo "Channel ID: $channelId" >&2
# Upload the file.
echo "Uploading file at $postAttachment (size: $postAttachmentSize)..." >&2
postAttachmentId="$(curl "$url/api/v4/files" -X POST -H "$acceptHeader" -H "$authHeader" \
-F "files=@$postAttachment" -F "channel_id=$channelId" -F "client_ids=test" | jq | tee /dev/stderr | jq -r '.file_infos[0].id')"
# Create the post with it attached.
postJson="$(echo '{}' | jq -c --arg channelId "$channelId" --arg message "$postContents" --arg fileId "$postAttachmentId" \
'{channel_id: $channelId, message: $message, file_ids: [$fileId]}')"
echo "Creating post with contents $postJson..." >&2
curl "$url/api/v4/posts" -X POST -H "$acceptHeader" -H "$authHeader" --json "$postJson" | jq >&2
fi
fi
if mmctl post list nixos:off-topic --json | jq | tee /dev/stderr | jq --arg message "$postContents" --arg size "$postAttachmentSize" -e "$postExists"; then
# Get the attachment ID.
getPostAttachmentId=".[] | $postPredicate | .file_ids[0]"
postAttachmentId="$(mmctl post list nixos:off-topic --json | jq | tee /dev/stderr | \
jq --arg message "$postContents" --arg size "$postAttachmentSize" -r "$getPostAttachmentId")"
echo "Expected post attachment hash: $postAttachmentHash" >&2
actualPostAttachmentHash="$(curl "$url/api/v4/files/$postAttachmentId?download=1" -H "$authHeader" | sha256sum | awk '{print $1}')"
echo "Actual post attachment hash: $postAttachmentHash" >&2
if [ "$actualPostAttachmentHash" != "$postAttachmentHash" ]; then
echo "Post attachment hash mismatched!" >&2
exit 1
else
echo "Post attachment hash was OK!" >&2
exit 0
fi
else
echo "Post didn't exist when it should have!" >&2
exit 1
fi
'';
in
''
import shlex
def wait_mattermost_up(node, site_name="${siteName}"):
node.systemctl("start mattermost.service")
node.wait_for_unit("mattermost.service")
node.wait_for_open_port(8065)
node.succeed(f"curl {shlex.quote('${url}')} >/dev/null")
node.succeed(f"curl {shlex.quote('${url}')}/index.html | grep {shlex.quote(site_name)}")
def restart_mattermost(node, site_name="${siteName}"):
node.systemctl("restart mattermost.service")
wait_mattermost_up(node, site_name)
def expect_config(node, mattermost_version, *configs):
for config in configs:
node.succeed(f"${expectConfig} {shlex.quote(config)} {shlex.quote(mattermost_version)}")
def expect_plugins(node, jq_or_code):
node.succeed(f"${expectPlugins} {shlex.quote(str(jq_or_code))}")
def ensure_post(node, fail_if_not_found=False):
node.succeed(f"${ensurePost} {shlex.quote('${url}')} {1 if fail_if_not_found else 0}")
def set_config(node, *configs, nixos_version='25.05'):
for config in configs:
args = [shlex.quote("${setConfig}")]
args.append(shlex.quote(config))
if nixos_version:
args.append(shlex.quote(str(nixos_version)))
node.succeed(' '.join(args))
def run_mattermost_tests(mutableToplevel: str, mutable,
mostlyMutableToplevel: str, mostlyMutable,
immutableToplevel: str, immutable,
environmentFileToplevel: str, environmentFile):
esr, latest = '${pkgs.mattermost.version}', '${pkgs.mattermostLatest.version}'
## Mutable node tests ##
mutable.start()
wait_mattermost_up(mutable)
# Get the initial config
expect_config(mutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
# Edit the config and make a post
set_config(
mutable,
'.SupportSettings.AboutLink = "https://mattermost.com"',
'.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"',
nixos_version='24.11' # Default 'mutable' config is an old version
)
ensure_post(mutable)
restart_mattermost(mutable)
# AboutLink and HelpLink should be changed, and the post should exist
expect_config(mutable, esr, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
ensure_post(mutable, fail_if_not_found=True)
# Switch to the newer config
mutable.succeed(f"{mutableToplevel}/specialisation/upgrade/bin/switch-to-configuration switch")
wait_mattermost_up(mutable)
# AboutLink and HelpLink should be changed, still, and the post should still exist
expect_config(mutable, esr, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
ensure_post(mutable, fail_if_not_found=True)
# Switch to the latest Mattermost version
mutable.succeed(f"{mutableToplevel}/specialisation/latest/bin/switch-to-configuration switch")
wait_mattermost_up(mutable)
# AboutLink and HelpLink should be changed, still, and the post should still exist
expect_config(mutable, latest, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
ensure_post(mutable, fail_if_not_found=True)
mutable.shutdown()
## Mostly mutable node tests ##
mostlyMutable.start()
wait_mattermost_up(mostlyMutable)
# Get the initial config
expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org"')
# No plugins.
expect_plugins(mostlyMutable, 'length == 0')
# Edit the config and make a post
set_config(
mostlyMutable,
'.SupportSettings.AboutLink = "https://mattermost.com"',
'.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"',
'.PluginSettings.PluginStates."com.mattermost.plugin-todo".Enable = true'
)
ensure_post(mostlyMutable)
restart_mattermost(mostlyMutable)
# AboutLink should be overridden by NixOS configuration; HelpLink should be what we set above
expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
# Single plugin that's now enabled.
expect_plugins(mostlyMutable, 'length == 1')
# Post should exist.
ensure_post(mostlyMutable, fail_if_not_found=True)
# Switch to the latest Mattermost version
mostlyMutable.succeed(f"{mostlyMutableToplevel}/specialisation/latest/bin/switch-to-configuration switch")
wait_mattermost_up(mostlyMutable)
# AboutLink should be overridden and the post should still exist
expect_config(mostlyMutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
ensure_post(mostlyMutable, fail_if_not_found=True)
mostlyMutable.shutdown()
## Immutable node tests ##
immutable.start()
wait_mattermost_up(immutable, "Patched Mattermost")
# Get the initial config
expect_config(immutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
# Edit the config and make a post
set_config(
immutable,
'.SupportSettings.AboutLink = "https://mattermost.com"',
'.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"'
)
ensure_post(immutable)
restart_mattermost(immutable, "Patched Mattermost")
# Our edits should be ignored on restart
expect_config(immutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
# No plugins.
expect_plugins(immutable, 'length == 0')
# Post should exist.
ensure_post(immutable, fail_if_not_found=True)
# Switch to the latest Mattermost version
immutable.succeed(f"{immutableToplevel}/specialisation/latest/bin/switch-to-configuration switch")
wait_mattermost_up(immutable)
# AboutLink and HelpLink should be changed, still, and the post should still exist
expect_config(immutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
ensure_post(immutable, fail_if_not_found=True)
immutable.shutdown()
## Environment File node tests ##
environmentFile.start()
wait_mattermost_up(environmentFile)
ensure_post(environmentFile)
# Settings in the environment file should override settings set otherwise, and the post should exist
expect_config(environmentFile, esr, '.AboutLink == "https://nixos.org"')
ensure_post(environmentFile, fail_if_not_found=True)
# Switch to the latest Mattermost version
environmentFile.succeed(f"{environmentFileToplevel}/specialisation/latest/bin/switch-to-configuration switch")
wait_mattermost_up(environmentFile)
# AboutLink should be changed still, and the post should still exist
expect_config(environmentFile, latest, '.AboutLink == "https://nixos.org"')
ensure_post(environmentFile, fail_if_not_found=True)
environmentFile.shutdown()
run_mattermost_tests(
"${nodes.mysqlMutable.system.build.toplevel}",
mysqlMutable,
"${nodes.mysqlMostlyMutable.system.build.toplevel}",
mysqlMostlyMutable,
"${nodes.mysqlImmutable.system.build.toplevel}",
mysqlImmutable,
"${nodes.mysqlEnvironmentFile.system.build.toplevel}",
mysqlEnvironmentFile
)
run_mattermost_tests(
"${nodes.postgresMutable.system.build.toplevel}",
postgresMutable,
"${nodes.postgresMostlyMutable.system.build.toplevel}",
postgresMostlyMutable,
"${nodes.postgresImmutable.system.build.toplevel}",
postgresImmutable,
"${nodes.postgresEnvironmentFile.system.build.toplevel}",
postgresEnvironmentFile
)
'';
}
)
Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

@@ -1725,6 +1725,18 @@ in
dependencies = [ self.plenary-nvim ];
};
git-conflict-nvim = super.git-conflict-nvim.overrideAttrs {
# TODO: Remove after next fixed version
# https://github.com/akinsho/git-conflict.nvim/issues/103
version = "2.1.0";
src = fetchFromGitHub {
owner = "akinsho";
repo = "git-conflict.nvim";
tag = "v2.1.0";
hash = "sha256-1t0kKxTGLuOvuRkoLgkoqMZpF+oKo8+gMsTdgPsSb+8=";
};
};
minimap-vim = super.minimap-vim.overrideAttrs {
preFixup = ''
substituteInPlace $out/plugin/minimap.vim \
@@ -39,7 +39,7 @@ stdenv.mkDerivation (finalAttrs: {
version = "0.0.34";
src = fetchFromGitHub {
owner = "mgerhardy";
owner = "vengi-voxel";
repo = "vengi";
rev = "v${finalAttrs.version}";
hash = "sha256-a78Oiwln3vyzCyjNewbK1/05bnGcSixxzKIgz4oiDmA=";
@@ -114,8 +114,8 @@ stdenv.mkDerivation (finalAttrs: {
filemanager and a command line tool to convert between several voxel
formats.
'';
homepage = "https://mgerhardy.github.io/vengi/";
downloadPage = "https://github.com/mgerhardy/vengi/releases";
homepage = "https://vengi-voxel.github.io/vengi/";
downloadPage = "https://github.com/vengi-voxel/vengi/releases";
license = [
licenses.mit
licenses.cc-by-sa-30
+2 -1
View File
@@ -2,12 +2,13 @@
fetchFromGitLab,
srcOnly,
fetchpatch,
stdenv,
}:
rec {
version = "2.2.5";
src = srcOnly {
pname = "paperwork-patched-src";
inherit version;
inherit version stdenv;
src = fetchFromGitLab {
domain = "gitlab.gnome.org";
repo = "paperwork";
+2 -3
View File
@@ -8,8 +8,7 @@
cmake,
pkg-config,
# See https://files.ettus.com/manual_archive/v3.15.0.0/html/page_build_guide.html for dependencies explanations
# Pin Boost 1.86 due to use of boost::asio::io_service.
boost186,
boost,
ncurses,
enableCApi ? true,
enablePythonApi ? true,
@@ -165,7 +164,7 @@ stdenv.mkDerivation (finalAttrs: {
buildInputs =
finalAttrs.pythonPath
++ [
boost186
boost
libusb1
]
++ optionals (enableExamples) [
@@ -1,43 +0,0 @@
{
lib,
stdenv,
fetchhg,
autoconf,
sqlite,
}:
stdenv.mkDerivation rec {
pname = "vcprompt";
version = "1.2.1";
src = fetchhg {
url = "http://hg.gerg.ca/vcprompt/";
rev = version;
sha256 = "03xqvp6bfl98bpacrw4n82qv9cw6a4fxci802s3vrygas989v1kj";
};
buildInputs = [
sqlite
autoconf
];
preConfigure = ''
autoconf
'';
makeFlags = [
"PREFIX=${placeholder "out"}"
];
meta = with lib; {
description = ''
A little C program that prints a short string with barebones information
about the current working directory for various version control systems
'';
homepage = "http://hg.gerg.ca/vcprompt";
maintainers = [ ];
platforms = with platforms; linux ++ darwin;
license = licenses.gpl2Plus;
mainProgram = "vcprompt";
};
}
@@ -40,11 +40,15 @@ stdenv.mkDerivation (finalAttrs: {
nativeCheckInputs = [
cmake
];
checkInputs = [
doctest
];
# CMake is just used for finding doctest.
dontUseCmakeConfigure = true;
strictDeps = true;
mesonFlags = [
(lib.mesonEnable "tests" (stdenv.buildPlatform.canExecute stdenv.hostPlatform))
];
+1 -1
View File
@@ -46,7 +46,7 @@ stdenv.mkDerivation (finalAttrs: {
meta = with lib; {
description = "Detects tRNA, mtRNA, and tmRNA genes in nucleotide sequences";
mainProgram = "aragorn";
homepage = "http://www.ansikte.se/ARAGORN/";
homepage = "https://www.trna.se/ARAGORN/";
license = licenses.gpl3Plus;
maintainers = [ maintainers.bzizou ];
platforms = platforms.unix;
+2 -2
View File
@@ -11,13 +11,13 @@
stdenv.mkDerivation rec {
pname = "bfs";
version = "4.0.4";
version = "4.0.5";
src = fetchFromGitHub {
repo = "bfs";
owner = "tavianator";
rev = version;
hash = "sha256-KcXbLYITTxNq2r8Bqf4FRy7cOZw1My9Ii6O/FDLhCGY=";
hash = "sha256-vYK3lQsHE3GD8mFCZLxJN+TrJZJGwq9+kNm6y0zAa2U=";
};
buildInputs =
@@ -6,14 +6,14 @@
python3.pkgs.buildPythonApplication rec {
pname = "changedetection-io";
version = "0.48.05";
version = "0.48.06";
format = "setuptools";
src = fetchFromGitHub {
owner = "dgtlmoon";
repo = "changedetection.io";
tag = version;
hash = "sha256-oOuHPOvs3qcQcibKyChe2AK1OB3JK/xRKUp1cj5p5PU=";
hash = "sha256-6ofCVmdO8Z/EyJjbzAQdwnqUfsjtPzveNd5Zfj3pcFM=";
};
pythonRelaxDeps = true;
+4
View File
@@ -18,6 +18,10 @@ stdenv.mkDerivation rec {
nativeBuildInputs = [ cmake ];
cmakeFlags = lib.optional (stdenv.cc.isClang && !stdenv.hostPlatform.isDarwin) (
lib.cmakeBool "ENABLE_CUSTOM_COMPILER_FLAGS" false
);
# cJSON actually uses C99 standard, not C89
# https://github.com/DaveGamble/cJSON/issues/275
postPatch = ''
+5 -5
View File
@@ -11,16 +11,16 @@ let
in
stdenv.mkDerivation (finalAttrs: {
pname = "clouddrive2";
version = "0.8.5";
version = "0.8.6";
src = fetchurl {
url = "https://github.com/cloud-fs/cloud-fs.github.io/releases/download/v${finalAttrs.version}/clouddrive-2-${os}-${arch}-${finalAttrs.version}.tgz";
hash =
{
x86_64-linux = "sha256-6zdP0d5XyBYG7+SGqb2DSaD6rJrBn8OjGr9BXfP1Ctc=";
aarch64-linux = "sha256-7u/AKZGL/AkUsakZexC/oxgjoayaxH7OiRE+xnH+Gus=";
x86_64-darwin = "sha256-/uDxZVlULl3PnuAaF7kWAyukaQoF7DV8m5gowTFdMEQ=";
aarch64-darwin = "sha256-xZ60pi2JYSLDLaR0Qe/fyEhzyu17U2fbDp1lo2qViIs=";
x86_64-linux = "sha256-79P356HchNTpiFd7V/XeOuFyS7xpS/SARyS7X7a3Ko4=";
aarch64-linux = "sha256-GXjr4RZCRE+oz+ldpJ4lgN5LxPD/BU1544ApNqULHTc=";
x86_64-darwin = "sha256-otkVfPTRYmdw818RESavkZh0PRpFyrum56TnNTol538=";
aarch64-darwin = "sha256-hePGS4CJibSTqav5Gk2/U27SO1JAeReCSDpCaijCa74=";
}
.${stdenv.hostPlatform.system} or (throw "unsupported system ${stdenv.hostPlatform.system}");
};
+1 -1
View File
@@ -64,7 +64,7 @@ stdenv.mkDerivation rec {
changes made to a collection of files, and all committed at the
same time (using a single "cvs commit" command).
'';
homepage = "http://www.cobite.com/cvsps/";
homepage = "https://sourceforge.net/projects/cvsps/";
license = lib.licenses.gpl2;
platforms = lib.platforms.unix;
mainProgram = "cvsps";
+3 -3
View File
@@ -11,16 +11,16 @@
buildGoModule rec {
pname = "fzf";
version = "0.57.0";
version = "0.58.0";
src = fetchFromGitHub {
owner = "junegunn";
repo = "fzf";
rev = "v${version}";
hash = "sha256-WEdCa6Krj+VicB1vxWzyY1rCHvmaL4t2njhhjq0Bppw=";
hash = "sha256-0HlmUwQFitd1He+F16JiwDcP0t9Bfo0sAm8owlb/Ygs=";
};
vendorHash = "sha256-utHQzXjtdnshUsYDQEQY2qoQGZsnfXXPj3A9VsDj0vQ=";
vendorHash = "sha256-rUG926YdBTZyJfpTG0kXr2zo+yw1eNEUlolS6Q7C+ng=";
env.CGO_ENABLED = 0;
+1 -1
View File
@@ -20,7 +20,7 @@ stdenvNoCC.mkDerivation rec {
meta = with lib; {
description = "Two-element sans-serif typeface, created by Małgorzata Budyta";
homepage = "https://jmn.pl/en/kurier-i-iwona/";
homepage = "https://jmn.pl/en/kurier/";
# "[...] GUST Font License (GFL), which is a free license, legally
# equivalent to the LaTeX Project Public # License (LPPL), version 1.3c or
# later." - GUST website
+153
View File
@@ -0,0 +1,153 @@
{
lib,
stdenv,
mattermost,
nodejs,
writeShellScriptBin,
buildGoModule,
golangci-lint,
gotestsum,
fetchNpmDeps,
npmHooks,
npm-lockfile-fix,
}:
{
# The name of the plugin.
pname,
# The plugin version.
version,
# The plugin source.
src,
# True to ignore golangci-lint warnings. By default set to true
# since plugins warn about the Mattermost interface but build fine.
ignoreGoLintWarnings ? true,
# The hash of the gomod vendor directory.
vendorHash ? lib.fakeHash,
# True to build the webapp.
buildWebapp ? true,
# The NPM dependency hash.
npmDepsHash ? lib.fakeHash,
# Any extra attributes to pass to buildGoModule.
extraGoModuleAttrs ? { },
}:
let
fakeGit = writeShellScriptBin "git" ''
case "$1" in
rev-parse|describe|tag)
echo ${lib.escapeShellArg version} ;;
config)
echo ${lib.escapeShellArg pname} ;;
*) ;;
esac
'';
fake-golangci-lint = writeShellScriptBin "golangci-lint" ''
set -uo pipefail
${lib.getExe golangci-lint} "$@"
result=$?
echo "golangci-lint returned: $result" >&2
${lib.optionalString (ignoreGoLintWarnings) ''
if [ $result != 0 ]; then
cat <<EOF >&2
Ignoring return value since ignoreGoLintWarnings was true.
Tell this plugin author to fix their lint.
EOF
result=0
fi
''}
exit $result
'';
in
buildGoModule (
rec {
name = "${pname}-${version}.tar.gz";
inherit version src vendorHash;
npmDeps =
if buildWebapp then
fetchNpmDeps {
src = "${src}/webapp";
hash = npmDepsHash;
forceGitDeps = true;
postFetch = ''
${lib.getExe npm-lockfile-fix} package-lock.json
'';
}
else
null;
makeCacheWritable = true;
forceGitDeps = true;
overrideModAttrs = final: {
preBuild = ''
go mod tidy
'';
# Adding the NPM config hook here breaks things, and isn't even needed.
nativeBuildInputs = lib.lists.remove npmHooks.npmConfigHook final.nativeBuildInputs;
};
prePatch = lib.optionalString buildWebapp ''
# Move important node.js files up a level and symlink the originals so the setup hook finds them
for file in package.json package-lock.json node_modules; do
if [ -f "webapp/$file" ]; then
mv "webapp/$file" .
fi
(cd webapp && ln -vsf "../$file")
done
# Don't allow Go installation in the sandbox, but also don't fail
substituteInPlace Makefile --replace-warn '$(GO) install' '@echo $(GO) install'
'';
nativeBuildInputs = [
fakeGit
nodejs
npmHooks.npmConfigHook
];
buildInputs = [ mattermost ];
preBuild = ''
# Or else Babel doesn't run.
export NODE_OPTIONS=--openssl-legacy-provider
# Only build GOOS and GOARCH plugins so we aren't
# spitting out FreeBSD/Windows/Darwin executables we don't use.
export MM_SERVICESETTINGS_ENABLEDEVELOPER=true
'';
buildPhase = ''
runHook preBuild
# These dependencies are ordinarily fetched via the Makefile, making
# $(GO) install only echo means we still need to install them.
mkdir -p bin
ln -sf ${lib.getExe fake-golangci-lint} bin/golangci-lint
ln -sf ${lib.getExe gotestsum} bin/gotestsum
# Do the build.
make
runHook postBuild
'';
installPhase = ''
plugin="$(ls dist/*.tar.gz | tail -n1)"
if [ -z "$plugin" ] || [ ! -f "$plugin" ]; then
echo "No plugin tarball in dist folder!" >&2
exit 1
fi
cp -av "$plugin" $out
'';
}
// extraGoModuleAttrs
)
+119 -53
View File
@@ -1,5 +1,7 @@
{
lib,
callPackage,
stdenvNoCC,
buildGoModule,
fetchFromGitHub,
buildNpmPackage,
@@ -16,7 +18,7 @@
# the version regex here as well.
#
# Ensure you also check ../mattermostLatest/package.nix.
regex = "^v(9\.11\.[0-9]+)$";
regex = "^v(9\\.11\\.[0-9]+)$";
version = "9.11.7";
srcHash = "sha256-KeGpYy3jr7/B2mtBk9em2MXJBJR2+Wajmvtz/yT4SG8=";
vendorHash = "sha256-alLPBfnA1o6bUUgPRqvYW/98UKR9wltmFTzKIGtVEm4=";
@@ -24,7 +26,60 @@
},
}:
buildGoModule rec {
let
/*
Helper function that sets the `withTests` and `withoutTests` passthru correctly,
and returns the version with tests.
The primary reason to use this helper over reindenting the whole file is to avoid
lots of manual backporting when the update script runs.
*/
buildMattermost =
{ passthru, ... }@args:
let
# Joins the webapp and Matermost derivation together.
# That way patches to the webapp won't cause a rebuild of the server.
wrapMattermost =
server:
stdenvNoCC.mkDerivation {
pname = "${server.pname}-wrapped";
inherit (server) version;
inherit server;
inherit (server) webapp;
dontUnpack = true;
# Just link all the server and webapp root directories together.
installPhase = ''
mkdir -p $out
for dir in "$server" "$webapp"; do
for path in "$dir"/*; do
ln -s "$path" "$out/$(basename -- "$path")"
done
done
'';
passthru = finalPassthru // {
inherit server;
inherit (server) webapp;
};
inherit (server) meta;
};
finalPassthru =
let
withoutTestsUnwrapped = buildGoModule (args // { passthru = finalPassthru; });
withTestsUnwrapped = callPackage ./tests.nix { mattermost = withoutTestsUnwrapped; };
in
lib.recursiveUpdate passthru rec {
withoutTests = wrapMattermost withoutTestsUnwrapped;
withTests = wrapMattermost withTestsUnwrapped;
tests.mattermostWithTests = withTests;
};
in
finalPassthru.withTests;
in
buildMattermost rec {
pname = "mattermost";
inherit (versionInfo) version;
@@ -64,14 +119,12 @@ buildGoModule rec {
# We use go 1.22's workspace vendor command, which is not yet available
# in the default version of go used in nixpkgs, nor is it used by upstream:
# https://github.com/mattermost/mattermost/issues/26221#issuecomment-1945351597
overrideModAttrs = (
_: {
buildPhase = ''
make setup-go-work
go work vendor -e
'';
}
);
overrideModAttrs = _: {
buildPhase = ''
make setup-go-work
go work vendor -e -v
'';
};
npmDeps = fetchNpmDeps {
inherit src;
@@ -81,46 +134,6 @@ buildGoModule rec {
forceGitDeps = true;
};
webapp = buildNpmPackage rec {
pname = "mattermost-webapp";
inherit version src;
sourceRoot = "${src.name}/webapp";
# Remove deprecated image-webpack-loader causing build failures
# See: https://github.com/tcoopman/image-webpack-loader#deprecated
postPatch = ''
substituteInPlace channels/webpack.config.js \
--replace-fail 'options: {}' 'options: { disable: true }'
'';
npmDepsHash = npmDeps.hash;
makeCacheWritable = true;
forceGitDeps = true;
npmRebuildFlags = [ "--ignore-scripts" ];
buildPhase = ''
runHook preBuild
npm run build --workspace=platform/types
npm run build --workspace=platform/client
npm run build --workspace=platform/components
npm run build --workspace=channels
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out
cp -a channels/dist/* $out
runHook postInstall
'';
};
inherit (versionInfo) vendorHash;
modRoot = "./server";
@@ -128,7 +141,10 @@ buildGoModule rec {
make setup-go-work
'';
subPackages = [ "cmd/mattermost" ];
subPackages = [
"cmd/mattermost"
"cmd/mmctl"
];
tags = [ "production" ];
@@ -147,8 +163,7 @@ buildGoModule rec {
shopt -s extglob
mkdir -p $out/{i18n,fonts,templates,config}
# Link in the client and copy the language packs.
ln -sf $webapp $out/client
# Copy the language packs.
cp -a $src/server/i18n/* $out/i18n/
# Fonts have the execute bit set, remove it.
@@ -162,6 +177,13 @@ buildGoModule rec {
go run -tags production ./scripts/config_generator
'';
doInstallCheck = true;
installCheckPhase = ''
for subPackage in $subPackages; do
"$out/bin/$(basename -- "$subPackage")" version | grep "$version"
done
'';
passthru = {
updateScript = nix-update-script {
extraArgs =
@@ -175,6 +197,50 @@ buildGoModule rec {
];
};
tests.mattermost = nixosTests.mattermost;
# Builds a Mattermost plugin.
buildPlugin = callPackage ./build-plugin.nix { };
# Builds the webapp.
webapp = buildNpmPackage rec {
pname = "mattermost-webapp";
inherit version src;
sourceRoot = "${src.name}/webapp";
# Remove deprecated image-webpack-loader causing build failures
# See: https://github.com/tcoopman/image-webpack-loader#deprecated
postPatch = ''
substituteInPlace channels/webpack.config.js \
--replace-fail 'options: {}' 'options: { disable: true }'
'';
npmDepsHash = npmDeps.hash;
makeCacheWritable = true;
forceGitDeps = true;
npmRebuildFlags = [ "--ignore-scripts" ];
buildPhase = ''
runHook preBuild
npm run build --workspace=platform/types
npm run build --workspace=platform/client
npm run build --workspace=platform/components
npm run build --workspace=channels
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/client
cp -a channels/dist/* $out/client
runHook postInstall
'';
};
};
meta = with lib; {
+399
View File
@@ -0,0 +1,399 @@
{
lib,
stdenv,
mattermost,
gotestsum,
which,
postgresql,
mariadb,
redis,
curl,
nettools,
runtimeShell,
}:
let
inherit (lib.lists) optionals;
inherit (lib.strings) versionAtLeast;
is10 = version: versionAtLeast version "10.0";
in
mattermost.overrideAttrs (
final: prev: {
doCheck = true;
checkTargets = [
"test-server"
"test-mmctl"
];
nativeCheckInputs = [
which
postgresql
mariadb
redis
curl
nettools
gotestsum
];
postPatch =
prev.postPatch or ""
+ ''
# Just echo install/get/mod commands in the Makefile, since the dependencies are locked.
substituteInPlace server/Makefile \
--replace-warn '$(GO) install' '@echo $(GO) install' \
--replace-warn '$(GO) get' '@echo $(GO) get' \
--replace-warn '$(GO) get' '@echo $(GO) mod'
# mmctl tests shell out by writing a bash script to a tempfile
substituteInPlace server/cmd/mmctl/commands/config_e2e_test.go \
--replace-fail '#!/bin/bash' '#!${runtimeShell}'
'';
# Make sure we disable tests that are broken.
# Use: `nix log <drv> | grep FAIL: | awk '{print $3}' | sort`
# and then try to pick the most specific test set to disable, such as:
# X TestFoo
# X TestFoo/TestBar
# -> TestFoo/TestBar/baz_test
disabledTests =
[
# All these plugin tests for mmctl reach out to the marketplace, which is impossible in the sandbox
"TestMmctlE2ESuite/TestPluginDeleteCmd/Delete_Plugin/SystemAdminClient"
"TestMmctlE2ESuite/TestPluginDeleteCmd/Delete_Plugin/LocalClient"
"TestMmctlE2ESuite/TestPluginDeleteCmd/Delete_a_Plugin_without_permissions"
"TestMmctlE2ESuite/TestPluginDeleteCmd/Delete_Unknown_Plugin/SystemAdminClient"
"TestMmctlE2ESuite/TestPluginDeleteCmd/Delete_Unknown_Plugin/LocalClient"
"TestMmctlE2ESuite/TestPluginInstallURLCmd/install_new_plugins/SystemAdminClient"
"TestMmctlE2ESuite/TestPluginInstallURLCmd/install_new_plugins/LocalClient"
"TestMmctlE2ESuite/TestPluginInstallURLCmd/install_an_already_installed_plugin_without_force/SystemAdminClient"
"TestMmctlE2ESuite/TestPluginInstallURLCmd/install_an_already_installed_plugin_without_force/LocalClient"
"TestMmctlE2ESuite/TestPluginInstallURLCmd/install_an_already_installed_plugin_with_force/SystemAdminClient"
"TestMmctlE2ESuite/TestPluginInstallURLCmd/install_an_already_installed_plugin_with_force/LocalClient"
"TestMmctlE2ESuite/TestPluginMarketplaceInstallCmd/install_a_plugin/SystemAdminClient"
"TestMmctlE2ESuite/TestPluginMarketplaceInstallCmd/install_a_plugin/LocalClient"
"TestMmctlE2ESuite/TestPluginMarketplaceListCmd/List_Marketplace_Plugins_for_Admin_User/SystemAdminClient"
"TestMmctlE2ESuite/TestPluginMarketplaceListCmd/List_Marketplace_Plugins_for_Admin_User/LocalClient"
# Seems to just be broken.
"TestMmctlE2ESuite/TestPreferenceUpdateCmd"
# Has a hardcoded "google.com" test which also verifies that the address isn't loopback,
# so we also can't just substituteInPlace to one that will resolve
"TestDialContextFilter"
# No interfaces but loopback in the sandbox, so returns empty
"TestGetServerIPAddress"
# S3 bucket tests (needs Minio)
"TestInsecureMakeBucket"
"TestMakeBucket"
"TestListDirectory"
"TestTimeout"
"TestStartServerNoS3Bucket"
"TestS3TestConnection"
"TestS3FileBackendTestSuite"
"TestS3FileBackendTestSuiteWithEncryption"
# Mail tests (needs a SMTP server)
"TestSendMailUsingConfig"
"TestSendMailUsingConfigAdvanced"
"TestSendMailWithEmbeddedFilesUsingConfig"
"TestSendCloudWelcomeEmail"
"TestMailConnectionAdvanced"
"TestMailConnectionFromConfig"
"TestEmailTest"
"TestBasicAPIPlugins/test_send_mail_plugin"
# Seems to be unreliable
"TestPluginAPIUpdateUserPreferences"
"TestPluginAPIGetUserPreferences"
# These invite tests try to send a welcome email and we don't have a SMTP server up.
"TestInviteUsersToTeam"
"TestInviteGuestsToTeam"
"TestSendInviteEmails"
"TestDeliver"
# https://github.com/mattermost/mattermost/issues/29184
"TestUpAndDownMigrations/Should_be_reversible_for_mysql"
]
++ optionals (is10 final.version) [
## mattermostLatest test ignores
# These bot related tests appear to be broken.
"TestCreateBot"
"TestPatchBot"
"TestGetBot"
"TestEnableBot"
"TestDisableBot"
"TestAssignBot"
"TestConvertBotToUser"
# Need Elasticsearch or Opensearch
"TestBlevePurgeIndexes"
"TestOpensearchAggregation"
"TestOpensearchInterfaceTestSuite"
"TestOpenSearchIndexerJobIsEnabled"
"TestOpenSearchIndexerPending"
"TestBulkProcessor"
"TestElasticsearchAggregation"
"TestElasticsearchInterfaceTestSuite"
"TestElasticSearchIndexerJobIsEnabled"
"TestElasticSearchIndexerPending"
# Appear to be broken.
"TestSessionStore/MySQL/SessionGetWithDeviceId"
"TestSessionStore/MySQL/GetMobileSessionMetadata"
]
++ optionals (!stdenv.isx86_64) [
# aarch64: invalid operating system or processor architecture
"TestCanIUpgradeToE0"
];
preCheck = ''
cleanup() {
runHook postCheck
}
trap cleanup EXIT
# Runs an iteration of the wait loop.
# Returns 0 if we should retry, 1 otherwise.
_wait_loop() {
local process="$1"
local direction="$2"
echo "Waiting for $process to go $direction ($_TRIES attempt(s) left)..." >&2
_TRIES=$((_TRIES-1))
if [ $_TRIES -le 0 ]; then
return 1
else
sleep 1
return 0
fi
}
# Waits on a command named '$1' with direction '$2'.
# The rest of the command is specified in $@.
# If the direction is up, waits for the command to succeed at 1 second intervals.
# If it's down, waits for the command to fail at 1 second intervals.
# Uses a maximum of 5 iterations. Returns 0 if all was ok, or 1 if we timed out.
wait_cmd() {
local process="$1"
local direction="$2"
local tries=10
_TRIES=$tries
shift; shift
if [ "$direction" == "up" ]; then
while ! "$@" &>/dev/null; do
if ! _wait_loop "$process" "$direction"; then
break
fi
done
else
while "$@" &>/dev/null; do
if ! _wait_loop "$process" "$direction"; then
break
fi
done
fi
if [ $_TRIES -le 0 ]; then
echo "Timed out after $tries tries" >&2
return 1
else
echo "OK, $process went $direction." >&2
return 0
fi
}
# Waits for MySQL to come up or down.
wait_mysql() {
wait_cmd mysql "$1" mysqladmin ping
}
# Waits for Postgres to come up or down.
wait_postgres() {
wait_cmd postgres "$1" pg_isready -h localhost
}
# Waits for Redis to come up or down.
wait_redis() {
wait_cmd redis "$1" redis-cli ping
}
# Starts MySQL.
start_mysql() {
echo "Starting MySQL at $MYSQL_HOME" >&2
mysqld &
mysql_pid=$!
echo "... PID $mysql_pid" >&2
wait_mysql up
}
# Stops MySQL.
stop_mysql() {
if [ "$mysql_pid" -gt 0 ]; then
echo "Terminating MySQL at $MYSQL_HOME (PID $mysql_pid)" >&2
mysqladmin --host=127.0.0.1 --user=root --password=mostest --wait-for-all-slaves --shutdown-timeout=30 shutdown
wait_mysql down
wait_cmd 'mysql pid' down kill -0 "$mysql_pid"
# Make sure the worker PID went down too (but it may be already gone).
local worker_pid="$(<"$MYSQL_HOME"/mysqld.pid || echo 0)"
if [ -n "$worker_pid" ] && [ $worker_pid -gt 0 ]; then
wait_cmd 'mysql workers' down kill -0 "$worker_pid"
fi
mysql_pid=0
fi
}
# Starts Postgres.
start_postgres() {
echo "Starting Postgres at $PGDATA" >&2
pg_ctl start
wait_postgres up
}
# Stops Postgres.
stop_postgres() {
echo "Terminating Postgres at $PGDATA" >&2
pg_ctl stop
wait_postgres down
}
# Starts redis.
start_redis() {
echo "Starting Redis" >&2
(cd "$REDIS_HOME" && exec redis-server ./redis.conf) &
redis_pid=$!
echo "... PID $redis_pid" >&2
wait_redis up
}
# Stops redis.
stop_redis() {
echo "Stopping Redis" >&2
kill -TERM "$redis_pid" >&2
wait_redis down
redis_pid=0
}
# Configure MySQL.
export MYSQL_HOME="$NIX_BUILD_TOP/.mysql"
mkdir -p "$MYSQL_HOME"
cat <<EOF >"$MYSQL_HOME/my.cnf"
[client]
port = 3306
default-character-set = utf8mb4
socket = $MYSQL_HOME/mysqld.sock
[mysqld]
skip-host-cache
skip-name-resolve
basedir = ${mariadb}
datadir = $MYSQL_HOME/
pid-file = $MYSQL_HOME/mysqld.pid
socket = $MYSQL_HOME/mysqld.sock
port = 3306
explicit_defaults_for_timestamp
collation-server = utf8mb4_general_ci
init-connect = 'SET NAMES utf8mb4'
character-set-server = utf8mb4
EOF
# Start MySQL.
mysql_install_db --skip-name-resolve --auth-root-authentication-method=normal
start_mysql
# Init MySQL.
cat <<EOF | mysql --defaults-file="$MYSQL_HOME/my.cnf" -u root -v
-- This is the admin password for tests; see the docker-compose:
-- https://github.com/mattermost/mattermost/blob/v${final.version}/server/docker-compose.yaml
create user if not exists 'mmuser' identified by 'mostest';
create database if not exists mattermost_test;
grant all privileges on *.* to 'mmuser' with grant option;
-- Also need to set up root (tests seem to override the user to root)
alter user 'root'@'127.0.0.1' identified by 'mostest';
flush privileges;
show grants for 'root'@'127.0.0.1';
show grants for 'mmuser';
EOF
# Need to change this so we use 127.0.0.1 in tests.
export TEST_DATABASE_MYSQL_DSN='root:mostest@tcp(127.0.0.1:3306)/mattermost_test?charset=utf8mb4&readTimeout=30s&writeTimeout=30s'
# Start Postgres.
export PGDATA="$NIX_BUILD_TOP/.postgres"
initdb -U postgres
mkdir -p "$PGDATA/run"
cat <<EOF >> "$PGDATA/postgresql.conf"
unix_socket_directories = '$PGDATA/run'
max_connections = 256
shared_buffers = 96MB
EOF
start_postgres
# Init Postgres.
cat <<EOF | psql -U postgres -h localhost
-- This is the admin password for tests; see the docker-compose:
-- https://github.com/mattermost/mattermost/blob/v${final.version}/server/docker-compose.yaml
create user mmuser superuser password 'mostest';
create database mattermost_test;
grant all on database mattermost_test to mmuser;
alter database mattermost_test owner to mmuser;
EOF
# Configure Redis.
export REDIS_HOME="$NIX_BUILD_TOP/.redis"
mkdir -p "$REDIS_HOME"
cat <<EOF > "$REDIS_HOME/redis.conf"
bind 127.0.0.1
port 6379
protected-mode no
EOF
# Start Redis.
start_redis
# Use gotestsum from nixpkgs instead of installing it ourselves.
mkdir -p bin
ln -s "$(which gotestsum)" bin/gotestsum
'';
checkPhase = ''
runHook preCheck
# Ensure we parallelize the tests, and skip the correct ones.
# Spaces are important here due to how the Makefile works.
export GOFLAGS=" -parallel=$NIX_BUILD_CORES -skip='$(echo "$disabledTests" | tr ' ' '|')' "
# ce n'est pas un conteneur
MMCTL_TESTFLAGS="$GOFLAGS" MM_NO_DOCKER=true make $checkTargets
runHook postCheck
'';
postCheck = ''
# Clean up MySQL.
if [ -d "$MYSQL_HOME" ]; then
stop_mysql
rm -rf "$MYSQL_HOME"
fi
# Clean up Postgres.
if [ -d "$PGDATA" ]; then
stop_postgres
rm -rf "$PGDATA"
fi
# Clean up Redis.
if [ -d "$REDIS_HOME" ]; then
stop_redis
rm -rf "$REDIS_HOME"
fi
# Delete the gotestsum link.
rm -f bin/gotestsum
'';
}
)
+1 -1
View File
@@ -10,7 +10,7 @@ mattermost.override {
# See https://docs.mattermost.com/about/mattermost-server-releases.html
# and make sure the version regex is up to date here.
# Ensure you also check ../mattermost/package.nix for ESR releases.
regex = "^v(10\.[0-9]+\.[0-9]+)$";
regex = "^v(10\\.[0-9]+\\.[0-9]+)$";
version = "10.4.1";
srcHash = "sha256-e7uT30tWhJpEQzlcDUY2huFcupDbe4l8B19Dgub2pg0=";
vendorHash = "sha256-AcemUxcBoytE/ZoXqaIlxkzAnmGV/C1laDqziMuE+XE=";
+1 -1
View File
@@ -58,7 +58,7 @@ stdenv.mkDerivation rec {
meta = with lib; {
description = "Lightweight WebKitGTK web browser";
mainProgram = "midori";
homepage = "https://www.midori-browser.org/";
homepage = "https://github.com/midori-browser/core";
license = with licenses; [ lgpl21Plus ];
platforms = with platforms; linux;
maintainers = with maintainers; [
+1 -1
View File
@@ -2,7 +2,7 @@
mattermost,
}:
mattermost.overrideAttrs (o: {
mattermost.withoutTests.server.overrideAttrs (o: {
pname = "mmctl";
subPackages = [ "cmd/mmctl" ];
+1 -1
View File
@@ -41,7 +41,7 @@ stdenv.mkDerivation {
meta = {
description = "Benchmark to measure the performance of many different types of networking";
homepage = "http://www.netperf.org/netperf/";
homepage = "https://github.com/HewlettPackard/netperf/";
license = lib.licenses.mit;
platforms = lib.platforms.unix;
+2 -2
View File
@@ -23,13 +23,13 @@
python3Packages.buildPythonApplication rec {
pname = "nwg-panel";
version = "0.9.59";
version = "0.9.61";
src = fetchFromGitHub {
owner = "nwg-piotr";
repo = "nwg-panel";
tag = "v${version}";
hash = "sha256-ey0Fb9ilm7I2QWG1gQpnHTlMPoQswNlkrZ/WhUaLbDk=";
hash = "sha256-1p6fWP4iS8yryVv0DC+yQSSJj5EeAYNdiJiklKpfqgM=";
};
# No tests
+1 -1
View File
@@ -66,7 +66,7 @@ stdenv.mkDerivation {
special effects by "spectral smoothing" the sounds.
It can transform any sound/music to a texture.
'';
homepage = "https://hypermammut.sourceforge.net/paulstretch/";
homepage = "https://github.com/paulnasca/paulstretch_cpp/";
platforms = platforms.linux;
license = licenses.gpl2;
mainProgram = "paulstretch";
+1 -1
View File
@@ -37,7 +37,7 @@ buildNpmPackage rec {
homepage = "https://github.com/yamadashy/repomix";
changelog = "https://github.com/yamadashy/repomix/releases/tag/v${version}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ thinnerthinker ];
maintainers = with lib.maintainers; [ boralg ];
mainProgram = "repomix";
};
}
+2 -2
View File
@@ -10,13 +10,13 @@
stdenv.mkDerivation (finalAttrs: {
pname = "simpleDBus";
version = "0.8.1";
version = "0.9.0";
src = fetchFromGitHub {
owner = "OpenBluetoothToolbox";
repo = "SimpleBLE";
rev = "v${finalAttrs.version}";
hash = "sha256-rtctBKHujVqZXkblgoaaOQmrHT15HiDmev+rS4ZnYqI=";
hash = "sha256-suVaiFE60g2OlIF4DLGoHKr7ehUtThLcB/GoVCOfxJg=";
};
outputs = [
+2 -2
View File
@@ -28,13 +28,13 @@ assert builtins.elem gpuBackend [
stdenv.mkDerivation rec {
pname = "SpFFT";
version = "1.1.0";
version = "1.1.1";
src = fetchFromGitHub {
owner = "eth-cscs";
repo = pname;
rev = "v${version}";
hash = "sha256-hZdB/QcjL8rjvR1YZS+CHe5U5zxedpfDq6msMih4Elc=";
hash = "sha256-Qc/omdRv7dW9NJUOczMZJKhc+Z/sXeIxv3SbpegAGdU=";
};
nativeBuildInputs = [
+1 -1
View File
@@ -42,7 +42,7 @@ stdenv.mkDerivation rec {
meta = {
mainProgram = "iostat";
homepage = "http://sebastien.godard.pagesperso-orange.fr/";
homepage = "https://sysstat.github.io/";
description = "Collection of performance monitoring tools for Linux (such as sar, iostat and pidstat)";
license = lib.licenses.gpl2Plus;
platforms = lib.platforms.linux;
+3 -3
View File
@@ -5,13 +5,13 @@
fetchFromGitHub,
}:
let
version = "0.21.0";
version = "0.21.2";
src = fetchFromGitHub {
owner = "go-spatial";
repo = "tegola";
tag = "v${version}";
hash = "sha256-EXCh+5t2+7j/huIKUWOqG7u+Lo4eziyvPkDGpw3xaO8=";
hash = "sha256-aJCxxeewOm7DOHmehnsDKoQPwPnUMsjVit41ccY6tLg=";
};
frontend = buildNpmPackage {
@@ -20,7 +20,7 @@ let
src = "${src}/ui";
npmDepsHash = "sha256-rhUdWt1X5/F0uvT8gI1T9ei6Y+HK1tKj2fuTKlMAwJk=";
npmDepsHash = "sha256-DHJ+l3ceLieGG97kH1ri+7yZAv7R2lVYRdBhjXCy/iM=";
installPhase = ''
cp -r dist $out
+8 -10
View File
@@ -8,16 +8,16 @@
}:
rustPlatform.buildRustPackage rec {
pname = "television";
version = "0.9.2";
version = "0.9.3";
src = fetchFromGitHub {
owner = "alexpasmantier";
repo = "television";
tag = version;
hash = "sha256-XMANif4WbI+imSYeQRlvZJYjtaVbKrD4wVx2mQ1HYHg=";
hash = "sha256-0VnDgDLsPmNaY1sjw891hm65TsE3HH9KBkkgp0TFQKg=";
};
cargoHash = "sha256-IXtmQdDO3OHBZALWQKhJVgEimvuNyAj0/7aUlnL395M=";
cargoHash = "sha256-WtB1rmgOfAnZ9OGJ8M5s5NqMm24s8gcPzlu14f2mTrE=";
passthru = {
tests.version = testers.testVersion {
@@ -28,15 +28,13 @@ rustPlatform.buildRustPackage rec {
};
meta = {
description = "Television is a blazingly fast general purpose fuzzy finder";
description = "Blazingly fast general purpose fuzzy finder TUI";
longDescription = ''
Television is a blazingly fast general purpose fuzzy finder TUI written
in Rust. It is inspired by the neovim telescope plugin and is designed
to be fast, efficient, simple to use and easily extensible. It is built
on top of tokio, ratatui and the nucleo matcher used by the helix editor.
Television is a fast and versatile fuzzy finder TUI.
It lets you quickly search through any kind of data source (files, git
repositories, environment variables, docker images, you name it) using a
fuzzy matching algorithm and is designed to be easily extensible.
'';
homepage = "https://github.com/alexpasmantier/television";
changelog = "https://github.com/alexpasmantier/television/releases/tag/${version}";
license = lib.licenses.mit;
+1 -1
View File
@@ -32,7 +32,7 @@ buildGoModule rec {
meta = with lib; {
description = "Transifex command-line client";
homepage = "https://github.com/transifex/transifex-cli";
homepage = "https://github.com/transifex/cli";
license = licenses.asl20;
maintainers = with maintainers; [ thornycrackers ];
mainProgram = "tx";
+4 -14
View File
@@ -81,8 +81,8 @@
},
{
"pname": "CliWrap",
"version": "3.7.0",
"hash": "sha256-hXClLGuhscCrcBaymrp57Prh4m8Qe0vdE4S2ErIM13w="
"version": "3.7.1",
"hash": "sha256-e0snh/9Ai6/Gw5ycQox2H5nGrPhKfT2sH9dQNjbrrCI="
},
{
"pname": "DialogHost.Avalonia",
@@ -91,8 +91,8 @@
},
{
"pname": "Downloader",
"version": "3.3.1",
"hash": "sha256-vJRRKgA+pUr5/kWBTu7oMy+pat+jKL9SD/G7CmV0WLk="
"version": "3.3.3",
"hash": "sha256-H8HJKL71qC+nHVmuhhPDEHy434/NXJNqPeitJOe856k="
},
{
"pname": "DynamicData",
@@ -284,11 +284,6 @@
"version": "2.1.2",
"hash": "sha256-e56+FgxEHqV3SGQx0ZAqzlscPxNUPXJ8Ls9rtqET1S4="
},
{
"pname": "System.CodeDom",
"version": "9.0.0",
"hash": "sha256-578lcBgswW0eM16r0EnJzfGodPx86RxxFoZHc2PSzsw="
},
{
"pname": "System.Collections.Immutable",
"version": "8.0.0",
@@ -309,11 +304,6 @@
"version": "8.0.0",
"hash": "sha256-LdpB1s4vQzsOODaxiKstLks57X9DTD5D6cPx8DE1wwE="
},
{
"pname": "System.Management",
"version": "9.0.0",
"hash": "sha256-UyLO5dgNVC7rBT1S6o/Ix6EQGlVTSWUQtVC+/cyTkfQ="
},
{
"pname": "System.Memory",
"version": "4.5.3",
+2 -2
View File
@@ -19,13 +19,13 @@
}:
buildDotnetModule rec {
pname = "v2rayn";
version = "7.6.2";
version = "7.7.0";
src = fetchFromGitHub {
owner = "2dust";
repo = "v2rayN";
tag = version;
hash = "sha256-o+aeBdV/OT4cFovCeivM2i60r4mbZ0FPOY8XNdKRrpg=";
hash = "sha256-gnGZtHSmmyxTf+/Dp1cEXI1odI8SiFLzATd9PNnAC7E=";
};
projectFile = "v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj";
+40
View File
@@ -0,0 +1,40 @@
{
lib,
stdenv,
fetchFromGitHub,
autoreconfHook,
sqlite,
}:
stdenv.mkDerivation rec {
pname = "vcprompt";
version = "1.3.0-unstable-2020-12-28";
src = fetchFromGitHub {
owner = "powerman";
repo = "vcprompt";
rev = "850bf44cd61723f6b46121f678ff94047e42f802";
hash = "sha256-w2gpekNx3RA7uxNLg0Nkf9/aoxZj3DR4foKI+4q8SKk=";
};
nativeBuildInputs = [
autoreconfHook
];
buildInputs = [
sqlite
];
makeFlags = [
"PREFIX=${placeholder "out"}"
];
meta = with lib; {
description = "Program that prints barebones information about the current working directory for various version control systems";
homepage = "https://github.com/powerman/vcprompt";
maintainers = [ ];
platforms = with platforms; linux ++ darwin;
license = licenses.gpl2Plus;
mainProgram = "vcprompt";
};
}
+2 -1
View File
@@ -50,8 +50,9 @@ swiftPackages.stdenv.mkDerivation (finalAttrs: {
'';
installPhase = ''
mkdir -p $out/bin
mkdir -p $out/bin $out/share/xcodegen
cp "$(swiftpmBinPath)/${finalAttrs.pname}" $out/bin/
cp -r SettingPresets $out/share/xcodegen/SettingPresets
'';
nativeInstallCheckInputs = [
+2 -2
View File
@@ -8,14 +8,14 @@
}:
python3Packages.buildPythonApplication rec {
pname = "ytdl-sub";
version = "2025.01.15";
version = "2025.01.17";
pyproject = true;
src = fetchFromGitHub {
owner = "jmbannon";
repo = "ytdl-sub";
tag = version;
hash = "sha256-UjCs71nXi77yvB9BhYxT+2G9I+qHEB5Jnhe+GJuppdY=";
hash = "sha256-6RazXOXkBXwhJz8eNhrLIoEAVXnFEAF3O+SDKSjAlYo=";
};
postPatch = ''
+9 -5
View File
@@ -309,12 +309,16 @@ rustPlatform.buildRustPackage rec {
};
fhs = fhs { };
fhsWithPackages = f: fhs { additionalPkgs = f; };
tests = {
remoteServerVersion = testers.testVersion {
package = zed-editor.remote_server;
command = "zed-remote-server-stable-${version} version";
tests =
{
remoteServerVersion = testers.testVersion {
package = zed-editor.remote_server;
command = "zed-remote-server-stable-${version} version";
};
}
// lib.optionalAttrs stdenv.hostPlatform.isLinux {
withGles = zed-editor.override { withGLES = true; };
};
};
};
meta = {
@@ -421,5 +421,10 @@ stdenv.mkDerivation (finalAttrs: {
# If rustc can't target a platform, we also can't build rustc for
# that platform.
badPlatforms = rustc.badTargetPlatforms;
# Builds, but can't actually compile anything
# https://github.com/NixOS/nixpkgs/issues/311930
# https://github.com/rust-lang/rust/issues/55120
# https://github.com/rust-lang/rust/issues/82521
broken = stdenv.hostPlatform.useLLVM;
};
})
@@ -42,7 +42,7 @@ python3Packages.buildPythonApplication rec {
dontWrapPythonPrograms = true;
meta = with lib; {
homepage = "http://cxxtest.com";
homepage = "http://github.com/CxxTest/cxxtest";
description = "Unit testing framework for C++";
mainProgram = "cxxtestgen";
license = licenses.lgpl3;
@@ -36,10 +36,11 @@ let fetched = coqPackages.metaFetch ({
else "elpi-v${v}.tbz";
location = { domain = "github.com"; owner = "LPCIC"; repo = "elpi"; };
}) version;
in
buildDunePackage {
in let inherit (fetched) version;
in buildDunePackage {
pname = "elpi";
inherit (fetched) version src;
inherit version;
inherit (fetched) src;
patches = lib.optional (version == "1.16.5")
./atd_2_10.patch;
@@ -43,6 +43,6 @@ buildPerlPackage {
growing variety of other databases and technologies.
'';
license = licenses.gpl2Plus;
homepage = "http://www.maatkit.org/";
homepage = "https://code.google.com/archive/p/maatkit/";
};
}
@@ -22,7 +22,7 @@
buildPythonPackage rec {
pname = "minio";
version = "7.2.14";
version = "7.2.15";
pyproject = true;
disabled = pythonOlder "3.8";
@@ -31,7 +31,7 @@ buildPythonPackage rec {
owner = "minio";
repo = "minio-py";
tag = version;
hash = "sha256-FnId8ewKU5+COnrWW6VJWfL7BLij1IIuGOjEWZrPKNQ=";
hash = "sha256-vJ+V8O2fJxG1XpFDwQCmaIT8VTo5pEKduDndg6rzf0s=";
};
postPatch = ''
@@ -10,7 +10,7 @@
buildPythonPackage rec {
pname = "pyexploitdb";
version = "0.2.63";
version = "0.2.64";
pyproject = true;
disabled = pythonOlder "3.7";
@@ -18,7 +18,7 @@ buildPythonPackage rec {
src = fetchPypi {
pname = "pyExploitDb";
inherit version;
hash = "sha256-PJfbs1qSiumTiHOoffZqag+jVpNbvTOeTpz/peRUlq0=";
hash = "sha256-Os5Sj8zsPCCPxGTdLfiGLJ/tknkDnp9uowWquO31aRQ=";
};
build-system = [ setuptools ];
@@ -1,7 +1,7 @@
{
buildPythonPackage,
lib,
fetchFromBitbucket,
fetchhg,
parse,
}:
@@ -11,9 +11,8 @@ buildPythonPackage rec {
format = "setuptools";
# Missing tests on Pypi
src = fetchFromBitbucket {
owner = "rw_grim";
repo = pname;
src = fetchhg {
url = "https://keep.imfreedom.org/grim/pyparser";
rev = "v${version}";
sha256 = "0aplb4zdpgbpmaw9qj0vr7qip9q5w7sl1m1lp1nc9jmjfij9i0hf";
};
@@ -24,7 +23,7 @@ buildPythonPackage rec {
meta = {
description = "Simple library that makes it easier to parse files";
homepage = "https://bitbucket.org/rw_grim/pyparser";
homepage = "https://keep.imfreedom.org/grim/pyparser";
license = lib.licenses.gpl3;
maintainers = [ lib.maintainers.nico202 ];
};
@@ -21,14 +21,14 @@
buildPythonPackage rec {
pname = "timm";
version = "1.0.13";
version = "1.0.14";
pyproject = true;
src = fetchFromGitHub {
owner = "huggingface";
repo = "pytorch-image-models";
tag = "v${version}";
hash = "sha256-VRQerCaTiOvS3Mm+Fksua7KUhNcH1Zxc2+4jaSbVj+c=";
hash = "sha256-mQd4xsKuAKj77lG6r14iHrkaBclRmBwICXuHs7pQoGI=";
};
build-system = [ pdm-backend ];
@@ -36,7 +36,7 @@ stdenv.mkDerivation rec {
meta = with lib; {
description = "Old-school vertical shoot-em-up / bullet hell";
mainProgram = "garden";
homepage = "https://garden.sourceforge.net/drupal/";
homepage = "https://sourceforge.net/projects/garden/";
maintainers = [ ];
license = licenses.gpl3;
};
@@ -30,5 +30,9 @@
"6.12": {
"version": "6.12.10",
"hash": "sha256:15xjjn8ff7g9q0ljr2g8k098ppxnpvxlgv22rdrplls8sxg6wlaa"
},
"6.13": {
"version": "6.13",
"hash": "sha256:0vhdz1as27kxav81rkf6fm85sqrbj5hjhz5hpyxcd5b6p1pcr7g7"
}
}
+5 -18
View File
@@ -61,24 +61,11 @@ stdenv.mkDerivation {
inherit (kernel) version src;
patches =
lib.optionals (lib.versionAtLeast kernel.version "5.10") [
# fix wrong path to dmesg
./fix-dmesg-path.diff
]
++ lib.optionals (lib.versions.majorMinor kernel.version == "6.10") [
(fetchpatch {
url = "https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/patch/?id=0f0e1f44569061e3dc590cd0b8cb74d8fd53706b";
hash = "sha256-9u/zhbsDgwOr4T4k9td/WJYRuSHIfbtfS+oNx8nbOlM=";
})
(fetchpatch {
url = "https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/patch/?id=366e17409f1f17ad872259ce4a4f8a92beb4c4ee";
hash = "sha256-NZK1u40qvMwWcgkgJPGpEax2eMo9xHrCQxSYYOK0rbo=";
})
(fetchpatch {
url = "https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/patch/?id=1d302f626c2a23e4fd05bb810eff300e8f2174fd";
hash = "sha256-KhCmof8LkyTcBBpfMEtolL3m3kmC5rukKzQvufVKCdI=";
})
];
lib.optionals (lib.versionAtLeast kernel.version "5.10" && lib.versionOlder kernel.version "6.13")
[
# fix wrong path to dmesg
./fix-dmesg-path.diff
];
postPatch =
''
+1 -28
View File
@@ -58,7 +58,6 @@ let
optionals
optional
makeBinPath
versionAtLeast
;
smartmon = smartmontools.override { inherit enableMail; };
@@ -71,7 +70,6 @@ let
"user"
"all"
];
isAtLeast22Series = versionAtLeast version "2.2.0";
# XXX: You always want to build kernel modules with the same stdenv as the
# kernel was built with. However, since zfs can also be built for userspace we
@@ -121,8 +119,7 @@ let
--replace-fail "/etc/default" "$out/etc/default"
substituteInPlace ./contrib/initramfs/Makefile.am \
--replace-fail "/usr/share/initramfs-tools" "$out/usr/share/initramfs-tools"
''
+ optionalString isAtLeast22Series ''
substituteInPlace ./udev/vdev_id \
--replace-fail "PATH=/bin:/sbin:/usr/bin:/usr/sbin" \
"PATH=${
@@ -140,24 +137,6 @@ let
"bashcompletiondir=$out/share/bash-completion/completions"
substituteInPlace ./cmd/arc_summary --replace-fail "/sbin/modinfo" "modinfo"
''
+ optionalString (!isAtLeast22Series) ''
substituteInPlace ./etc/zfs/Makefile.am --replace-fail "\$(sysconfdir)/zfs" "$out/etc/zfs"
find ./contrib/initramfs -name Makefile.am -exec sed -i -e 's|/usr/share/initramfs-tools|'$out'/share/initramfs-tools|g' {} \;
substituteInPlace ./cmd/arc_summary/arc_summary3 --replace-fail "/sbin/modinfo" "modinfo"
substituteInPlace ./cmd/vdev_id/vdev_id \
--replace-fail "PATH=/bin:/sbin:/usr/bin:/usr/sbin" \
"PATH=${
makeBinPath [
coreutils
gawk
gnused
gnugrep
systemd
]
}"
'';
nativeBuildInputs =
@@ -260,12 +239,6 @@ let
# Remove tests because they add a runtime dependency on gcc
rm -rf $out/share/zfs/zfs-tests
${optionalString (lib.versionOlder version "2.2") ''
# Add Bash completions.
install -v -m444 -D -t $out/share/bash-completion/completions contrib/bash_completion.d/zfs
(cd $out/share/bash-completion/completions; ln -s zfs zpool)
''}
'';
postFixup =
+1 -1
View File
@@ -91,7 +91,7 @@ stdenv.mkDerivation {
'';
meta = with lib; {
homepage = "http://www.adaptivecomputing.com/products/open-source/torque";
homepage = "https://github.com/adaptivecomputing/torque";
description = "Resource management system for submitting and controlling jobs on supercomputers, clusters, and grids";
platforms = platforms.linux;
license = "TORQUEv1.1";
+2 -2
View File
@@ -16,11 +16,11 @@
stdenv.mkDerivation rec {
pname = "nsd";
version = "4.11.0";
version = "4.11.1";
src = fetchurl {
url = "https://www.nlnetlabs.nl/downloads/${pname}/${pname}-${version}.tar.gz";
sha256 = "sha256-k5VtkNRf+p+E+MovcYpCEF5CNtCUzgMiEYSfGhLNwVg=";
sha256 = "sha256-aW5QBSAI3k+nqx2BjVt362MkfuovBXURTJWS/5GIphQ=";
};
prePatch = ''
+1
View File
@@ -48,6 +48,7 @@ let
bachp
globin
ma27
britter
];
license = lib.licenses.agpl3Plus;
platforms = lib.platforms.linux;
+1 -1
View File
@@ -13,7 +13,7 @@ bundlerApp {
meta = with lib; {
description = "Run processes in the background (and foreground) on Mac & Linux from a Procfile (for production and/or development environments)";
homepage = "https://adam.ac/procodile";
homepage = "https://github.com/adamcooke/procodile";
license = with licenses; mit;
maintainers = with maintainers; [
manveru
+2
View File
@@ -744,6 +744,7 @@ mapAliases {
linuxPackages_6_10 = linuxKernel.packages.linux_6_10;
linuxPackages_6_11 = linuxKernel.packages.linux_6_11;
linuxPackages_6_12 = linuxKernel.packages.linux_6_12;
linuxPackages_6_13 = linuxKernel.packages.linux_6_13;
linuxPackages_rpi0 = linuxKernel.packages.linux_rpi1;
linuxPackages_rpi02w = linuxKernel.packages.linux_rpi3;
linuxPackages_rpi1 = linuxKernel.packages.linux_rpi1;
@@ -769,6 +770,7 @@ mapAliases {
linux_6_10 = linuxKernel.kernels.linux_6_10;
linux_6_11 = linuxKernel.kernels.linux_6_11;
linux_6_12 = linuxKernel.kernels.linux_6_12;
linux_6_13 = linuxKernel.kernels.linux_6_13;
linux_rpi0 = linuxKernel.kernels.linux_rpi1;
linux_rpi02w = linuxKernel.kernels.linux_rpi3;
linux_rpi1 = linuxKernel.kernels.linux_rpi1;
+1 -5
View File
@@ -12558,7 +12558,7 @@ with pkgs;
zfs_2_2
zfs_2_3
zfs_unstable;
zfs = zfs_2_2;
zfs = zfs_2_3;
### DATA
@@ -15488,10 +15488,6 @@ with pkgs;
valentina = libsForQt5.callPackage ../applications/misc/valentina { };
vcprompt = callPackage ../applications/version-management/vcprompt {
autoconf = buildPackages.autoconf269;
};
vdirsyncer = with python3Packages; toPythonApplication vdirsyncer;
vengi-tools = darwin.apple_sdk_11_0.callPackage ../applications/graphics/vengi-tools {
+11 -2
View File
@@ -197,6 +197,14 @@ in {
];
};
linux_6_13 = callPackage ../os-specific/linux/kernel/mainline.nix {
branch = "6.13";
kernelPatches = [
kernelPatches.bridge_stp_helper
kernelPatches.request_key_helper
];
};
linux_testing = let
testing = callPackage ../os-specific/linux/kernel/mainline.nix {
# A special branch that tracks the kernel under the release process
@@ -645,6 +653,7 @@ in {
linux_6_6 = recurseIntoAttrs (packagesFor kernels.linux_6_6);
linux_6_11 = recurseIntoAttrs (packagesFor kernels.linux_6_11);
linux_6_12 = recurseIntoAttrs (packagesFor kernels.linux_6_12);
linux_6_13 = recurseIntoAttrs (packagesFor kernels.linux_6_13);
} // lib.optionalAttrs config.allowAliases {
linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11"; # Added 2023-10-11
linux_4_19 = throw "linux 4.19 was removed because it will reach its end of life within 24.11"; # Added 2024-09-21
@@ -709,9 +718,9 @@ in {
});
packageAliases = {
linux_default = packages.linux_6_6;
linux_default = packages.linux_6_12;
# Update this when adding the newest kernel major version!
linux_latest = packages.linux_6_12;
linux_latest = packages.linux_6_13;
linux_rt_default = packages.linux_rt_5_15;
linux_rt_latest = packages.linux_rt_6_6;
} // lib.optionalAttrs config.allowAliases {
+1 -1
View File
@@ -11464,7 +11464,7 @@ with self; {
'';
meta = {
description = "Pluggable Markov engine analogous to MegaHAL";
homepage = "https://hailo.org";
homepage = "https://github.com/hailo/hailo";
license = with lib.licenses; [ artistic1 gpl1Plus ];
mainProgram = "hailo";
};