stockholm/krebs/3modules/urlwatch.nix

228 lines
5.7 KiB
Nix
Raw Permalink Normal View History

2015-07-11 14:55:22 +00:00
{ config, lib, pkgs, ... }:
# TODO multiple users
# TODO inform about unused caches
# cache = url: "${cfg.dataDir}/.urlwatch/cache/${hashString "sha1" url}"
2023-06-10 10:50:53 +00:00
with import ../../lib/pure.nix { inherit lib; };
2015-07-11 14:55:22 +00:00
let
2015-07-24 09:55:16 +00:00
cfg = config.krebs.urlwatch;
2015-07-11 14:55:22 +00:00
# TODO assert sendmail's existence
out = {
2015-07-24 09:55:16 +00:00
options.krebs.urlwatch = api;
2016-02-14 15:43:44 +00:00
config = lib.mkIf cfg.enable imp;
};
2015-07-11 14:55:22 +00:00
api = {
2015-07-24 09:55:16 +00:00
enable = mkEnableOption "krebs.urlwatch";
2015-07-11 14:55:22 +00:00
dataDir = mkOption {
type = types.str;
default = "/var/lib/urlwatch";
description = ''
Directory where the urlwatch service should store its state.
'';
};
from = mkOption {
type = types.str;
2017-04-12 09:28:10 +00:00
default = "${user.name}@${config.networking.hostName}.r";
2015-07-11 14:55:22 +00:00
description = ''
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.
'';
};
2015-07-11 14:55:22 +00:00
mailto = mkOption {
type = types.str;
2015-07-27 00:39:41 +00:00
default = config.krebs.build.user.mail;
2015-07-11 14:55:22 +00:00
description = ''
Content of the To: header of the generated mails. [AKA recipient :)]
'';
};
onCalendar = mkOption {
type = types.str;
2015-07-27 00:39:41 +00:00
default = "04:23";
2015-07-11 14:55:22 +00:00
description = ''
Run urlwatch at this interval.
The format is described in systemd.time(7), CALENDAR EVENTS.
'';
};
sendmail.enable = mkEnableOption "krebs.urlwatch.sendmail" // {
default = true;
};
telegram = {
enable = mkEnableOption "krebs.urlwatch.telegram";
botToken = mkOption {
type = types.str;
};
chatId = mkOption {
type = types.listOf types.str;
};
};
2015-07-11 14:55:22 +00:00
urls = mkOption {
type = with types; listOf (either str subtypes.job);
2015-07-27 00:39:41 +00:00
default = [];
2015-07-11 14:55:22 +00:00
description = "URL to watch.";
example = [
https://nixos.org/channels/nixos-unstable/git-revision
{ url = http://localhost ; filter = [ (grep "important.*stuff") ]; }
2015-07-11 14:55:22 +00:00
];
apply = map (x: getAttr (typeOf x) {
set = x;
2019-08-13 07:41:55 +00:00
string.url = x;
});
2015-07-11 14:55:22 +00:00
};
2015-10-25 23:04:15 +00:00
verbose = mkOption {
type = types.bool;
default = false;
description = ''
verbose output of urlwatch
'';
};
2015-07-11 14:55:22 +00:00
};
urlsFile = pkgs.writeText "urls"
(concatMapStringsSep "\n---\n"
(x: toJSON (filterAttrs (n: v: n != "_module") x)) cfg.urls);
hooksFile = cfg.hooksFile;
2019-08-13 07:44:26 +00:00
configFile = pkgs.writeJSON "urlwatch.yaml" {
display = {
error = true;
new = true;
unchanged = false;
};
report = {
email = {
enabled = false;
from = "";
html = false;
smtp = {
host = "localhost";
keyring = true;
port = 25;
starttls = true;
};
subject = "{count} changes: {jobs}";
to = "";
};
html.diff = "unified";
stdout = {
color = true;
enabled = true;
};
${if cfg.telegram.enable then "telegram" else null} = {
enabled = cfg.telegram.enable;
bot_token = cfg.telegram.botToken;
chat_id = cfg.telegram.chatId;
};
text = {
details = true;
footer = true;
line_length = 75;
};
};
2019-08-13 07:44:26 +00:00
};
2015-07-11 14:55:22 +00:00
imp = {
2015-07-11 14:55:22 +00:00
systemd.timers.urlwatch = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.onCalendar;
Persistent = "true";
};
};
systemd.services.urlwatch = {
path = with pkgs; [
coreutils
gnused
urlwatch
];
environment = {
HOME = cfg.dataDir;
LC_ALL = "en_US.UTF-8";
LOCALE_ARCHIVE = "${pkgs.glibcLocales}/lib/locale/locale-archive";
2015-08-26 15:10:02 +00:00
SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
2015-07-11 14:55:22 +00:00
};
serviceConfig = {
2015-07-22 17:25:51 +00:00
User = user.name;
2015-07-11 14:55:22 +00:00
PermissionsStartOnly = "true";
PrivateTmp = "true";
SyslogIdentifier = "urlwatch";
2015-07-11 14:55:22 +00:00
Type = "oneshot";
ExecStart = pkgs.writeDash "urlwatch" ''
2015-07-11 14:55:22 +00:00
set -euf
cd /tmp
urlwatch \
${optionalString cfg.verbose "-v"} \
--config=${shell.escape configFile} \
${optionalString (hooksFile != null)
"--hooks=${shell.escape hooksFile}"
} \
--urls=${shell.escape urlsFile} \
> changes || :
2015-07-11 14:55:22 +00:00
${optionalString cfg.sendmail.enable /* sh */ ''
2019-07-09 18:29:41 +00:00
if test -s changes; then
{
echo Date: $(date -R)
echo From: ${shell.escape cfg.from}
echo Subject: $(
sed -nr 's/^(CHANGED|ERROR|NEW): //p' changes |
sed '1!s/^ //'
2019-07-09 18:29:41 +00:00
)
echo To: ${shell.escape cfg.mailto}
echo Mime-Version: 1.0
echo Content-Type: text/plain\; charset=UTF-8
echo Content-Transfer-Encoding: base64
2019-07-09 18:29:41 +00:00
echo
base64 changes
2019-07-09 18:29:41 +00:00
} | /run/wrappers/bin/sendmail -t
fi
''}
2015-07-11 14:55:22 +00:00
'';
};
};
users.users.${user.name} = {
inherit (user) uid;
home = cfg.dataDir;
createHome = true;
2021-06-05 13:52:49 +00:00
isSystemUser = true;
2021-12-04 21:20:50 +00:00
group = user.name;
2015-07-22 17:25:51 +00:00
};
2021-12-04 21:20:50 +00:00
users.groups.${user.name} = {};
2015-07-11 14:55:22 +00:00
};
2015-12-26 04:55:13 +00:00
user = rec {
2015-07-22 17:25:51 +00:00
name = "urlwatch";
uid = genid_uint31 name;
2015-07-22 17:25:51 +00:00
};
subtypes.job = types.submodule {
options = {
url = mkOption {
type = types.str;
};
filter = mkOption {
2019-08-13 07:41:55 +00:00
default = null;
type =
with types;
nullOr (either str (listOf (pkgs.formats.json {}).type));
};
2019-08-13 07:42:14 +00:00
ignore_cached = mkOption {
default = null;
type = with types; nullOr bool;
};
};
};
in out