diff --git a/flake.nix b/flake.nix index 190eb576c..602a3481f 100644 --- a/flake.nix +++ b/flake.nix @@ -7,151 +7,153 @@ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; }; - outputs = { - self, - nixpkgs, - ... - } @ inputs: let - inherit (nixpkgs) lib; + outputs = + { self, nixpkgs, ... }: + let + inherit (nixpkgs) lib; - nixDir = ./packaging/nix; + nixDir = ./packaging/nix; - # Add separateDebugInfo to a derivation - addSeparateDebugInfo = d: - d.overrideAttrs { - separateDebugInfo = true; - }; + # Add separateDebugInfo to a derivation + addSeparateDebugInfo = d: d.overrideAttrs { separateDebugInfo = true; }; - # Supported systems for native compilation - supportedSystems = ["x86_64-linux" "aarch64-linux"]; + # Supported systems for native compilation + supportedSystems = [ + "x86_64-linux" + "aarch64-linux" + ]; - # Generate attributes corresponding to all the supported systems - forSupportedSystems = lib.genAttrs supportedSystems; + # Generate attributes corresponding to all the supported systems + forSupportedSystems = lib.genAttrs supportedSystems; - # Initialize nixpkgs for the specified `system` - pkgsFor = system: - import nixpkgs { - inherit system; - overlays = with self.overlays; [default]; - }; - - # Initialize development nixpkgs for the specified `system` - devPkgsFor = system: - import nixpkgs { - inherit system; - overlays = with self.overlays; [default debug]; - }; - - # Build villas and its dependencies for the specified `pkgs` - packagesWith = pkgs: rec { - default = villas-node; - - villas-node-python = pkgs.callPackage (nixDir + "/python.nix") { - src = ./.; - }; - - villas-node-minimal = pkgs.callPackage (nixDir + "/villas.nix") { - src = ./.; - version = "minimal"; - }; - - villas-node = villas-node-minimal.override { - version = "full"; - withAllExtras = true; - withAllFormats = true; - withAllHooks = true; - withAllNodes = true; - }; - }; - in { - # Standard flake attribute for normal packages (not cross-compiled) - packages = forSupportedSystems ( - system: - packagesWith (pkgsFor system) - ); - - # Standard flake attribute allowing you to add the villas packages to your nixpkgs - overlays = { - default = final: prev: packagesWith final; - debug = final: prev: { - jansson = addSeparateDebugInfo prev.jansson; - libmodbus = addSeparateDebugInfo prev.libmodbus; - }; - minimal = final: prev: { - mosquitto = prev.mosquitto.override {systemd = final.systemdMinimal;}; - rdma-core = prev.rdma-core.override {udev = final.systemdMinimal;}; - }; - }; - - # Standard flake attribute for defining developer environments - devShells = forSupportedSystems ( - system: let - pkgs = devPkgsFor system; - shellHook = ''[ -z "$PS1" ] || exec "$SHELL"''; - hardeningDisable = ["all"]; - packages = with pkgs; [ - bashInteractive - bc - boxfort - clang-tools - criterion - jq - libffi - libgit2 - pcre - reuse - cppcheck - ]; - in rec { - default = full; - - full = pkgs.mkShell { - inherit shellHook hardeningDisable packages; - name = "full"; - inputsFrom = with pkgs; [villas-node]; + # Initialize nixpkgs for the specified `system` + pkgsFor = + system: + import nixpkgs { + inherit system; + overlays = with self.overlays; [ default ]; }; - python = pkgs.mkShell { - inherit shellHook hardeningDisable; - name = "python"; - inputsFrom = with pkgs; [villas-node-python]; - packages = with pkgs; - packages - ++ [ - (python3.withPackages (python-pkgs: [ - python-pkgs.build - python-pkgs.twine - ])) - ]; + # Initialize development nixpkgs for the specified `system` + devPkgsFor = + system: + import nixpkgs { + inherit system; + overlays = with self.overlays; [ + default + debug + ]; }; - } - ); - # Standard flake attribute to add additional checks to `nix flake check` - checks = forSupportedSystems ( - system: let - pkgs = pkgsFor system; - in { - fmt = pkgs.runCommand "check-fmt" {} '' - cd ${self} - "${pkgs.nixfmt}/bin/nixfmt" --check . 2>> $out - ''; - } - ); + # Build villas and its dependencies for the specified `pkgs` + packagesWith = pkgs: rec { + default = villas-node; - # Standard flake attribute specifying the formatter invoked on `nix fmt` - formatter = forSupportedSystems (system: (pkgsFor system).alejandra); + villas-node-python = pkgs.callPackage (nixDir + "/python.nix") { src = ./.; }; - # Standard flake attribute for NixOS modules - nixosModules = rec { - default = villas; + villas-node-minimal = pkgs.callPackage (nixDir + "/villas.nix") { + src = ./.; + version = "minimal"; + }; - villas = { - imports = [(nixDir + "/module.nix")]; - nixpkgs.overlays = [ - self.overlays.default - ]; + villas-node = villas-node-minimal.override { + version = "full"; + withAllExtras = true; + withAllFormats = true; + withAllHooks = true; + withAllNodes = true; + }; + }; + in + { + # Standard flake attribute for normal packages (not cross-compiled) + packages = forSupportedSystems (system: packagesWith (pkgsFor system)); + + # Standard flake attribute allowing you to add the villas packages to your nixpkgs + overlays = { + default = final: prev: packagesWith final; + debug = final: prev: { + jansson = addSeparateDebugInfo prev.jansson; + libmodbus = addSeparateDebugInfo prev.libmodbus; + }; + minimal = final: prev: { + mosquitto = prev.mosquitto.override { systemd = final.systemdMinimal; }; + rdma-core = prev.rdma-core.override { udev = final.systemdMinimal; }; + }; + }; + + # Standard flake attribute for defining developer environments + devShells = forSupportedSystems ( + system: + let + pkgs = devPkgsFor system; + shellHook = ''[ -z "$PS1" ] || exec "$SHELL"''; + hardeningDisable = [ "all" ]; + packages = with pkgs; [ + bashInteractive + bc + boxfort + clang-tools + criterion + jq + libffi + libgit2 + pcre + reuse + cppcheck + ]; + in + rec { + default = full; + + full = pkgs.mkShell { + inherit shellHook hardeningDisable packages; + name = "full"; + inputsFrom = with pkgs; [ villas-node ]; + }; + + python = pkgs.mkShell { + inherit shellHook hardeningDisable; + name = "python"; + inputsFrom = with pkgs; [ villas-node-python ]; + packages = + with pkgs; + packages + ++ [ + (python3.withPackages (python-pkgs: [ + python-pkgs.build + python-pkgs.twine + ])) + ]; + }; + } + ); + + # Standard flake attribute to add additional checks to `nix flake check` + checks = forSupportedSystems ( + system: + let + pkgs = pkgsFor system; + in + { + fmt = pkgs.runCommand "check-fmt" { } '' + cd ${self} + "${pkgs.nixfmt}/bin/nixfmt" --check . 2>> $out + ''; + } + ); + + # Standard flake attribute specifying the formatter invoked on `nix fmt` + formatter = forSupportedSystems (system: (pkgsFor system).alejandra); + + # Standard flake attribute for NixOS modules + nixosModules = rec { + default = villas; + + villas = { + imports = [ (nixDir + "/module.nix") ]; + nixpkgs.overlays = [ self.overlays.default ]; + }; }; }; - }; } diff --git a/packaging/nix/module.nix b/packaging/nix/module.nix index 29b1d3d45..145e59f24 100644 --- a/packaging/nix/module.nix +++ b/packaging/nix/module.nix @@ -5,70 +5,73 @@ lib, pkgs, ... -}: let +}: +let cfg = config.services.villas.node; villasNodeCfg = pkgs.writeText "villas-node.conf" (builtins.toJSON cfg.config); in - with lib; { - options = { - services.villas.node = { - enable = mkEnableOption (lib.mdDoc "VILLASnode is a client/server application to connect simulation equipment and software."); +with lib; +{ + options = { + services.villas.node = { + enable = mkEnableOption ( + lib.mdDoc "VILLASnode is a client/server application to connect simulation equipment and software." + ); - package = mkPackageOption pkgs "villas-node" {}; + package = mkPackageOption pkgs "villas-node" { }; - configPath = mkOption { - type = types.nullOr types.path; - description = mdDoc '' - A path to a VILLASnode configuration file. - ''; - default = null; + configPath = mkOption { + type = types.nullOr types.path; + description = mdDoc '' + A path to a VILLASnode configuration file. + ''; + default = null; + }; + + config = mkOption { + type = types.attrsOf types.anything; + default = { + nodes = { }; + paths = [ ]; + idle_stop = false; # Do not stop daemon because of empty paths }; - config = mkOption { - type = types.attrsOf types.anything; - default = { - nodes = {}; - paths = []; - idle_stop = false; # Do not stop daemon because of empty paths - }; + description = mdDoc '' + Contents of the VILLASnode configuration file, + {file}`villas-node.json`. - description = mdDoc '' - Contents of the VILLASnode configuration file, - {file}`villas-node.json`. - - See: https://villas.fein-aachen.org/docs/node/config/ - ''; - }; + See: https://villas.fein-aachen.org/docs/node/config/ + ''; }; }; + }; - config = mkIf cfg.enable { - assertions = [ - { - assertion = cfg.config != null && cfg.config != {}; - message = "You must provide services.villas.node.config."; - } - ]; + config = mkIf cfg.enable { + assertions = [ + { + assertion = cfg.config != null && cfg.config != { }; + message = "You must provide services.villas.node.config."; + } + ]; - # Configuration file indirection is needed to support reloading - environment.etc."villas/node.json" = mkIf (builtins.isNull cfg.configPath) { - source = villasNodeCfg; - }; + # Configuration file indirection is needed to support reloading + environment.etc."villas/node.json" = mkIf (builtins.isNull cfg.configPath) { + source = villasNodeCfg; + }; - systemd.services.villas-node = { - description = "VILLASnode"; - after = ["network.target"]; - wantedBy = ["multi-user.target"]; - serviceConfig = { - Type = "simple"; - ExecStart = let - cfgPath = - if isNull cfg.configPath - then "/etc/villas/node.json" - else cfg.configPath; - in "${lib.getExe cfg.package} node ${cfgPath}"; - }; + systemd.services.villas-node = { + description = "VILLASnode"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "simple"; + ExecStart = + let + cfgPath = if isNull cfg.configPath then "/etc/villas/node.json" else cfg.configPath; + in + "${lib.getExe cfg.package} node ${cfgPath}"; }; }; - } + }; +} diff --git a/packaging/nix/python.nix b/packaging/nix/python.nix index 842503bd0..d91af6ef0 100644 --- a/packaging/nix/python.nix +++ b/packaging/nix/python.nix @@ -14,9 +14,7 @@ python3Packages.buildPythonPackage { requests protobuf ]; - build-system = with python3Packages; [ - setuptools - ]; + build-system = with python3Packages; [ setuptools ]; nativeCheckInputs = with python3Packages; [ black flake8 diff --git a/packaging/nix/villas.nix b/packaging/nix/villas.nix index f174eb78e..923b35c81 100644 --- a/packaging/nix/villas.nix +++ b/packaging/nix/villas.nix @@ -78,12 +78,15 @@ stdenv.mkDerivation { inherit src version; pname = "villas"; - outputs = ["out" "dev"]; + outputs = [ + "out" + "dev" + ]; separateDebugInfo = true; cmakeFlags = - [] - ++ lib.optionals (!withGpl) ["-DWITHOUT_GPL=ON"] - ++ lib.optionals withFormatProtobuf ["-DCMAKE_FIND_ROOT_PATH=${protobufcBuildBuild}/bin"]; + [ ] + ++ lib.optionals (!withGpl) [ "-DWITHOUT_GPL=ON" ] + ++ lib.optionals withFormatProtobuf [ "-DCMAKE_FIND_ROOT_PATH=${protobufcBuildBuild}/bin" ]; postPatch = '' patchShebangs --host ./tools ''; @@ -93,16 +96,28 @@ stdenv.mkDerivation { rm -d $out/include/villas fi wrapProgram $out/bin/villas \ - --set PATH ${lib.makeBinPath [(placeholder "out") gnugrep coreutils]} + --set PATH ${ + lib.makeBinPath [ + (placeholder "out") + gnugrep + coreutils + ] + } wrapProgram $out/bin/villas-api \ - --set PATH ${lib.makeBinPath [coreutils curl jq]} + --set PATH ${ + lib.makeBinPath [ + coreutils + curl + jq + ] + } ''; nativeBuildInputs = [ cmake makeWrapper pkg-config ]; - depsBuildBuild = lib.optionals withFormatProtobuf [protobufcBuildBuild]; + depsBuildBuild = lib.optionals withFormatProtobuf [ protobufcBuildBuild ]; buildInputs = [ jansson @@ -112,27 +127,30 @@ stdenv.mkDerivation { curl spdlog ] - ++ lib.optionals withExtraConfig [libconfig] - ++ lib.optionals withExtraGraphviz [graphviz] - ++ lib.optionals withFormatProtobuf [protobufc] - ++ lib.optionals withHookLua [lua] - ++ lib.optionals withNodeAmqp [rabbitmq-c] - ++ lib.optionals withNodeComedi [comedilib] - ++ lib.optionals withNodeEthercat [ethercat] - ++ lib.optionals withNodeIec60870 [lib60870] - ++ lib.optionals withNodeIec61850 [libiec61850] - ++ lib.optionals withNodeInfiniband [rdma-core] - ++ lib.optionals withNodeKafka [rdkafka] - ++ lib.optionals withNodeModbus [libmodbus] - ++ lib.optionals withNodeMqtt [mosquitto] - ++ lib.optionals withNodeNanomsg [nanomsg] - ++ lib.optionals withNodeRedis [redis-plus-plus] - ++ lib.optionals withNodeRtp [libre] - ++ lib.optionals withNodeSocket [libnl] - ++ lib.optionals withNodeTemper [libusb] - ++ lib.optionals withNodeUldaq [libuldaq] - ++ lib.optionals withNodeWebrtc [libdatachannel] - ++ lib.optionals withNodeZeromq [czmq libsodium]; + ++ lib.optionals withExtraConfig [ libconfig ] + ++ lib.optionals withExtraGraphviz [ graphviz ] + ++ lib.optionals withFormatProtobuf [ protobufc ] + ++ lib.optionals withHookLua [ lua ] + ++ lib.optionals withNodeAmqp [ rabbitmq-c ] + ++ lib.optionals withNodeComedi [ comedilib ] + ++ lib.optionals withNodeEthercat [ ethercat ] + ++ lib.optionals withNodeIec60870 [ lib60870 ] + ++ lib.optionals withNodeIec61850 [ libiec61850 ] + ++ lib.optionals withNodeInfiniband [ rdma-core ] + ++ lib.optionals withNodeKafka [ rdkafka ] + ++ lib.optionals withNodeModbus [ libmodbus ] + ++ lib.optionals withNodeMqtt [ mosquitto ] + ++ lib.optionals withNodeNanomsg [ nanomsg ] + ++ lib.optionals withNodeRedis [ redis-plus-plus ] + ++ lib.optionals withNodeRtp [ libre ] + ++ lib.optionals withNodeSocket [ libnl ] + ++ lib.optionals withNodeTemper [ libusb ] + ++ lib.optionals withNodeUldaq [ libuldaq ] + ++ lib.optionals withNodeWebrtc [ libdatachannel ] + ++ lib.optionals withNodeZeromq [ + czmq + libsodium + ]; meta = with lib; { mainProgram = "villas"; description = "a tool connecting real-time power grid simulation equipment";