mirror of
https://github.com/nix-community/home-manager
synced 2025-02-26 20:37:18 +00:00
Merge branch 'nix-community:master' into joplin-desktop
This commit is contained in:
commit
08db478dab
36 changed files with 1017 additions and 68 deletions
6
flake.lock
generated
6
flake.lock
generated
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1731139594,
|
||||
"narHash": "sha256-IigrKK3vYRpUu+HEjPL/phrfh7Ox881er1UEsZvw9Q4=",
|
||||
"lastModified": 1732014248,
|
||||
"narHash": "sha256-y/MEyuJ5oBWrWAic/14LaIr/u5E0wRVzyYsouYY3W6w=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "76612b17c0ce71689921ca12d9ffdc9c23ce40b2",
|
||||
"rev": "23e89b7da85c3640bbc2173fe04f4bd114342367",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -8,8 +8,8 @@ msgstr ""
|
|||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2024-04-17 23:19+0200\n"
|
||||
"PO-Revision-Date: 2024-02-29 10:10+0000\n"
|
||||
"Last-Translator: FedFer98123 <fede.ferrari123@gmail.com>\n"
|
||||
"PO-Revision-Date: 2024-11-18 15:00+0000\n"
|
||||
"Last-Translator: Lorenzo Bevilacqua <lorenzobevilacqua02@gmail.com>\n"
|
||||
"Language-Team: Italian <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"it/>\n"
|
||||
"Language: it\n"
|
||||
|
@ -17,12 +17,12 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.5-dev\n"
|
||||
"X-Generator: Weblate 5.9-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
msgid "%s: missing argument for %s"
|
||||
msgstr ""
|
||||
msgstr "%s: argomento mancante per %s"
|
||||
|
||||
#: home-manager/home-manager:64
|
||||
msgid "No configuration file found at %s"
|
||||
|
|
|
@ -8,8 +8,8 @@ msgstr ""
|
|||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2024-04-17 23:19+0200\n"
|
||||
"PO-Revision-Date: 2024-02-18 14:02+0000\n"
|
||||
"Last-Translator: Сергій <sergiy.goncharuk.1@gmail.com>\n"
|
||||
"PO-Revision-Date: 2024-11-18 15:00+0000\n"
|
||||
"Last-Translator: wadsaek <wadsaek@gmail.com>\n"
|
||||
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/home-manager/"
|
||||
"cli/uk/>\n"
|
||||
"Language: uk\n"
|
||||
|
@ -18,12 +18,12 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Weblate 5.4\n"
|
||||
"X-Generator: Weblate 5.9-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
msgid "%s: missing argument for %s"
|
||||
msgstr ""
|
||||
msgstr "%s: відсутній аргумент для %s"
|
||||
|
||||
#: home-manager/home-manager:64
|
||||
msgid "No configuration file found at %s"
|
||||
|
|
|
@ -45,6 +45,17 @@ let
|
|||
gtk config generation for {option}`home.pointerCursor`
|
||||
'';
|
||||
};
|
||||
|
||||
hyprcursor = {
|
||||
enable = mkEnableOption "hyprcursor config generation";
|
||||
|
||||
size = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
example = 32;
|
||||
default = null;
|
||||
description = "The cursor size for hyprcursor.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -178,5 +189,13 @@ in {
|
|||
(mkIf cfg.gtk.enable {
|
||||
gtk.cursorTheme = mkDefault { inherit (cfg) package name size; };
|
||||
})
|
||||
|
||||
(mkIf cfg.hyprcursor.enable {
|
||||
home.sessionVariables = {
|
||||
HYPRCURSOR_THEME = cfg.name;
|
||||
HYPRCURSOR_SIZE =
|
||||
if cfg.hyprcursor.size != null then cfg.hyprcursor.size else cfg.size;
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -27,9 +27,6 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions =
|
||||
[ (hm.assertions.assertPlatform "programs.abook" pkgs platforms.linux) ];
|
||||
|
||||
home.packages = [ pkgs.abook ];
|
||||
|
||||
xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{ modulePath, name, description ? null, wrappedPackageName ? null
|
||||
, unwrappedPackageName ? null, platforms, visible ? false }:
|
||||
, unwrappedPackageName ? null, platforms, visible ? false
|
||||
, enableBookmarks ? true }:
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
|
@ -435,6 +436,7 @@ in {
|
|||
};
|
||||
|
||||
bookmarks = mkOption {
|
||||
internal = !enableBookmarks;
|
||||
type = let
|
||||
bookmarkSubmodule = types.submodule ({ config, name, ... }: {
|
||||
options = {
|
||||
|
|
|
@ -14,20 +14,35 @@ let
|
|||
'') prefs)}
|
||||
'';
|
||||
|
||||
modulePath = [ "programs" "librewolf" ];
|
||||
|
||||
mkFirefoxModule = import ./firefox/mkFirefoxModule.nix;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.onny ];
|
||||
meta.maintainers = [ maintainers.chayleaf maintainers.onny ];
|
||||
|
||||
imports = [
|
||||
(mkFirefoxModule {
|
||||
inherit modulePath;
|
||||
name = "LibreWolf";
|
||||
description = "LibreWolf is a privacy enhanced Firefox fork.";
|
||||
wrappedPackageName = "librewolf";
|
||||
unwrappedPackageName = "librewolf-unwrapped";
|
||||
|
||||
platforms.linux = {
|
||||
vendorPath = ".librewolf";
|
||||
configPath = ".librewolf";
|
||||
};
|
||||
platforms.darwin = {
|
||||
vendorPath = "Library/Application Support/LibreWolf";
|
||||
configPath = "Library/Application Support/LibreWolf";
|
||||
};
|
||||
|
||||
enableBookmarks = false;
|
||||
})
|
||||
];
|
||||
|
||||
options.programs.librewolf = {
|
||||
enable =
|
||||
mkEnableOption "Librewolf browser, a privacy enhanced Firefox fork";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.librewolf;
|
||||
defaultText = literalExpression "pkgs.librewolf";
|
||||
description = "The LibreWolf package to use.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf (either bool (either int str));
|
||||
default = { };
|
||||
|
@ -38,7 +53,7 @@ in {
|
|||
}
|
||||
'';
|
||||
description = ''
|
||||
Attribute set of LibreWolf settings and overrides. Refer to
|
||||
Attribute set of global LibreWolf settings and overrides. Refer to
|
||||
<https://librewolf.net/docs/settings/>
|
||||
for details on supported values.
|
||||
'';
|
||||
|
@ -51,9 +66,7 @@ in {
|
|||
lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.file.".librewolf/librewolf.overrides.cfg".text =
|
||||
mkOverridesFile cfg.settings;
|
||||
home.file.".librewolf/librewolf.overrides.cfg" =
|
||||
lib.mkIf (cfg.settings != { }) { text = mkOverridesFile cfg.settings; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -22,6 +22,13 @@ in {
|
|||
|
||||
package = mkPackageOption pkgs "zed-editor" { };
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = [ ];
|
||||
example = literalExpression "[ pkgs.nixd ]";
|
||||
description = "Extra packages available to Zed.";
|
||||
};
|
||||
|
||||
userSettings = mkOption {
|
||||
type = jsonFormat.type;
|
||||
default = { };
|
||||
|
@ -76,7 +83,22 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
home.packages = if cfg.extraPackages != [ ] then
|
||||
[
|
||||
(pkgs.symlinkJoin {
|
||||
name =
|
||||
"${lib.getName cfg.package}-wrapped-${lib.getVersion cfg.package}";
|
||||
paths = [ cfg.package ];
|
||||
preferLocalBuild = true;
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
postBuild = ''
|
||||
wrapProgram $out/bin/zeditor \
|
||||
--suffix PATH : ${lib.makeBinPath cfg.extraPackages}
|
||||
'';
|
||||
})
|
||||
]
|
||||
else
|
||||
[ cfg.package ];
|
||||
|
||||
xdg.configFile."zed/settings.json" = (mkIf (mergedSettings != { }) {
|
||||
source = jsonFormat.generate "zed-user-settings" mergedSettings;
|
||||
|
|
|
@ -41,7 +41,7 @@ in with lib; {
|
|||
Service = {
|
||||
Restart = "always";
|
||||
RestartSec = "3";
|
||||
ExecStart = toString ([ "${pkgs.conky}/bin/conky" ]
|
||||
ExecStart = toString ([ "${cfg.package}/bin/conky" ]
|
||||
++ optional (cfg.extraConfig != "")
|
||||
"--config ${pkgs.writeText "conky.conf" cfg.extraConfig}");
|
||||
};
|
||||
|
|
|
@ -41,7 +41,6 @@ let
|
|||
# to work without wrapping it.
|
||||
socketDir = "%t/emacs";
|
||||
socketPath = "${socketDir}/server";
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.tadfisher ];
|
||||
|
||||
|
@ -112,12 +111,7 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "services.emacs" pkgs
|
||||
lib.platforms.linux)
|
||||
];
|
||||
|
||||
(mkIf pkgs.stdenv.isLinux {
|
||||
systemd.user.services.emacs = {
|
||||
Unit = {
|
||||
Description = "Emacs text editor";
|
||||
|
@ -190,9 +184,9 @@ in {
|
|||
}/bin/emacsclient "''${@:---create-frame}"'');
|
||||
};
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
(mkIf cfg.socketActivation.enable {
|
||||
(mkIf (cfg.socketActivation.enable && pkgs.stdenv.isLinux) {
|
||||
systemd.user.sockets.emacs = {
|
||||
Unit = {
|
||||
Description = "Emacs text editor";
|
||||
|
@ -222,5 +216,20 @@ in {
|
|||
};
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf pkgs.stdenv.isDarwin {
|
||||
launchd.agents.emacs = {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [ "${cfg.package}/bin/emacs" "--fg-daemon" ]
|
||||
++ cfg.extraOptions;
|
||||
RunAtLoad = true;
|
||||
KeepAlive = {
|
||||
Crashed = true;
|
||||
SuccessfulExit = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ in {
|
|||
Description = "hypridle";
|
||||
After = [ "graphical-session-pre.target" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
X-Restart-Triggers =
|
||||
X-Restart-Triggers = mkIf (cfg.settings != { })
|
||||
[ "${config.xdg.configFile."hypr/hypridle.conf".source}" ];
|
||||
};
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ in {
|
|||
Description = "hyprpaper";
|
||||
After = [ "graphical-session-pre.target" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
X-Restart-Triggers =
|
||||
X-Restart-Triggers = mkIf (cfg.settings != { })
|
||||
[ "${config.xdg.configFile."hypr/hyprpaper.conf".source}" ];
|
||||
};
|
||||
|
||||
|
|
|
@ -126,10 +126,13 @@ in {
|
|||
Description = "mopidy music player daemon";
|
||||
Documentation = [ "https://mopidy.com/" ];
|
||||
After = [ "network.target" "sound.target" ];
|
||||
X-Restart-Triggers = mkIf (cfg.settings != { })
|
||||
[ "${config.xdg.configFile."mopidy/mopidy.conf".source}" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${mopidyEnv}/bin/mopidy --config ${configFilePaths}";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
let
|
||||
cfg = config.services.podman;
|
||||
toml = pkgs.formats.toml { };
|
||||
in {
|
||||
meta.maintainers = with lib.hm.maintainers; [ bamhm182 n-hass ];
|
||||
|
||||
imports =
|
||||
|
@ -8,10 +10,90 @@
|
|||
|
||||
options.services.podman = {
|
||||
enable = lib.mkEnableOption "Podman, a daemonless container engine";
|
||||
|
||||
settings = {
|
||||
containers = lib.mkOption {
|
||||
type = toml.type;
|
||||
default = { };
|
||||
description = "containers.conf configuration";
|
||||
};
|
||||
|
||||
storage = lib.mkOption {
|
||||
type = toml.type;
|
||||
description = "storage.conf configuration";
|
||||
};
|
||||
|
||||
registries = {
|
||||
search = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "docker.io" ];
|
||||
description = ''
|
||||
List of repositories to search.
|
||||
'';
|
||||
};
|
||||
|
||||
insecure = lib.mkOption {
|
||||
default = [ ];
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = ''
|
||||
List of insecure repositories.
|
||||
'';
|
||||
};
|
||||
|
||||
block = lib.mkOption {
|
||||
default = [ ];
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = ''
|
||||
List of blocked repositories.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
policy = lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrs;
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
default = [ { type = "insecureAcceptAnything"; } ];
|
||||
transports = {
|
||||
docker-daemon = {
|
||||
"" = [ { type = "insecureAcceptAnything"; } ];
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Signature verification policy file.
|
||||
If this option is empty the default policy file from
|
||||
`skopeo` will be used.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.podman.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions =
|
||||
[ (lib.hm.assertions.assertPlatform "podman" pkgs lib.platforms.linux) ];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
services.podman.settings.storage = {
|
||||
storage.driver = lib.mkDefault "overlay";
|
||||
};
|
||||
|
||||
xdg.configFile = {
|
||||
"containers/policy.json".source = if cfg.settings.policy != { } then
|
||||
pkgs.writeText "policy.json" (builtins.toJSON cfg.settings.policy)
|
||||
else
|
||||
"${pkgs.skopeo.policy}/default-policy.json";
|
||||
"containers/registries.conf".source = toml.generate "registries.conf" {
|
||||
registries =
|
||||
lib.mapAttrs (n: v: { registries = v; }) cfg.settings.registries;
|
||||
};
|
||||
"containers/storage.conf".source =
|
||||
toml.generate "storage.conf" cfg.settings.storage;
|
||||
"containers/containers.conf".source =
|
||||
toml.generate "containers.conf" cfg.settings.containers;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,44 +5,584 @@ with lib;
|
|||
let
|
||||
|
||||
cfg = config.services.syncthing;
|
||||
settingsFormat = pkgs.formats.json { };
|
||||
cleanedConfig =
|
||||
converge (filterAttrsRecursive (_: v: v != null && v != { })) cfg.settings;
|
||||
|
||||
isUnixGui = (builtins.substring 0 1 cfg.guiAddress) == "/";
|
||||
|
||||
# Syncthing supports serving the GUI over Unix sockets. If that happens, the
|
||||
# API is served over the Unix socket as well. This function returns the correct
|
||||
# curl arguments for the address portion of the curl command for both network
|
||||
# and Unix socket addresses.
|
||||
curlAddressArgs = path:
|
||||
if isUnixGui
|
||||
# if cfg.guiAddress is a unix socket, tell curl explicitly about it
|
||||
# note that the dot in front of `${path}` is the hostname, which is
|
||||
# required.
|
||||
then
|
||||
"--unix-socket ${cfg.guiAddress} http://.${path}"
|
||||
# no adjustements are needed if cfg.guiAddress is a network address
|
||||
else
|
||||
"${cfg.guiAddress}${path}";
|
||||
|
||||
devices = mapAttrsToList (_: device: device // { deviceID = device.id; })
|
||||
cfg.settings.devices;
|
||||
|
||||
folders = mapAttrsToList (_: folder:
|
||||
folder // {
|
||||
devices = map (device:
|
||||
if builtins.isString device then {
|
||||
deviceId = cfg.settings.devices.${device}.id;
|
||||
} else
|
||||
device) folder.devices;
|
||||
}) (filterAttrs (_: folder: folder.enable) cfg.settings.folders);
|
||||
|
||||
jq = "${pkgs.jq}/bin/jq";
|
||||
sleep = "${pkgs.coreutils}/bin/sleep";
|
||||
printf = "${pkgs.coreutils}/bin/printf";
|
||||
cat = "${pkgs.coreutils}/bin/cat";
|
||||
curl = "${pkgs.curl}/bin/curl";
|
||||
install = "${pkgs.coreutils}/bin/install";
|
||||
syncthing = "${pkgs.syncthing}/bin/syncthing";
|
||||
|
||||
updateConfig = pkgs.writers.writeBash "merge-syncthing-config" (''
|
||||
set -efu
|
||||
|
||||
# be careful not to leak secrets in the filesystem or in process listings
|
||||
umask 0077
|
||||
|
||||
curl() {
|
||||
# get the api key by parsing the config.xml
|
||||
while
|
||||
! ${pkgs.libxml2}/bin/xmllint \
|
||||
--xpath 'string(configuration/gui/apikey)' \
|
||||
''${XDG_STATE_HOME:-$HOME/.local/state}/syncthing/config.xml \
|
||||
>"$RUNTIME_DIRECTORY/api_key"
|
||||
do ${sleep} 1; done
|
||||
(${printf} "X-API-Key: "; ${cat} "$RUNTIME_DIRECTORY/api_key") >"$RUNTIME_DIRECTORY/headers"
|
||||
${curl} -sSLk -H "@$RUNTIME_DIRECTORY/headers" \
|
||||
--retry 1000 --retry-delay 1 --retry-all-errors \
|
||||
"$@"
|
||||
}
|
||||
'' +
|
||||
|
||||
/* Syncthing's rest API for the folders and devices is almost identical.
|
||||
Hence we iterate them using lib.pipe and generate shell commands for both at
|
||||
the same time.
|
||||
*/
|
||||
(lib.pipe {
|
||||
# The attributes below are the only ones that are different for devices /
|
||||
# folders.
|
||||
devs = {
|
||||
new_conf_IDs = map (v: v.id) devices;
|
||||
GET_IdAttrName = "deviceID";
|
||||
override = cfg.overrideDevices;
|
||||
conf = devices;
|
||||
baseAddress = curlAddressArgs "/rest/config/devices";
|
||||
};
|
||||
dirs = {
|
||||
new_conf_IDs = map (v: v.id) folders;
|
||||
GET_IdAttrName = "id";
|
||||
override = cfg.overrideFolders;
|
||||
conf = folders;
|
||||
baseAddress = curlAddressArgs "/rest/config/folders";
|
||||
};
|
||||
} [
|
||||
# Now for each of these attributes, write the curl commands that are
|
||||
# identical to both folders and devices.
|
||||
(mapAttrs (conf_type: s:
|
||||
# We iterate the `conf` list now, and run a curl -X POST command for each, that
|
||||
# should update that device/folder only.
|
||||
lib.pipe s.conf [
|
||||
# Quoting https://docs.syncthing.net/rest/config.html:
|
||||
#
|
||||
# > PUT takes an array and POST a single object. In both cases if a
|
||||
# given folder/device already exists, it’s replaced, otherwise a new
|
||||
# one is added.
|
||||
#
|
||||
# What's not documented, is that using PUT will remove objects that
|
||||
# don't exist in the array given. That's why we use here `POST`, and
|
||||
# only if s.override == true then we DELETE the relevant folders
|
||||
# afterwards.
|
||||
(map (new_cfg: ''
|
||||
curl -d ${
|
||||
lib.escapeShellArg (builtins.toJSON new_cfg)
|
||||
} -X POST ${s.baseAddress}
|
||||
''))
|
||||
(lib.concatStringsSep "\n")
|
||||
]
|
||||
/* If we need to override devices/folders, we iterate all currently configured
|
||||
IDs, via another `curl -X GET`, and we delete all IDs that are not part of
|
||||
the Nix configured list of IDs
|
||||
*/
|
||||
+ lib.optionalString s.override ''
|
||||
stale_${conf_type}_ids="$(curl -X GET ${s.baseAddress} | ${jq} \
|
||||
--argjson new_ids ${
|
||||
lib.escapeShellArg (builtins.toJSON s.new_conf_IDs)
|
||||
} \
|
||||
--raw-output \
|
||||
'[.[].${s.GET_IdAttrName}] - $new_ids | .[]'
|
||||
)"
|
||||
for id in ''${stale_${conf_type}_ids}; do
|
||||
curl -X DELETE ${s.baseAddress}/$id
|
||||
done
|
||||
''))
|
||||
builtins.attrValues
|
||||
(lib.concatStringsSep "\n")
|
||||
]) +
|
||||
/* Now we update the other settings defined in cleanedConfig which are not
|
||||
"folders" or "devices".
|
||||
*/
|
||||
(lib.pipe cleanedConfig [
|
||||
builtins.attrNames
|
||||
(lib.subtractLists [ "folders" "devices" ])
|
||||
(map (subOption: ''
|
||||
curl -X PUT -d ${
|
||||
lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})
|
||||
} ${curlAddressArgs "/rest/config/${subOption}"}
|
||||
''))
|
||||
(lib.concatStringsSep "\n")
|
||||
]) + lib.optionalString (cfg.passwordFile != null) ''
|
||||
syncthing_password=$(${cat} ${cfg.passwordFile})
|
||||
curl -X PATCH -d '{"password": "'$syncthing_password'"}' ${
|
||||
curlAddressArgs "/rest/config/gui"
|
||||
}
|
||||
'' + ''
|
||||
# restart Syncthing if required
|
||||
if curl ${curlAddressArgs "/rest/config/restart-required"} |
|
||||
${jq} -e .requiresRestart > /dev/null; then
|
||||
curl -X POST ${curlAddressArgs "/rest/system/restart"}
|
||||
fi
|
||||
'');
|
||||
|
||||
defaultSyncthingArgs = [
|
||||
"${pkgs.syncthing}/bin/syncthing"
|
||||
"${syncthing}"
|
||||
"-no-browser"
|
||||
"-no-restart"
|
||||
"-no-upgrade"
|
||||
"-gui-address=${if isUnixGui then "unix://" else ""}${cfg.guiAddress}"
|
||||
"-logflags=0"
|
||||
];
|
||||
|
||||
syncthingArgs = defaultSyncthingArgs ++ cfg.extraOptions;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
options = with types; {
|
||||
services.syncthing = {
|
||||
enable = mkEnableOption "Syncthing continuous file synchronization";
|
||||
enable = mkEnableOption ''
|
||||
Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync.
|
||||
Further declarative configuration options only supported on Linux devices.
|
||||
'';
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--gui-apikey=apiKey" ];
|
||||
cert = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Extra command-line arguments to pass to {command}`syncthing`.
|
||||
Path to the `cert.pem` file, which will be copied into Syncthing's
|
||||
config directory.
|
||||
'';
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the `key.pem` file, which will be copied into Syncthing's
|
||||
config directory.
|
||||
'';
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the gui password file.
|
||||
'';
|
||||
};
|
||||
|
||||
overrideDevices = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the devices which are not configured via the
|
||||
[devices](#opt-services.syncthing.settings.devices) option.
|
||||
If set to `false`, devices added via the web
|
||||
interface will persist and will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
|
||||
overrideFolders = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the folders which are not configured via the
|
||||
[folders](#opt-services.syncthing.settings.folders) option.
|
||||
If set to `false`, folders added via the web
|
||||
interface will persist and will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
# global options
|
||||
options = mkOption {
|
||||
default = { };
|
||||
description = ''
|
||||
The options element contains all other global configuration options
|
||||
'';
|
||||
type = submodule ({ name, ... }: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
localAnnounceEnabled = mkOption {
|
||||
type = nullOr bool;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether to send announcements to the local LAN, also use such announcements to find other devices.
|
||||
'';
|
||||
};
|
||||
|
||||
localAnnouncePort = mkOption {
|
||||
type = nullOr int;
|
||||
default = null;
|
||||
description = ''
|
||||
The port on which to listen and send IPv4 broadcast announcements to.
|
||||
'';
|
||||
};
|
||||
|
||||
relaysEnabled = mkOption {
|
||||
type = nullOr bool;
|
||||
default = null;
|
||||
description = ''
|
||||
When true, relays will be connected to and potentially used for device to device connections.
|
||||
'';
|
||||
};
|
||||
|
||||
urAccepted = mkOption {
|
||||
type = nullOr int;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether the user has accepted to submit anonymous usage data.
|
||||
The default, 0, mean the user has not made a choice, and Syncthing will ask at some point in the future.
|
||||
"-1" means no, a number above zero means that that version of usage reporting has been accepted.
|
||||
'';
|
||||
};
|
||||
|
||||
limitBandwidthInLan = mkOption {
|
||||
type = nullOr bool;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether to apply bandwidth limits to devices in the same broadcast domain as the local device.
|
||||
'';
|
||||
};
|
||||
|
||||
maxFolderConcurrency = mkOption {
|
||||
type = nullOr int;
|
||||
default = null;
|
||||
description = ''
|
||||
This option controls how many folders may concurrently be in I/O-intensive operations such as syncing or scanning.
|
||||
The mechanism is described in detail in a [separate chapter](https://docs.syncthing.net/advanced/option-max-concurrency.html).
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
# device settings
|
||||
devices = mkOption {
|
||||
default = { };
|
||||
description = ''
|
||||
Peers/devices which Syncthing should communicate with.
|
||||
|
||||
Note that you can still add devices manually, but those changes
|
||||
will be reverted on restart if [overrideDevices](#opt-services.syncthing.overrideDevices)
|
||||
is enabled.
|
||||
'';
|
||||
example = {
|
||||
bigbox = {
|
||||
id =
|
||||
"7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
|
||||
addresses = [ "tcp://192.168.0.10:51820" ];
|
||||
};
|
||||
};
|
||||
type = attrsOf (submodule ({ name, ... }: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
description = ''
|
||||
The name of the device.
|
||||
'';
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
The device ID. See <https://docs.syncthing.net/dev/device-ids.html>.
|
||||
'';
|
||||
};
|
||||
|
||||
autoAcceptFolders = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Automatically create or share folders that this device advertises at the default path.
|
||||
See <https://docs.syncthing.net/users/config.html?highlight=autoaccept#config-file-format>.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
# folder settings
|
||||
folders = mkOption {
|
||||
default = { };
|
||||
description = ''
|
||||
Folders which should be shared by Syncthing.
|
||||
|
||||
Note that you can still add folders manually, but those changes
|
||||
will be reverted on restart if [overrideFolders](#opt-services.syncthing.overrideFolders)
|
||||
is enabled.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
"/home/user/sync" = {
|
||||
id = "syncme";
|
||||
devices = [ "bigbox" ];
|
||||
};
|
||||
}
|
||||
'';
|
||||
type = attrsOf (submodule ({ name, ... }: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to share this folder.
|
||||
This option is useful when you want to define all folders
|
||||
in one place, but not every machine should share all folders.
|
||||
'';
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = str // {
|
||||
check = x:
|
||||
str.check x
|
||||
&& (substring 0 1 x == "/" || substring 0 2 x == "~/");
|
||||
description = str.description + " starting with / or ~/";
|
||||
};
|
||||
default = name;
|
||||
description = ''
|
||||
The path to the folder which should be shared.
|
||||
Only absolute paths (starting with `/`) and paths relative to
|
||||
the user's home directory (starting with `~/`) are allowed.
|
||||
'';
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
description = ''
|
||||
The ID of the folder. Must be the same on all devices.
|
||||
'';
|
||||
};
|
||||
|
||||
label = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
description = ''
|
||||
The label of the folder.
|
||||
'';
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = enum [
|
||||
"sendreceive"
|
||||
"sendonly"
|
||||
"receiveonly"
|
||||
"receiveencrypted"
|
||||
];
|
||||
default = "sendreceive";
|
||||
description = ''
|
||||
Controls how the folder is handled by Syncthing.
|
||||
See <https://docs.syncthing.net/users/config.html#config-option-folder.type>.
|
||||
'';
|
||||
};
|
||||
|
||||
devices = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
The devices this folder should be shared with. Each device must
|
||||
be defined in the [devices](#opt-services.syncthing.settings.devices) option.
|
||||
'';
|
||||
};
|
||||
|
||||
versioning = mkOption {
|
||||
default = null;
|
||||
description = ''
|
||||
How to keep changed/deleted files with Syncthing.
|
||||
There are 4 different types of versioning with different parameters.
|
||||
See <https://docs.syncthing.net/users/versioning.html>.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
{
|
||||
versioning = {
|
||||
type = "simple";
|
||||
params.keep = "10";
|
||||
};
|
||||
}
|
||||
{
|
||||
versioning = {
|
||||
type = "trashcan";
|
||||
params.cleanoutDays = "1000";
|
||||
};
|
||||
}
|
||||
{
|
||||
versioning = {
|
||||
type = "staggered";
|
||||
fsPath = "/syncthing/backup";
|
||||
params = {
|
||||
cleanInterval = "3600";
|
||||
maxAge = "31536000";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
versioning = {
|
||||
type = "external";
|
||||
params.versionsPath = pkgs.writers.writeBash "backup" '''
|
||||
folderpath="$1"
|
||||
filepath="$2"
|
||||
rm -rf "$folderpath/$filepath"
|
||||
''';
|
||||
};
|
||||
}
|
||||
]
|
||||
'';
|
||||
type = with types;
|
||||
nullOr (submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
type = mkOption {
|
||||
type = enum [
|
||||
"external"
|
||||
"simple"
|
||||
"staggered"
|
||||
"trashcan"
|
||||
];
|
||||
description = ''
|
||||
The type of versioning.
|
||||
See <https://docs.syncthing.net/users/versioning.html>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
copyOwnershipFromParent = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
On Unix systems, tries to copy file/folder ownership from
|
||||
the parent directory (the directory it’s located in).
|
||||
Requires running Syncthing as a privileged user, or
|
||||
granting it additional capabilities (e.g. CAP_CHOWN on
|
||||
Linux).
|
||||
'';
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = ''
|
||||
Extra configuration options for Syncthing.
|
||||
See <https://docs.syncthing.net/users/config.html>.
|
||||
Note that this attribute set does not exactly match the documented
|
||||
XML format. Instead, this is the format of the JSON REST API. There
|
||||
are slight differences. For example, this XML:
|
||||
```xml
|
||||
<options>
|
||||
<listenAddress>default</listenAddress>
|
||||
<minHomeDiskFree unit="%">1</minHomeDiskFree>
|
||||
</options>
|
||||
```
|
||||
corresponds to the Nix code:
|
||||
```nix
|
||||
{
|
||||
options = {
|
||||
listenAddresses = [
|
||||
"default"
|
||||
];
|
||||
minHomeDiskFree = {
|
||||
unit = "%";
|
||||
value = 1;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
'';
|
||||
example = {
|
||||
options.localAnnounceEnabled = false;
|
||||
gui.theme = "black";
|
||||
};
|
||||
};
|
||||
|
||||
guiAddress = mkOption {
|
||||
type = str;
|
||||
default = "127.0.0.1:8384";
|
||||
description = ''
|
||||
The address to serve the web interface at.
|
||||
'';
|
||||
};
|
||||
|
||||
allProxy = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
example = "socks5://address.com:1234";
|
||||
description = ''
|
||||
Overwrites the {env}`all_proxy` environment variable for the Syncthing
|
||||
process to the given value. This is normally used to let Syncthing
|
||||
connect through a SOCKS5 proxy server. See
|
||||
<https://docs.syncthing.net/users/proxying.html>.
|
||||
'';
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
example = [ "--reset-deltas" ];
|
||||
description = ''
|
||||
Extra command-line arguments to pass to {command}`syncthing`
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "syncthing" { };
|
||||
|
||||
tray = mkOption {
|
||||
type = with types;
|
||||
either bool (submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Whether to enable a syncthing tray service.";
|
||||
};
|
||||
|
||||
command = mkOption {
|
||||
type = types.str;
|
||||
type = str;
|
||||
default = "syncthingtray";
|
||||
defaultText = literalExpression "syncthingtray";
|
||||
example = literalExpression "qsyncthingtray";
|
||||
|
@ -50,7 +590,7 @@ in {
|
|||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
type = package;
|
||||
default = pkgs.syncthingtray-minimal;
|
||||
defaultText = literalExpression "pkgs.syncthingtray-minimal";
|
||||
example = literalExpression "pkgs.qsyncthingtray";
|
||||
|
@ -78,10 +618,28 @@ in {
|
|||
};
|
||||
|
||||
Service = {
|
||||
ExecStartPre = mkIf (cfg.cert != null || cfg.key != null) "+${
|
||||
pkgs.writers.writeBash "syncthing-copy-keys" ''
|
||||
syncthing_dir="''${XDG_STATE_HOME:-$HOME/.local/state}/syncthing"
|
||||
${install} -dm700 "$syncthing_dir"
|
||||
${optionalString (cfg.cert != null) ''
|
||||
${install} -Dm400 ${
|
||||
toString cfg.cert
|
||||
} "$syncthing_dir/cert.pem"
|
||||
''}
|
||||
${optionalString (cfg.key != null) ''
|
||||
${install} -Dm400 ${
|
||||
toString cfg.key
|
||||
} "$syncthing_dir/key.pem"
|
||||
''}
|
||||
''
|
||||
}";
|
||||
ExecStart = escapeShellArgs syncthingArgs;
|
||||
Restart = "on-failure";
|
||||
SuccessExitStatus = [ 3 4 ];
|
||||
RestartForceExitStatus = [ 3 4 ];
|
||||
Environment =
|
||||
mkIf (cfg.allProxy != null) { all_proxy = cfg.allProxy; };
|
||||
|
||||
# Sandboxing.
|
||||
LockPersonality = true;
|
||||
|
@ -95,6 +653,23 @@ in {
|
|||
|
||||
Install = { WantedBy = [ "default.target" ]; };
|
||||
};
|
||||
|
||||
syncthing-init = mkIf (cleanedConfig != { }) {
|
||||
Unit = {
|
||||
Description = "Syncthing configuration updater";
|
||||
Requires = [ "syncthing.service" ];
|
||||
After = [ "syncthing.service" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = updateConfig;
|
||||
RuntimeDirectory = "syncthing-init";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
|
||||
Install = { WantedBy = [ "default.target" ]; };
|
||||
};
|
||||
};
|
||||
|
||||
launchd.agents.syncthing = {
|
||||
|
|
|
@ -7,7 +7,7 @@ let
|
|||
cfg = config.services.volnoti;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.imalison ];
|
||||
meta.maintainers = with maintainers; [ imalison tomodachi94 ];
|
||||
|
||||
options = {
|
||||
services.volnoti = {
|
||||
|
@ -37,7 +37,7 @@ in {
|
|||
|
||||
Install = { WantedBy = [ "graphical-session.target" ]; };
|
||||
|
||||
Service = { ExecStart = "${pkgs.volnoti}/bin/volnoti -v -n"; };
|
||||
Service = { ExecStart = "${lib.getExe cfg.package} -v -n"; };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -173,6 +173,7 @@ in import nmtSrc {
|
|||
./modules/xresources
|
||||
] ++ lib.optionals isDarwin [
|
||||
./modules/launchd
|
||||
./modules/services/emacs-darwin
|
||||
./modules/services/espanso-darwin
|
||||
./modules/services/git-sync-darwin
|
||||
./modules/services/imapnotify-darwin
|
||||
|
@ -286,6 +287,7 @@ in import nmtSrc {
|
|||
./modules/services/trayscale
|
||||
./modules/services/twmn
|
||||
./modules/services/udiskie
|
||||
./modules/services/volnoti
|
||||
./modules/services/window-managers/bspwm
|
||||
./modules/services/window-managers/herbstluftwm
|
||||
./modules/services/window-managers/hyprland
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
start_all()
|
||||
|
||||
machine.wait_for_unit("home-manager-alice.service")
|
||||
machine.wait_for_console_text("Finished Home Manager environment for alice.")
|
||||
|
||||
with subtest("Home Manager file"):
|
||||
# The file should be linked with the expected content.
|
||||
|
@ -73,7 +73,7 @@
|
|||
fail_as_alice("pueue status")
|
||||
|
||||
machine.systemctl("restart home-manager-alice.service")
|
||||
machine.wait_for_unit("home-manager-alice.service")
|
||||
machine.wait_for_console_text("Finished Home Manager environment for alice.")
|
||||
|
||||
actual = succeed_as_alice("pueue status")
|
||||
expected = "running"
|
||||
|
|
23
tests/modules/services/emacs-darwin/basic.nix
Normal file
23
tests/modules/services/emacs-darwin/basic.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(self: super: rec {
|
||||
emacs = pkgs.writeShellScriptBin "dummy-emacs-28.0.5" "" // {
|
||||
outPath = "@emacs@";
|
||||
};
|
||||
emacsPackagesFor = _:
|
||||
lib.makeScope super.newScope (_: { emacsWithPackages = _: emacs; });
|
||||
})
|
||||
];
|
||||
|
||||
services.emacs = { enable = true; };
|
||||
|
||||
nmt.script = ''
|
||||
serviceFile=LaunchAgents/org.nix-community.home.emacs.plist
|
||||
|
||||
assertFileExists "$serviceFile"
|
||||
|
||||
assertFileContent "$serviceFile" ${./expected-agent.plist}
|
||||
'';
|
||||
}
|
1
tests/modules/services/emacs-darwin/default.nix
Normal file
1
tests/modules/services/emacs-darwin/default.nix
Normal file
|
@ -0,0 +1 @@
|
|||
{ emacs-service-basic = ./basic.nix; }
|
22
tests/modules/services/emacs-darwin/expected-agent.plist
Normal file
22
tests/modules/services/emacs-darwin/expected-agent.plist
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>KeepAlive</key>
|
||||
<dict>
|
||||
<key>Crashed</key>
|
||||
<true/>
|
||||
<key>SuccessfulExit</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Label</key>
|
||||
<string>org.nix-community.home.emacs</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>@emacs@/bin/emacs</string>
|
||||
<string>--fg-daemon</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -10,7 +10,9 @@ global_vars:
|
|||
matches:
|
||||
- replace: It's {{currentdate}} {{currenttime}}
|
||||
trigger: :now
|
||||
- replace: "line1\nline2"
|
||||
- replace: 'line1
|
||||
|
||||
line2'
|
||||
trigger: :hello
|
||||
- regex: :hi(?P<person>.*)\.
|
||||
replace: Hi {{person}}!
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
{ hypridle-basic-configuration = ./basic-configuration.nix; }
|
||||
{
|
||||
hypridle-basic-configuration = ./basic-configuration.nix;
|
||||
hypridle-no-configuration = ./no-configuration.nix;
|
||||
}
|
||||
|
|
14
tests/modules/services/hypridle/no-configuration.nix
Normal file
14
tests/modules/services/hypridle/no-configuration.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
services.hypridle.enable = true;
|
||||
|
||||
test.stubs.hypridle = { };
|
||||
|
||||
nmt.script = ''
|
||||
config=home-files/.config/hypr/hypridle.conf
|
||||
clientServiceFile=home-files/.config/systemd/user/hypridle.service
|
||||
assertPathNotExists $config
|
||||
assertFileExists $clientServiceFile
|
||||
'';
|
||||
}
|
|
@ -1 +1,4 @@
|
|||
{ hyprpaper-basic-configuration = ./basic-configuration.nix; }
|
||||
{
|
||||
hyprpaper-basic-configuration = ./basic-configuration.nix;
|
||||
hyprpaper-no-configuration = ./no-configuration.nix;
|
||||
}
|
||||
|
|
17
tests/modules/services/hyprpaper/no-configuration.nix
Normal file
17
tests/modules/services/hyprpaper/no-configuration.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
services.hyprpaper = {
|
||||
enable = true;
|
||||
settings = { };
|
||||
};
|
||||
|
||||
test.stubs.hyprpaper = { };
|
||||
|
||||
nmt.script = ''
|
||||
config=home-files/.config/hypr/hyprpaper.conf
|
||||
clientServiceFile=home-files/.config/systemd/user/hyprpaper.service
|
||||
assertPathNotExists $config
|
||||
assertFileExists $clientServiceFile
|
||||
'';
|
||||
}
|
|
@ -29,7 +29,28 @@
|
|||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.config/systemd/user/mopidy.service
|
||||
serviceFile=home-files/.config/systemd/user/mopidy.service
|
||||
assertFileExists $serviceFile
|
||||
serviceFile=$(normalizeStorePaths $serviceFile)
|
||||
assertFileContent $serviceFile \
|
||||
${
|
||||
builtins.toFile "expected-mopidy.service" ''
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/nix/store/00000000000000000000000000000000-mopidy-with-extensions/bin/mopidy --config /home/hm-user/.config/mopidy/mopidy.conf
|
||||
Restart=on-failure
|
||||
|
||||
[Unit]
|
||||
After=network.target
|
||||
After=sound.target
|
||||
Description=mopidy music player daemon
|
||||
Documentation=https://mopidy.com/
|
||||
X-Restart-Triggers=/nix/store/00000000000000000000000000000000-mopidy-hm-user
|
||||
''
|
||||
}
|
||||
|
||||
assertPathNotExists home-files/.config/systemd/user/mopidy-scan.service
|
||||
|
||||
assertFileExists home-files/.config/mopidy/mopidy.conf
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
[network]
|
||||
default_subnet = "172.16.10.0/24"
|
||||
|
||||
[[network.default_subnet_pools]]
|
||||
base = "172.16.11.0/24"
|
||||
size = 24
|
||||
|
||||
[[network.default_subnet_pools]]
|
||||
base = "172.16.12.0/24"
|
||||
size = 24
|
|
@ -0,0 +1 @@
|
|||
{"default":[{"type":"insecureAcceptAnything"}]}
|
|
@ -0,0 +1,8 @@
|
|||
[registries.block]
|
||||
registries = ["ghcr.io", "gallery.ecr.aws"]
|
||||
|
||||
[registries.insecure]
|
||||
registries = ["quay.io"]
|
||||
|
||||
[registries.search]
|
||||
registries = ["docker.io"]
|
|
@ -0,0 +1,4 @@
|
|||
[storage]
|
||||
driver = "overlay"
|
||||
graphroot = "$HOME/.containers/graphroot"
|
||||
runroot = "$HOME/.containers/runroot"
|
63
tests/modules/services/podman-linux/configuration.nix
Normal file
63
tests/modules/services/podman-linux/configuration.nix
Normal file
|
@ -0,0 +1,63 @@
|
|||
{ ... }:
|
||||
|
||||
{
|
||||
services.podman = {
|
||||
enable = true;
|
||||
settings = {
|
||||
containers = {
|
||||
network = {
|
||||
default_subnet = "172.16.10.0/24";
|
||||
default_subnet_pools = [
|
||||
{
|
||||
base = "172.16.11.0/24";
|
||||
size = 24;
|
||||
}
|
||||
{
|
||||
base = "172.16.12.0/24";
|
||||
size = 24;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
storage = {
|
||||
storage = {
|
||||
runroot = "$HOME/.containers/runroot";
|
||||
graphroot = "$HOME/.containers/graphroot";
|
||||
};
|
||||
};
|
||||
registries = {
|
||||
block = [ "ghcr.io" "gallery.ecr.aws" ];
|
||||
insecure = [ "quay.io" ];
|
||||
search = [ "docker.io" ];
|
||||
};
|
||||
policy = { default = [{ type = "insecureAcceptAnything"; }]; };
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
configPath=home-files/.config/containers
|
||||
containersFile=$configPath/containers.conf
|
||||
policyFile=$configPath/policy.json
|
||||
registriesFile=$configPath/registries.conf
|
||||
storageFile=$configPath/storage.conf
|
||||
|
||||
assertFileExists $containersFile
|
||||
assertFileExists $policyFile
|
||||
assertFileExists $registriesFile
|
||||
assertFileExists $storageFile
|
||||
|
||||
containersFile=$(normalizeStorePaths $containersFile)
|
||||
policyFile=$(normalizeStorePaths $policyFile)
|
||||
registriesFile=$(normalizeStorePaths $registriesFile)
|
||||
storageFile=$(normalizeStorePaths $storageFile)
|
||||
|
||||
assertFileContent $containersFile ${
|
||||
./configuration-containers-expected.conf
|
||||
}
|
||||
assertFileContent $policyFile ${./configuration-policy-expected.json}
|
||||
assertFileContent $registriesFile ${
|
||||
./configuration-registries-expected.conf
|
||||
}
|
||||
assertFileContent $storageFile ${./configuration-storage-expected.conf}
|
||||
'';
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
podman-configuration = ./configuration.nix;
|
||||
podman-container = ./container.nix;
|
||||
podman-integration = ./integration.nix;
|
||||
podman-manifest = ./manifest.nix;
|
||||
|
|
|
@ -13,7 +13,7 @@ lib.mkMerge [
|
|||
nmt.script = ''
|
||||
assertFileExists home-files/.config/systemd/user/syncthing.service
|
||||
assertFileContains home-files/.config/systemd/user/syncthing.service \
|
||||
"ExecStart=@syncthing@/bin/syncthing -no-browser -no-restart '-logflags=0' -foo '-bar \"baz\"'"
|
||||
"ExecStart=@syncthing@/bin/syncthing -no-browser -no-restart -no-upgrade '-gui-address=127.0.0.1:8384' '-logflags=0' -foo '-bar \"baz\"'"
|
||||
'';
|
||||
})
|
||||
(lib.mkIf pkgs.stdenv.isDarwin {
|
||||
|
|
1
tests/modules/services/volnoti/default.nix
Normal file
1
tests/modules/services/volnoti/default.nix
Normal file
|
@ -0,0 +1 @@
|
|||
{ volnoti-package-option = ./package-option.nix; }
|
31
tests/modules/services/volnoti/package-option.nix
Normal file
31
tests/modules/services/volnoti/package-option.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
services.volnoti = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage {
|
||||
name = "volnoti";
|
||||
outPath = "@volnoti@";
|
||||
};
|
||||
};
|
||||
|
||||
test.stubs.volnoti = { };
|
||||
|
||||
nmt.script = ''
|
||||
serviceFile=home-files/.config/systemd/user/volnoti.service
|
||||
assertFileExists $serviceFile
|
||||
assertFileContent $serviceFile \
|
||||
${
|
||||
builtins.toFile "expected-volnoti.service" ''
|
||||
[Install]
|
||||
WantedBy=graphical-session.target
|
||||
|
||||
[Service]
|
||||
ExecStart=@volnoti@/bin/volnoti -v -n
|
||||
|
||||
[Unit]
|
||||
Description=volnoti
|
||||
''
|
||||
}
|
||||
'';
|
||||
}
|
Loading…
Add table
Reference in a new issue