···2122 nixosSystem = args:
23 import ./nixos/lib/eval-config.nix (
24- args // { inherit (self) lib; } // lib.optionalAttrs (! args?system) {
025 # Allow system to be set modularly in nixpkgs.system.
26 # We set it to null, to remove the "legacy" entrypoint's
27 # non-hermetic default.
28 system = null;
29- }
30 );
31 });
3233- checks.x86_64-linux.tarball = jobs.tarball;
0000000000000000000003435 htmlDocs = {
36 nixpkgsManual = jobs.manual;
···2122 nixosSystem = args:
23 import ./nixos/lib/eval-config.nix (
24+ {
25+ lib = final;
26 # Allow system to be set modularly in nixpkgs.system.
27 # We set it to null, to remove the "legacy" entrypoint's
28 # non-hermetic default.
29 system = null;
30+ } // args
31 );
32 });
3334+ checks.x86_64-linux = {
35+ tarball = jobs.tarball;
36+ # Test that ensures that the nixosSystem function can accept a lib argument
37+ # Note: prefer not to extend or modify `lib`, especially if you want to share reusable modules
38+ # alternatives include: `import` a file, or put a custom library in an option or in `_module.args.<libname>`
39+ nixosSystemAcceptsLib = (self.lib.nixosSystem {
40+ lib = self.lib.extend (final: prev: {
41+ ifThisFunctionIsMissingTheTestFails = final.id;
42+ });
43+ modules = [
44+ ./nixos/modules/profiles/minimal.nix
45+ ({ lib, ... }: lib.ifThisFunctionIsMissingTheTestFails {
46+ # Define a minimal config without eval warnings
47+ nixpkgs.hostPlatform = "x86_64-linux";
48+ boot.loader.grub.enable = false;
49+ fileSystems."/".device = "nodev";
50+ # See https://search.nixos.org/options?show=system.stateVersion&query=stateversion
51+ system.stateVersion = lib.versions.majorMinor lib.version; # DON'T do this in real configs!
52+ })
53+ ];
54+ }).config.system.build.toplevel;
55+ };
5657 htmlDocs = {
58 nixpkgsManual = jobs.manual;
···113 , # Description of the type, defined recursively by embedding the wrapped type if any.
114 description ? null
115 # A hint for whether or not this description needs parentheses. Possible values:
116- # - "noun": a simple noun phrase such as "positive integer"
117- # - "conjunction": a phrase with a potentially ambiguous "or" connective.
00118 # - "composite": a phrase with an "of" connective
000119 # See the `optionDescriptionPhrase` function.
120 , descriptionClass ? null
121 , # DO NOT USE WITHOUT KNOWING WHAT YOU ARE DOING!
···338 unsigned = addCheck types.int (x: x >= 0) // {
339 name = "unsignedInt";
340 description = "unsigned integer, meaning >=0";
0341 };
342 positive = addCheck types.int (x: x > 0) // {
343 name = "positiveInt";
344 description = "positive integer, meaning >0";
0345 };
346 u8 = unsign 8 256;
347 u16 = unsign 16 65536;
···383 nonnegative = addCheck number (x: x >= 0) // {
384 name = "numberNonnegative";
385 description = "nonnegative integer or floating point number, meaning >=0";
0386 };
387 positive = addCheck number (x: x > 0) // {
388 name = "numberPositive";
389 description = "positive integer or floating point number, meaning >0";
0390 };
391 };
392···463 passwdEntry = entryType: addCheck entryType (str: !(hasInfix ":" str || hasInfix "\n" str)) // {
464 name = "passwdEntry ${entryType.name}";
465 description = "${optionDescriptionPhrase (class: class == "noun") entryType}, not containing newlines or colons";
0466 };
467468 attrs = mkOptionType {
···870 # Either value of type `t1` or `t2`.
871 either = t1: t2: mkOptionType rec {
872 name = "either";
873- description = "${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") t1} or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction" || class == "composite") t2}";
000000874 descriptionClass = "conjunction";
875 check = x: t1.check x || t2.check x;
876 merge = loc: defs:
···113 , # Description of the type, defined recursively by embedding the wrapped type if any.
114 description ? null
115 # A hint for whether or not this description needs parentheses. Possible values:
116+ # - "noun": a noun phrase
117+ # Example description: "positive integer",
118+ # - "conjunction": a phrase with a potentially ambiguous "or" connective
119+ # Example description: "int or string"
120 # - "composite": a phrase with an "of" connective
121+ # Example description: "list of string"
122+ # - "nonRestrictiveClause": a noun followed by a comma and a clause
123+ # Example description: "positive integer, meaning >0"
124 # See the `optionDescriptionPhrase` function.
125 , descriptionClass ? null
126 , # DO NOT USE WITHOUT KNOWING WHAT YOU ARE DOING!
···343 unsigned = addCheck types.int (x: x >= 0) // {
344 name = "unsignedInt";
345 description = "unsigned integer, meaning >=0";
346+ descriptionClass = "nonRestrictiveClause";
347 };
348 positive = addCheck types.int (x: x > 0) // {
349 name = "positiveInt";
350 description = "positive integer, meaning >0";
351+ descriptionClass = "nonRestrictiveClause";
352 };
353 u8 = unsign 8 256;
354 u16 = unsign 16 65536;
···390 nonnegative = addCheck number (x: x >= 0) // {
391 name = "numberNonnegative";
392 description = "nonnegative integer or floating point number, meaning >=0";
393+ descriptionClass = "nonRestrictiveClause";
394 };
395 positive = addCheck number (x: x > 0) // {
396 name = "numberPositive";
397 description = "positive integer or floating point number, meaning >0";
398+ descriptionClass = "nonRestrictiveClause";
399 };
400 };
401···472 passwdEntry = entryType: addCheck entryType (str: !(hasInfix ":" str || hasInfix "\n" str)) // {
473 name = "passwdEntry ${entryType.name}";
474 description = "${optionDescriptionPhrase (class: class == "noun") entryType}, not containing newlines or colons";
475+ descriptionClass = "nonRestrictiveClause";
476 };
477478 attrs = mkOptionType {
···880 # Either value of type `t1` or `t2`.
881 either = t1: t2: mkOptionType rec {
882 name = "either";
883+ description =
884+ if t1.descriptionClass or null == "nonRestrictiveClause"
885+ then
886+ # Plain, but add comma
887+ "${t1.description}, or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") t2}"
888+ else
889+ "${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") t1} or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction" || class == "composite") t2}";
890 descriptionClass = "conjunction";
891 check = x: t1.check x || t2.check x;
892 merge = loc: defs:
···3031- [rspamd-trainer](https://gitlab.com/onlime/rspamd-trainer), script triggered by a helper which reads mails from a specific mail inbox and feeds them into rspamd for spam/ham training.
320033- [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable).
34The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares.
35···7677 `CONFIG_FILE_NAME` includes `bpf_pinning`, `ematch_map`, `group`, `nl_protos`, `rt_dsfield`, `rt_protos`, `rt_realms`, `rt_scopes`, and `rt_tables`.
780000000000079## Other Notable Changes {#sec-release-24.05-notable-changes}
8081<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
···91 The `nimPackages` and `nim2Packages` sets have been removed.
92 See https://nixos.org/manual/nixpkgs/unstable#nim for more information.
930000094- `libass` now uses the native CoreText backend on Darwin, which may fix subtitle rendering issues with `mpv`, `ffmpeg`, etc.
00000000009596- The Yama LSM is now enabled by default in the kernel, which prevents ptracing
97 non-child processes. This means you will not be able to attach gdb to an
···3031- [rspamd-trainer](https://gitlab.com/onlime/rspamd-trainer), script triggered by a helper which reads mails from a specific mail inbox and feeds them into rspamd for spam/ham training.
3233+- [ollama](https://ollama.ai), server for running large language models locally.
34+35- [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable).
36The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares.
37···7879 `CONFIG_FILE_NAME` includes `bpf_pinning`, `ematch_map`, `group`, `nl_protos`, `rt_dsfield`, `rt_protos`, `rt_realms`, `rt_scopes`, and `rt_tables`.
8081+- The `systemd.oomd` module behavior is changed as:
82+83+ - Raise ManagedOOMMemoryPressureLimit from 50% to 80%. This should make systemd-oomd kill things less often, and fix issues like [this](https://pagure.io/fedora-workstation/issue/358).
84+ Reference: [commit](https://src.fedoraproject.org/rpms/systemd/c/806c95e1c70af18f81d499b24cd7acfa4c36ffd6?branch=806c95e1c70af18f81d499b24cd7acfa4c36ffd6)
85+86+ - Remove swap policy. This helps prevent killing processes when user's swap is small.
87+88+ - Expand the memory pressure policy to system.slice, user-.slice, and all user owned slices. Reference: [commit](https://src.fedoraproject.org/rpms/systemd/c/7665e1796f915dedbf8e014f0a78f4f576d609bb)
89+90+ - `systemd.oomd.enableUserServices` is renamed to `systemd.oomd.enableUserSlices`.
91+92## Other Notable Changes {#sec-release-24.05-notable-changes}
9394<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
···104 The `nimPackages` and `nim2Packages` sets have been removed.
105 See https://nixos.org/manual/nixpkgs/unstable#nim for more information.
106107+- [Portunus](https://github.com/majewsky/portunus) has been updated to 2.0.
108+ This version of Portunus supports strong password hashes, but the legacy hash SHA-256 is also still supported to ensure a smooth migration of existing user accounts.
109+ After upgrading, follow the instructions on the [upstream release notes](https://github.com/majewsky/portunus/releases/tag/v2.0.0) to upgrade all user accounts to strong password hashes.
110+ Support for weak password hashes will be removed in NixOS 24.11.
111+112- `libass` now uses the native CoreText backend on Darwin, which may fix subtitle rendering issues with `mpv`, `ffmpeg`, etc.
113+114+- The following options of the Nextcloud module were moved into [`services.nextcloud.extraOptions`](#opt-services.nextcloud.extraOptions) and renamed to match the name from Nextcloud's `config.php`:
115+ - `logLevel` -> [`loglevel`](#opt-services.nextcloud.extraOptions.loglevel),
116+ - `logType` -> [`log_type`](#opt-services.nextcloud.extraOptions.log_type),
117+ - `defaultPhoneRegion` -> [`default_phone_region`](#opt-services.nextcloud.extraOptions.default_phone_region),
118+ - `overwriteProtocol` -> [`overwriteprotocol`](#opt-services.nextcloud.extraOptions.overwriteprotocol),
119+ - `skeletonDirectory` -> [`skeletondirectory`](#opt-services.nextcloud.extraOptions.skeletondirectory),
120+ - `globalProfiles` -> [`profile.enabled`](#opt-services.nextcloud.extraOptions._profile.enabled_),
121+ - `extraTrustedDomains` -> [`trusted_domains`](#opt-services.nextcloud.extraOptions.trusted_domains) and
122+ - `trustedProxies` -> [`trusted_proxies`](#opt-services.nextcloud.extraOptions.trusted_proxies).
123124- The Yama LSM is now enabled by default in the kernel, which prevents ptracing
125 non-child processes. This means you will not be able to attach gdb to an
···102 ldap = {
103 package = mkOption {
104 type = types.package;
105- # needs openldap built with a libxcrypt that support crypt sha256 until https://github.com/majewsky/portunus/issues/2 is solved
00106 default = pkgs.openldap.override { libxcrypt = pkgs.libxcrypt-legacy; };
107 defaultText = lib.literalExpression "pkgs.openldap.override { libxcrypt = pkgs.libxcrypt-legacy; }";
108 description = lib.mdDoc "The OpenLDAP package to use.";
···102 ldap = {
103 package = mkOption {
104 type = types.package;
105+ # needs openldap built with a libxcrypt that support crypt sha256 until users have had time to migrate to newer hashes
106+ # Ref: <https://github.com/majewsky/portunus/issues/2>
107+ # TODO: remove in NixOS 24.11 (cf. same note on pkgs/servers/portunus/default.nix)
108 default = pkgs.openldap.override { libxcrypt = pkgs.libxcrypt-legacy; };
109 defaultText = lib.literalExpression "pkgs.openldap.override { libxcrypt = pkgs.libxcrypt-legacy; }";
110 description = lib.mdDoc "The OpenLDAP package to use.";
···51In case the application serves multiple domains (those are checked with
52[`$_SERVER['HTTP_HOST']`](https://www.php.net/manual/en/reserved.variables.server.php))
53it's needed to add them to
54-[`services.nextcloud.config.extraTrustedDomains`](#opt-services.nextcloud.config.extraTrustedDomains).
5556Auto updates for Nextcloud apps can be enabled using
57[`services.nextcloud.autoUpdateApps`](#opt-services.nextcloud.autoUpdateApps.enable).
···51In case the application serves multiple domains (those are checked with
52[`$_SERVER['HTTP_HOST']`](https://www.php.net/manual/en/reserved.variables.server.php))
53it's needed to add them to
54+[`services.nextcloud.extraOptions.trusted_domains`](#opt-services.nextcloud.extraOptions.trusted_domains).
5556Auto updates for Nextcloud apps can be enabled using
57[`services.nextcloud.autoUpdateApps`](#opt-services.nextcloud.autoUpdateApps.enable).
+177-143
nixos/modules/services/web-apps/nextcloud.nix
···23 catch_workers_output = "yes";
24 };
25000000000000000000000000000000000000026 inherit (cfg) datadir;
2728 phpPackage = cfg.phpPackage.buildEnv {
···4546 occ = pkgs.writeScriptBin "nextcloud-occ" ''
47 #! ${pkgs.runtimeShell}
48- cd ${cfg.package}
49 sudo=exec
50 if [[ "$USER" != nextcloud ]]; then
51 sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR --preserve-env=OC_PASS'
···94 (mkRemovedOptionModule [ "services" "nextcloud" "disableImagemagick" ] ''
95 Use services.nextcloud.enableImagemagick instead.
96 '')
000000000000000097 ];
9899 options.services.nextcloud = {
···157 Set this to false to disable the installation of apps from the global appstore. App management is always enabled regardless of this setting.
158 '';
159 };
160- logLevel = mkOption {
161- type = types.ints.between 0 4;
162- default = 2;
163- description = lib.mdDoc ''
164- Log level value between 0 (DEBUG) and 4 (FATAL).
165-166- - 0 (debug): Log all activity.
167-168- - 1 (info): Log activity such as user logins and file activities, plus warnings, errors, and fatal errors.
169-170- - 2 (warn): Log successful operations, as well as warnings of potential problems, errors and fatal errors.
171-172- - 3 (error): Log failed operations and fatal errors.
173-174- - 4 (fatal): Log only fatal errors that cause the server to stop.
175- '';
176- };
177- logType = mkOption {
178- type = types.enum [ "errorlog" "file" "syslog" "systemd" ];
179- default = "syslog";
180- description = lib.mdDoc ''
181- Logging backend to use.
182- systemd requires the php-systemd package to be added to services.nextcloud.phpExtraExtensions.
183- See the [nextcloud documentation](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/logging_configuration.html) for details.
184- '';
185- };
186 https = mkOption {
187 type = types.bool;
188 default = false;
···206 '';
207 };
208209- skeletonDirectory = mkOption {
210- default = "";
211- type = types.str;
212- description = lib.mdDoc ''
213- The directory where the skeleton files are located. These files will be
214- copied to the data directory of new users. Leave empty to not copy any
215- skeleton files.
216- '';
217- };
218-219 webfinger = mkOption {
220 type = types.bool;
221 default = false;
···315316 };
317318-319 config = {
320 dbtype = mkOption {
321 type = types.enum [ "sqlite" "pgsql" "mysql" ];
···380 setup of Nextcloud by the systemd service `nextcloud-setup.service`.
381 '';
382 };
383-384- extraTrustedDomains = mkOption {
385- type = types.listOf types.str;
386- default = [];
387- description = lib.mdDoc ''
388- Trusted domains from which the Nextcloud installation will be
389- accessible. You don't need to add
390- `services.nextcloud.hostname` here.
391- '';
392- };
393-394- trustedProxies = mkOption {
395- type = types.listOf types.str;
396- default = [];
397- description = lib.mdDoc ''
398- Trusted proxies to provide if the Nextcloud installation is being
399- proxied to secure against, e.g. spoofing.
400- '';
401- };
402-403- overwriteProtocol = mkOption {
404- type = types.nullOr (types.enum [ "http" "https" ]);
405- default = null;
406- example = "https";
407-408- description = lib.mdDoc ''
409- Force Nextcloud to always use HTTP or HTTPS i.e. for link generation.
410- Nextcloud uses the currently used protocol by default, but when
411- behind a reverse-proxy, it may use `http` for everything although
412- Nextcloud may be served via HTTPS.
413- '';
414- };
415-416- defaultPhoneRegion = mkOption {
417- default = null;
418- type = types.nullOr types.str;
419- example = "DE";
420- description = lib.mdDoc ''
421- An [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html)
422- country code which replaces automatic phone-number detection
423- without a country code.
424-425- As an example, with `DE` set as the default phone region,
426- the `+49` prefix can be omitted for phone numbers.
427- '';
428- };
429-430 objectstore = {
431 s3 = {
432 enable = mkEnableOption (lib.mdDoc ''
···609 The nextcloud-occ program preconfigured to target this Nextcloud instance.
610 '';
611 };
612- globalProfiles = mkEnableOption (lib.mdDoc "global profiles") // {
613- description = lib.mdDoc ''
614- Makes user-profiles globally available under `nextcloud.tld/u/user.name`.
615- Even though it's enabled by default in Nextcloud, it must be explicitly enabled
616- here because it has the side-effect that personal information is even accessible to
617- unauthenticated users by default.
618619- By default, the following properties are set to “Show to everyone”
620- if this flag is enabled:
621- - About
622- - Full name
623- - Headline
624- - Organisation
625- - Profile picture
626- - Role
627- - Twitter
628- - Website
629630- Only has an effect in Nextcloud 23 and later.
631- '';
632- };
00633634- extraOptions = mkOption {
635- type = jsonFormat.type;
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000636 default = {};
637 description = lib.mdDoc ''
638 Extra options which should be appended to Nextcloud's config.php file.
···766 # When upgrading the Nextcloud package, Nextcloud can report errors such as
767 # "The files of the app [all apps in /var/lib/nextcloud/apps] were not replaced correctly"
768 # Restarting phpfpm on Nextcloud package update fixes these issues (but this is a workaround).
769- phpfpm-nextcloud.restartTriggers = [ cfg.package ];
770771 nextcloud-setup = let
772 c = cfg.config;
773- writePhpArray = a: "[${concatMapStringsSep "," (val: ''"${toString val}"'') a}]";
774 requiresReadSecretFunction = c.dbpassFile != null || c.objectstore.s3.enable;
775 objectstoreConfig = let s3 = c.objectstore.s3; in optionalString s3.enable ''
776 'objectstore' => [
···800801 nextcloudGreaterOrEqualThan = req: versionAtLeast cfg.package.version req;
8020000803 overrideConfig = pkgs.writeText "nextcloud-config.php" ''
804 <?php
805 ${optionalString requiresReadSecretFunction ''
···828 }
829 $CONFIG = [
830 'apps_paths' => [
831- ${optionalString (cfg.extraApps != { }) "[ 'path' => '${cfg.home}/nix-apps', 'url' => '/nix-apps', 'writable' => false ],"}
832- [ 'path' => '${cfg.home}/apps', 'url' => '/apps', 'writable' => false ],
833- [ 'path' => '${cfg.home}/store-apps', 'url' => '/store-apps', 'writable' => true ],
834 ],
835 ${optionalString (showAppStoreSetting) "'appstoreenabled' => ${renderedAppStoreSetting},"}
836- 'datadirectory' => '${datadir}/data',
837- 'skeletondirectory' => '${cfg.skeletonDirectory}',
838 ${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"}
839- 'log_type' => '${cfg.logType}',
840- 'loglevel' => '${builtins.toString cfg.logLevel}',
841- ${optionalString (c.overwriteProtocol != null) "'overwriteprotocol' => '${c.overwriteProtocol}',"}
842 ${optionalString (c.dbname != null) "'dbname' => '${c.dbname}',"}
843 ${optionalString (c.dbhost != null) "'dbhost' => '${c.dbhost}',"}
844 ${optionalString (c.dbport != null) "'dbport' => '${toString c.dbport}',"}
···851 ''
852 }
853 'dbtype' => '${c.dbtype}',
854- 'trusted_domains' => ${writePhpArray ([ cfg.hostName ] ++ c.extraTrustedDomains)},
855- 'trusted_proxies' => ${writePhpArray (c.trustedProxies)},
856- ${optionalString (c.defaultPhoneRegion != null) "'default_phone_region' => '${c.defaultPhoneRegion}',"}
857- ${optionalString (nextcloudGreaterOrEqualThan "23") "'profile.enabled' => ${boolToString cfg.globalProfiles},"}
858 ${objectstoreConfig}
859 ];
860···907 (i: v: ''
908 ${occ}/bin/nextcloud-occ config:system:set trusted_domains \
909 ${toString i} --value="${toString v}"
910- '') ([ cfg.hostName ] ++ cfg.config.extraTrustedDomains));
911912 in {
913 wantedBy = [ "multi-user.target" ];
···935 exit 1
936 fi
937938- ln -sf ${cfg.package}/apps ${cfg.home}/
939-940- # Install extra apps
941- ln -sfT \
942- ${pkgs.linkFarm "nix-apps"
943- (mapAttrsToList (name: path: { inherit name path; }) cfg.extraApps)} \
944- ${cfg.home}/nix-apps
945946 # create nextcloud directories.
947 # if the directories exist already with wrong permissions, we fix that
948- for dir in ${datadir}/config ${datadir}/data ${cfg.home}/store-apps ${cfg.home}/nix-apps; do
949 if [ ! -e $dir ]; then
950 install -o nextcloud -g nextcloud -d $dir
951 elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then
···982 environment.NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
983 serviceConfig.Type = "oneshot";
984 serviceConfig.User = "nextcloud";
985- serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php";
986 };
987 nextcloud-update-plugins = mkIf cfg.autoUpdateApps.enable {
988 after = [ "nextcloud-setup.service" ];
···1043 user = "nextcloud";
1044 };
10451046- services.nextcloud = lib.mkIf cfg.configureRedis {
1047- caching.redis = true;
1048- extraOptions = {
0001049 "memcache.distributed" = ''\OC\Memcache\Redis'';
1050 "memcache.locking" = ''\OC\Memcache\Redis'';
1051 redis = {
1052 host = config.services.redis.servers.nextcloud.unixSocket;
1053 port = 0;
1054 };
1055- };
1056 };
10571058 services.nginx.enable = mkDefault true;
10591060 services.nginx.virtualHosts.${cfg.hostName} = {
1061- root = cfg.package;
1062 locations = {
1063 "= /robots.txt" = {
1064 priority = 100;
···1074 return 302 /remote.php/webdav/$is_args$args;
1075 }
1076 '';
1077- };
1078- "~ ^/store-apps" = {
1079- priority = 201;
1080- extraConfig = "root ${cfg.home};";
1081- };
1082- "~ ^/nix-apps" = {
1083- priority = 201;
1084- extraConfig = "root ${cfg.home};";
1085 };
1086 "^~ /.well-known" = {
1087 priority = 210;
···23 catch_workers_output = "yes";
24 };
2526+ appStores = {
27+ # default apps bundled with pkgs.nextcloudXX, e.g. files, contacts
28+ apps = {
29+ enabled = true;
30+ writable = false;
31+ };
32+ # apps installed via cfg.extraApps
33+ nix-apps = {
34+ enabled = cfg.extraApps != { };
35+ linkTarget = pkgs.linkFarm "nix-apps"
36+ (mapAttrsToList (name: path: { inherit name path; }) cfg.extraApps);
37+ writable = false;
38+ };
39+ # apps installed via the app store.
40+ store-apps = {
41+ enabled = cfg.appstoreEnable == null || cfg.appstoreEnable;
42+ linkTarget = "${cfg.home}/store-apps";
43+ writable = true;
44+ };
45+ };
46+47+ webroot = pkgs.runCommand
48+ "${cfg.package.name or "nextcloud"}-with-apps"
49+ { }
50+ ''
51+ mkdir $out
52+ ln -sfv "${cfg.package}"/* "$out"
53+ ${concatStrings
54+ (mapAttrsToList (name: store: optionalString (store.enabled && store?linkTarget) ''
55+ if [ -e "$out"/${name} ]; then
56+ echo "Didn't expect ${name} already in $out!"
57+ exit 1
58+ fi
59+ ln -sfTv ${store.linkTarget} "$out"/${name}
60+ '') appStores)}
61+ '';
62+63 inherit (cfg) datadir;
6465 phpPackage = cfg.phpPackage.buildEnv {
···8283 occ = pkgs.writeScriptBin "nextcloud-occ" ''
84 #! ${pkgs.runtimeShell}
85+ cd ${webroot}
86 sudo=exec
87 if [[ "$USER" != nextcloud ]]; then
88 sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR --preserve-env=OC_PASS'
···131 (mkRemovedOptionModule [ "services" "nextcloud" "disableImagemagick" ] ''
132 Use services.nextcloud.enableImagemagick instead.
133 '')
134+ (mkRenamedOptionModule
135+ [ "services" "nextcloud" "logLevel" ] [ "services" "nextcloud" "extraOptions" "loglevel" ])
136+ (mkRenamedOptionModule
137+ [ "services" "nextcloud" "logType" ] [ "services" "nextcloud" "extraOptions" "log_type" ])
138+ (mkRenamedOptionModule
139+ [ "services" "nextcloud" "config" "defaultPhoneRegion" ] [ "services" "nextcloud" "extraOptions" "default_phone_region" ])
140+ (mkRenamedOptionModule
141+ [ "services" "nextcloud" "config" "overwriteProtocol" ] [ "services" "nextcloud" "extraOptions" "overwriteprotocol" ])
142+ (mkRenamedOptionModule
143+ [ "services" "nextcloud" "skeletonDirectory" ] [ "services" "nextcloud" "extraOptions" "skeletondirectory" ])
144+ (mkRenamedOptionModule
145+ [ "services" "nextcloud" "config" "globalProfiles" ] [ "services" "nextcloud" "extraOptions" "profile.enabled" ])
146+ (mkRenamedOptionModule
147+ [ "services" "nextcloud" "config" "extraTrustedDomains" ] [ "services" "nextcloud" "extraOptions" "trusted_domains" ])
148+ (mkRenamedOptionModule
149+ [ "services" "nextcloud" "config" "trustedProxies" ] [ "services" "nextcloud" "extraOptions" "trusted_proxies" ])
150 ];
151152 options.services.nextcloud = {
···210 Set this to false to disable the installation of apps from the global appstore. App management is always enabled regardless of this setting.
211 '';
212 };
00000000000000000000000000213 https = mkOption {
214 type = types.bool;
215 default = false;
···233 '';
234 };
2350000000000236 webfinger = mkOption {
237 type = types.bool;
238 default = false;
···332333 };
3340335 config = {
336 dbtype = mkOption {
337 type = types.enum [ "sqlite" "pgsql" "mysql" ];
···396 setup of Nextcloud by the systemd service `nextcloud-setup.service`.
397 '';
398 };
00000000000000000000000000000000000000000000000399 objectstore = {
400 s3 = {
401 enable = mkEnableOption (lib.mdDoc ''
···578 The nextcloud-occ program preconfigured to target this Nextcloud instance.
579 '';
580 };
000000581582+ extraOptions = mkOption {
583+ type = types.submodule {
584+ freeformType = jsonFormat.type;
585+ options = {
000000586587+ loglevel = mkOption {
588+ type = types.ints.between 0 4;
589+ default = 2;
590+ description = lib.mdDoc ''
591+ Log level value between 0 (DEBUG) and 4 (FATAL).
592593+ - 0 (debug): Log all activity.
594+595+ - 1 (info): Log activity such as user logins and file activities, plus warnings, errors, and fatal errors.
596+597+ - 2 (warn): Log successful operations, as well as warnings of potential problems, errors and fatal errors.
598+599+ - 3 (error): Log failed operations and fatal errors.
600+601+ - 4 (fatal): Log only fatal errors that cause the server to stop.
602+ '';
603+ };
604+ log_type = mkOption {
605+ type = types.enum [ "errorlog" "file" "syslog" "systemd" ];
606+ default = "syslog";
607+ description = lib.mdDoc ''
608+ Logging backend to use.
609+ systemd requires the php-systemd package to be added to services.nextcloud.phpExtraExtensions.
610+ See the [nextcloud documentation](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/logging_configuration.html) for details.
611+ '';
612+ };
613+ skeletondirectory = mkOption {
614+ default = "";
615+ type = types.str;
616+ description = lib.mdDoc ''
617+ The directory where the skeleton files are located. These files will be
618+ copied to the data directory of new users. Leave empty to not copy any
619+ skeleton files.
620+ '';
621+ };
622+ trusted_domains = mkOption {
623+ type = types.listOf types.str;
624+ default = [];
625+ description = lib.mdDoc ''
626+ Trusted domains, from which the nextcloud installation will be
627+ accessible. You don't need to add
628+ `services.nextcloud.hostname` here.
629+ '';
630+ };
631+ trusted_proxies = mkOption {
632+ type = types.listOf types.str;
633+ default = [];
634+ description = lib.mdDoc ''
635+ Trusted proxies, to provide if the nextcloud installation is being
636+ proxied to secure against e.g. spoofing.
637+ '';
638+ };
639+ overwriteprotocol = mkOption {
640+ type = types.enum [ "" "http" "https" ];
641+ default = "";
642+ example = "https";
643+ description = lib.mdDoc ''
644+ Force Nextcloud to always use HTTP or HTTPS i.e. for link generation.
645+ Nextcloud uses the currently used protocol by default, but when
646+ behind a reverse-proxy, it may use `http` for everything although
647+ Nextcloud may be served via HTTPS.
648+ '';
649+ };
650+ default_phone_region = mkOption {
651+ default = "";
652+ type = types.str;
653+ example = "DE";
654+ description = lib.mdDoc ''
655+ An [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html)
656+ country code which replaces automatic phone-number detection
657+ without a country code.
658+659+ As an example, with `DE` set as the default phone region,
660+ the `+49` prefix can be omitted for phone numbers.
661+ '';
662+ };
663+ "profile.enabled" = mkEnableOption (lib.mdDoc "global profiles") // {
664+ description = lib.mdDoc ''
665+ Makes user-profiles globally available under `nextcloud.tld/u/user.name`.
666+ Even though it's enabled by default in Nextcloud, it must be explicitly enabled
667+ here because it has the side-effect that personal information is even accessible to
668+ unauthenticated users by default.
669+ By default, the following properties are set to “Show to everyone”
670+ if this flag is enabled:
671+ - About
672+ - Full name
673+ - Headline
674+ - Organisation
675+ - Profile picture
676+ - Role
677+ - Twitter
678+ - Website
679+ Only has an effect in Nextcloud 23 and later.
680+ '';
681+ };
682+ };
683+ };
684 default = {};
685 description = lib.mdDoc ''
686 Extra options which should be appended to Nextcloud's config.php file.
···814 # When upgrading the Nextcloud package, Nextcloud can report errors such as
815 # "The files of the app [all apps in /var/lib/nextcloud/apps] were not replaced correctly"
816 # Restarting phpfpm on Nextcloud package update fixes these issues (but this is a workaround).
817+ phpfpm-nextcloud.restartTriggers = [ webroot ];
818819 nextcloud-setup = let
820 c = cfg.config;
0821 requiresReadSecretFunction = c.dbpassFile != null || c.objectstore.s3.enable;
822 objectstoreConfig = let s3 = c.objectstore.s3; in optionalString s3.enable ''
823 'objectstore' => [
···847848 nextcloudGreaterOrEqualThan = req: versionAtLeast cfg.package.version req;
849850+ mkAppStoreConfig = name: { enabled, writable, ... }: optionalString enabled ''
851+ [ 'path' => '${webroot}/${name}', 'url' => '/${name}', 'writable' => ${boolToString writable} ],
852+ '';
853+854 overrideConfig = pkgs.writeText "nextcloud-config.php" ''
855 <?php
856 ${optionalString requiresReadSecretFunction ''
···879 }
880 $CONFIG = [
881 'apps_paths' => [
882+ ${concatStrings (mapAttrsToList mkAppStoreConfig appStores)}
00883 ],
884 ${optionalString (showAppStoreSetting) "'appstoreenabled' => ${renderedAppStoreSetting},"}
00885 ${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"}
000886 ${optionalString (c.dbname != null) "'dbname' => '${c.dbname}',"}
887 ${optionalString (c.dbhost != null) "'dbhost' => '${c.dbhost}',"}
888 ${optionalString (c.dbport != null) "'dbport' => '${toString c.dbport}',"}
···895 ''
896 }
897 'dbtype' => '${c.dbtype}',
0000898 ${objectstoreConfig}
899 ];
900···947 (i: v: ''
948 ${occ}/bin/nextcloud-occ config:system:set trusted_domains \
949 ${toString i} --value="${toString v}"
950+ '') ([ cfg.hostName ] ++ cfg.extraOptions.trusted_domains));
951952 in {
953 wantedBy = [ "multi-user.target" ];
···975 exit 1
976 fi
977978+ ${concatMapStrings (name: ''
979+ if [ -d "${cfg.home}"/${name} ]; then
980+ echo "Cleaning up ${name}; these are now bundled in the webroot store-path!"
981+ rm -r "${cfg.home}"/${name}
982+ fi
983+ '') [ "nix-apps" "apps" ]}
0984985 # create nextcloud directories.
986 # if the directories exist already with wrong permissions, we fix that
987+ for dir in ${datadir}/config ${datadir}/data ${cfg.home}/store-apps; do
988 if [ ! -e $dir ]; then
989 install -o nextcloud -g nextcloud -d $dir
990 elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then
···1021 environment.NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
1022 serviceConfig.Type = "oneshot";
1023 serviceConfig.User = "nextcloud";
1024+ serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${webroot}/cron.php";
1025 };
1026 nextcloud-update-plugins = mkIf cfg.autoUpdateApps.enable {
1027 after = [ "nextcloud-setup.service" ];
···1082 user = "nextcloud";
1083 };
10841085+ services.nextcloud = {
1086+ caching.redis = lib.mkIf cfg.configureRedis true;
1087+ extraOptions = mkMerge [({
1088+ datadirectory = lib.mkDefault "${datadir}/data";
1089+ trusted_domains = [ cfg.hostName ];
1090+ }) (lib.mkIf cfg.configureRedis {
1091 "memcache.distributed" = ''\OC\Memcache\Redis'';
1092 "memcache.locking" = ''\OC\Memcache\Redis'';
1093 redis = {
1094 host = config.services.redis.servers.nextcloud.unixSocket;
1095 port = 0;
1096 };
1097+ })];
1098 };
10991100 services.nginx.enable = mkDefault true;
11011102 services.nginx.virtualHosts.${cfg.hostName} = {
1103+ root = webroot;
1104 locations = {
1105 "= /robots.txt" = {
1106 priority = 100;
···1116 return 302 /remote.php/webdav/$is_args$args;
1117 }
1118 '';
000000001119 };
1120 "^~ /.well-known" = {
1121 priority = 210;
+19-6
nixos/modules/system/boot/systemd/oomd.nix
···3 cfg = config.systemd.oomd;
45in {
00006 options.systemd.oomd = {
7 enable = lib.mkEnableOption (lib.mdDoc "the `systemd-oomd` OOM killer") // { default = true; };
89 # Fedora enables the first and third option by default. See the 10-oomd-* files here:
10- # https://src.fedoraproject.org/rpms/systemd/tree/acb90c49c42276b06375a66c73673ac351025597
11 enableRootSlice = lib.mkEnableOption (lib.mdDoc "oomd on the root slice (`-.slice`)");
12 enableSystemSlice = lib.mkEnableOption (lib.mdDoc "oomd on the system slice (`system.slice`)");
13- enableUserServices = lib.mkEnableOption (lib.mdDoc "oomd on all user services (`user@.service`)");
1415 extraConfig = lib.mkOption {
16 type = with lib.types; attrsOf (oneOf [ str int bool ]);
···44 users.groups.systemd-oom = { };
4546 systemd.slices."-".sliceConfig = lib.mkIf cfg.enableRootSlice {
47- ManagedOOMSwap = "kill";
048 };
49 systemd.slices."system".sliceConfig = lib.mkIf cfg.enableSystemSlice {
50- ManagedOOMSwap = "kill";
051 };
52- systemd.services."user@".serviceConfig = lib.mkIf cfg.enableUserServices {
53 ManagedOOMMemoryPressure = "kill";
54- ManagedOOMMemoryPressureLimit = "50%";
000000055 };
56 };
57}
···3 cfg = config.systemd.oomd;
45in {
6+ imports = [
7+ (lib.mkRemovedOptionModule [ "systemd" "oomd" "enableUserServices" ] "Use systemd.oomd.enableUserSlices instead.")
8+ ];
9+10 options.systemd.oomd = {
11 enable = lib.mkEnableOption (lib.mdDoc "the `systemd-oomd` OOM killer") // { default = true; };
1213 # Fedora enables the first and third option by default. See the 10-oomd-* files here:
14+ # https://src.fedoraproject.org/rpms/systemd/tree/806c95e1c70af18f81d499b24cd7acfa4c36ffd6
15 enableRootSlice = lib.mkEnableOption (lib.mdDoc "oomd on the root slice (`-.slice`)");
16 enableSystemSlice = lib.mkEnableOption (lib.mdDoc "oomd on the system slice (`system.slice`)");
17+ enableUserSlices = lib.mkEnableOption (lib.mdDoc "oomd on all user slices (`user@.slice`) and all user owned slices");
1819 extraConfig = lib.mkOption {
20 type = with lib.types; attrsOf (oneOf [ str int bool ]);
···48 users.groups.systemd-oom = { };
4950 systemd.slices."-".sliceConfig = lib.mkIf cfg.enableRootSlice {
51+ ManagedOOMMemoryPressure = "kill";
52+ ManagedOOMMemoryPressureLimit = "80%";
53 };
54 systemd.slices."system".sliceConfig = lib.mkIf cfg.enableSystemSlice {
55+ ManagedOOMMemoryPressure = "kill";
56+ ManagedOOMMemoryPressureLimit = "80%";
57 };
58+ systemd.slices."user-".sliceConfig = lib.mkIf cfg.enableUserSlices {
59 ManagedOOMMemoryPressure = "kill";
60+ ManagedOOMMemoryPressureLimit = "80%";
61+ };
62+ systemd.user.units."slice" = lib.mkIf cfg.enableUserSlices {
63+ text = ''
64+ ManagedOOMMemoryPressure=kill
65+ ManagedOOMMemoryPressureLimit=80%
66+ '';
67+ overrideStrategy = "asDropin";
68 };
69 };
70}
···23stdenv.mkDerivation rec {
4 pname = "tdlib";
5- version = "1.8.22";
67 src = fetchFromGitHub {
8 owner = "tdlib";
···11 # The tdlib authors do not set tags for minor versions, but
12 # external programs depending on tdlib constrain the minor
13 # version, hence we set a specific commit with a known version.
14- rev = "24893faf75d84b2b885f3f7aeb9d5a3c056fa7be";
15- hash = "sha256-4cfnre71+rQSuPrtFJMzIEPYVCZH/W142b4Pn2NxvqI=";
16 };
1718 buildInputs = [ gperf openssl readline zlib ];
···23stdenv.mkDerivation rec {
4 pname = "tdlib";
5+ version = "1.8.23";
67 src = fetchFromGitHub {
8 owner = "tdlib";
···11 # The tdlib authors do not set tags for minor versions, but
12 # external programs depending on tdlib constrain the minor
13 # version, hence we set a specific commit with a known version.
14+ rev = "27c3eaeb4964bd5f18d8488e354abde1a4383e49";
15+ hash = "sha256-TxgzZn/OF5b5FWzwnOWIozH+1d7O0RG3h+WKV10rxpE=";
16 };
1718 buildInputs = [ gperf openssl readline zlib ];
···603 mess = throw "'mess' has been renamed to/replaced by 'mame'"; # Converted to throw 2023-09-10
604 microsoft_gsl = microsoft-gsl; # Added 2023-05-26
605 migraphx = throw "'migraphx' has been replaced with 'rocmPackages.migraphx'"; # Added 2023-10-08
0606 miopen = throw "'miopen' has been replaced with 'rocmPackages.miopen'"; # Added 2023-10-08
607 miopengemm = throw "'miopengemm' has been replaced with 'rocmPackages.miopengemm'"; # Added 2023-10-08
608 miopen-hip = throw "'miopen-hip' has been replaced with 'rocmPackages.miopen-hip'"; # Added 2023-10-08
···603 mess = throw "'mess' has been renamed to/replaced by 'mame'"; # Converted to throw 2023-09-10
604 microsoft_gsl = microsoft-gsl; # Added 2023-05-26
605 migraphx = throw "'migraphx' has been replaced with 'rocmPackages.migraphx'"; # Added 2023-10-08
606+ minishift = throw "'minishift' has been removed as it was discontinued upstream. Use 'crc' to setup a microshift cluster instead"; # Added 2023-12-30
607 miopen = throw "'miopen' has been replaced with 'rocmPackages.miopen'"; # Added 2023-10-08
608 miopengemm = throw "'miopengemm' has been replaced with 'rocmPackages.miopengemm'"; # Added 2023-10-08
609 miopen-hip = throw "'miopen-hip' has been replaced with 'rocmPackages.miopen-hip'"; # Added 2023-10-08