fix: packetTracer wrapper not accepting path

This commit is contained in:
Peritia 2025-10-01 15:56:44 +02:00
parent 8da6048c48
commit f1b88ffb81

View file

@ -2,28 +2,36 @@
# #
# This NixOS module installs Cisco Packet Tracer declaratively. # This NixOS module installs Cisco Packet Tracer declaratively.
# #
# Supported input formats for `source`: # Supports multiple formats for `source`:
# - /nix/store/<hash>-file.deb (preferred, pure and cached)
# - "https://example.com/file.deb" (requires `sha256`)
# - ./relative/path/to/file.deb (will be imported into the Nix store)
# #
# Example: # 1. URL Mode (must start with http/https):
# source = "http://example.com/PacketTracer.deb";
# sha256 = "...";
#
# 2. Derivation / Path Mode (outputs from fetchzip, fetchgit, or /nix/store/...):
# source = pkgs.fetchzip { ... };
# source = /nix/store/<hash>-PacketTracer.deb;
#
# 3. Directory Mode (path or derivation pointing to a folder — auto-detects .deb):
# source = /nix/store/<hash>-packettracer-src/;
#
# Example Usage:
# #
# nyx-module.system.packetTracer = { # nyx-module.system.packetTracer = {
# enable = true; # enable = true;
# source = ./Packet_Tracer822_amd64_signed.deb; # source = "http://example.com/PacketTracer.deb";
# sha256 = ".....";
# }; # };
# #
# Notes: # nyx-module.system.packetTracer = {
# • If using a URL Cisco's official download links may not work without login # enable = true;
# Thats why I recommend using a local path that you added into the store # source = pkgs.fetchzip {
# • If using a local non-store absolute path (e.g. /home/user/file.deb), # url = "https://example.com/archivedPacketTracer.zip";
# you must first import it: # sha256 = "sha256-...";
# };
# };
# #
# nix store add-path /home/user/file.deb
# #
# Then use the resulting /nix/store/... path instead.
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
@ -32,42 +40,68 @@ with lib;
let let
cfg = config.nyx-module.system.packetTracer; cfg = config.nyx-module.system.packetTracer;
isUrl = s: hasPrefix "http://" s || hasPrefix "https://" s; isUrl = s:
isAbsolute = s: hasPrefix "/" s; builtins.isString s
isNixStore = s: hasPrefix "/nix/store/" s; && (hasPrefix "http://" s || hasPrefix "https://" s);
isRelative = s: hasPrefix "./" s;
isPathType = v: builtins.isPath v;
isPathString = s:
builtins.isString s && hasPrefix "/" s;
# Normalize `source` into something that can be given to PacketTracer override
src = src =
if isPathType cfg.source then if isUrl cfg.source then
cfg.source
else if isUrl cfg.source then
pkgs.fetchurl { pkgs.fetchurl {
url = cfg.source; url = cfg.source;
sha256 = cfg.sha256; sha256 = cfg.sha256;
} }
else else if isDerivation cfg.source || builtins.isPath cfg.source || isPathString cfg.source then
cfg.source; let
# Convert to string path
pathStr = toString cfg.source;
# Read directory?
entries = builtins.tryEval (builtins.readDir pathStr);
in in
{ if entries.success then
# Directory mode — auto-detect *.deb
let
files = builtins.attrNames entries.value;
debs = builtins.filter (n: lib.hasSuffix ".deb" n) files;
in
if builtins.length debs == 1 then
pathStr + "/" + builtins.elemAt debs 0
else if builtins.length debs == 0 then
(throw "nyx.packetTracer: No .deb found in directory ${pathStr}")
else
(throw "nyx.packetTracer: Multiple .deb files found in directory ${pathStr}")
else
# Probably a direct file
pathStr
else
throw "nyx.packetTracer: Invalid source; must be URL, derivation, or path.";
in {
options.nyx-module.system.packetTracer = { options.nyx-module.system.packetTracer = {
enable = mkEnableOption "Cisco Packet Tracer installation"; enable = mkEnableOption "Cisco Packet Tracer installation";
source = mkOption { source = mkOption {
type = with types; oneOf [ path str ]; type = with types; oneOf [ str path ];
default = ""; default = "";
description = '' description = ''
Allowed: Source of the Packet Tracer .deb file.
/nix/store/<hash>-file.deb
https://example.com/file.deb (requires sha256) Accepted:
./relative/path.deb "https://example.com/file.deb" (requires sha256)
pkgs.fetchzip { ... }
Checkout https://github.com/Peritia-System/Nyx-Modules/blob/main/Modules/System/Application/Special-Applications/packettracer.nix
''; '';
}; };
sha256 = mkOption { sha256 = mkOption {
type = types.str; type = types.str;
default = lib.fakeSha256; default = "";
description = "SHA-256 for URL sources."; description = "Required only when `source` is a URL.";
}; };
}; };
@ -75,29 +109,13 @@ in
assertions = [ assertions = [
{ {
assertion = cfg.source != ""; assertion = isUrl cfg.source || isDerivation cfg.source
message = "nyx-module.system.packetTracer.source must be set when packetTracer is enabled."; || builtins.isPath cfg.source || isPathString cfg.source;
message = "source must be URL, derivation, or /nix/store path.";
} }
{ {
assertion = !(isAbsolute cfg.source && !isNixStore cfg.source); assertion = !(isUrl cfg.source && cfg.sha256 == "");
message = '' message = "sha256 is required when source is a URL.";
nyx-module.system.packetTracer.source points to a non-store absolute path:
${cfg.source}
Pure evaluation cannot use /home, /tmp, /mnt, or other "normal" paths.
It can only use /nix/store/... paths
First import it into the Nix store:
nix store add-path ${cfg.source}
Then use the resulting /nix/store/... path instead.
'';
}
{
assertion = !(isUrl cfg.source && cfg.sha256 == lib.fakeSha256);
message = "nyx-module.system.packetTracer.sha256 must be set when using a URL source.";
} }
]; ];