Merge master into staging-next
This commit is contained in:
@@ -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.
|
||||
@@ -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 backwards‐incompatible 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}
|
||||
|
||||
@@ -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`
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 {};
|
||||
|
||||
@@ -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"''}")
|
||||
'';
|
||||
}
|
||||
)
|
||||
@@ -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,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";
|
||||
|
||||
@@ -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))
|
||||
];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
@@ -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}");
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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; {
|
||||
|
||||
@@ -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
|
||||
'';
|
||||
}
|
||||
)
|
||||
@@ -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=";
|
||||
|
||||
@@ -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; [
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
mattermost,
|
||||
}:
|
||||
|
||||
mattermost.overrideAttrs (o: {
|
||||
mattermost.withoutTests.server.overrideAttrs (o: {
|
||||
pname = "mmctl";
|
||||
subPackages = [ "cmd/mmctl" ];
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
Generated
+4
-14
@@ -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",
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
}
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 =
|
||||
''
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
@@ -48,6 +48,7 @@ let
|
||||
bachp
|
||||
globin
|
||||
ma27
|
||||
britter
|
||||
];
|
||||
license = lib.licenses.agpl3Plus;
|
||||
platforms = lib.platforms.linux;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user