summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lass/3modules/bindfs.nix51
-rw-r--r--lass/3modules/default.nix2
-rw-r--r--lass/3modules/sync-containers.nix165
3 files changed, 218 insertions, 0 deletions
diff --git a/lass/3modules/bindfs.nix b/lass/3modules/bindfs.nix
new file mode 100644
index 000000000..5c8df8dc5
--- /dev/null
+++ b/lass/3modules/bindfs.nix
@@ -0,0 +1,51 @@
+with import <stockholm/lib>;
+{ config, pkgs, ... }:
+let
+ cfg = config.lass.bindfs;
+in {
+ options.lass.bindfs = mkOption {
+ type = types.attrsOf (types.submodule ({ config, ... }: {
+ options = {
+ target = mkOption {
+ description = ''
+ destination where bindfs mounts to.
+ second positional argument to bindfs.
+ '';
+ default = config._module.args.name;
+ type = types.absolute-pathname;
+ };
+ source = mkOption {
+ description = ''
+ source folder where the mounted directory is originally.
+ first positional argument to bindfs.
+ '';
+ type = types.absolute-pathname;
+ };
+ options = mkOption {
+ description = ''
+ additional arguments to bindfs
+ '';
+ type = types.listOf types.str;
+ default = [];
+ };
+ };
+ }));
+ default = {};
+ };
+
+ config = mkIf (cfg != {}) {
+ systemd.services = mapAttrs' (n: mount: let
+ name = replaceStrings [ "/" ] [ "_" ] n;
+ in nameValuePair "bindfs-${name}" {
+ wantedBy = [ "local-fs.target" ];
+ path = [ pkgs.coreutils ];
+ serviceConfig = {
+ ExecStartPre = pkgs.writeDash "bindfs-init-${name}" ''
+ mkdir -p '${mount.source}'
+ mkdir -p '${mount.target}'
+ '';
+ ExecStart = "${pkgs.bindfs}/bin/bindfs -f ${concatStringsSep " " mount.options} ${mount.source} ${mount.target}";
+ };
+ }) cfg;
+ };
+}
diff --git a/lass/3modules/default.nix b/lass/3modules/default.nix
index c3c73bdcb..8bee08caa 100644
--- a/lass/3modules/default.nix
+++ b/lass/3modules/default.nix
@@ -1,6 +1,7 @@
_:
{
imports = [
+ ./bindfs.nix
./dnsmasq.nix
./ejabberd
./folderPerms.nix
@@ -12,6 +13,7 @@ _:
./pyload.nix
./restic.nix
./screenlock.nix
+ ./sync-containers.nix
./usershadow.nix
./xjail.nix
./autowifi.nix
diff --git a/lass/3modules/sync-containers.nix b/lass/3modules/sync-containers.nix
new file mode 100644
index 000000000..990e32127
--- /dev/null
+++ b/lass/3modules/sync-containers.nix
@@ -0,0 +1,165 @@
+with import <stockholm/lib>;
+{ config, pkgs, ... }: let
+ cfg = config.lass.sync-containers;
+ paths = cname: {
+ plain = "/var/lib/containers/${cname}/var/state";
+ ecryptfs = "${cfg.dataLocation}/${cname}/ecryptfs";
+ securefs = "${cfg.dataLocation}/${cname}/securefs";
+ };
+ start = cname: {
+ plain = ''
+ '';
+ ecryptfs = ''
+ if ! mount | grep -q '${cfg.dataLocation}/${cname}/ecryptfs on /var/lib/containers/${cname}/var/state type ecryptfs'; then
+ if [ -e ${cfg.dataLocation}/${cname}/ecryptfs/.cfg.json ]; then
+ ${pkgs.ecrypt}/bin/ecrypt mount ${cfg.dataLocation}/${cname}/ecryptfs /var/lib/containers/${cname}/var/state
+ else
+ ${pkgs.ecrypt}/bin/ecrypt init ${cfg.dataLocation}/${cname}/ecryptfs /var/lib/containers/${cname}/var/state
+ fi
+ fi
+ '';
+ securefs = ''
+ ## TODO init file systems if it does not exist
+ # ${pkgs.securefs}/bin/securefs create --format 3 ${cfg.dataLocation}/${cname}/securefs
+ if ! ${pkgs.mount}/bin/mount | grep -q '^securefs on /var/lib/containers/${cname}/var/state type fuse.securefs'; then
+ ${pkgs.securefs}/bin/securefs mount ${cfg.dataLocation}/${cname}/securefs /var/lib/containers/${cname}/var/state -b -o allow_other -o default_permissions
+ fi
+ '';
+ };
+ stop = cname: {
+ plain = ''
+ '';
+ ecryptfs = ''
+ ${pkgs.ecrypt}/bin/ecrypt unmount ${cfg.dataLocation}/${cname}/ecryptfs /var/lib/containers/${cname}/var/state
+ '';
+ securefs = ''
+ umount /var/lib/containers/${cname}/var/state
+ '';
+ };
+in {
+ options.lass.sync-containers = {
+ dataLocation = mkOption {
+ description = ''
+ location where the encrypted sync-container lie around
+ '';
+ default = "/var/lib/sync-containers";
+ type = types.absolute-pathname;
+ };
+ containers = mkOption {
+ type = types.attrsOf (types.submodule ({ config, ... }: {
+ options = {
+ name = mkOption {
+ description = ''
+ name of the container
+ '';
+ default = config._module.args.name;
+ type = types.str;
+ };
+ peers = mkOption {
+ description = ''
+ syncthing peers to share this container with
+ '';
+ default = [];
+ type = types.listOf types.str;
+ };
+ hostIp = mkOption { # TODO find this automatically
+ description = ''
+ hostAddress of the privateNetwork
+ '';
+ example = "10.233.2.15";
+ type = types.str;
+ };
+ localIp = mkOption { # TODO find this automatically
+ description = ''
+ localAddress of the privateNetwork
+ '';
+ example = "10.233.2.16";
+ type = types.str;
+ };
+ format = mkOption {
+ description = ''
+ file system encrption format of the container
+ '';
+ type = types.enum [ "plain" "ecryptfs" "securefs" ];
+ };
+ };
+ }));
+ default = {};
+ };
+ };
+
+ config = mkIf (cfg.containers != {}) {
+ programs.fuse.userAllowOther = true;
+
+ services.syncthing.declarative.folders = (mapAttrs' (_: ctr: nameValuePair "${(paths ctr.name).${ctr.format}}" ({
+ devices = ctr.peers;
+ ignorePerms = false;
+ })) cfg.containers);
+
+ krebs.permown = (mapAttrs' (_: ctr: nameValuePair "${(paths ctr.name).${ctr.format}}" ({
+ owner = "root";
+ group = "syncthing";
+ umask = "0007";
+ })) cfg.containers);
+
+ systemd.services = mapAttrs' (n: ctr: nameValuePair "containers@${ctr.name}" ({
+ reloadIfChanged = mkForce false;
+ })) cfg.containers;
+
+ containers = mapAttrs' (n: ctr: nameValuePair ctr.name ({
+ config = { ... }: {
+ environment.systemPackages = [
+ pkgs.git
+ ];
+ system.activationScripts.fuse = {
+ text = ''
+ ${pkgs.coreutils}/bin/mknod /dev/fuse c 10 229
+ '';
+ deps = [];
+ };
+ };
+ allowedDevices = [
+ { modifier = "rwm"; node = "/dev/fuse"; }
+ ];
+ autoStart = false;
+ enableTun = true;
+ privateNetwork = true;
+ hostAddress = ctr.hostIp;
+ localAddress = ctr.localIp;
+ })) cfg.containers;
+
+ environment.systemPackages = flatten (mapAttrsToList (n: ctr: [
+ (pkgs.writeDashBin "start-${ctr.name}" ''
+ set -euf
+ set -x
+
+ mkdir -p /var/lib/containers/${ctr.name}/var/state
+
+ ${(start ctr.name).${ctr.format}}
+
+ STATE=$(${pkgs.nixos-container}/bin/nixos-container status ${ctr.name})
+ if [ "$STATE" = 'down' ]; then
+ ${pkgs.nixos-container}/bin/nixos-container start ${ctr.name}
+ fi
+
+ ${pkgs.nixos-container}/bin/nixos-container run ${ctr.name} -- ${pkgs.writeDash "deploy-${ctr.name}" ''
+ set -x
+
+ mkdir -p /var/state/var_src
+ ln -sfTr /var/state/var_src /var/src
+ touch /etc/NIXOS
+ ''}
+
+ if [ -h /var/lib/containers/${ctr.name}/var/src/nixos-config ] && (! ping -c1 -q -w5 ${ctr.name}.r); then
+ ${pkgs.nixos-container}/bin/nixos-container run ${ctr.name} -- nixos-rebuild -I /var/src switch
+ fi
+ '')
+ (pkgs.writeDashBin "stop-${ctr.name}" ''
+ set -euf
+
+ ${pkgs.nixos-container}/bin/nixos-container stop ${ctr.name}
+ ${(stop ctr.name).${ctr.format}}
+ '')
+ ]) cfg.containers);
+ };
+}