orthanc: init at 1.12.6, nixos/orthanc: init (#385329)

authored by Pol Dellaiera and committed by GitHub 79e95661 7f72350d

+295
+2
nixos/doc/manual/release-notes/rl-2505.section.md
··· 192 193 - [Limine](https://github.com/limine-bootloader/limine) a modern, advanced, portable, multiprotocol bootloader and boot manager. Available as [boot.loader.limine](#opt-boot.loader.limine.enable) 194 195 <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> 196 197 ## Backward Incompatibilities {#sec-release-25.05-incompatibilities}
··· 192 193 - [Limine](https://github.com/limine-bootloader/limine) a modern, advanced, portable, multiprotocol bootloader and boot manager. Available as [boot.loader.limine](#opt-boot.loader.limine.enable) 194 195 + - [Orthanc](https://orthanc.uclouvain.be/) a lightweight, RESTful DICOM server for healthcare and medical research. Available as [services.orthanc](#opt-services.orthanc.enable). 196 + 197 <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> 198 199 ## Backward Incompatibilities {#sec-release-25.05-incompatibilities}
+1
nixos/modules/module-list.nix
··· 848 ./services/misc/ombi.nix 849 ./services/misc/omnom.nix 850 ./services/misc/open-webui.nix 851 ./services/misc/osrm.nix 852 ./services/misc/owncast.nix 853 ./services/misc/packagekit.nix
··· 848 ./services/misc/ombi.nix 849 ./services/misc/omnom.nix 850 ./services/misc/open-webui.nix 851 + ./services/misc/orthanc.nix 852 ./services/misc/osrm.nix 853 ./services/misc/owncast.nix 854 ./services/misc/packagekit.nix
+134
nixos/modules/services/misc/orthanc.nix
···
··· 1 + { 2 + config, 3 + options, 4 + lib, 5 + pkgs, 6 + ... 7 + }: 8 + let 9 + inherit (lib) types; 10 + 11 + cfg = config.services.orthanc; 12 + opt = options.services.orthanc; 13 + 14 + settingsFormat = pkgs.formats.json { }; 15 + in 16 + { 17 + options = { 18 + services.orthanc = { 19 + enable = lib.mkEnableOption "Orthanc server"; 20 + package = lib.mkPackageOption pkgs "orthanc" { }; 21 + 22 + stateDir = lib.mkOption { 23 + type = types.path; 24 + default = "/var/lib/orthanc"; 25 + example = "/home/foo"; 26 + description = "State directory of Orthanc."; 27 + }; 28 + 29 + environment = lib.mkOption { 30 + type = types.attrsOf types.str; 31 + default = { 32 + }; 33 + example = '' 34 + { 35 + ORTHANC_NAME = "Orthanc server"; 36 + } 37 + ''; 38 + description = '' 39 + Extra environment variables 40 + For more details see <https://orthanc.uclouvain.be/book/users/configuration.html> 41 + ''; 42 + }; 43 + 44 + environmentFile = lib.mkOption { 45 + description = '' 46 + Environment file to be passed to the systemd service. 47 + Useful for passing secrets to the service to prevent them from being 48 + world-readable in the Nix store. 49 + ''; 50 + type = lib.types.nullOr lib.types.path; 51 + default = null; 52 + example = "/var/lib/secrets/orthancSecrets"; 53 + }; 54 + 55 + settings = lib.mkOption { 56 + type = lib.types.submodule { 57 + freeformType = settingsFormat.type; 58 + }; 59 + default = { 60 + HttpPort = lib.mkDefault 8042; 61 + IndexDirectory = lib.mkDefault "/var/lib/orthanc/"; 62 + StorageDirectory = lib.mkDefault "/var/lib/orthanc/"; 63 + }; 64 + example = { 65 + Name = "My Orthanc Server"; 66 + HttpPort = 12345; 67 + }; 68 + description = '' 69 + Configuration written to a json file that is read by orthanc. 70 + See <https://orthanc.uclouvain.be/book/index.html> for more. 71 + ''; 72 + }; 73 + 74 + openFirewall = lib.mkOption { 75 + type = types.bool; 76 + default = false; 77 + description = '' 78 + Whether to open the firewall for Orthanc. 79 + This adds `services.orthanc.settings.HttpPort` to `networking.firewall.allowedTCPPorts`. 80 + ''; 81 + }; 82 + }; 83 + }; 84 + 85 + config = lib.mkIf cfg.enable { 86 + services.orthanc.settings = options.services.orthanc.settings.default; 87 + 88 + systemd.services.orthanc = { 89 + description = "Orthanc is a lightweight, RESTful DICOM server for healthcare and medical research"; 90 + wantedBy = [ "multi-user.target" ]; 91 + after = [ "network.target" ]; 92 + 93 + environment = cfg.environment; 94 + 95 + serviceConfig = 96 + let 97 + config-json = settingsFormat.generate "orthanc-config.json" (cfg.settings); 98 + in 99 + { 100 + ExecStart = "${lib.getExe cfg.package} ${config-json}"; 101 + EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile; 102 + WorkingDirectory = cfg.stateDir; 103 + BindReadOnlyPaths = [ 104 + "-/etc/localtime" 105 + ]; 106 + StateDirectory = "orthanc"; 107 + RuntimeDirectory = "orthanc"; 108 + RuntimeDirectoryMode = "0755"; 109 + PrivateTmp = true; 110 + DynamicUser = true; 111 + DevicePolicy = "closed"; 112 + LockPersonality = true; 113 + PrivateUsers = true; 114 + ProtectHome = true; 115 + ProtectHostname = true; 116 + ProtectKernelLogs = true; 117 + ProtectKernelModules = true; 118 + ProtectKernelTunables = true; 119 + ProtectControlGroups = true; 120 + RestrictNamespaces = true; 121 + RestrictRealtime = true; 122 + SystemCallArchitectures = "native"; 123 + UMask = "0077"; 124 + }; 125 + }; 126 + 127 + networking.firewall = lib.mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.settings.HttpPort ]; }; 128 + 129 + # Orthanc requires /etc/localtime to be present 130 + time.timeZone = lib.mkDefault "UTC"; 131 + }; 132 + 133 + meta.maintainers = with lib.maintainers; [ drupol ]; 134 + }
+1
nixos/tests/all-tests.nix
··· 874 opentelemetry-collector = handleTest ./opentelemetry-collector.nix {}; 875 open-web-calendar = handleTest ./web-apps/open-web-calendar.nix {}; 876 ocsinventory-agent = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./ocsinventory-agent.nix {}; 877 owncast = handleTest ./owncast.nix {}; 878 outline = handleTest ./outline.nix {}; 879 image-contents = handleTest ./image-contents.nix {};
··· 874 opentelemetry-collector = handleTest ./opentelemetry-collector.nix {}; 875 open-web-calendar = handleTest ./web-apps/open-web-calendar.nix {}; 876 ocsinventory-agent = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./ocsinventory-agent.nix {}; 877 + orthanc = runTest ./orthanc.nix; 878 owncast = handleTest ./owncast.nix {}; 879 outline = handleTest ./outline.nix {}; 880 image-contents = handleTest ./image-contents.nix {};
+27
nixos/tests/orthanc.nix
···
··· 1 + { lib, ... }: 2 + 3 + { 4 + name = "orthanc"; 5 + 6 + nodes = { 7 + machine = 8 + { pkgs, ... }: 9 + { 10 + services.orthanc = { 11 + enable = true; 12 + settings = { 13 + HttpPort = 12345; 14 + }; 15 + }; 16 + }; 17 + }; 18 + 19 + testScript = '' 20 + machine.start() 21 + machine.wait_for_unit("orthanc.service") 22 + machine.wait_for_open_port(12345) 23 + machine.wait_for_open_port(4242) 24 + ''; 25 + 26 + meta.maintainers = [ lib.maintainers.drupol ]; 27 + }
+10
pkgs/by-name/or/orthanc/add-missing-include.patch
···
··· 1 + diff -r cba3e8ca3a87 OrthancServer/Sources/OrthancInitialization.cpp 2 + --- a/Sources/OrthancInitialization.cpp Tue Mar 11 10:46:15 2025 +0100 3 + +++ b/Sources/OrthancInitialization.cpp Thu Mar 13 18:20:00 2025 +0100 4 + @@ -59,6 +59,7 @@ 5 + # undef __FILE__ 6 + # define __FILE__ __ORTHANC_FILE__ 7 + # endif 8 + +# include <google/protobuf/stubs/common.h> 9 + # include <google/protobuf/any.h> 10 + #endif
+120
pkgs/by-name/or/orthanc/package.nix
···
··· 1 + { 2 + lib, 3 + stdenv, 4 + fetchhg, 5 + boost, 6 + charls, 7 + civetweb, 8 + cmake, 9 + curl, 10 + dcmtk, 11 + gtest, 12 + jsoncpp, 13 + libjpeg, 14 + libpng, 15 + libuuid, 16 + log4cplus, 17 + lua, 18 + openssl, 19 + protobuf, 20 + pugixml, 21 + python3, 22 + sqlite, 23 + unzip, 24 + versionCheckHook, 25 + nixosTests, 26 + }: 27 + 28 + stdenv.mkDerivation (finalAttrs: { 29 + pname = "orthanc"; 30 + version = "1.12.6"; 31 + 32 + src = fetchhg { 33 + url = "https://orthanc.uclouvain.be/hg/orthanc/"; 34 + rev = "Orthanc-${finalAttrs.version}"; 35 + hash = "sha256-1ztA95PiCGL1oD6zVfsEhwrwGNID13/NcyZDD3eHYv0="; 36 + }; 37 + 38 + patches = [ 39 + # Without this patch, the build fails to find `GOOGLE_PROTOBUF_VERIFY_VERSION` 40 + # The patch has been included upstream, it need to be removed in the next release. 41 + ./add-missing-include.patch 42 + ]; 43 + 44 + sourceRoot = "${finalAttrs.src.name}/OrthancServer"; 45 + 46 + nativeBuildInputs = [ 47 + cmake 48 + protobuf 49 + python3 50 + unzip 51 + ]; 52 + 53 + buildInputs = [ 54 + protobuf 55 + boost 56 + charls 57 + civetweb 58 + curl 59 + dcmtk 60 + gtest 61 + jsoncpp 62 + libjpeg 63 + libpng 64 + libuuid 65 + log4cplus 66 + lua 67 + openssl 68 + pugixml 69 + sqlite 70 + ]; 71 + 72 + strictDeps = true; 73 + 74 + enableParallelBuilding = true; 75 + 76 + cmakeFlags = [ 77 + (lib.cmakeFeature "DCMTK_DICTIONARY_DIR_AUTO" "${dcmtk}/share/dcmtk-${dcmtk.version}") 78 + (lib.cmakeFeature "DCMTK_LIBRARIES" "dcmjpls;oflog;ofstd") 79 + (lib.cmakeFeature "CMAKE_BUILD_TYPE" "Release") 80 + 81 + (lib.cmakeBool "BUILD_CONNECTIVITY_CHECKS" false) 82 + (lib.cmakeBool "UNIT_TESTS_WITH_HTTP_CONNEXIONS" false) 83 + (lib.cmakeBool "STANDALONE_BUILD" true) 84 + (lib.cmakeBool "USE_SYSTEM_BOOST" true) 85 + (lib.cmakeBool "USE_SYSTEM_CIVETWEB" true) 86 + (lib.cmakeBool "USE_SYSTEM_DCMTK" true) 87 + (lib.cmakeBool "USE_SYSTEM_GOOGLE_TEST" true) 88 + (lib.cmakeBool "USE_SYSTEM_JSONCPP" true) 89 + (lib.cmakeBool "USE_SYSTEM_LIBICONV" true) 90 + (lib.cmakeBool "USE_SYSTEM_LIBJPEG" true) 91 + (lib.cmakeBool "USE_SYSTEM_LIBPNG" true) 92 + (lib.cmakeBool "USE_SYSTEM_LUA" true) 93 + (lib.cmakeBool "USE_SYSTEM_OPENSSL" true) 94 + (lib.cmakeBool "USE_SYSTEM_PROTOBUF" true) 95 + (lib.cmakeBool "USE_SYSTEM_PUGIXML" true) 96 + (lib.cmakeBool "USE_SYSTEM_SQLITE" true) 97 + (lib.cmakeBool "USE_SYSTEM_UUID" true) 98 + (lib.cmakeBool "USE_SYSTEM_ZLIB" true) 99 + ]; 100 + 101 + nativeInstallCheckInputs = [ 102 + versionCheckHook 103 + ]; 104 + versionCheckProgram = "${placeholder "out"}/bin/${finalAttrs.meta.mainProgram}"; 105 + versionCheckProgramArg = "--version"; 106 + doInstallCheck = true; 107 + 108 + passthru.tests = { 109 + inherit (nixosTests) orthanc; 110 + }; 111 + 112 + meta = { 113 + description = "Orthanc is a lightweight, RESTful DICOM server for healthcare and medical research"; 114 + homepage = "https://www.orthanc-server.com/"; 115 + license = lib.licenses.gpl3Plus; 116 + mainProgram = "Orthanc"; 117 + maintainers = with lib.maintainers; [ drupol ]; 118 + platforms = lib.platforms.linux; 119 + }; 120 + })