diff options
Diffstat (limited to 'krebs/3modules')
-rw-r--r-- | krebs/3modules/backup.nix | 23 | ||||
-rw-r--r-- | krebs/3modules/build.nix | 132 | ||||
-rw-r--r-- | krebs/3modules/default.nix | 40 | ||||
-rw-r--r-- | krebs/3modules/exim-retiolum.nix | 36 | ||||
-rw-r--r-- | krebs/3modules/exim-smarthost.nix | 42 | ||||
-rw-r--r-- | krebs/3modules/git.nix | 6 | ||||
-rw-r--r-- | krebs/3modules/lass/default.nix | 2 | ||||
-rw-r--r-- | krebs/3modules/lib.nix | 2 | ||||
-rw-r--r-- | krebs/3modules/makefu/default.nix | 2 | ||||
-rw-r--r-- | krebs/3modules/miefda/default.nix | 2 | ||||
-rw-r--r-- | krebs/3modules/mv/default.nix | 2 | ||||
-rw-r--r-- | krebs/3modules/secret.nix | 39 | ||||
-rw-r--r-- | krebs/3modules/shared/default.nix | 1 | ||||
-rw-r--r-- | krebs/3modules/tv/default.nix | 7 | ||||
-rw-r--r-- | krebs/3modules/urlwatch.nix | 69 |
15 files changed, 252 insertions, 153 deletions
diff --git a/krebs/3modules/backup.nix b/krebs/3modules/backup.nix index 0aa86dec9..97082f56a 100644 --- a/krebs/3modules/backup.nix +++ b/krebs/3modules/backup.nix @@ -117,6 +117,14 @@ let "$dst_user@$dst_host" \ -T "$with_dst_path_lock_script" } + rsh="ssh -F /dev/null -i $identity ''${dst_port:+-p $dst_port}" + local_rsync() { + rsync "$@" + } + remote_rsync=${shell.escape (concatStringsSep " && " [ + "mkdir -m 0700 -p ${shell.escape plan.dst.path}/current" + "exec flock -n ${shell.escape plan.dst.path} rsync" + ])} ''; pull = '' identity=${shell.escape plan.dst.host.ssh.privkey.path} @@ -131,6 +139,12 @@ let dst_shell() { eval "$with_dst_path_lock_script" } + rsh="ssh -F /dev/null -i $identity ''${src_port:+-p $src_port}" + local_rsync() { + mkdir -m 0700 -p ${shell.escape plan.dst.path}/current + flock -n ${shell.escape plan.dst.path} rsync "$@" + } + remote_rsync=rsync ''; }} # Note that this only works because we trust date +%s to produce output @@ -140,13 +154,10 @@ let with_dst_path_lock_script="exec env start_date=$(date +%s) "${shell.escape "flock -n ${shell.escape plan.dst.path} /bin/sh" } - rsync >&2 \ + local_rsync >&2 \ -aAXF --delete \ - -e "ssh -F /dev/null -i $identity ''${dst_port:+-p $dst_port}" \ - --rsync-path ${shell.escape (concatStringsSep " && " [ - "mkdir -m 0700 -p ${shell.escape plan.dst.path}/current" - "exec flock -n ${shell.escape plan.dst.path} rsync" - ])} \ + --rsh="$rsh" \ + --rsync-path="$remote_rsync" \ --link-dest="$dst_path/current" \ "$src/" \ "$dst/.partial" diff --git a/krebs/3modules/build.nix b/krebs/3modules/build.nix index a1f446188..d4c6b08df 100644 --- a/krebs/3modules/build.nix +++ b/krebs/3modules/build.nix @@ -20,35 +20,19 @@ let type = types.user; }; - options.krebs.build.source = let - raw = types.either types.str types.path; - url = types.submodule { + options.krebs.build.source = mkOption { + type = with types; attrsOf (either str (submodule { options = { - url = mkOption { - type = types.str; - }; - rev = mkOption { - type = types.str; - }; - dev = mkOption { - type = types.str; - }; + url = str; + rev = str; }; - }; - in mkOption { - type = types.attrsOf (types.either types.str url); - apply = let f = mapAttrs (_: value: { - string = value; - path = toString value; - set = f value; - }.${typeOf value}); in f; + })); default = {}; }; options.krebs.build.populate = mkOption { type = types.str; default = let - source = config.krebs.build.source; target-user = maybeEnv "target_user" "root"; target-host = maybeEnv "target_host" config.krebs.build.host.name; target-port = maybeEnv "target_port" "22"; @@ -57,13 +41,16 @@ let #! /bin/sh set -eu + ssh=''${ssh-ssh} + verbose() { - printf '+%s\n' "$(printf ' %q' "$@")" >&2 + printf '%s%s\n' "$PS5$(printf ' %q' "$@")" >&2 "$@" } - echo ${shell.escape git-script} \ - | ssh -p ${shell.escape target-port} \ + { printf 'PS5=%q%q\n' @ "$PS5" + echo ${shell.escape git-script} + } | verbose $ssh -p ${shell.escape target-port} \ ${shell.escape "${target-user}@${target-host}"} -T unset tmpdir @@ -75,61 +62,34 @@ let tmpdir=$(mktemp -dt stockholm.XXXXXXXX) chmod 0755 "$tmpdir" - ${concatStringsSep "\n" - (mapAttrsToList - (name: spec: let dst = removePrefix "symlink:" (get-url spec); in - "verbose ln -s ${shell.escape dst} $tmpdir/${shell.escape name}") - symlink-specs)} + ${concatStringsSep "\n" (mapAttrsToList (name: symlink: '' + verbose ln -s ${shell.escape symlink.target} \ + "$tmpdir"/${shell.escape name} + '') source-by-method.symlink)} verbose proot \ - -b $tmpdir:${shell.escape target-path} \ - ${concatStringsSep " \\\n " - (mapAttrsToList - (name: spec: - "-b ${shell.escape "${get-url spec}:${target-path}/${name}"}") - file-specs)} \ + -b "$tmpdir":${shell.escape target-path} \ + ${concatStringsSep " \\\n " (mapAttrsToList (name: file: + "-b ${shell.escape "${file.path}:${target-path}/${name}"}" + ) source-by-method.file)} \ rsync \ -f ${shell.escape "P /*"} \ - ${concatMapStringsSep " \\\n " - (name: "-f ${shell.escape "R /${name}"}") - (attrNames file-specs)} \ + ${concatMapStringsSep " \\\n " (name: + "-f ${shell.escape "R /${name}"}" + ) (attrNames source-by-method.file)} \ --delete \ -vFrlptD \ - -e ${shell.escape "ssh -p ${target-port}"} \ + -e "$ssh -p ${shell.escape target-port}" \ ${shell.escape target-path}/ \ ${shell.escape "${target-user}@${target-host}:${target-path}"} ''; - get-schema = uri: - if substring 0 1 uri == "/" - then "file" - else head (splitString ":" uri); - - has-schema = schema: uri: get-schema uri == schema; - - get-url = spec: { - string = spec; - path = toString spec; - set = get-url spec.url; - }.${typeOf spec}; - - git-specs = - filterAttrs (_: spec: has-schema "https" (get-url spec)) source // - filterAttrs (_: spec: has-schema "http" (get-url spec)) source // - filterAttrs (_: spec: has-schema "git" (get-url spec)) source; - - file-specs = - filterAttrs (_: spec: has-schema "file" (get-url spec)) source; - - symlink-specs = - filterAttrs (_: spec: has-schema "symlink" (get-url spec)) source; - git-script = '' #! /bin/sh set -efu verbose() { - printf '+%s\n' "$(printf ' %q' "$@")" >&2 + printf '%s%s\n' "$PS5$(printf ' %q' "$@")" >&2 "$@" } @@ -156,26 +116,48 @@ let if ! test "$(git log --format=%H -1)" = "$hash"; then git fetch origin git checkout "$hash" -- "$dst_dir" - git checkout "$hash" + git checkout -f "$hash" fi git clean -dxf )} - ${concatStringsSep "\n" - (mapAttrsToList - (name: spec: toString (map shell.escape [ - "verbose" - "fetch_git" - "${target-path}/${name}" - spec.url - spec.rev - ])) - git-specs)} + ${concatStringsSep "\n" (mapAttrsToList (name: git: '' + verbose fetch_git ${concatMapStringsSep " " shell.escape [ + "${target-path}/${name}" + git.url + git.rev + ]} + '') source-by-method.git)} ''; in out; }; }; + source-by-method = let + known-methods = ["git" "file" "symlink"]; + in genAttrs known-methods (const {}) // recursiveUpdate source-by-scheme { + git = source-by-scheme.http or {} // + source-by-scheme.https or {}; + }; + + source-by-scheme = foldl' (out: { k, v }: recursiveUpdate out { + ${v.scheme}.${k} = v; + }) {} (mapAttrsToList (k: v: { inherit k v; }) normalized-source); + + normalized-source = mapAttrs (name: let f = x: getAttr (typeOf x) { + path = f (toString x); + string = f { + url = if substring 0 1 x == "/" then "file://${x}" else x; + }; + set = let scheme = head (splitString ":" x.url); in recursiveUpdate x { + inherit scheme; + } // { + symlink.target = removePrefix "symlink:" x.url; + file.path = # TODO file://host/... + assert hasPrefix "file:///" x.url; + removePrefix "file://" x.url; + }.${scheme} or {}; + }; in f) config.krebs.build.source; in out diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix index c06f3754e..186469e97 100644 --- a/krebs/3modules/default.nix +++ b/krebs/3modules/default.nix @@ -28,6 +28,7 @@ let ./realwallpaper.nix ./retiolum-bootstrap.nix ./retiolum.nix + ./secret.nix ./setuid.nix ./tinc_graphs.nix ./urlwatch.nix @@ -42,9 +43,7 @@ let dns = { providers = mkOption { - # TODO with types; tree dns.label dns.provider, so we can merge. - # Currently providers can only be merged if aliases occur just once. - type = with types; attrsOf unspecified; + type = with types; attrsOf str; }; }; @@ -94,7 +93,7 @@ let { krebs = import ./tv { inherit config lib; }; } { krebs.dns.providers = { - de.krebsco = "zones"; + "krebsco.de" = "zones"; gg23 = "hosts"; shack = "hosts"; i = "hosts"; @@ -103,13 +102,27 @@ let retiolum = "hosts"; }; - networking.extraHosts = concatStringsSep "\n" (flatten ( + krebs.users = { + krebs = { + home = "/krebs"; + mail = "spam@krebsco.de"; + }; + root = { + home = "/root"; + pubkey = config.krebs.build.host.ssh.pubkey; + uid = 0; + }; + }; + + networking.extraHosts = let + domains = attrNames (filterAttrs (_: eq "hosts") cfg.dns.providers); + check = hostname: any (domain: hasSuffix ".${domain}" hostname) domains; + in concatStringsSep "\n" (flatten ( mapAttrsToList (hostname: host: mapAttrsToList (netname: net: let aliases = longs ++ shorts; - providers = dns.split-by-provider net.aliases cfg.dns.providers; - longs = providers.hosts; + longs = filter check net.aliases; shorts = let s = ".${cfg.search-domain}"; in map (removeSuffix s) (filter (hasSuffix s) longs); in @@ -130,12 +143,11 @@ let { text=(stripEmptyLines value); }) all-zones; krebs.exim-smarthost.internet-aliases = let - format = from: to: + format = from: to: { + inherit from; # TODO assert is-retiolum-mail-address to; - { inherit from; - to = if typeOf to == "list" - then concatMapStringsSep "," (getAttr "mail") to - else to.mail; }; + to = concatMapStringsSep "," (getAttr "mail") (toList to); + }; in mapAttrsToList format (with config.krebs.users; let spam-ml = [ lass @@ -154,6 +166,10 @@ let "makefu@retiolum" = makefu; "spam@retiolum" = spam-ml; "tv@retiolum" = tv; + "lass@r" = lass; + "makefu@r" = makefu; + "spam@r" = spam-ml; + "tv@r" = tv; }); services.openssh.hostKeys = diff --git a/krebs/3modules/exim-retiolum.nix b/krebs/3modules/exim-retiolum.nix index 1722eef1f..6e6928f89 100644 --- a/krebs/3modules/exim-retiolum.nix +++ b/krebs/3modules/exim-retiolum.nix @@ -11,6 +11,24 @@ let api = { enable = mkEnableOption "krebs.exim-retiolum"; + local_domains = mkOption { + type = with types; listOf hostname; + default = ["localhost"] ++ config.krebs.build.host.nets.retiolum.aliases; + }; + primary_hostname = mkOption { + type = types.str; + default = let x = "${config.krebs.build.host.name}.r"; in + assert elem x config.krebs.build.host.nets.retiolum.aliases; + x; + }; + relay_to_domains = mkOption { + # TODO hostname with wildcards + type = with types; listOf str; + default = [ + "*.r" + "*.retiolum" + ]; + }; }; imp = { @@ -21,9 +39,9 @@ let # TODO modular configuration assert config.krebs.retiolum.enable; '' - primary_hostname = ${retiolumHostname} - domainlist local_domains = @ : localhost - domainlist relay_to_domains = *.retiolum + primary_hostname = ${cfg.primary_hostname} + domainlist local_domains = ${concatStringsSep ":" cfg.local_domains} + domainlist relay_to_domains = ${concatStringsSep ":" cfg.relay_to_domains} hostlist relay_from_hosts = <; 127.0.0.1 ; ::1 acl_smtp_rcpt = acl_check_rcpt @@ -85,7 +103,7 @@ let retiolum: driver = manualroute - domains = ! ${retiolumHostname} : *.retiolum + domains = ! +local_domains : +relay_to_domains transport = remote_smtp route_list = ^.* $0 byname no_more @@ -125,8 +143,8 @@ let # mode = 0660 begin retry - *.retiolum * F,42d,1m - * * F,2h,15m; G,16h,1h,1.5; F,4d,6h + ${concatMapStringsSep "\n" (k: "${k} * F,42d,1m") cfg.relay_to_domains} + * * F,2h,15m; G,16h,1h,1.5; F,4d,6h begin rewrite @@ -134,8 +152,4 @@ let ''; }; }; - - # TODO get the hostname from somewhere else. - retiolumHostname = "${config.networking.hostName}.retiolum"; -in -out +in out diff --git a/krebs/3modules/exim-smarthost.nix b/krebs/3modules/exim-smarthost.nix index 267ee2900..c976e89de 100644 --- a/krebs/3modules/exim-smarthost.nix +++ b/krebs/3modules/exim-smarthost.nix @@ -25,14 +25,31 @@ let })); }; + local_domains = mkOption { + type = with types; listOf hostname; + default = ["localhost"] ++ config.krebs.build.host.nets.retiolum.aliases; + }; + relay_from_hosts = mkOption { type = with types; listOf str; default = []; + apply = xs: ["127.0.0.1" "::1"] ++ xs; + }; + + relay_to_domains = mkOption { + # TODO hostname with wildcards + type = with types; listOf str; + default = [ + "*.r" + "*.retiolum" + ]; }; primary_hostname = mkOption { type = types.str; - default = "${config.networking.hostName}.retiolum"; + default = let x = "${config.krebs.build.host.name}.r"; in + assert elem x config.krebs.build.host.nets.retiolum.aliases; + x; }; sender_domains = mkOption { @@ -63,19 +80,11 @@ let # HOST_REDIR contains the real destinations for "local_domains". #HOST_REDIR = /etc/exim4/host_redirect - # Domains not listed in local_domains need to be deliverable remotely. # XXX We abuse local_domains to mean "domains, we're the gateway for". - domainlist local_domains = @ : localhost - domainlist relay_to_domains = - hostlist relay_from_hosts = <;${concatStringsSep ";" ( - [ - "127.0.0.1" - "::1" - ] - ++ - cfg.relay_from_hosts - )} + domainlist local_domains = ${concatStringsSep ":" cfg.local_domains} + domainlist relay_to_domains = ${concatStringsSep ":" cfg.relay_to_domains} + hostlist relay_from_hosts = <;${concatStringsSep ";" cfg.relay_from_hosts} acl_smtp_rcpt = acl_check_rcpt acl_smtp_data = acl_check_data @@ -144,7 +153,7 @@ let retiolum: debug_print = "R: retiolum for $local_part@$domain" driver = manualroute - domains = ! ${cfg.primary_hostname} : *.retiolum + domains = ! +local_domains : +relay_to_domains transport = retiolum_smtp route_list = ^.* $0 byname no_more @@ -197,8 +206,11 @@ let return_path_add begin retry - *.retiolum * F,42d,1m - * * F,2h,15m; G,16h,1h,1.5; F,4d,6h + ${concatMapStringsSep "\n" (k: "${k} * F,42d,1m") cfg.relay_to_domains} + ${concatMapStringsSep "\n" (k: "${k} * F,42d,1m") + # TODO don't include relay_to_domains + (map (getAttr "from") cfg.internet-aliases)} + * * F,2h,15m; G,16h,1h,1.5; F,4d,6h begin rewrite begin authenticators diff --git a/krebs/3modules/git.nix b/krebs/3modules/git.nix index a9542718d..0cc2f11c9 100644 --- a/krebs/3modules/git.nix +++ b/krebs/3modules/git.nix @@ -232,13 +232,15 @@ let ]) (filter (rule: rule.perm.allow-receive-ref != null) cfg.rules)); }; - users.extraUsers = singleton rec { + # TODO cfg.user + users.users.git = rec { description = "Git repository hosting user"; name = "git"; shell = "/bin/sh"; openssh.authorizedKeys.keys = mapAttrsToList (_: makeAuthorizedKey git-ssh-command) - config.krebs.users; + (filterAttrs (_: user: isString user.pubkey) + config.krebs.users); uid = genid name; }; }; diff --git a/krebs/3modules/lass/default.nix b/krebs/3modules/lass/default.nix index 41a609105..4bf10ac56 100644 --- a/krebs/3modules/lass/default.nix +++ b/krebs/3modules/lass/default.nix @@ -3,7 +3,7 @@ with config.krebs.lib; { - hosts = { + hosts = mapAttrs (_: setAttr "owner" config.krebs.users.lass) { dishfire = { cores = 4; nets = rec { diff --git a/krebs/3modules/lib.nix b/krebs/3modules/lib.nix index b19f275b5..ccd6a6afa 100644 --- a/krebs/3modules/lib.nix +++ b/krebs/3modules/lib.nix @@ -10,6 +10,6 @@ let type = types.attrs; }; imp = { - krebs.lib = lib // import ../4lib { inherit lib; } // builtins; + krebs.lib = lib // import ../4lib { inherit config lib; } // builtins; }; in out diff --git a/krebs/3modules/makefu/default.nix b/krebs/3modules/makefu/default.nix index 6af77ad9b..d309c1714 100644 --- a/krebs/3modules/makefu/default.nix +++ b/krebs/3modules/makefu/default.nix @@ -3,7 +3,7 @@ with config.krebs.lib; { - hosts = { + hosts = mapAttrs (_: setAttr "owner" config.krebs.users.makefu) { pnp = { cores = 1; nets = { diff --git a/krebs/3modules/miefda/default.nix b/krebs/3modules/miefda/default.nix index 6587ad92d..9a5866294 100644 --- a/krebs/3modules/miefda/default.nix +++ b/krebs/3modules/miefda/default.nix @@ -3,7 +3,7 @@ with config.krebs.lib; { - hosts = { + hosts = mapAttrs (_: setAttr "owner" config.krebs.users.miefda) { bobby = { cores = 4; nets = { diff --git a/krebs/3modules/mv/default.nix b/krebs/3modules/mv/default.nix index 33f941aae..3b4001e7a 100644 --- a/krebs/3modules/mv/default.nix +++ b/krebs/3modules/mv/default.nix @@ -3,7 +3,7 @@ with config.krebs.lib; { - hosts = { + hosts = mapAttrs (_: setAttr "owner" config.krebs.users.mv) { stro = { cores = 4; nets = { diff --git a/krebs/3modules/secret.nix b/krebs/3modules/secret.nix new file mode 100644 index 000000000..579f375f3 --- /dev/null +++ b/krebs/3modules/secret.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }@args: with config.krebs.lib; let + cfg = config.krebs.secret; +in { + options.krebs.secret = { + files = mkOption { + type = with types; attrsOf secret-file; + default = {}; + }; + }; + config = lib.mkIf (cfg.files != {}) { + systemd.services.secret = let + # TODO fail if two files have the same path but differ otherwise + files = unique (map (flip removeAttrs ["_module"]) + (attrValues cfg.files)); + in { + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + SyslogIdentifier = "secret"; + ExecStart = pkgs.writeDash "install-secret-files" '' + exit_code=0 + ${concatMapStringsSep "\n" (file: '' + ${pkgs.coreutils}/bin/install \ + -D \ + --compare \ + --verbose \ + --mode=${shell.escape file.mode} \ + --owner=${shell.escape file.owner.name} \ + --group=${shell.escape file.group-name} \ + ${shell.escape file.source-path} \ + ${shell.escape file.path} \ + || exit_code=1 + '') files} + exit $exit_code + ''; + }; + }; + }; +} diff --git a/krebs/3modules/shared/default.nix b/krebs/3modules/shared/default.nix index 208b596f8..ccd15b569 100644 --- a/krebs/3modules/shared/default.nix +++ b/krebs/3modules/shared/default.nix @@ -15,6 +15,7 @@ let addrs4 = ["10.243.111.111"]; addrs6 = ["42:0:0:0:0:0:0:7357"]; aliases = [ + "test.r" "test.retiolum" ]; tinc.pubkey = '' diff --git a/krebs/3modules/tv/default.nix b/krebs/3modules/tv/default.nix index f8d3d8671..533502914 100644 --- a/krebs/3modules/tv/default.nix +++ b/krebs/3modules/tv/default.nix @@ -4,9 +4,9 @@ with config.krebs.lib; { dns.providers = { - de.viljetic = "regfish"; + "viljetic.de" = "regfish"; }; - hosts = { + hosts = mapAttrs (_: setAttr "owner" config.krebs.users.tv) { cd = rec { cores = 2; extraZones = { @@ -352,8 +352,9 @@ with config.krebs.lib; pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGer9e2+Lew7vnisgBbsFNECEIkpNJgEaqQqgb9inWkQ mv@vod"; }; tv = { - mail = "tv@wu.retiolum"; + mail = "tv@nomic.retiolum"; pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAEAQDFR//RnCvEZAt0F6ExDsatKZ/DDdifanuSL360mqOhaFieKI34RoOwfQT9T+Ga52Vh5V2La6esvlph686EdgzeKLvDoxEwFM9ZYFBcMrNzu4bMTlgE7YUYw5JiORyXNfznBGnme6qpuvx9ibYhUyiZo99kM8ys5YrUHrP2JXQJMezDFZHxT4GFMOuSdh/1daGoKKD6hYL/jEHX8CI4E3BSmKK6ygYr1fVX0K0Tv77lIi5mLXucjR7CytWYWYnhM6DC3Hxpv2zRkPgf3k0x/Y1hrw3V/r0Me5h90pd2C8pFaWA2ZoUT/fmyVqvx1tZPYToU/O2dMItY0zgx2kR0yD+6g7Aahz3R+KlXkV8k5c8bbTbfGnZWDR1ZlbLRM9Yt5vosfwapUD90MmVkpmR3wUkO2sUKi80QfC7b4KvSDXQ+MImbGxMaU5Bnsq1PqLN95q+uat3nlAVBAELkcx51FlE9CaIS65y4J7FEDg8BE5JeuCNshh62VSYRXVSFt8bk3f/TFGgzC8OIo14BhVmiRQQ503Z1sROyf5xLX2a/EJavMm1i2Bs2TH6ROKY9z5Pz8hT5US0r381V8oG7TZyLF9HTtoy3wCYsgWA5EmLanjAsVU2YEeAA0rxzdtYP8Y2okFiJ6u+M4HQZ3Wg3peSodyp3vxdYce2vk4EKeqEFuuS82850DYb7Et7fmp+wQQUT8Q/bMO0DreWjHoMM5lE4LJ4ME6AxksmMiFtfo/4Fe2q9D+LAqZ+ANOcv9M+8Rn6ngiYmuRNd0l/a02q1PEvO6vTfXgcl4f7Z1IULHPEaDNZHCJS1K5RXYFqYQ6OHsTmOm7hnwaRAS97+VFMo1i5uvTx9nYaAcY7yzq3Ckfb67dMBKApGOpJpkvPgfrP7bgBO5rOZXM1opXqVPb09nljAhhAhyCTh1e/8+mJrBo0cLQ/LupQzVxGDgm3awSMPxsZAN45PSWz76zzxdDa1MMo51do+VJHfs7Wl0NcXAQrniOBYL9Wqt0qNkn1gY5smkkISGeQ/vxNap4MmzeZE7b5fpOy+2fpcRVQLpc4nooQzJvSVTFz+25lgZ6iHf45K87gQFMIAri1Pf/EDDpL87az+bRWvWi+BA2kMe1kf+Ay1LyMz8r+g51H0ma0bNFh6+fbWMfUiD9JCepIObclnUJ4NlWfcgHxTf17d/4tl6z4DTcLpCCk8Da77JouSHgvtcRbRlFV1OfhWZLXUsrlfpaQTiItv6TGIr3k7+7b66o3Qw/GQVs5GmYifaIZIz8n8my4XjkaMBd0SZfBzzvFjHMq6YUP9+SbjvReqofuoO+5tW1wTYZXitFFBfwuHlXm6w77K5QDBW6olT7pat41/F5eGxLcz tv@wu"; + uid = 1337; # TODO use default }; tv-nomic = { inherit (tv) mail; diff --git a/krebs/3modules/urlwatch.nix b/krebs/3modules/urlwatch.nix index cd4976a21..ed1a21260 100644 --- a/krebs/3modules/urlwatch.nix +++ b/krebs/3modules/urlwatch.nix @@ -3,7 +3,6 @@ # TODO multiple users # TODO inform about unused caches # cache = url: "${cfg.dataDir}/.urlwatch/cache/${hashString "sha1" url}" -# TODO hooks.py with config.krebs.lib; let @@ -32,6 +31,14 @@ let Content of the From: header of the generated mails. ''; }; + # TODO hooks :: attrsOf hook + hooksFile = mkOption { + type = with types; nullOr path; + default = null; + description = '' + File to use as hooks.py module. + ''; + }; mailto = mkOption { type = types.str; default = config.krebs.build.user.mail; @@ -48,7 +55,7 @@ let ''; }; urls = mkOption { - type = with types; listOf str; + type = with types; listOf (either str subtypes.job); default = []; description = "URL to watch."; example = [ @@ -56,7 +63,10 @@ let ]; apply = map (x: getAttr (typeOf x) { set = x; - string.url = x; + string = { + url = x; + filter = null; + }; }); }; verbose = mkOption { @@ -68,9 +78,12 @@ let }; }; - urlsFile = toFile "urls" (concatMapStringsSep "\n---\n" toJSON cfg.urls); + urlsFile = pkgs.writeText "urls" + (concatMapStringsSep "\n---\n" toJSON cfg.urls); + + hooksFile = cfg.hooksFile; - configFile = toFile "urlwatch.yaml" (toJSON { + configFile = pkgs.writeText "urlwatch.yaml" (toJSON { display = { error = true; new = true; @@ -127,10 +140,10 @@ let User = user.name; PermissionsStartOnly = "true"; PrivateTmp = "true"; + SyslogIdentifier = "urlwatch"; Type = "oneshot"; ExecStartPre = - pkgs.writeScript "urlwatch-prestart" '' - #! /bin/sh + pkgs.writeDash "urlwatch-prestart" '' set -euf dataDir=$HOME @@ -140,31 +153,29 @@ let chown ${user.name}: "$dataDir" fi ''; - ExecStart = pkgs.writeScript "urlwatch" '' - #! /bin/sh + ExecStart = pkgs.writeDash "urlwatch" '' set -euf - from=${escapeShellArg cfg.from} - mailto=${escapeShellArg cfg.mailto} - urlsFile=${escapeShellArg urlsFile} - configFile=${escapeShellArg configFile} cd /tmp urlwatch \ ${optionalString cfg.verbose "-v"} \ - --urls="$urlsFile" \ - --config="$configFile" \ + --config=${shell.escape configFile} \ + ${optionalString (hooksFile != null) + "--hooks=${shell.escape hooksFile}" + } \ + --urls=${shell.escape urlsFile} \ > changes || : if test -s changes; then - date=$(date -R) - subject=$(sed -n 's/^\(CHANGED\|ERROR\|NEW\): //p' changes \ - | tr \\n \ ) { - echo "Date: $date" - echo "From: $from" - echo "Subject: $subject" - echo "To: $mailto" + echo Date: $(date -R) + echo From: ${shell.escape cfg.from} + echo Subject: $( + sed -n 's/^\(CHANGED\|ERROR\|NEW\): //p' changes \ + | tr '\n' ' ' + ) + echo To: ${shell.escape cfg.mailto} echo cat changes } | /var/setuid-wrappers/sendmail -t @@ -181,5 +192,15 @@ let name = "urlwatch"; uid = genid name; }; -in -out + + subtypes.job = types.submodule { + options = { + url = mkOption { + type = types.str; + }; + filter = mkOption { + type = with types; nullOr str; # TODO nullOr subtypes.filter + }; + }; + }; +in out |