zfs: respect canmount

Also refactor `zpool` type to use `zfs_fs` to construct the root dataset
for the zpool, which means we no longer need to duplicate the dataset
create and mount logic inside the `zpool` type.
This commit is contained in:
Michael Hoang 2023-12-30 11:25:06 +11:00 committed by mergify[bot]
parent 2791cedcba
commit ce3b896151
2 changed files with 34 additions and 28 deletions

View File

@ -6,17 +6,27 @@
default = config._module.args.name; default = config._module.args.name;
description = "Name of the dataset"; description = "Name of the dataset";
}; };
_name = lib.mkOption {
type = lib.types.str;
default = "${config._parent.name}/${config.name}";
internal = true;
description = "Fully quantified name for dataset";
};
type = lib.mkOption { type = lib.mkOption {
type = lib.types.enum [ "zfs_fs" ]; type = lib.types.enum [ "zfs_fs" ];
default = "zfs_fs"; default = "zfs_fs";
internal = true; internal = true;
description = "Type"; description = "Type";
}; };
options = lib.mkOption { options = lib.mkOption {
type = lib.types.attrsOf lib.types.str; type = lib.types.attrsOf lib.types.str;
default = { }; default = { };
description = "Options to set for the dataset"; description = "Options to set for the dataset";
}; };
mountOptions = lib.mkOption { mountOptions = lib.mkOption {
type = lib.types.listOf lib.types.str; type = lib.types.listOf lib.types.str;
default = [ "defaults" ]; default = [ "defaults" ];
@ -33,6 +43,7 @@
internal = true; internal = true;
default = parent; default = parent;
}; };
_meta = lib.mkOption { _meta = lib.mkOption {
internal = true; internal = true;
readOnly = true; readOnly = true;
@ -40,6 +51,7 @@
default = _dev: { }; default = _dev: { };
description = "Metadata"; description = "Metadata";
}; };
_create = diskoLib.mkCreateOption { _create = diskoLib.mkCreateOption {
inherit config options; inherit config options;
# -u prevents mounting newly created datasets, which is # -u prevents mounting newly created datasets, which is
@ -47,17 +59,18 @@
# since (create order != mount order) # since (create order != mount order)
# -p creates parents automatically # -p creates parents automatically
default = '' default = ''
zfs create -up ${config._parent.name}/${config.name} \ zfs create -up ${config._name} \
${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "-o ${n}=${v}") config.options)} ${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "-o ${n}=${v}") config.options)}
''; '';
}; } // { readOnly = false; };
_mount = diskoLib.mkMountOption { _mount = diskoLib.mkMountOption {
inherit config options; inherit config options;
default = default =
lib.optionalAttrs (config.options.mountpoint or "" != "none") { lib.optionalAttrs (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
fs.${config.mountpoint} = '' fs.${config.mountpoint} = ''
if ! findmnt ${config._parent.name}/${config.name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then if ! findmnt ${config._name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
mount ${config._parent.name}/${config.name} "${rootMountPoint}${config.mountpoint}" \ mount ${config._name} "${rootMountPoint}${config.mountpoint}" \
-o X-mount.mkdir \ -o X-mount.mkdir \
${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \ ${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \
${lib.optionalString ((config.options.mountpoint or "") != "legacy") "-o zfsutil"} \ ${lib.optionalString ((config.options.mountpoint or "") != "legacy") "-o zfsutil"} \
@ -66,19 +79,21 @@
''; '';
}; };
}; };
_config = lib.mkOption { _config = lib.mkOption {
internal = true; internal = true;
readOnly = true; readOnly = true;
default = default =
lib.optional (config.options.mountpoint or "" != "none") { lib.optional (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
fileSystems.${config.mountpoint} = { fileSystems.${config.mountpoint} = {
device = "${config._parent.name}/${config.name}"; device = "${config._name}";
fsType = "zfs"; fsType = "zfs";
options = config.mountOptions ++ lib.optional ((config.options.mountpoint or "") != "legacy") "zfsutil"; options = config.mountOptions ++ lib.optional ((config.options.mountpoint or "") != "legacy") "zfsutil";
}; };
}; };
description = "NixOS configuration"; description = "NixOS configuration";
}; };
_pkgs = lib.mkOption { _pkgs = lib.mkOption {
internal = true; internal = true;
readOnly = true; readOnly = true;

View File

@ -85,32 +85,13 @@
zpool import -l -R ${rootMountPoint} '${config.name}' zpool import -l -R ${rootMountPoint} '${config.name}'
${lib.concatMapStrings (x: x.dev or "") (lib.attrValues datasetMounts)} ${lib.concatMapStrings (x: x.dev or "") (lib.attrValues datasetMounts)}
''; '';
fs = (datasetMounts.fs or { }) // lib.optionalAttrs (config.mountpoint != null) { inherit (datasetMounts) fs;
${config.mountpoint} = ''
if ! findmnt ${config.name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
mount ${config.name} "${rootMountPoint}${config.mountpoint}" \
${lib.optionalString ((config.options.mountpoint or "") != "legacy") "-o zfsutil"} \
${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \
-o X-mount.mkdir \
-t zfs
fi
'';
};
}; };
}; };
_config = lib.mkOption { _config = lib.mkOption {
internal = true; internal = true;
readOnly = true; readOnly = true;
default = [ default = map (dataset: dataset._config) (lib.attrValues config.datasets);
(map (dataset: dataset._config) (lib.attrValues config.datasets))
(lib.optional (config.mountpoint != null) {
fileSystems.${config.mountpoint} = {
device = config.name;
fsType = "zfs";
options = config.mountOptions ++ lib.optional ((config.options.mountpoint or "") != "legacy") "zfsutil";
};
})
];
description = "NixOS configuration"; description = "NixOS configuration";
}; };
_pkgs = lib.mkOption { _pkgs = lib.mkOption {
@ -121,4 +102,14 @@
description = "Packages"; description = "Packages";
}; };
}; };
config = {
datasets."__root" = {
_name = config.name;
_create = "";
type = "zfs_fs";
mountpoint = config.mountpoint;
options = config.rootFsOptions;
};
};
} }