photoncloud-monorepo/nix/modules/coronafs.nix

152 lines
4.6 KiB
Nix

{ config, lib, pkgs, ... }:
let
cfg = config.services.coronafs;
tomlFormat = pkgs.formats.toml { };
coronafsConfigFile = tomlFormat.generate "coronafs.toml" {
listen_addr = "0.0.0.0:${toString cfg.port}";
advertise_host = cfg.advertiseHost;
data_dir = toString cfg.dataDir;
export_bind_addr = cfg.exportBindAddr;
export_base_port = cfg.exportBasePort;
export_port_count = cfg.exportPortCount;
export_shared_clients = cfg.exportSharedClients;
export_cache_mode = cfg.exportCacheMode;
export_aio_mode = cfg.exportAioMode;
export_discard_mode = cfg.exportDiscardMode;
export_detect_zeroes_mode = cfg.exportDetectZeroesMode;
preallocate = cfg.preallocate;
sync_on_write = cfg.syncOnWrite;
qemu_nbd_path = "${pkgs.qemu}/bin/qemu-nbd";
qemu_img_path = "${pkgs.qemu}/bin/qemu-img";
log_level = "info";
};
in
{
options.services.coronafs = {
enable = lib.mkEnableOption "CoronaFS block volume service";
port = lib.mkOption {
type = lib.types.port;
default = 50088;
description = "Port for the CoronaFS control API.";
};
advertiseHost = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "Host or IP placed into exported NBD URIs.";
example = "10.0.0.11";
};
exportBindAddr = lib.mkOption {
type = lib.types.str;
default = "0.0.0.0";
description = "Bind address for qemu-nbd exports.";
};
exportBasePort = lib.mkOption {
type = lib.types.port;
default = 11000;
description = "First TCP port reserved for CoronaFS NBD exports.";
};
exportPortCount = lib.mkOption {
type = lib.types.int;
default = 512;
description = "Number of NBD export ports reserved for CoronaFS volumes.";
};
exportSharedClients = lib.mkOption {
type = lib.types.int;
default = 32;
description = "Maximum number of concurrent clients per exported CoronaFS volume.";
};
exportCacheMode = lib.mkOption {
type = lib.types.enum [ "none" "writeback" "writethrough" "directsync" "unsafe" ];
default = "none";
description = "qemu-nbd cache mode for CoronaFS exports.";
};
exportAioMode = lib.mkOption {
type = lib.types.enum [ "native" "io_uring" "threads" ];
default = "io_uring";
description = "qemu-nbd AIO mode for CoronaFS exports.";
};
exportDiscardMode = lib.mkOption {
type = lib.types.enum [ "ignore" "unmap" ];
default = "unmap";
description = "qemu-nbd discard handling for CoronaFS exports.";
};
exportDetectZeroesMode = lib.mkOption {
type = lib.types.enum [ "off" "on" "unmap" ];
default = "unmap";
description = "qemu-nbd detect-zeroes mode for CoronaFS exports.";
};
preallocate = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Preallocate blank CoronaFS volumes with fallocate when possible.";
};
syncOnWrite = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Force sync_all after volume import writes.";
};
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/coronafs";
description = "Data directory for CoronaFS volumes, metadata, and export pid files.";
};
package = lib.mkOption {
type = lib.types.package;
default = pkgs.coronafs-server or (throw "coronafs-server package not found");
description = "Package to use for CoronaFS.";
};
};
config = lib.mkIf cfg.enable {
users.users.coronafs = {
isSystemUser = true;
group = "coronafs";
description = "CoronaFS service user";
home = cfg.dataDir;
};
users.groups.coronafs = { };
systemd.services.coronafs = {
description = "CoronaFS Block Volume Service";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
path = [ pkgs.qemu pkgs.util-linux pkgs.procps pkgs.coreutils ];
serviceConfig = {
Type = "simple";
User = "coronafs";
Group = "coronafs";
UMask = "0007";
Restart = "on-failure";
RestartSec = "5s";
StateDirectory = "coronafs";
StateDirectoryMode = "0750";
ReadWritePaths = [ cfg.dataDir ];
ExecStart = "${cfg.package}/bin/coronafs-server --config ${coronafsConfigFile}";
};
};
systemd.tmpfiles.rules = [
"d ${toString cfg.dataDir} 0750 coronafs coronafs -"
"d ${toString cfg.dataDir}/volumes 0750 coronafs coronafs -"
"d ${toString cfg.dataDir}/metadata 0750 coronafs coronafs -"
"d ${toString cfg.dataDir}/pids 0750 coronafs coronafs -"
];
};
}