From 0f2df9ff19b97d6a854d6649e8a8dbaf4e98d6f3 Mon Sep 17 00:00:00 2001 From: Leona Maroni Date: Tue, 9 Jan 2024 19:39:15 +0100 Subject: nixos/youtrack: rebuild module for 2023.x support --- nixos/modules/services/web-apps/youtrack.md | 30 ++++ nixos/modules/services/web-apps/youtrack.nix | 237 +++++++++++++++++++-------- 2 files changed, 196 insertions(+), 71 deletions(-) create mode 100644 nixos/modules/services/web-apps/youtrack.md (limited to 'nixos/modules') diff --git a/nixos/modules/services/web-apps/youtrack.md b/nixos/modules/services/web-apps/youtrack.md new file mode 100644 index 000000000000..f33f482ff970 --- /dev/null +++ b/nixos/modules/services/web-apps/youtrack.md @@ -0,0 +1,30 @@ +# YouTrack {#module-services-youtrack} + +YouTrack is a browser-based bug tracker, issue tracking system and project management software. + +## Installation {#module-services-youtrack-installation} + +YouTrack exposes a web GUI installer on first login. +You need a token to access it. +You can find this token in the log of the `youtrack` service. The log line looks like +``` +* JetBrains YouTrack 2023.3 Configuration Wizard will be available on [http://127.0.0.1:8090/?wizard_token=somelongtoken] after start +``` + +## Upgrade from 2022.3 to 2023.x {#module-services-youtrack-upgrade-2022_3-2023_1} + +Starting with YouTrack 2023.1, JetBrains no longer distributes it as as JAR. +The new distribution with the JetBrains Launcher as a ZIP changed the basic data structure and also some configuration parameters. +Check out https://www.jetbrains.com/help/youtrack/server/YouTrack-Java-Start-Parameters.html for more information on the new configuration options. +When upgrading to YouTrack 2023.1 or higher, a migration script will move the old state directory to `/var/lib/youtrack/2022_3` as a backup. +A one-time manual update is required: + +1. Before you update take a backup of your YouTrack instance! +2. Migrate the options you set in `services.youtrack.extraParams` and `services.youtrack.jvmOpts` to `services.youtrack.generalParameters` and `services.youtrack.environmentalParameters` (see the examples and [the YouTrack docs](https://www.jetbrains.com/help/youtrack/server/2023.3/YouTrack-Java-Start-Parameters.html)) +2. To start the upgrade set `services.youtrack.package = pkgs.youtrack` +3. YouTrack then starts in upgrade mode, meaning you need to obtain the wizard token as above +4. Select you want to **Upgrade** YouTrack +5. As source you select `/var/lib/youtrack/2022_3/teamsysdata/` (adopt if you have a different state path) +6. Change the data directory location to `/var/lib/youtrack/data/`. The other paths should already be right. + +If you migrate a larger YouTrack instance, it might be useful to set `-Dexodus.entityStore.refactoring.forceAll=true` in `services.youtrack.generalParameters` for the first startup of YouTrack 2023.x. diff --git a/nixos/modules/services/web-apps/youtrack.nix b/nixos/modules/services/web-apps/youtrack.nix index 79e1d12e0abb..abb4292113b6 100644 --- a/nixos/modules/services/web-apps/youtrack.nix +++ b/nixos/modules/services/web-apps/youtrack.nix @@ -1,130 +1,224 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.services.youtrack; - - extraAttr = concatStringsSep " " (mapAttrsToList (k: v: "-D${k}=${v}") (stdParams // cfg.extraParams)); - mergeAttrList = lib.foldl' lib.mergeAttrs {}; - - stdParams = mergeAttrList [ - (optionalAttrs (cfg.baseUrl != null) { - "jetbrains.youtrack.baseUrl" = cfg.baseUrl; - }) - { - "java.aws.headless" = "true"; - "jetbrains.youtrack.disableBrowser" = "true"; - } - ]; in { - options.services.youtrack = { + imports = [ + (lib.mkRenamedOptionModule [ "services" "youtrack" "baseUrl" ] [ "services" "youtrack" "environmentalParameters" "base-url" ]) + (lib.mkRenamedOptionModule [ "services" "youtrack" "port" ] [ "services" "youtrack" "environmentalParameters" "listen-port" ]) + (lib.mkRemovedOptionModule [ "services" "youtrack" "maxMemory" ] "Please instead use `services.youtrack.generalParameters`.") + (lib.mkRemovedOptionModule [ "services" "youtrack" "maxMetaspaceSize" ] "Please instead use `services.youtrack.generalParameters`.") + ]; - enable = mkEnableOption (lib.mdDoc "YouTrack service"); + options.services.youtrack = { + enable = lib.mkEnableOption (lib.mdDoc "YouTrack service"); - address = mkOption { + address = lib.mkOption { description = lib.mdDoc '' The interface youtrack will listen on. ''; default = "127.0.0.1"; - type = types.str; + type = lib.types.str; }; - baseUrl = mkOption { - description = lib.mdDoc '' - Base URL for youtrack. Will be auto-detected and stored in database. - ''; - type = types.nullOr types.str; - default = null; - }; - - extraParams = mkOption { + extraParams = lib.mkOption { default = {}; description = lib.mdDoc '' - Extra parameters to pass to youtrack. See + Extra parameters to pass to youtrack. + Use to configure YouTrack 2022.x, deprecated with YouTrack 2023.x. Use `services.youtrack.generalParameters`. https://www.jetbrains.com/help/youtrack/standalone/YouTrack-Java-Start-Parameters.html for more information. ''; - example = literalExpression '' + example = lib.literalExpression '' { "jetbrains.youtrack.overrideRootPassword" = "tortuga"; } ''; - type = types.attrsOf types.str; + type = lib.types.attrsOf lib.types.str; + visible = false; }; - package = mkPackageOption pkgs "youtrack" { }; - - port = mkOption { + package = lib.mkOption { description = lib.mdDoc '' - The port youtrack will listen on. + Package to use. ''; - default = 8080; - type = types.port; + type = lib.types.package; + default = null; + relatedPackages = [ "youtrack_2022_3" "youtrack" ]; }; - statePath = mkOption { + + statePath = lib.mkOption { description = lib.mdDoc '' - Where to keep the youtrack database. + Path were the YouTrack state is stored. + To this path the base version (e.g. 2023_1) of the used package will be appended. ''; - type = types.path; + type = lib.types.path; default = "/var/lib/youtrack"; }; - virtualHost = mkOption { + virtualHost = lib.mkOption { description = lib.mdDoc '' Name of the nginx virtual host to use and setup. If null, do not setup anything. ''; default = null; - type = types.nullOr types.str; + type = lib.types.nullOr lib.types.str; }; - jvmOpts = mkOption { + jvmOpts = lib.mkOption { description = lib.mdDoc '' Extra options to pass to the JVM. + Only has a use with YouTrack 2022.x, deprecated with YouTrack 2023.x. Use `serivces.youtrack.generalParameters`. See https://www.jetbrains.com/help/youtrack/standalone/Configure-JVM-Options.html for more information. ''; - type = types.separatedString " "; - example = "-XX:MetaspaceSize=250m"; + type = lib.types.separatedString " "; + example = "--J-XX:MetaspaceSize=250m"; default = ""; + visible = false; }; - maxMemory = mkOption { + autoUpgrade = lib.mkOption { + type = lib.types.bool; + default = true; + description = lib.mdDoc "Whether YouTrack should auto upgrade it without showing the upgrade dialog."; + }; + + generalParameters = lib.mkOption { + type = with lib.types; listOf str; description = lib.mdDoc '' - Maximum Java heap size + General configuration parameters and other JVM options. + Only has an effect for YouTrack 2023.x. + See https://www.jetbrains.com/help/youtrack/server/2023.3/youtrack-java-start-parameters.html#general-parameters + for more information. ''; - type = types.str; - default = "1g"; + example = lib.literalExpression '' + [ + "-Djetbrains.youtrack.admin.restore=true" + "-Xmx1024m" + ]; + ''; + default = []; }; - maxMetaspaceSize = mkOption { + environmentalParameters = lib.mkOption { + type = lib.types.submodule { + freeformType = with lib.types; attrsOf (oneOf [ int str port ]); + options = { + listen-address = lib.mkOption { + type = lib.types.str; + default = "0.0.0.0"; + description = lib.mdDoc "The interface YouTrack will listen on."; + }; + listen-port = lib.mkOption { + type = lib.types.port; + default = 8080; + description = lib.mdDoc "The port YouTrack will listen on."; + }; + }; + }; description = lib.mdDoc '' - Maximum java Metaspace memory. + Environmental configuration parameters, set imperatively. The values doesn't get removed, when removed in Nix. + Only has an effect for YouTrack 2023.x. + See https://www.jetbrains.com/help/youtrack/server/2023.3/youtrack-java-start-parameters.html#environmental-parameters + for more information. + ''; + example = lib.literalExpression '' + { + secure-mode = "tls"; + } ''; - type = types.str; - default = "350m"; + default = {}; }; }; - config = mkIf cfg.enable { - - systemd.services.youtrack = { - environment.HOME = cfg.statePath; - environment.YOUTRACK_JVM_OPTS = "${extraAttr}"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - path = with pkgs; [ unixtools.hostname ]; - serviceConfig = { - Type = "simple"; - User = "youtrack"; - Group = "youtrack"; - Restart = "on-failure"; - ExecStart = ''${cfg.package}/bin/youtrack --J-Xmx${cfg.maxMemory} --J-XX:MaxMetaspaceSize=${cfg.maxMetaspaceSize} ${cfg.jvmOpts} ${cfg.address}:${toString cfg.port}''; + config = lib.mkIf cfg.enable { + warnings = lib.optional (lib.versions.major cfg.package.version <= "2022") + "YouTrack 2022.x is deprecated. See https://nixos.org/manual/nixos/unstable/index.html#module-services-youtrack for details on how to upgrade." + ++ lib.optional (cfg.extraParams != "" && (lib.versions.major cfg.package.version >= "2023")) + "'services.youtrack.extraParams' is deprecated and has no effect on YouTrack 2023.x and newer. Please migrate to 'services.youtrack.generalParameters'" + ++ lib.optional (cfg.jvmOpts != "" && (lib.versions.major cfg.package.version >= "2023")) + "'services.youtrack.jvmOpts' is deprecated and has no effect on YouTrack 2023.x and newer. Please migrate to 'services.youtrack.generalParameters'"; + + # XXX: Drop all version feature switches at the point when we consider YT 2022.3 as outdated. + services.youtrack.package = lib.mkDefault ( + if lib.versionAtLeast config.system.stateVersion "24.11" then pkgs.youtrack + else pkgs.youtrack_2022_3 + ); + + services.youtrack.generalParameters = lib.optional (lib.versions.major cfg.package.version >= "2023") + "-Ddisable.configuration.wizard.on.upgrade=${lib.boolToString cfg.autoUpgrade}" + ++ (lib.mapAttrsToList (k: v: "-D${k}=${v}") cfg.extraParams); + + systemd.services.youtrack = let + service_jar = let + mergeAttrList = lib.foldl' lib.mergeAttrs {}; + stdParams = mergeAttrList [ + (lib.optionalAttrs (cfg.environmentalParameters ? base-url && cfg.environmentalParameters.base-url != null) { + "jetbrains.youtrack.baseUrl" = cfg.environmentalParameters.base-url; + }) + { + "java.aws.headless" = "true"; + "jetbrains.youtrack.disableBrowser" = "true"; + } + ]; + extraAttr = lib.concatStringsSep " " (lib.mapAttrsToList (k: v: "-D${k}=${v}") (stdParams // cfg.extraParams)); + in { + environment.HOME = cfg.statePath; + environment.YOUTRACK_JVM_OPTS = "${extraAttr}"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ unixtools.hostname ]; + serviceConfig = { + Type = "simple"; + User = "youtrack"; + Group = "youtrack"; + Restart = "on-failure"; + ExecStart = ''${cfg.package}/bin/youtrack ${cfg.jvmOpts} ${cfg.environmentalParameters.listen-address}:${toString cfg.environmentalParameters.listen-port}''; + }; }; - }; + service_zip = let + jvmoptions = pkgs.writeTextFile { + name = "youtrack.jvmoptions"; + text = (lib.concatStringsSep "\n" cfg.generalParameters); + }; + + package = cfg.package.override { + statePath = cfg.statePath; + }; + in { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ unixtools.hostname ]; + preStart = '' + # This detects old (i.e. <= 2022.3) installations that were not migrated yet + # and migrates them to the new state directory style + if [[ -d ${cfg.statePath}/teamsysdata ]] && [[ ! -d ${cfg.statePath}/2022_3 ]] + then + mkdir -p ${cfg.statePath}/2022_3 + mv ${cfg.statePath}/teamsysdata ${cfg.statePath}/2022_3 + mv ${cfg.statePath}/.youtrack ${cfg.statePath}/2022_3 + fi + mkdir -p ${cfg.statePath}/{backups,conf,data,logs,temp} + ${pkgs.coreutils}/bin/ln -fs ${jvmoptions} ${cfg.statePath}/conf/youtrack.jvmoptions + ${package}/bin/youtrack configure ${lib.concatStringsSep " " (lib.mapAttrsToList (name: value: "--${name}=${toString value}") cfg.environmentalParameters )} + ''; + serviceConfig = lib.mkMerge [ + { + Type = "simple"; + User = "youtrack"; + Group = "youtrack"; + Restart = "on-failure"; + ExecStart = "${package}/bin/youtrack run"; + } + (lib.mkIf (cfg.statePath == "/var/lib/youtrack") { + StateDirectory = "youtrack"; + }) + ]; + }; + in if (lib.versions.major cfg.package.version >= "2023") then service_zip else service_jar; users.users.youtrack = { description = "Youtrack service user"; @@ -136,7 +230,7 @@ in users.groups.youtrack = {}; - services.nginx = mkIf (cfg.virtualHost != null) { + services.nginx = lib.mkIf (cfg.virtualHost != null) { upstreams.youtrack.servers."${cfg.address}:${toString cfg.port}" = {}; virtualHosts.${cfg.virtualHost}.locations = { "/" = { @@ -166,9 +260,10 @@ in proxy_set_header X-Forwarded-Proto $scheme; ''; }; - }; }; - }; + + meta.doc = ./youtrack.md; + meta.maintainers = [ lib.maintainers.leona ]; } -- cgit 1.4.1