diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 8b1cbbb11037..e8577f8c175c 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -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"; diff --git a/nixos/doc/manual/configuration/configuration.md b/nixos/doc/manual/configuration/configuration.md index 4c966f3325b9..fae8874b8323 100644 --- a/nixos/doc/manual/configuration/configuration.md +++ b/nixos/doc/manual/configuration/configuration.md @@ -22,6 +22,7 @@ subversion.chapter.md ```{=include=} chapters profiles.chapter.md +mattermost.chapter.md kubernetes.chapter.md ``` diff --git a/nixos/doc/manual/configuration/mattermost.chapter.md b/nixos/doc/manual/configuration/mattermost.chapter.md new file mode 100644 index 000000000000..f247134ce49a --- /dev/null +++ b/nixos/doc/manual/configuration/mattermost.chapter.md @@ -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. diff --git a/nixos/doc/manual/redirects.json b/nixos/doc/manual/redirects.json index a7ebb49b62b8..443cc445ad69 100644 --- a/nixos/doc/manual/redirects.json +++ b/nixos/doc/manual/redirects.json @@ -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" ], diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md index 44af73915382..a6f796885f96 100644 --- a/nixos/doc/manual/release-notes/rl-2505.section.md +++ b/nixos/doc/manual/release-notes/rl-2505.section.md @@ -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. + ## New Modules {#sec-release-25.05-new-modules} diff --git a/nixos/modules/services/web-apps/mattermost.nix b/nixos/modules/services/web-apps/mattermost.nix index 4f12774327f2..9b420f8a51fc 100644 --- a/nixos/modules/services/web-apps/mattermost.nix +++ b/nixos/modules/services/web-apps/mattermost.nix @@ -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 = ""; + 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 ]; } diff --git a/nixos/modules/system/boot/loader/init-script/init-script-builder.sh b/nixos/modules/system/boot/loader/init-script/init-script-builder.sh index 60b9fe901db0..6c21dfaac09d 100644 --- a/nixos/modules/system/boot/loader/init-script/init-script-builder.sh +++ b/nixos/modules/system/boot/loader/init-script/init-script-builder.sh @@ -27,9 +27,6 @@ tmpOther="$targetOther.tmp" configurationCounter=0 -numAlienEntries=`cat <&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"''}") - ''; - } -) diff --git a/nixos/tests/mattermost/default.nix b/nixos/tests/mattermost/default.nix new file mode 100644 index 000000000000..99ad4b110118 --- /dev/null +++ b/nixos/tests/mattermost/default.nix @@ -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 + ) + ''; + } +) diff --git a/nixos/tests/mattermost/test.jpg b/nixos/tests/mattermost/test.jpg new file mode 100644 index 000000000000..2b1e8e1b4fab Binary files /dev/null and b/nixos/tests/mattermost/test.jpg differ diff --git a/pkgs/applications/editors/vim/plugins/overrides.nix b/pkgs/applications/editors/vim/plugins/overrides.nix index adec08943624..b97ec9349a3b 100644 --- a/pkgs/applications/editors/vim/plugins/overrides.nix +++ b/pkgs/applications/editors/vim/plugins/overrides.nix @@ -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 \ diff --git a/pkgs/applications/graphics/vengi-tools/default.nix b/pkgs/applications/graphics/vengi-tools/default.nix index b4a99396fb97..47be62abfe35 100644 --- a/pkgs/applications/graphics/vengi-tools/default.nix +++ b/pkgs/applications/graphics/vengi-tools/default.nix @@ -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 diff --git a/pkgs/applications/office/paperwork/src.nix b/pkgs/applications/office/paperwork/src.nix index 7038309799e8..84bd20231599 100644 --- a/pkgs/applications/office/paperwork/src.nix +++ b/pkgs/applications/office/paperwork/src.nix @@ -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"; diff --git a/pkgs/applications/radio/uhd/default.nix b/pkgs/applications/radio/uhd/default.nix index 9b05d201f933..6ff0c16a3106 100644 --- a/pkgs/applications/radio/uhd/default.nix +++ b/pkgs/applications/radio/uhd/default.nix @@ -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) [ diff --git a/pkgs/applications/version-management/vcprompt/default.nix b/pkgs/applications/version-management/vcprompt/default.nix deleted file mode 100644 index e78c6d5bcaa0..000000000000 --- a/pkgs/applications/version-management/vcprompt/default.nix +++ /dev/null @@ -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"; - }; -} diff --git a/pkgs/applications/window-managers/wayfire/wf-config.nix b/pkgs/applications/window-managers/wayfire/wf-config.nix index 8ebbd647bcd7..80511e5abb67 100644 --- a/pkgs/applications/window-managers/wayfire/wf-config.nix +++ b/pkgs/applications/window-managers/wayfire/wf-config.nix @@ -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)) ]; diff --git a/pkgs/by-name/ar/aragorn/package.nix b/pkgs/by-name/ar/aragorn/package.nix index 23a7c12d927c..5f0d71683a8f 100644 --- a/pkgs/by-name/ar/aragorn/package.nix +++ b/pkgs/by-name/ar/aragorn/package.nix @@ -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; diff --git a/pkgs/by-name/bf/bfs/package.nix b/pkgs/by-name/bf/bfs/package.nix index 285b047eaf9b..01f3b1b65965 100644 --- a/pkgs/by-name/bf/bfs/package.nix +++ b/pkgs/by-name/bf/bfs/package.nix @@ -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 = diff --git a/pkgs/by-name/ch/changedetection-io/package.nix b/pkgs/by-name/ch/changedetection-io/package.nix index 390f4079216b..56943720cc0b 100644 --- a/pkgs/by-name/ch/changedetection-io/package.nix +++ b/pkgs/by-name/ch/changedetection-io/package.nix @@ -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; diff --git a/pkgs/by-name/cj/cjson/package.nix b/pkgs/by-name/cj/cjson/package.nix index d344e5ad45ec..7f1eac88571a 100644 --- a/pkgs/by-name/cj/cjson/package.nix +++ b/pkgs/by-name/cj/cjson/package.nix @@ -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 = '' diff --git a/pkgs/by-name/cl/clouddrive2/package.nix b/pkgs/by-name/cl/clouddrive2/package.nix index a42d9906a4d2..fdb21c2c94ec 100644 --- a/pkgs/by-name/cl/clouddrive2/package.nix +++ b/pkgs/by-name/cl/clouddrive2/package.nix @@ -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}"); }; diff --git a/pkgs/by-name/cv/cvsps/package.nix b/pkgs/by-name/cv/cvsps/package.nix index cd2d043539d4..055ade25d49e 100644 --- a/pkgs/by-name/cv/cvsps/package.nix +++ b/pkgs/by-name/cv/cvsps/package.nix @@ -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"; diff --git a/pkgs/by-name/fz/fzf/package.nix b/pkgs/by-name/fz/fzf/package.nix index a0a218db10bd..15e9a0fc6289 100644 --- a/pkgs/by-name/fz/fzf/package.nix +++ b/pkgs/by-name/fz/fzf/package.nix @@ -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; diff --git a/pkgs/by-name/iw/iwona/package.nix b/pkgs/by-name/iw/iwona/package.nix index 49f6ffc13441..c6bb9fec58d7 100644 --- a/pkgs/by-name/iw/iwona/package.nix +++ b/pkgs/by-name/iw/iwona/package.nix @@ -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 diff --git a/pkgs/by-name/ma/mattermost/build-plugin.nix b/pkgs/by-name/ma/mattermost/build-plugin.nix new file mode 100644 index 000000000000..8dd89211e2e2 --- /dev/null +++ b/pkgs/by-name/ma/mattermost/build-plugin.nix @@ -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 <&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 +) diff --git a/pkgs/by-name/ma/mattermost/package.nix b/pkgs/by-name/ma/mattermost/package.nix index 54559408399b..4cea5382b88e 100644 --- a/pkgs/by-name/ma/mattermost/package.nix +++ b/pkgs/by-name/ma/mattermost/package.nix @@ -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; { diff --git a/pkgs/by-name/ma/mattermost/tests.nix b/pkgs/by-name/ma/mattermost/tests.nix new file mode 100644 index 000000000000..3e70be5e5ade --- /dev/null +++ b/pkgs/by-name/ma/mattermost/tests.nix @@ -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 | 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 <"$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 <> "$PGDATA/postgresql.conf" + unix_socket_directories = '$PGDATA/run' + max_connections = 256 + shared_buffers = 96MB + EOF + start_postgres + + # Init Postgres. + cat < "$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 + ''; + } +) diff --git a/pkgs/by-name/ma/mattermostLatest/package.nix b/pkgs/by-name/ma/mattermostLatest/package.nix index 6fe04afdd92e..3b3b2674c756 100644 --- a/pkgs/by-name/ma/mattermostLatest/package.nix +++ b/pkgs/by-name/ma/mattermostLatest/package.nix @@ -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="; diff --git a/pkgs/by-name/mi/midori-unwrapped/package.nix b/pkgs/by-name/mi/midori-unwrapped/package.nix index 70f3d294493d..855f54c87aa4 100644 --- a/pkgs/by-name/mi/midori-unwrapped/package.nix +++ b/pkgs/by-name/mi/midori-unwrapped/package.nix @@ -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; [ diff --git a/pkgs/by-name/mm/mmctl/package.nix b/pkgs/by-name/mm/mmctl/package.nix index f5e6c29916f6..555f8e99f573 100644 --- a/pkgs/by-name/mm/mmctl/package.nix +++ b/pkgs/by-name/mm/mmctl/package.nix @@ -2,7 +2,7 @@ mattermost, }: -mattermost.overrideAttrs (o: { +mattermost.withoutTests.server.overrideAttrs (o: { pname = "mmctl"; subPackages = [ "cmd/mmctl" ]; diff --git a/pkgs/by-name/ne/netperf/package.nix b/pkgs/by-name/ne/netperf/package.nix index 338b645556d8..53081ccff956 100644 --- a/pkgs/by-name/ne/netperf/package.nix +++ b/pkgs/by-name/ne/netperf/package.nix @@ -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; diff --git a/pkgs/by-name/nw/nwg-panel/package.nix b/pkgs/by-name/nw/nwg-panel/package.nix index 5e64db8b9542..5031835507eb 100644 --- a/pkgs/by-name/nw/nwg-panel/package.nix +++ b/pkgs/by-name/nw/nwg-panel/package.nix @@ -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 diff --git a/pkgs/by-name/pa/paulstretch/package.nix b/pkgs/by-name/pa/paulstretch/package.nix index 18648c5e5f30..756b2e99d73a 100644 --- a/pkgs/by-name/pa/paulstretch/package.nix +++ b/pkgs/by-name/pa/paulstretch/package.nix @@ -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"; diff --git a/pkgs/by-name/re/repomix/package.nix b/pkgs/by-name/re/repomix/package.nix index 0e3405fd8795..2db363a63a26 100644 --- a/pkgs/by-name/re/repomix/package.nix +++ b/pkgs/by-name/re/repomix/package.nix @@ -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"; }; } diff --git a/pkgs/by-name/si/simpleDBus/package.nix b/pkgs/by-name/si/simpleDBus/package.nix index 97dfd36492e0..6adc64739811 100644 --- a/pkgs/by-name/si/simpleDBus/package.nix +++ b/pkgs/by-name/si/simpleDBus/package.nix @@ -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 = [ diff --git a/pkgs/by-name/sp/spfft/package.nix b/pkgs/by-name/sp/spfft/package.nix index 1045173353b3..bcef437f72c8 100644 --- a/pkgs/by-name/sp/spfft/package.nix +++ b/pkgs/by-name/sp/spfft/package.nix @@ -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 = [ diff --git a/pkgs/by-name/sy/sysstat/package.nix b/pkgs/by-name/sy/sysstat/package.nix index a2f59f04fe4a..d8651425fea7 100644 --- a/pkgs/by-name/sy/sysstat/package.nix +++ b/pkgs/by-name/sy/sysstat/package.nix @@ -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; diff --git a/pkgs/by-name/te/tegola/package.nix b/pkgs/by-name/te/tegola/package.nix index 5ec1f983e343..00ca64faf802 100644 --- a/pkgs/by-name/te/tegola/package.nix +++ b/pkgs/by-name/te/tegola/package.nix @@ -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 diff --git a/pkgs/by-name/te/television/package.nix b/pkgs/by-name/te/television/package.nix index 52453f93333b..3c9af991b718 100644 --- a/pkgs/by-name/te/television/package.nix +++ b/pkgs/by-name/te/television/package.nix @@ -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; diff --git a/pkgs/by-name/tr/transifex-cli/package.nix b/pkgs/by-name/tr/transifex-cli/package.nix index a4551be0f8c6..0a46be3e71b3 100644 --- a/pkgs/by-name/tr/transifex-cli/package.nix +++ b/pkgs/by-name/tr/transifex-cli/package.nix @@ -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"; diff --git a/pkgs/by-name/v2/v2rayn/deps.json b/pkgs/by-name/v2/v2rayn/deps.json index 5f222d833fad..847a4f37d9ec 100644 --- a/pkgs/by-name/v2/v2rayn/deps.json +++ b/pkgs/by-name/v2/v2rayn/deps.json @@ -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", diff --git a/pkgs/by-name/v2/v2rayn/package.nix b/pkgs/by-name/v2/v2rayn/package.nix index 73969743821d..3391c8a1504c 100644 --- a/pkgs/by-name/v2/v2rayn/package.nix +++ b/pkgs/by-name/v2/v2rayn/package.nix @@ -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"; diff --git a/pkgs/by-name/vc/vcprompt/package.nix b/pkgs/by-name/vc/vcprompt/package.nix new file mode 100644 index 000000000000..e2dc6dff770b --- /dev/null +++ b/pkgs/by-name/vc/vcprompt/package.nix @@ -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"; + }; +} diff --git a/pkgs/by-name/xc/xcodegen/package.nix b/pkgs/by-name/xc/xcodegen/package.nix index d302092be93c..b898315b471a 100644 --- a/pkgs/by-name/xc/xcodegen/package.nix +++ b/pkgs/by-name/xc/xcodegen/package.nix @@ -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 = [ diff --git a/pkgs/by-name/yt/ytdl-sub/package.nix b/pkgs/by-name/yt/ytdl-sub/package.nix index 1bc1c30ae0c5..05c35224b26c 100644 --- a/pkgs/by-name/yt/ytdl-sub/package.nix +++ b/pkgs/by-name/yt/ytdl-sub/package.nix @@ -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 = '' diff --git a/pkgs/by-name/ze/zed-editor/package.nix b/pkgs/by-name/ze/zed-editor/package.nix index 5394efcf7073..48a383965144 100644 --- a/pkgs/by-name/ze/zed-editor/package.nix +++ b/pkgs/by-name/ze/zed-editor/package.nix @@ -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 = { diff --git a/pkgs/development/compilers/rust/rustc.nix b/pkgs/development/compilers/rust/rustc.nix index af287fcc9079..d7a1ee625f9c 100644 --- a/pkgs/development/compilers/rust/rustc.nix +++ b/pkgs/development/compilers/rust/rustc.nix @@ -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; }; }) diff --git a/pkgs/development/libraries/cxxtest/default.nix b/pkgs/development/libraries/cxxtest/default.nix index ae1e9c302000..b15d9dbe96a2 100644 --- a/pkgs/development/libraries/cxxtest/default.nix +++ b/pkgs/development/libraries/cxxtest/default.nix @@ -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; diff --git a/pkgs/development/ocaml-modules/elpi/default.nix b/pkgs/development/ocaml-modules/elpi/default.nix index 69af0157d5d3..a9dc8597b8dd 100644 --- a/pkgs/development/ocaml-modules/elpi/default.nix +++ b/pkgs/development/ocaml-modules/elpi/default.nix @@ -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; diff --git a/pkgs/development/perl-modules/maatkit/default.nix b/pkgs/development/perl-modules/maatkit/default.nix index 7a0ad7bae4b7..f6793b9bb4a5 100644 --- a/pkgs/development/perl-modules/maatkit/default.nix +++ b/pkgs/development/perl-modules/maatkit/default.nix @@ -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/"; }; } diff --git a/pkgs/development/python-modules/minio/default.nix b/pkgs/development/python-modules/minio/default.nix index 8d905c20a7a8..643239ac5a18 100644 --- a/pkgs/development/python-modules/minio/default.nix +++ b/pkgs/development/python-modules/minio/default.nix @@ -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 = '' diff --git a/pkgs/development/python-modules/pyexploitdb/default.nix b/pkgs/development/python-modules/pyexploitdb/default.nix index 843774d365be..8568f1d41452 100644 --- a/pkgs/development/python-modules/pyexploitdb/default.nix +++ b/pkgs/development/python-modules/pyexploitdb/default.nix @@ -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 ]; diff --git a/pkgs/development/python-modules/pyparser/default.nix b/pkgs/development/python-modules/pyparser/default.nix index 7b78bf6f27f0..57ce2f2f9d9b 100644 --- a/pkgs/development/python-modules/pyparser/default.nix +++ b/pkgs/development/python-modules/pyparser/default.nix @@ -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 ]; }; diff --git a/pkgs/development/python-modules/timm/default.nix b/pkgs/development/python-modules/timm/default.nix index 8dd7cd7ebdd1..a70d1f503723 100644 --- a/pkgs/development/python-modules/timm/default.nix +++ b/pkgs/development/python-modules/timm/default.nix @@ -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 ]; diff --git a/pkgs/games/garden-of-coloured-lights/default.nix b/pkgs/games/garden-of-coloured-lights/default.nix index a26cea279612..77e252633532 100644 --- a/pkgs/games/garden-of-coloured-lights/default.nix +++ b/pkgs/games/garden-of-coloured-lights/default.nix @@ -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; }; diff --git a/pkgs/os-specific/linux/kernel/kernels-org.json b/pkgs/os-specific/linux/kernel/kernels-org.json index 8f7975b4746d..3c7665c5b5ab 100644 --- a/pkgs/os-specific/linux/kernel/kernels-org.json +++ b/pkgs/os-specific/linux/kernel/kernels-org.json @@ -30,5 +30,9 @@ "6.12": { "version": "6.12.10", "hash": "sha256:15xjjn8ff7g9q0ljr2g8k098ppxnpvxlgv22rdrplls8sxg6wlaa" + }, + "6.13": { + "version": "6.13", + "hash": "sha256:0vhdz1as27kxav81rkf6fm85sqrbj5hjhz5hpyxcd5b6p1pcr7g7" } } diff --git a/pkgs/os-specific/linux/kernel/perf/default.nix b/pkgs/os-specific/linux/kernel/perf/default.nix index b947a2650f2d..c74aa7f4285a 100644 --- a/pkgs/os-specific/linux/kernel/perf/default.nix +++ b/pkgs/os-specific/linux/kernel/perf/default.nix @@ -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 = '' diff --git a/pkgs/os-specific/linux/zfs/generic.nix b/pkgs/os-specific/linux/zfs/generic.nix index ad6fd902c682..e00db1d6229e 100644 --- a/pkgs/os-specific/linux/zfs/generic.nix +++ b/pkgs/os-specific/linux/zfs/generic.nix @@ -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 = diff --git a/pkgs/servers/computing/torque/default.nix b/pkgs/servers/computing/torque/default.nix index 74b5fa8dd043..49210ab7179a 100644 --- a/pkgs/servers/computing/torque/default.nix +++ b/pkgs/servers/computing/torque/default.nix @@ -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"; diff --git a/pkgs/servers/dns/nsd/default.nix b/pkgs/servers/dns/nsd/default.nix index fe282767fe89..d6da9df4cc8c 100644 --- a/pkgs/servers/dns/nsd/default.nix +++ b/pkgs/servers/dns/nsd/default.nix @@ -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 = '' diff --git a/pkgs/servers/nextcloud/default.nix b/pkgs/servers/nextcloud/default.nix index 624212f6efed..a06f49658769 100644 --- a/pkgs/servers/nextcloud/default.nix +++ b/pkgs/servers/nextcloud/default.nix @@ -48,6 +48,7 @@ let bachp globin ma27 + britter ]; license = lib.licenses.agpl3Plus; platforms = lib.platforms.linux; diff --git a/pkgs/tools/system/procodile/default.nix b/pkgs/tools/system/procodile/default.nix index 43faa0af6e59..45a17384e6db 100644 --- a/pkgs/tools/system/procodile/default.nix +++ b/pkgs/tools/system/procodile/default.nix @@ -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 diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 08a598b64105..e3dfdfb89649 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -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; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a21f709c36bf..24c85dd9efca 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -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 { diff --git a/pkgs/top-level/linux-kernels.nix b/pkgs/top-level/linux-kernels.nix index 7939e8df371c..a63c22a7a8c9 100644 --- a/pkgs/top-level/linux-kernels.nix +++ b/pkgs/top-level/linux-kernels.nix @@ -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 { diff --git a/pkgs/top-level/perl-packages.nix b/pkgs/top-level/perl-packages.nix index dc986b09f8b1..802fd4371d09 100644 --- a/pkgs/top-level/perl-packages.nix +++ b/pkgs/top-level/perl-packages.nix @@ -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"; };