From 0b3efa2f612f183fddcb1a8399d95ce4b3d74dca Mon Sep 17 00:00:00 2001 From: Alois Date: Sat, 16 May 2026 16:28:29 +0200 Subject: [PATCH 1/8] [Add] Nix Flake --- flake.lock | 78 ++++++++++++++++++++ flake.nix | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..2875c20 --- /dev/null +++ b/flake.lock @@ -0,0 +1,78 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1778716662, + "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1778869304, + "narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d233902339c02a9c334e7e593de68855ad26c4cb", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1777168982, + "narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "f5901329dade4a6ea039af1433fb087bd9c1fe14", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs", + "ttp": "ttp" + } + }, + "ttp": { + "flake": false, + "locked": { + "lastModified": 1778329030, + "narHash": "sha256-qEEPlOuGVco1g6lI/kfEvIZkJmBbjehuchGWPTywR10=", + "rev": "929cb9d3a6aebebe6365973f13062ac2a8e03af6", + "revCount": 115, + "type": "git", + "url": "https://git.methanium.net/Tensamin/TTP.git" + }, + "original": { + "rev": "929cb9d3a6aebebe6365973f13062ac2a8e03af6", + "type": "git", + "url": "https://git.methanium.net/Tensamin/TTP.git" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..9b4c07b --- /dev/null +++ b/flake.nix @@ -0,0 +1,206 @@ +{ + description = "Iota"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + ttp = { + url = "git+https://git.methanium.net/Tensamin/TTP.git?rev=929cb9d3a6aebebe6365973f13062ac2a8e03af6"; + flake = false; + }; + }; + + outputs = inputs@{ self, nixpkgs, flake-parts, ttp, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + + perSystem = { self', pkgs, ... }: { + packages = { + default = self'.packages.iota; + iota = pkgs.rustPlatform.buildRustPackage { + pname = "iota"; + version = "0.1.0"; + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + allowBuiltinFetchGit = true; + }; + nativeBuildInputs = with pkgs; [ cmake perl pkg-config ]; + buildInputs = with pkgs; [ openssl sqlite ]; + dontUseCmakeConfigure = true; + preConfigure = '' + if [ -d ../cargo-vendor-dir/ttp-core-0.1.0 ]; then + cp ${ttp}/ttp-codec.json ../cargo-vendor-dir/ttp-codec.json + fi + ''; + postInstall = '' + mv $out/bin/iota-core $out/bin/iota + for f in $out/bin/*; do + if [ "$(basename "$f")" != "iota" ]; then + rm "$f" + fi + done + ''; + passthru.dataDir = "/var/lib/iota"; + }; + }; + }; + + flake = { + nixosModules.default = { config, pkgs, lib, ... }: + let + 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}"); + + configFile = if cfg.settingsFile != null then cfg.settingsFile else + pkgs.writeText "iota-config.json" (builtins.toJSON cfg.settings); + + descriptionText = "Iota Service" + + lib.optionalString cfg.useTmux " (attach TUI: tmux -S ${cfg.dataDir}/tmux.sock attach -t iota)"; + in + { + options.services.iota = { + enable = lib.mkEnableOption "the Iota service"; + + dataDir = lib.mkOption { + type = lib.types.str; + default = cfg.package.passthru.dataDir or "/var/lib/iota"; + defaultText = lib.literalExpression ''config.services.iota.package.passthru.dataDir or "/var/lib/iota"''; + description = "Directory where Iota stores its data, config, and certificates."; + }; + + certFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Path to the SSL certificate file (cert.pem)."; + }; + + keyFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Path to the SSL private key file (cert.key)."; + }; + + environmentFiles = lib.mkOption { + type = lib.types.listOf lib.types.path; + default = [ ]; + description = "Environment files to load for the Iota service."; + }; + + openFirewall = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether to open the firewall for ports used by Iota."; + }; + + package = lib.mkOption { + type = lib.types.package; + default = defaultPackage; + description = "The Iota package to use."; + }; + + useTmux = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether to run Iota inside a tmux session for shared TUI access."; + }; + + settings = lib.mkOption { + type = lib.types.attrs; + default = { }; + description = "Configuration attributes for Iota, written to config.json."; + }; + + settingsFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Path to an existing config.json file to use instead of generating from settings."; + }; + }; + + config = lib.mkIf cfg.enable { + users.users.iota = { + isSystemUser = true; + group = "iota"; + home = cfg.dataDir; + createHome = true; + description = "Iota service user"; + }; + + users.groups.iota = { }; + + systemd.services.iota = { + description = descriptionText; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + Type = "simple"; + User = "iota"; + Group = "iota"; + WorkingDirectory = cfg.dataDir; + + ExecStart = if cfg.useTmux then + pkgs.writeShellScript "iota-start" '' + ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota ${cfg.package}/bin/iota + while ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock has-session -t iota 2>/dev/null; do + sleep 2 + done + '' + else + "${cfg.package}/bin/iota"; + + ExecStartPre = [ + ("+" + pkgs.writeShellScript "iota-setup" '' + mkdir -p ${cfg.dataDir}/certs + + ${lib.optionalString (cfg.certFile != null) "ln -sf ${cfg.certFile} ${cfg.dataDir}/certs/cert.pem"} + ${lib.optionalString (cfg.keyFile != null) "ln -sf ${cfg.keyFile} ${cfg.dataDir}/certs/cert.key"} + + install -m 644 ${configFile} ${cfg.dataDir}/config.json + + chown -R iota:iota ${cfg.dataDir} + + ${lib.optionalString cfg.useTmux '' + echo "Iota started under tmux. Attach with: tmux -S ${cfg.dataDir}/tmux.sock attach -t iota" >&2 + ''} + '') + ]; + + Restart = "unless-stopped"; + RestartSec = "5"; + + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; + + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + NoNewPrivileges = true; + ReadWritePaths = [ cfg.dataDir ]; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + } // lib.optionalAttrs (cfg.environmentFiles != [ ]) { + EnvironmentFile = cfg.environmentFiles; + }; + }; + + networking.firewall = lib.mkIf cfg.openFirewall { + allowedTCPPorts = [ 1984 ]; + allowedUDPPorts = [ 1984 ]; + }; + }; + }; + }; + }; +} From 7313c4af998b8cff33fc16aafcd92d8995b78df3 Mon Sep 17 00:00:00 2001 From: Alois Date: Sat, 16 May 2026 17:14:36 +0200 Subject: [PATCH 2/8] [Fix] Nix Flake --- flake.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 9b4c07b..b83cbd6 100644 --- a/flake.nix +++ b/flake.nix @@ -172,8 +172,8 @@ '') ]; - Restart = "unless-stopped"; - RestartSec = "5"; + Restart = "always"; + RestartSec = "5s"; AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; From f25815aa1b99dabbeaf544e1c7ea4695af330876 Mon Sep 17 00:00:00 2001 From: Alois Date: Sat, 16 May 2026 19:01:54 +0200 Subject: [PATCH 3/8] Added tppBind --- Cargo.lock | 4 ++-- flake.lock | 10 +++++----- flake.nix | 18 +++++++++++++++++- web-ui/src/server.rs | 11 +++++++---- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b19efe..420eb6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4317,7 +4317,7 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "ttp-core" version = "0.1.0" -source = "git+https://git.methanium.net/Tensamin/TTP.git#929cb9d3a6aebebe6365973f13062ac2a8e03af6" +source = "git+https://git.methanium.net/Tensamin/TTP.git#7e5d1953df8592a1feba0f390d205d0ef61a3119" dependencies = [ "base64", "byteorder", @@ -4330,7 +4330,7 @@ dependencies = [ [[package]] name = "ttp-native" version = "0.1.0" -source = "git+https://git.methanium.net/Tensamin/TTP.git#929cb9d3a6aebebe6365973f13062ac2a8e03af6" +source = "git+https://git.methanium.net/Tensamin/TTP.git#7e5d1953df8592a1feba0f390d205d0ef61a3119" dependencies = [ "quinn", "rustls", diff --git a/flake.lock b/flake.lock index 2875c20..dffc9d8 100644 --- a/flake.lock +++ b/flake.lock @@ -59,15 +59,15 @@ "ttp": { "flake": false, "locked": { - "lastModified": 1778329030, - "narHash": "sha256-qEEPlOuGVco1g6lI/kfEvIZkJmBbjehuchGWPTywR10=", - "rev": "929cb9d3a6aebebe6365973f13062ac2a8e03af6", - "revCount": 115, + "lastModified": 1778948017, + "narHash": "sha256-hqBYSZnPq7f/F2Z6nJK+6a8ITk6WRCcVBcNT0CR6SnM=", + "rev": "7e5d1953df8592a1feba0f390d205d0ef61a3119", + "revCount": 117, "type": "git", "url": "https://git.methanium.net/Tensamin/TTP.git" }, "original": { - "rev": "929cb9d3a6aebebe6365973f13062ac2a8e03af6", + "rev": "7e5d1953df8592a1feba0f390d205d0ef61a3119", "type": "git", "url": "https://git.methanium.net/Tensamin/TTP.git" } diff --git a/flake.nix b/flake.nix index b83cbd6..533af31 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; ttp = { - url = "git+https://git.methanium.net/Tensamin/TTP.git?rev=929cb9d3a6aebebe6365973f13062ac2a8e03af6"; + url = "git+https://git.methanium.net/Tensamin/TTP.git?rev=7e5d1953df8592a1feba0f390d205d0ef61a3119"; flake = false; }; }; @@ -98,6 +98,18 @@ description = "Whether to open the firewall for ports used by Iota."; }; + ttpBind = lib.mkOption { + type = lib.types.str; + default = "0.0.0.0"; + description = "IP address to bind the TTP/QUIC server to."; + }; + + bindAddress = lib.mkOption { + type = lib.types.str; + default = "0.0.0.0"; + description = "IP address to bind the HTTP server to."; + }; + package = lib.mkOption { type = lib.types.package; default = defaultPackage; @@ -190,6 +202,10 @@ RestrictSUIDSGID = true; LockPersonality = true; MemoryDenyWriteExecute = true; + Environment = [ + "TTP_BIND=${cfg.ttpBind}" + "BIND_ADDRESS=${cfg.bindAddress}" + ]; } // lib.optionalAttrs (cfg.environmentFiles != [ ]) { EnvironmentFile = cfg.environmentFiles; }; diff --git a/web-ui/src/server.rs b/web-ui/src/server.rs index edecfdd..263256e 100644 --- a/web-ui/src/server.rs +++ b/web-ui/src/server.rs @@ -19,10 +19,13 @@ use tokio::sync::oneshot; pub async fn start(port: u16) -> bool { let (tx, rx) = oneshot::channel::(); + let bind_addr = std::env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0".to_string()); + let bind_ip: std::net::IpAddr = bind_addr.parse().expect("Invalid BIND_ADDRESS"); + let _ = tokio::spawn(async move { let server = match load_tls_config() { Ok(Some(tls_config)) => { - log!("HTTPS (HTTP/2) Server running on 0.0.0.0:{}", port); + log!("HTTPS (HTTP/2) Server running on {}:{}", bind_addr, port); let _config = (*tls_config).clone(); HttpServer::new(move || { App::new() @@ -30,19 +33,19 @@ pub async fn start(port: u16) -> bool { .configure(api_config) .default_service(web::to(web_path_parser::handle)) }) - .bind(("0.0.0.0", port)) + .bind((bind_ip, port)) .unwrap() .run() } Ok(_) => { - log!("HTTP Server running on 0.0.0.0:{}", port); + log!("HTTP Server running on {}:{}", bind_addr, port); HttpServer::new(move || { App::new() .app_data(web::Data::new(false)) .configure(api_config) .default_service(web::to(web_path_parser::handle)) }) - .bind(("0.0.0.0", port)) + .bind((bind_ip, port)) .unwrap() .run() } From 83bd05b79146f3f8f8bc293d0a9bfd11c20c139a Mon Sep 17 00:00:00 2001 From: Alois Date: Sun, 17 May 2026 13:44:17 +0200 Subject: [PATCH 4/8] [Add] nix dev shell --- flake.lock | 21 +++++++++++++++ flake.nix | 77 ++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 69 insertions(+), 29 deletions(-) diff --git a/flake.lock b/flake.lock index dffc9d8..fb5bf79 100644 --- a/flake.lock +++ b/flake.lock @@ -53,9 +53,30 @@ "inputs": { "flake-parts": "flake-parts", "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay", "ttp": "ttp" } }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1778987862, + "narHash": "sha256-V3qGt9P1eJP/r/1ONablphfGiH0RP4agQhrRANpDYx8=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "6f44d8874ac29806c8d5cae42bf8e19ebb5ce0d3", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "ttp": { "flake": false, "locked": { diff --git a/flake.nix b/flake.nix index 533af31..8e9327e 100644 --- a/flake.nix +++ b/flake.nix @@ -4,13 +4,17 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; ttp = { url = "git+https://git.methanium.net/Tensamin/TTP.git?rev=7e5d1953df8592a1feba0f390d205d0ef61a3119"; flake = false; }; }; - outputs = inputs@{ self, nixpkgs, flake-parts, ttp, ... }: + outputs = inputs@{ self, nixpkgs, flake-parts, rust-overlay, ttp, ... }: flake-parts.lib.mkFlake { inherit inputs; } { systems = [ "x86_64-linux" @@ -19,37 +23,52 @@ "aarch64-darwin" ]; - perSystem = { self', pkgs, ... }: { - packages = { - default = self'.packages.iota; - iota = pkgs.rustPlatform.buildRustPackage { - pname = "iota"; - version = "0.1.0"; - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - allowBuiltinFetchGit = true; - }; - nativeBuildInputs = with pkgs; [ cmake perl pkg-config ]; - buildInputs = with pkgs; [ openssl sqlite ]; - dontUseCmakeConfigure = true; - preConfigure = '' - if [ -d ../cargo-vendor-dir/ttp-core-0.1.0 ]; then - cp ${ttp}/ttp-codec.json ../cargo-vendor-dir/ttp-codec.json - fi - ''; - postInstall = '' - mv $out/bin/iota-core $out/bin/iota - for f in $out/bin/*; do - if [ "$(basename "$f")" != "iota" ]; then - rm "$f" + perSystem = { self', pkgs, system, ... }: + let + rustPkgs = import nixpkgs { + inherit system; + overlays = [ (import rust-overlay) ]; + }; + rustToolchain = rustPkgs.rust-bin.stable.latest.default.override { + extensions = [ "rust-src" "rust-analyzer" "clippy" "rustfmt" ]; + }; + in + { + packages = { + default = self'.packages.iota; + iota = pkgs.rustPlatform.buildRustPackage { + pname = "iota"; + version = "0.1.0"; + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + allowBuiltinFetchGit = true; + }; + nativeBuildInputs = with pkgs; [ cmake perl pkg-config ]; + buildInputs = with pkgs; [ openssl sqlite ]; + dontUseCmakeConfigure = true; + preConfigure = '' + if [ -d ../cargo-vendor-dir/ttp-core-0.1.0 ]; then + cp ${ttp}/ttp-codec.json ../cargo-vendor-dir/ttp-codec.json fi - done - ''; - passthru.dataDir = "/var/lib/iota"; + ''; + postInstall = '' + mv $out/bin/iota-core $out/bin/iota + for f in $out/bin/*; do + if [ "$(basename "$f")" != "iota" ]; then + rm "$f" + fi + done + ''; + passthru.dataDir = "/var/lib/iota"; + }; + }; + + devShells.default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ rustToolchain git cmake perl pkg-config ]; + buildInputs = with pkgs; [ openssl sqlite ]; }; }; - }; flake = { nixosModules.default = { config, pkgs, lib, ... }: From 045e2ff15cc52514579c5efd4da3ee8809bbb42a Mon Sep 17 00:00:00 2001 From: Alois Date: Sun, 17 May 2026 19:30:11 +0200 Subject: [PATCH 5/8] [Add] systemd log wrapper to nix flake --- flake.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 8e9327e..8cea3ba 100644 --- a/flake.nix +++ b/flake.nix @@ -178,13 +178,14 @@ ExecStart = if cfg.useTmux then pkgs.writeShellScript "iota-start" '' - ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota ${cfg.package}/bin/iota + ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota \ + '${cfg.package}/bin/iota 2>&1 | ${pkgs.systemd}/bin/systemd-cat -t iota-daemon' while ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock has-session -t iota 2>/dev/null; do sleep 2 done '' else - "${cfg.package}/bin/iota"; + "${pkgs.systemd}/bin/systemd-cat -t iota-daemon ${cfg.package}/bin/iota"; ExecStartPre = [ ("+" + pkgs.writeShellScript "iota-setup" '' From 5d5585cb7f1b3dadd919ab215a9d6fd0c12aae4d Mon Sep 17 00:00:00 2001 From: Alois Date: Sun, 17 May 2026 19:43:55 +0200 Subject: [PATCH 6/8] Updated systemd stuff --- flake.nix | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index 8cea3ba..32e59e0 100644 --- a/flake.nix +++ b/flake.nix @@ -178,14 +178,22 @@ ExecStart = if cfg.useTmux then pkgs.writeShellScript "iota-start" '' - ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota \ - '${cfg.package}/bin/iota 2>&1 | ${pkgs.systemd}/bin/systemd-cat -t iota-daemon' + ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota ' + ${cfg.package}/bin/iota 2>&1 | ${pkgs.coreutils}/bin/tee ${cfg.dataDir}/iota-output.log + EXIT_CODE=$? + echo "" + echo "============================================" + echo "Iota exited with code: $EXIT_CODE" + echo "Output saved to: ${cfg.dataDir}/iota-output.log" + echo "Press ENTER to close this session..." + read -r + ' while ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock has-session -t iota 2>/dev/null; do sleep 2 done '' else - "${pkgs.systemd}/bin/systemd-cat -t iota-daemon ${cfg.package}/bin/iota"; + "${cfg.package}/bin/iota"; ExecStartPre = [ ("+" + pkgs.writeShellScript "iota-setup" '' From b7f6ccf8a7cf002940ca100747185ee2cdd3603a Mon Sep 17 00:00:00 2001 From: Alois Date: Sun, 17 May 2026 20:06:08 +0200 Subject: [PATCH 7/8] [Add] debugging to systemd nix service --- flake.nix | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index 32e59e0..7b5e19f 100644 --- a/flake.nix +++ b/flake.nix @@ -179,11 +179,9 @@ ExecStart = if cfg.useTmux then pkgs.writeShellScript "iota-start" '' ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota ' + echo "debug: starting iota..." ${cfg.package}/bin/iota 2>&1 | ${pkgs.coreutils}/bin/tee ${cfg.dataDir}/iota-output.log EXIT_CODE=$? - echo "" - echo "============================================" - echo "Iota exited with code: $EXIT_CODE" echo "Output saved to: ${cfg.dataDir}/iota-output.log" echo "Press ENTER to close this session..." read -r From e18e8d1151567afe892ce6b4d430e440a54a801d Mon Sep 17 00:00:00 2001 From: Alois Date: Sun, 17 May 2026 20:21:58 +0200 Subject: [PATCH 8/8] [Fix] tmux based systemd service --- flake.nix | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/flake.nix b/flake.nix index 7b5e19f..b422ab5 100644 --- a/flake.nix +++ b/flake.nix @@ -169,30 +169,29 @@ description = descriptionText; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; + path = [ pkgs.tmux pkgs.bash pkgs.coreutils pkgs.systemd ]; serviceConfig = { - Type = "simple"; + Type = if cfg.useTmux then "forking" else "simple"; User = "iota"; Group = "iota"; WorkingDirectory = cfg.dataDir; ExecStart = if cfg.useTmux then pkgs.writeShellScript "iota-start" '' - ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota ' - echo "debug: starting iota..." - ${cfg.package}/bin/iota 2>&1 | ${pkgs.coreutils}/bin/tee ${cfg.dataDir}/iota-output.log - EXIT_CODE=$? - echo "Output saved to: ${cfg.dataDir}/iota-output.log" - echo "Press ENTER to close this session..." - read -r - ' - while ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock has-session -t iota 2>/dev/null; do - sleep 2 - done + ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota \ + "${pkgs.bash}/bin/bash -lc 'exec > >(${pkgs.coreutils}/bin/tee -a ${cfg.dataDir}/iota-output.log >(${pkgs.systemd}/bin/systemd-cat -t iota-daemon)) 2>&1; ${cfg.package}/bin/iota; status=$?; printf \"\nProcess exited with status %s. Press any key to close this tmux session...\" \"\$status\"; read -r -n 1; exit \"\$status\"'" '' else "${cfg.package}/bin/iota"; + ExecStop = if cfg.useTmux then + (pkgs.writeShellScript "iota-stop" '' + ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock kill-session -t iota 2>/dev/null || true + '') + else + null; + ExecStartPre = [ ("+" + pkgs.writeShellScript "iota-setup" '' mkdir -p ${cfg.dataDir}/certs