152 lines
4.6 KiB
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 -"
|
|
];
|
|
};
|
|
}
|