nixos-config/modules/wrapper-manager/sandboxing/bubblewrap/filesystem.nix

105 lines
3.4 KiB
Nix

# Essentially a poor man's version of NixOS filesystem module except that is
# made for Bubblewrap environment. Everything here should only make use of
# Bubblewrap's filesystem options from the command-line application.
{ config, lib, ... }:
let
cfg = config.sandboxing.bubblewrap;
bubblewrapModuleFactory = { isGlobal ? false }: let
filesystemSubmodule = { config, lib, name, ... }: {
options = {
source = lib.mkOption {
type = lib.types.path;
description = ''
The source of the path to be copied from.
'';
example = lib.literalExpression "./files/example.file";
};
perms = lib.mkOption {
type = with lib.types; nullOr (strMatch "[0-7]{0,4}");
description = ''
The permissions of the node in octal.
'';
default = null;
example = "0755";
};
symlink = lib.mkEnableOption "create the file as a symlink";
createDir = lib.mkEnableOption "create the directory in the Bubblewrap environment";
bindMount = lib.mkEnableOption "bind-mount the given source to the Bubblewrap environment";
bindMountReadOnly = lib.mkEnableOption "bind-mount read-only the given source to the Bubblewrap environment";
};
};
in {
options.filesystem = lib.mkOption {
type = with lib.types; attrsOf (submodule filesystemSubmodule);
description =
if isGlobal then ''
Set of filesystem configurations to be copied to per-wrapper.
'' else ''
Set of wrapper-specific filesystem configurations in the Bubblewrap
environment.
'';
default = if isGlobal then { } else cfg.filesystem;
example = lib.literalExpression ''
{
"/etc/hello" = {
source = ./files/hello;
perms = "0700";
};
"/etc/xdg" = {
source = ./configs;
perms = "0700";
};
"/srv/data" = {
source = "/srv/data";
symlink = true;
};
"/srv/logs".createDir = true;
}
'';
};
};
in
{
options.sandboxing.bubblewrap = bubblewrapModuleFactory { isGlobal = true; };
options.wrappers =
let
bubblewrapModule = { config, lib, name, ... }: let
submoduleCfg = config;
in {
options.sandboxing.bubblewrap = bubblewrapModuleFactory { isGlobal = false; };
config = lib.mkIf (config.sandboxing.variant == "bubblewrap") {
bubblewrap.extraArgs =
lib.lists.flatten
(lib.mapAttrsToList
(dst: metadata:
lib.optionals (metadata.perms != null) [ "--perms ${metadata.perms}" ]
++ (let
inherit (metadata) source;
in
if metadata.createDir
then [ "--dir ${dst}"]
else if metadata.symlink
then [ "--symlink ${source} ${dst}"]
else if metadata.bindMount
then [ "--bind-data ${source} ${dst}" ]
else if metadata.bindMountReadOnly
then [ "--ro-bind-data ${source} ${dst}" ]
else [ "--file ${source} ${dst}"]))
submoduleCfg.filesystem);
};
};
in
lib.mkOption {
type = with lib.types; attrsOf (submodule bubblewrapModule);
};
}