Wire production daemon settings in NixOS module
This commit is contained in:
parent
01f1834e25
commit
577660884c
1 changed files with 285 additions and 189 deletions
160
flake.nix
160
flake.nix
|
|
@ -14,7 +14,8 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs @ {
|
outputs =
|
||||||
|
inputs@{
|
||||||
self,
|
self,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
flake-parts,
|
flake-parts,
|
||||||
|
|
@ -29,22 +30,37 @@
|
||||||
"aarch64-darwin"
|
"aarch64-darwin"
|
||||||
];
|
];
|
||||||
|
|
||||||
perSystem = {
|
perSystem =
|
||||||
|
{
|
||||||
self',
|
self',
|
||||||
pkgs,
|
pkgs,
|
||||||
system,
|
system,
|
||||||
...
|
...
|
||||||
}: let
|
}:
|
||||||
|
let
|
||||||
rustPkgs = import nixpkgs {
|
rustPkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [ (import rust-overlay) ];
|
overlays = [ (import rust-overlay) ];
|
||||||
};
|
};
|
||||||
rustToolchain = rustPkgs.rust-bin.stable.latest.default.override {
|
rustToolchain = rustPkgs.rust-bin.stable.latest.default.override {
|
||||||
extensions = ["rust-src" "rust-analyzer" "clippy" "rustfmt"];
|
extensions = [
|
||||||
|
"rust-src"
|
||||||
|
"rust-analyzer"
|
||||||
|
"clippy"
|
||||||
|
"rustfmt"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
commonBuildInputs = with pkgs; [openssl sqlite];
|
commonBuildInputs = with pkgs; [
|
||||||
commonNativeBuildInputs = with pkgs; [cmake perl pkg-config];
|
openssl
|
||||||
in {
|
sqlite
|
||||||
|
];
|
||||||
|
commonNativeBuildInputs = with pkgs; [
|
||||||
|
cmake
|
||||||
|
perl
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
packages = {
|
packages = {
|
||||||
default = pkgs.rustPlatform.buildRustPackage {
|
default = pkgs.rustPlatform.buildRustPackage {
|
||||||
pname = "iota";
|
pname = "iota";
|
||||||
|
|
@ -73,7 +89,10 @@
|
||||||
|
|
||||||
iota-daemon = self'.packages.default.overrideAttrs (old: {
|
iota-daemon = self'.packages.default.overrideAttrs (old: {
|
||||||
pname = "iota-daemon";
|
pname = "iota-daemon";
|
||||||
cargoBuildFlags = ["-p" "iota-daemon"];
|
cargoBuildFlags = [
|
||||||
|
"-p"
|
||||||
|
"iota-daemon"
|
||||||
|
];
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
for f in $out/bin/*; do
|
for f in $out/bin/*; do
|
||||||
if [ "$(basename "$f")" != "iota-daemon" ]; then
|
if [ "$(basename "$f")" != "iota-daemon" ]; then
|
||||||
|
|
@ -85,7 +104,10 @@
|
||||||
|
|
||||||
iota-ui = self'.packages.default.overrideAttrs (old: {
|
iota-ui = self'.packages.default.overrideAttrs (old: {
|
||||||
pname = "iota-ui";
|
pname = "iota-ui";
|
||||||
cargoBuildFlags = ["-p" "iota"];
|
cargoBuildFlags = [
|
||||||
|
"-p"
|
||||||
|
"iota"
|
||||||
|
];
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
for f in $out/bin/*; do
|
for f in $out/bin/*; do
|
||||||
if [ "$(basename "$f")" != "iota" ]; then
|
if [ "$(basename "$f")" != "iota" ]; then
|
||||||
|
|
@ -100,29 +122,54 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
nativeBuildInputs = with pkgs; [rustToolchain git cmake perl pkg-config];
|
nativeBuildInputs = with pkgs; [
|
||||||
|
rustToolchain
|
||||||
|
git
|
||||||
|
cmake
|
||||||
|
perl
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
buildInputs = commonBuildInputs;
|
buildInputs = commonBuildInputs;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake = {
|
flake = {
|
||||||
nixosModules.default = {
|
nixosModules.default =
|
||||||
|
{
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}:
|
||||||
|
let
|
||||||
cfg = config.services.iota;
|
cfg = config.services.iota;
|
||||||
defaultPackage = self.packages.${pkgs.stdenv.hostPlatform.system}.default or (throw "iota: no pre-built package for system ${pkgs.stdenv.hostPlatform.system}");
|
defaultPackage =
|
||||||
|
self.packages.${pkgs.stdenv.hostPlatform.system}.default
|
||||||
|
or (throw "iota: no pre-built package for system ${pkgs.stdenv.hostPlatform.system}");
|
||||||
|
|
||||||
configFormat = pkgs.formats.yaml { };
|
configFormat = pkgs.formats.yaml { };
|
||||||
|
effectiveSettings = lib.recursiveUpdate {
|
||||||
|
port = cfg.port;
|
||||||
|
web = {
|
||||||
|
mode = "network";
|
||||||
|
bind = cfg.bindAddress;
|
||||||
|
port = cfg.port;
|
||||||
|
required = true;
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (cfg.certFile != null) {
|
||||||
|
certificate = "${cfg.stateDir}/tls/cert.pem";
|
||||||
|
key = "${cfg.stateDir}/tls/key.pem";
|
||||||
|
};
|
||||||
|
} cfg.settings;
|
||||||
configFile =
|
configFile =
|
||||||
if cfg.settingsFile != null
|
if cfg.settingsFile != null then
|
||||||
then cfg.settingsFile
|
cfg.settingsFile
|
||||||
else configFormat.generate "iota-config.yaml" cfg.settings;
|
else
|
||||||
|
configFormat.generate "iota-config.yaml" effectiveSettings;
|
||||||
|
|
||||||
descriptionText = "Tensamin Iota daemon";
|
descriptionText = "Tensamin Iota daemon";
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.services.iota = {
|
options.services.iota = {
|
||||||
enable = lib.mkEnableOption "Enable the Iota service.";
|
enable = lib.mkEnableOption "Enable the Iota service.";
|
||||||
|
|
||||||
|
|
@ -131,25 +178,37 @@
|
||||||
default = "/var/lib/iota";
|
default = "/var/lib/iota";
|
||||||
description = "Persistent mutable Iota state.";
|
description = "Persistent mutable Iota state.";
|
||||||
};
|
};
|
||||||
cacheDir = lib.mkOption { type = lib.types.str; default = "/var/cache/iota"; };
|
cacheDir = lib.mkOption {
|
||||||
runtimeDir = lib.mkOption { type = lib.types.str; default = "/run/iota"; };
|
type = lib.types.str;
|
||||||
logDir = lib.mkOption { type = lib.types.str; default = "/var/log/iota"; };
|
default = "/var/cache/iota";
|
||||||
assetDir = lib.mkOption { type = lib.types.str; default = "${cfg.package}/share/iota/web"; };
|
};
|
||||||
|
runtimeDir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/run/iota";
|
||||||
|
};
|
||||||
|
logDir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/log/iota";
|
||||||
|
};
|
||||||
|
assetDir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "${cfg.package}/share/iota/web";
|
||||||
|
};
|
||||||
|
|
||||||
certFile = lib.mkOption {
|
certFile = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.path;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default = null;
|
default = null;
|
||||||
description = "Path to the SSL certificate file (cert.pem).";
|
description = "Path to the SSL certificate file (cert.pem).";
|
||||||
};
|
};
|
||||||
|
|
||||||
keyFile = lib.mkOption {
|
keyFile = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.path;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default = null;
|
default = null;
|
||||||
description = "Path to the SSL private key file (cert.key).";
|
description = "Path to the SSL private key file (cert.key).";
|
||||||
};
|
};
|
||||||
|
|
||||||
environmentFiles = lib.mkOption {
|
environmentFiles = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.path;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = "Environment files to load for the Iota service.";
|
description = "Environment files to load for the Iota service.";
|
||||||
};
|
};
|
||||||
|
|
@ -166,6 +225,18 @@
|
||||||
description = "IP address to bind the HTTP server to.";
|
description = "IP address to bind the HTTP server to.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 1984;
|
||||||
|
description = "TCP and UDP port for protocol-only Iota.";
|
||||||
|
};
|
||||||
|
|
||||||
|
omegaApiUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "https://omega.tensamin.net";
|
||||||
|
description = "Omega discovery API URL.";
|
||||||
|
};
|
||||||
|
|
||||||
package = lib.mkOption {
|
package = lib.mkOption {
|
||||||
type = lib.types.package;
|
type = lib.types.package;
|
||||||
default = defaultPackage;
|
default = defaultPackage;
|
||||||
|
|
@ -186,6 +257,13 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = (cfg.certFile == null) == (cfg.keyFile == null);
|
||||||
|
message = "services.iota: certFile and keyFile must be set together.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
users.users.iota = {
|
users.users.iota = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
group = "iota";
|
group = "iota";
|
||||||
|
|
@ -215,11 +293,15 @@
|
||||||
systemd.services.iota = {
|
systemd.services.iota = {
|
||||||
description = descriptionText;
|
description = descriptionText;
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = ["network.target" "iota.socket"];
|
after = [
|
||||||
|
"network.target"
|
||||||
|
"iota.socket"
|
||||||
|
];
|
||||||
requires = [ "iota.socket" ];
|
requires = [ "iota.socket" ];
|
||||||
|
|
||||||
serviceConfig =
|
environment.OMEGA_API_URL = cfg.omegaApiUrl;
|
||||||
{
|
|
||||||
|
serviceConfig = {
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
User = "iota";
|
User = "iota";
|
||||||
Group = "iota";
|
Group = "iota";
|
||||||
|
|
@ -251,8 +333,16 @@
|
||||||
ProtectHome = true;
|
ProtectHome = true;
|
||||||
PrivateTmp = true;
|
PrivateTmp = true;
|
||||||
NoNewPrivileges = true;
|
NoNewPrivileges = true;
|
||||||
ReadWritePaths = [cfg.stateDir cfg.cacheDir cfg.runtimeDir cfg.logDir];
|
ReadWritePaths = [
|
||||||
ReadOnlyPaths = [configFile cfg.assetDir];
|
cfg.stateDir
|
||||||
|
cfg.cacheDir
|
||||||
|
cfg.runtimeDir
|
||||||
|
cfg.logDir
|
||||||
|
];
|
||||||
|
ReadOnlyPaths = [
|
||||||
|
configFile
|
||||||
|
cfg.assetDir
|
||||||
|
];
|
||||||
ProtectKernelTunables = true;
|
ProtectKernelTunables = true;
|
||||||
ProtectKernelModules = true;
|
ProtectKernelModules = true;
|
||||||
ProtectControlGroups = true;
|
ProtectControlGroups = true;
|
||||||
|
|
@ -261,7 +351,6 @@
|
||||||
LockPersonality = true;
|
LockPersonality = true;
|
||||||
MemoryDenyWriteExecute = true;
|
MemoryDenyWriteExecute = true;
|
||||||
Environment = [
|
Environment = [
|
||||||
"BIND_ADDRESS=${cfg.bindAddress}"
|
|
||||||
"IOTA_SOCKET=/run/iota/iota.sock"
|
"IOTA_SOCKET=/run/iota/iota.sock"
|
||||||
"IOTA_CONFIG_FILE=${configFile}"
|
"IOTA_CONFIG_FILE=${configFile}"
|
||||||
"IOTA_STATE_DIR=${cfg.stateDir}"
|
"IOTA_STATE_DIR=${cfg.stateDir}"
|
||||||
|
|
@ -273,14 +362,21 @@
|
||||||
"IOTA_SUPERVISOR=systemd"
|
"IOTA_SUPERVISOR=systemd"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
// lib.optionalAttrs (cfg.certFile != null) {
|
||||||
|
ExecStartPre = "+${pkgs.writeShellScript "iota-setup-tls" ''
|
||||||
|
install -d -m 0700 -o iota -g iota ${cfg.stateDir}/tls
|
||||||
|
install -m 0644 -o iota -g iota ${cfg.certFile} ${cfg.stateDir}/tls/cert.pem
|
||||||
|
install -m 0600 -o iota -g iota ${cfg.keyFile} ${cfg.stateDir}/tls/key.pem
|
||||||
|
''}";
|
||||||
|
}
|
||||||
// lib.optionalAttrs (cfg.environmentFiles != [ ]) {
|
// lib.optionalAttrs (cfg.environmentFiles != [ ]) {
|
||||||
EnvironmentFile = cfg.environmentFiles;
|
EnvironmentFile = cfg.environmentFiles;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||||
allowedTCPPorts = [1984];
|
allowedTCPPorts = [ cfg.port ];
|
||||||
allowedUDPPorts = [1984];
|
allowedUDPPorts = [ cfg.port ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue