[Clean] Remove legacy TTP flake configuration

This commit is contained in:
Alois 2026-07-20 18:56:49 +02:00
commit 9d67824f28
2 changed files with 265 additions and 265 deletions

19
flake.lock generated
View file

@ -53,8 +53,7 @@
"inputs": { "inputs": {
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay", "rust-overlay": "rust-overlay"
"ttp": "ttp"
} }
}, },
"rust-overlay": { "rust-overlay": {
@ -76,22 +75,6 @@
"repo": "rust-overlay", "repo": "rust-overlay",
"type": "github" "type": "github"
} }
},
"ttp": {
"flake": false,
"locked": {
"lastModified": 1780494955,
"narHash": "sha256-i2VRRF6yNips3c4JHgfvmvMxb0HTkTCn69lmsKZLHRw=",
"ref": "refs/heads/main",
"rev": "23438fa8f884e6ad0d32ca1004c0dedcce0cc8d2",
"revCount": 125,
"type": "git",
"url": "https://git.methanium.net/tensamin/ttp.git"
},
"original": {
"type": "git",
"url": "https://git.methanium.net/tensamin/ttp.git"
}
} }
}, },
"root": "root", "root": "root",

483
flake.nix
View file

@ -8,21 +8,17 @@
url = "github:oxalica/rust-overlay"; url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
ttp = {
url = "git+https://git.methanium.net/tensamin/ttp.git";
flake = false;
};
}; };
outputs = inputs @ { outputs =
self, inputs@{
nixpkgs, self,
flake-parts, nixpkgs,
rust-overlay, flake-parts,
ttp, rust-overlay,
... ...
}: }:
flake-parts.lib.mkFlake {inherit inputs;} { flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ systems = [
"x86_64-linux" "x86_64-linux"
"aarch64-linux" "aarch64-linux"
@ -30,253 +26,274 @@
"aarch64-darwin" "aarch64-darwin"
]; ];
perSystem = { perSystem =
self', {
pkgs, self',
system, pkgs,
... system,
}: let ...
rustPkgs = import nixpkgs { }:
inherit system; let
overlays = [(import rust-overlay)]; rustPkgs = import nixpkgs {
}; inherit system;
rustToolchain = rustPkgs.rust-bin.stable.latest.default.override { overlays = [ (import rust-overlay) ];
extensions = ["rust-src" "rust-analyzer" "clippy" "rustfmt"]; };
}; rustToolchain = rustPkgs.rust-bin.stable.latest.default.override {
in { extensions = [
packages = { "rust-src"
default = self'.packages.iota; "rust-analyzer"
iota = pkgs.rustPlatform.buildRustPackage { "clippy"
pname = "iota"; "rustfmt"
version = "0.1.0"; ];
src = ./.; };
cargoLock = { in
lockFile = ./Cargo.lock; {
allowBuiltinFetchGit = true; 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;
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";
}; };
nativeBuildInputs = with pkgs; [cmake perl pkg-config]; };
buildInputs = with pkgs; [openssl sqlite];
dontUseCmakeConfigure = true; devShells.default = pkgs.mkShell {
preConfigure = '' nativeBuildInputs = with pkgs; [
if [ -d ../cargo-vendor-dir/ttp-core-0.1.0 ]; then rustToolchain
cp ${ttp}/ttp-codec.json ../cargo-vendor-dir/ttp-codec.json git
fi cmake
''; perl
postInstall = '' pkg-config
mv $out/bin/iota-core $out/bin/iota ];
for f in $out/bin/*; do buildInputs = with pkgs; [
if [ "$(basename "$f")" != "iota" ]; then openssl
rm "$f" sqlite
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 = { flake = {
nixosModules.default = { nixosModules.default =
config, {
pkgs, config,
lib, 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}"); 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 = configFile =
if cfg.settingsFile != null if cfg.settingsFile != null then
then cfg.settingsFile cfg.settingsFile
else pkgs.writeText "iota-config.json" (builtins.toJSON cfg.settings); else
pkgs.writeText "iota-config.json" (builtins.toJSON cfg.settings);
descriptionText = "Tensamin Iota"; descriptionText = "Tensamin Iota";
#+ lib.optionalString cfg.useTmux " (attach TUI: tmux -S ${cfg.dataDir}/tmux.sock attach -t iota)"; #+ lib.optionalString cfg.useTmux " (attach TUI: tmux -S ${cfg.dataDir}/tmux.sock attach -t iota)";
in { in
options.services.iota = { {
enable = lib.mkEnableOption "Enable the Iota service."; options.services.iota = {
enable = lib.mkEnableOption "Enable the Iota service.";
dataDir = lib.mkOption { dataDir = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = cfg.package.passthru.dataDir or "/var/lib/iota"; default = cfg.package.passthru.dataDir or "/var/lib/iota";
defaultText = lib.literalExpression ''config.services.iota.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."; 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.";
};
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;
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.";
};
}; };
certFile = lib.mkOption { config = lib.mkIf cfg.enable {
type = lib.types.nullOr lib.types.path; users.users.iota = {
default = null; isSystemUser = true;
description = "Path to the SSL certificate file (cert.pem)."; group = "iota";
}; home = cfg.dataDir;
createHome = true;
description = "Iota service user";
shell = pkgs.bash;
};
keyFile = lib.mkOption { users.groups.iota = { };
type = lib.types.nullOr lib.types.path;
default = null;
description = "Path to the SSL private key file (cert.key).";
};
environmentFiles = lib.mkOption { systemd.services.iota =
type = lib.types.listOf lib.types.path; let
default = []; iotaTmuxCmd = pkgs.writeShellScript "iota-tmux-cmd" ''
description = "Environment files to load for the Iota service."; mkdir -p ${cfg.dataDir}
}; echo "[$(date)] Running Iota..."
${cfg.package}/bin/iota
openFirewall = lib.mkOption { status=$?
type = lib.types.bool; echo ""
default = true; echo "[$(date)] Iota exited with status: $status"
description = "Whether to open the firewall for ports used by Iota."; echo "Press any key to exit..."
}; read -r -n 1
exit $status
ttpBind = lib.mkOption { '';
type = lib.types.str; in
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;
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";
shell = pkgs.bash;
};
users.groups.iota = {};
systemd.services.iota = let
iotaTmuxCmd = pkgs.writeShellScript "iota-tmux-cmd" ''
mkdir -p ${cfg.dataDir}
echo "[$(date)] Running Iota..."
${cfg.package}/bin/iota
status=$?
echo ""
echo "[$(date)] Iota exited with status: $status"
echo "Press any key to exit..."
read -r -n 1
exit $status
'';
in {
description = descriptionText;
wantedBy = ["multi-user.target"];
after = ["network.target"];
serviceConfig =
{ {
Type = "simple"; description = descriptionText;
User = "iota"; wantedBy = [ "multi-user.target" ];
Group = "iota"; after = [ "network.target" ];
WorkingDirectory = cfg.dataDir;
ExecStart = serviceConfig = {
if cfg.useTmux Type = "simple";
then User = "iota";
pkgs.writeShellScript "iota-start" '' Group = "iota";
set -e WorkingDirectory = cfg.dataDir;
export TMUX_TMPDIR=${cfg.dataDir}
${pkgs.coreutils}/bin/mkdir -p ${cfg.dataDir}
${pkgs.coreutils}/bin/chown iota:iota ${cfg.dataDir}
echo "[iota-start] Creating tmux session..." ExecStart =
if ! ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota "${iotaTmuxCmd}"; then if cfg.useTmux then
echo "[iota-start] ERROR: tmux new-session failed" pkgs.writeShellScript "iota-start" ''
exit 1 set -e
fi export TMUX_TMPDIR=${cfg.dataDir}
echo "[iota-start] tmux session created, waiting..." ${pkgs.coreutils}/bin/mkdir -p ${cfg.dataDir}
echo "[iota-start] Run 'tmux -S ${cfg.dataDir}/tmux.sock attach -t iota' to attach to the tmux session." ${pkgs.coreutils}/bin/chown iota:iota ${cfg.dataDir}
while ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock has-session -t iota 2>/dev/null; do echo "[iota-start] Creating tmux session..."
sleep 2 if ! ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock new-session -d -s iota "${iotaTmuxCmd}"; then
done echo "[iota-start] ERROR: tmux new-session failed"
echo "[iota-start] tmux session ended" exit 1
'' fi
else "${cfg.package}/bin/iota"; echo "[iota-start] tmux session created, waiting..."
echo "[iota-start] Run 'tmux -S ${cfg.dataDir}/tmux.sock attach -t iota' to attach to the tmux session."
ExecStartPre = [ while ${pkgs.tmux}/bin/tmux -S ${cfg.dataDir}/tmux.sock has-session -t iota 2>/dev/null; do
("+" sleep 2
+ pkgs.writeShellScript "iota-setup" '' done
mkdir -p ${cfg.dataDir}/certs echo "[iota-start] tmux session ended"
''
else
"${cfg.package}/bin/iota";
${lib.optionalString (cfg.certFile != null) "ln -sf ${cfg.certFile} ${cfg.dataDir}/certs/cert.pem"} ExecStartPre = [
${lib.optionalString (cfg.keyFile != null) "ln -sf ${cfg.keyFile} ${cfg.dataDir}/certs/cert.key"} (
"+"
+ pkgs.writeShellScript "iota-setup" ''
mkdir -p ${cfg.dataDir}/certs
install -m 644 ${configFile} ${cfg.dataDir}/config.json ${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"}
chown -R iota:iota ${cfg.dataDir} install -m 644 ${configFile} ${cfg.dataDir}/config.json
'')
];
Restart = "always"; chown -R iota:iota ${cfg.dataDir}
RestartSec = "5s"; ''
)
];
AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; Restart = "always";
CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"]; RestartSec = "5s";
ProtectSystem = "strict"; AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
ProtectHome = true; CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
PrivateTmp = true;
NoNewPrivileges = true; ProtectSystem = "strict";
ReadWritePaths = [cfg.dataDir]; ProtectHome = true;
ProtectKernelTunables = true; PrivateTmp = true;
ProtectKernelModules = true; NoNewPrivileges = true;
ProtectControlGroups = true; ReadWritePaths = [ cfg.dataDir ];
RestrictRealtime = true; ProtectKernelTunables = true;
RestrictSUIDSGID = true; ProtectKernelModules = true;
LockPersonality = true; ProtectControlGroups = true;
MemoryDenyWriteExecute = true; RestrictRealtime = true;
Environment = [ RestrictSUIDSGID = true;
"TTP_BIND=${cfg.ttpBind}" LockPersonality = true;
"BIND_ADDRESS=${cfg.bindAddress}" MemoryDenyWriteExecute = true;
]; Environment = [
} "BIND_ADDRESS=${cfg.bindAddress}"
// lib.optionalAttrs (cfg.environmentFiles != []) { ];
EnvironmentFile = cfg.environmentFiles; }
// lib.optionalAttrs (cfg.environmentFiles != [ ]) {
EnvironmentFile = cfg.environmentFiles;
};
}; };
};
networking.firewall = lib.mkIf cfg.openFirewall { networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [1984]; allowedTCPPorts = [ 1984 ];
allowedUDPPorts = [1984]; allowedUDPPorts = [ 1984 ];
};
}; };
}; };
};
}; };
}; };
} }