summaryrefslogtreecommitdiffstats
path: root/3modules
diff options
context:
space:
mode:
Diffstat (limited to '3modules')
-rw-r--r--3modules/krebs/default.nix168
-rw-r--r--3modules/krebs/urlwatch.nix4
-rw-r--r--3modules/tv/consul.nix118
-rw-r--r--3modules/tv/default.nix9
-rw-r--r--3modules/tv/ejabberd.nix166
-rw-r--r--3modules/tv/iptables.nix126
6 files changed, 136 insertions, 455 deletions
diff --git a/3modules/krebs/default.nix b/3modules/krebs/default.nix
index 3c2f7c9..9e25df0 100644
--- a/3modules/krebs/default.nix
+++ b/3modules/krebs/default.nix
@@ -20,8 +20,108 @@ let
enable = mkEnableOption "krebs";
build = mkOption {
- type = types.submodule {
+ type = types.submodule ({ config, ... }: {
options = {
+ target = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ };
+ deps = mkOption {
+ type = with types; attrsOf (submodule {
+ options = {
+ url = mkOption {
+ type = str;
+ };
+ rev = mkOption {
+ type = nullOr str;
+ default = null;
+ };
+ };
+ });
+ default = {};
+ };
+ script = mkOption {
+ type = types.str;
+ default = ''
+ #! /bin/sh
+ set -efux
+
+ target=${escapeShellArg cfg.build.target}
+
+ push(){(
+ src=$1/
+ dst=$target:$2
+ rsync \
+ --exclude .git \
+ --exclude .graveyard \
+ --exclude old \
+ --rsync-path="mkdir -p \"$dst\" && rsync" \
+ --usermap=\*:0 \
+ --groupmap=\*:0 \
+ --delete-excluded \
+ -vrLptgoD \
+ "$src" "$dst"
+ )}
+
+ ${concatStrings (mapAttrsToList (name: { url, rev, ... }:
+ optionalString (rev == null) ''
+ push ${toString (map escapeShellArg [
+ "${url}"
+ "/root/src/${name}"
+ ])}
+ '') config.deps)}
+
+ exec ssh -S none "$target" /bin/sh <<\EOF
+ set -efux
+ fetch(){(
+ url=$1
+ rev=$2
+ dst=$3
+ mkdir -p "$dst"
+ cd "$dst"
+ if ! test -e .git; then
+ git init
+ fi
+ if ! cur_url=$(git config remote.origin.url 2>/dev/null); then
+ git remote add origin "$url"
+ elif test "$cur_url" != "$url"; then
+ git remote set-url origin "$url"
+ fi
+ if test "$(git rev-parse --verify HEAD 2>/dev/null)" != "$rev"; then
+ git fetch origin
+ git checkout "$rev" -- .
+ git checkout -q "$rev"
+ git submodule init
+ git submodule update
+ fi
+ git clean -dxf
+ )}
+
+ ${concatStrings (mapAttrsToList (name: { url, rev, ... }:
+ optionalString (rev != null) ''
+ fetch ${toString (map escapeShellArg [
+ url
+ rev
+ "/root/src/${name}"
+ ])}
+ '') config.deps)}
+
+ echo build system...
+ profile=/nix/var/nix/profiles/system
+ NIX_PATH=/root/src \
+ nix-env \
+ -Q \
+ -p "$profile" \
+ -f '<stockholm>' \
+ --set \
+ -A system \
+ --argstr user-name ${escapeShellArg cfg.build.user.name} \
+ --argstr system-name ${escapeShellArg cfg.build.host.name}
+
+ exec "$profile"/bin/switch-to-configuration switch
+ EOF
+ '';
+ };
host = mkOption {
type = types.host;
};
@@ -29,11 +129,19 @@ let
type = types.user;
};
};
- };
+ });
# Define defaul value, so unset values of the submodule get reported.
default = {};
};
+ 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;
+ };
+ };
+
hosts = mkOption {
type = with types; attrsOf host;
};
@@ -46,8 +154,7 @@ let
# TODO search-domains :: listOf hostname
search-domain = mkOption {
type = types.hostname;
- default = "";
- example = "retiolum";
+ default = "retiolum";
};
};
@@ -56,38 +163,26 @@ let
{ krebs = makefu-imp; }
{ krebs = tv-imp; }
{
- # XXX This overlaps with krebs.retiolum
- networking.extraHosts =
- let
- # TODO move domain name providers to a dedicated module
- # providers : tree label providername
- providers = {
- internet = "hosts";
- retiolum = "hosts";
- de.viljetic = "regfish";
- de.krebsco = "ovh";
- };
-
- # splitByProvider : [alias] -> listset providername alias
- splitByProvider = foldl (acc: alias: listset-insert (providerOf alias) alias acc) {};
+ krebs.dns.providers = {
+ de.krebsco = "ovh";
+ internet = "hosts";
+ retiolum = "hosts";
+ };
- # providerOf : alias -> providername
- providerOf = alias:
- tree-get (splitString "." alias) providers;
- in
- concatStringsSep "\n" (flatten (
- # TODO deepMap ["hosts" "nets"] (hostname: host: netname: net:
- mapAttrsToList (hostname: host:
- mapAttrsToList (netname: net:
- let
- aliases = toString (unique (longs ++ shorts));
- longs = (splitByProvider net.aliases).hosts;
- shorts = map (removeSuffix ".${cfg.search-domain}") longs;
- in
- map (addr: "${addr} ${aliases}") net.addrs
- ) host.nets
- ) config.krebs.hosts
- ));
+ # XXX This overlaps with krebs.retiolum
+ networking.extraHosts = concatStringsSep "\n" (flatten (
+ mapAttrsToList (hostname: host:
+ mapAttrsToList (netname: net:
+ let
+ aliases = toString (unique (longs ++ shorts));
+ providers = dns.split-by-provider net.aliases cfg.dns.providers;
+ longs = providers.hosts;
+ shorts = map (removeSuffix ".${cfg.search-domain}") longs;
+ in
+ map (addr: "${addr} ${aliases}") net.addrs
+ ) host.nets
+ ) cfg.hosts
+ ));
}
];
@@ -140,6 +235,9 @@ let
};
tv-imp = {
+ dns.providers = {
+ de.viljetic = "regfish";
+ };
hosts = addNames {
cd = {
cores = 2;
diff --git a/3modules/krebs/urlwatch.nix b/3modules/krebs/urlwatch.nix
index 58de72f..39d9fec 100644
--- a/3modules/krebs/urlwatch.nix
+++ b/3modules/krebs/urlwatch.nix
@@ -35,20 +35,22 @@ let
};
mailto = mkOption {
type = types.str;
+ default = config.krebs.build.user.mail;
description = ''
Content of the To: header of the generated mails. [AKA recipient :)]
'';
};
onCalendar = mkOption {
type = types.str;
+ default = "04:23";
description = ''
Run urlwatch at this interval.
The format is described in systemd.time(7), CALENDAR EVENTS.
'';
- example = "04:23";
};
urls = mkOption {
type = with types; listOf str;
+ default = [];
description = "URL to watch.";
example = [
https://nixos.org/channels/nixos-unstable/git-revision
diff --git a/3modules/tv/consul.nix b/3modules/tv/consul.nix
deleted file mode 100644
index 4e54c2a..0000000
--- a/3modules/tv/consul.nix
+++ /dev/null
@@ -1,118 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-# if quorum gets lost, then start any node with a config that doesn't contain bootstrap_expect
-# but -bootstrap
-# TODO consul-bootstrap HOST that actually does is
-# TODO tools to inspect state of a cluster in outage state
-
-with import ../../4lib/tv { inherit lib pkgs; };
-let
- cfg = config.tv.consul;
-
- out = {
- options.tv.consul = api;
- config = mkIf cfg.enable (mkMerge [
- imp
- { tv.iptables.input-retiolum-accept-new-tcp = [ "8300" "8301" ]; }
- # TODO udp for 8301
- ]);
- };
-
- api = {
- enable = mkEnableOption "tv.consul";
-
- dc = mkOption {
- type = types.label;
- };
- hosts = mkOption {
- type = with types; listOf host;
- };
- encrypt-file = mkOption {
- type = types.str; # TODO path (but not just into store)
- default = "/root/src/secrets/consul-encrypt.json";
- };
- data-dir = mkOption {
- type = types.str; # TODO path (but not just into store)
- default = "/var/lib/consul";
- };
- self = mkOption {
- type = types.host;
- };
- server = mkOption {
- type = types.bool;
- default = false;
- };
- GOMAXPROCS = mkOption {
- type = types.int;
- default = cfg.self.cores;
- };
- };
-
- consul-config = {
- datacenter = cfg.dc;
- data_dir = cfg.data-dir;
- log_level = "INFO";
- #node_name =
- server = cfg.server;
- enable_syslog = true;
- retry_join =
- # TODO allow consul in other nets than retiolum [maybe]
- concatMap (host: host.nets.retiolum.addrs)
- (filter (host: host.name != cfg.self.name) cfg.hosts);
- leave_on_terminate = true;
- } // optionalAttrs cfg.server {
- bootstrap_expect = length cfg.hosts;
- leave_on_terminate = false;
- };
-
- imp = {
- environment.systemPackages = with pkgs; [
- consul
- ];
-
- systemd.services.consul = {
- after = [ "network.target" ];
- wantedBy = [ "multi-user.target" ];
- path = with pkgs; [
- consul
- ];
- environment = {
- GOMAXPROCS = toString cfg.GOMAXPROCS;
- };
- serviceConfig = {
- PermissionsStartOnly = "true";
- SyslogIdentifier = "consul";
- User = user.name;
- PrivateTmp = "true";
- Restart = "always";
- ExecStartPre = pkgs.writeScript "consul-init" ''
- #! /bin/sh
- mkdir -p ${cfg.data-dir}
- chown ${user.name}: ${cfg.data-dir}
- install -o ${user.name} -m 0400 ${cfg.encrypt-file} /tmp/encrypt.json
- '';
- ExecStart = pkgs.writeScript "consul-service" ''
- #! /bin/sh
- set -euf
- exec >/dev/null
- exec consul agent \
- -config-file=${toFile "consul.json" (toJSON consul-config)} \
- -config-file=/tmp/encrypt.json
- '';
- #-node=${cfg.self.fqdn} \
- #ExecStart = "${tinc}/sbin/tincd -c ${confDir} -d 0 -U ${user} -D";
- };
- };
-
- users.extraUsers = singleton {
- inherit (user) name uid;
- };
- };
-
- user = {
- name = "consul";
- uid = 2999951406; # genid consul
- };
-
-in
-out
diff --git a/3modules/tv/default.nix b/3modules/tv/default.nix
deleted file mode 100644
index bb10d82..0000000
--- a/3modules/tv/default.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-_:
-
-{
- imports = [
- ./consul.nix
- ./ejabberd.nix
- ./iptables.nix
- ];
-}
diff --git a/3modules/tv/ejabberd.nix b/3modules/tv/ejabberd.nix
deleted file mode 100644
index 2910a9a..0000000
--- a/3modules/tv/ejabberd.nix
+++ /dev/null
@@ -1,166 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with builtins;
-with lib;
-let
- cfg = config.tv.ejabberd;
-
- out = {
- options.tv.ejabberd = api;
- config = mkIf cfg.enable imp;
- };
-
- api = {
- enable = mkEnableOption "tv.ejabberd";
-
- certFile = mkOption {
- type = types.str;
- default = "/root/src/secrets/ejabberd.pem";
- };
-
- hosts = mkOption {
- type = with types; listOf str;
- };
- };
-
- imp = {
- environment.systemPackages = [ my-ejabberdctl ];
-
- systemd.services.ejabberd = {
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" ];
- serviceConfig = {
- Type = "oneshot";
- RemainAfterExit = "yes";
- PermissionsStartOnly = "true";
- SyslogIdentifier = "ejabberd";
- User = user.name;
- ExecStartPre = pkgs.writeScript "ejabberd-start" ''
- #! /bin/sh
- install -o ${user.name} -m 0400 ${cfg.certFile} /etc/ejabberd/ejabberd.pem
- '';
- ExecStart = pkgs.writeScript "ejabberd-service" ''
- #! /bin/sh
- ${my-ejabberdctl}/bin/ejabberdctl start
- '';
- };
- };
-
- users.extraUsers = singleton {
- inherit (user) name uid;
- home = "/var/ejabberd";
- createHome = true;
- };
- };
-
- user = {
- name = "ejabberd";
- uid = 3499746127; # genid ejabberd
- };
-
- my-ejabberdctl = pkgs.writeScriptBin "ejabberdctl" ''
- #! /bin/sh
- set -euf
- exec env \
- SPOOLDIR=/var/ejabberd \
- EJABBERD_CONFIG_PATH=${config-file} \
- ${pkgs.ejabberd}/bin/ejabberdctl \
- --logs /var/ejabberd \
- "$@"
- '';
-
- config-file = pkgs.writeText "ejabberd.cfg" ''
- {loglevel, 3}.
- {hosts, ${toErlang cfg.hosts}}.
- {listen,
- [
- {5222, ejabberd_c2s, [
- starttls,
- {certfile, "/etc/ejabberd/ejabberd.pem"},
- {access, c2s},
- {shaper, c2s_shaper},
- {max_stanza_size, 65536}
- ]},
- {5269, ejabberd_s2s_in, [
- {shaper, s2s_shaper},
- {max_stanza_size, 131072}
- ]},
- {5280, ejabberd_http, [
- captcha,
- http_bind,
- http_poll,
- web_admin
- ]}
- ]}.
- {s2s_use_starttls, required}.
- {s2s_certfile, "/etc/ejabberd/ejabberd.pem"}.
- {auth_method, internal}.
- {shaper, normal, {maxrate, 1000}}.
- {shaper, fast, {maxrate, 50000}}.
- {max_fsm_queue, 1000}.
- {acl, local, {user_regexp, ""}}.
- {access, max_user_sessions, [{10, all}]}.
- {access, max_user_offline_messages, [{5000, admin}, {100, all}]}.
- {access, local, [{allow, local}]}.
- {access, c2s, [{deny, blocked},
- {allow, all}]}.
- {access, c2s_shaper, [{none, admin},
- {normal, all}]}.
- {access, s2s_shaper, [{fast, all}]}.
- {access, announce, [{allow, admin}]}.
- {access, configure, [{allow, admin}]}.
- {access, muc_admin, [{allow, admin}]}.
- {access, muc_create, [{allow, local}]}.
- {access, muc, [{allow, all}]}.
- {access, pubsub_createnode, [{allow, local}]}.
- {access, register, [{allow, all}]}.
- {language, "en"}.
- {modules,
- [
- {mod_adhoc, []},
- {mod_announce, [{access, announce}]},
- {mod_blocking,[]},
- {mod_caps, []},
- {mod_configure,[]},
- {mod_disco, []},
- {mod_irc, []},
- {mod_http_bind, []},
- {mod_last, []},
- {mod_muc, [
- {access, muc},
- {access_create, muc_create},
- {access_persistent, muc_create},
- {access_admin, muc_admin}
- ]},
- {mod_offline, [{access_max_user_messages, max_user_offline_messages}]},
- {mod_ping, []},
- {mod_privacy, []},
- {mod_private, []},
- {mod_pubsub, [
- {access_createnode, pubsub_createnode},
- {ignore_pep_from_offline, true},
- {last_item_cache, false},
- {plugins, ["flat", "hometree", "pep"]}
- ]},
- {mod_register, [
- {welcome_message, {"Welcome!",
- "Hi.\nWelcome to this XMPP server."}},
- {ip_access, [{allow, "127.0.0.0/8"},
- {deny, "0.0.0.0/0"}]},
- {access, register}
- ]},
- {mod_roster, []},
- {mod_shared_roster,[]},
- {mod_stats, []},
- {mod_time, []},
- {mod_vcard, []},
- {mod_version, []}
- ]}.
- '';
-
-
- # XXX this is a placeholder that happens to work the default strings.
- toErlang = builtins.toJSON;
-
-in
-out
diff --git a/3modules/tv/iptables.nix b/3modules/tv/iptables.nix
deleted file mode 100644
index 173e582..0000000
--- a/3modules/tv/iptables.nix
+++ /dev/null
@@ -1,126 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with builtins;
-with lib;
-let
- cfg = config.tv.iptables;
-
- out = {
- options.tv.iptables = api;
- config = mkIf cfg.enable imp;
- };
-
- api = {
- enable = mkEnableOption "tv.iptables";
-
- input-internet-accept-new-tcp = mkOption {
- type = with types; listOf (either int str);
- default = [];
- };
-
- input-retiolum-accept-new-tcp = mkOption {
- type = with types; listOf (either int str);
- default = [];
- };
- };
-
- imp = {
- networking.firewall.enable = false;
-
- systemd.services.tv-iptables = {
- description = "tv-iptables";
- wantedBy = [ "network-pre.target" ];
- before = [ "network-pre.target" ];
- after = [ "systemd-modules-load.service" ];
-
- path = with pkgs; [
- iptables
- ];
-
- restartIfChanged = true;
-
- serviceConfig = {
- Type = "simple";
- RemainAfterExit = true;
- Restart = "always";
- ExecStart = "@${startScript} tv-iptables_start";
- };
- };
- };
-
-
- accept-new-tcp = port:
- "-p tcp -m tcp --dport ${port} -m conntrack --ctstate NEW -j ACCEPT";
-
- rules = iptables-version:
- pkgs.writeText "tv-iptables-rules${toString iptables-version}" ''
- *nat
- :PREROUTING ACCEPT [0:0]
- :INPUT ACCEPT [0:0]
- :OUTPUT ACCEPT [0:0]
- :POSTROUTING ACCEPT [0:0]
- ${concatMapStringsSep "\n" (rule: "-A PREROUTING ${rule}") ([]
- ++ [
- "! -i retiolum -p tcp -m tcp --dport 22 -j REDIRECT --to-ports 0"
- "-p tcp -m tcp --dport 11423 -j REDIRECT --to-ports 22"
- ]
- )}
- COMMIT
- *filter
- :INPUT DROP [0:0]
- :FORWARD DROP [0:0]
- :OUTPUT ACCEPT [0:0]
- :Retiolum - [0:0]
- ${concatMapStringsSep "\n" (rule: "-A INPUT ${rule}") ([]
- ++ [
- "-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT"
- "-i lo -j ACCEPT"
- ]
- ++ map accept-new-tcp (unique (map toString cfg.input-internet-accept-new-tcp))
- ++ ["-i retiolum -j Retiolum"]
- )}
- ${concatMapStringsSep "\n" (rule: "-A Retiolum ${rule}") ([]
- ++ {
- ip4tables = [
- "-p icmp -m icmp --icmp-type echo-request -j ACCEPT"
- ];
- ip6tables = [
- "-p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT"
- ];
- }."ip${toString iptables-version}tables"
- ++ map accept-new-tcp (unique (map toString cfg.input-retiolum-accept-new-tcp))
- ++ {
- ip4tables = [
- "-p tcp -j REJECT --reject-with tcp-reset"
- "-p udp -j REJECT --reject-with icmp-port-unreachable"
- "-j REJECT --reject-with icmp-proto-unreachable"
- ];
- ip6tables = [
- "-p tcp -j REJECT --reject-with tcp-reset"
- "-p udp -j REJECT --reject-with icmp6-port-unreachable"
- "-j REJECT"
- ];
- }."ip${toString iptables-version}tables"
- )}
- COMMIT
- '';
-
- startScript = pkgs.writeScript "tv-iptables_start" ''
- #! /bin/sh
- set -euf
- iptables-restore < ${rules 4}
- ip6tables-restore < ${rules 6}
- '';
-
-in
-out
-
-#let
-# cfg = config.tv.iptables;
-# arg' = arg // { inherit cfg; };
-#in
-#
-#{
-# options.tv.iptables = import ./options.nix arg';
-# config = lib.mkIf cfg.enable (import ./config.nix arg');
-#}