Unverified Commit c3cff660 authored by nixpkgs-ci[bot]'s avatar nixpkgs-ci[bot] Committed by GitHub
Browse files

Merge master into staging-nixos

parents b3ca854a e3f77cfc
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -9,9 +9,9 @@
      },
      "branch": "nixpkgs-unstable",
      "submodules": false,
      "revision": "106eb93cbb9d4e4726bf6bc367a3114f7ed6b32f",
      "url": "https://github.com/NixOS/nixpkgs/archive/106eb93cbb9d4e4726bf6bc367a3114f7ed6b32f.tar.gz",
      "hash": "0wyyhddz2mqhmq938d337223675jpd83dd5lsks2nhz0hs4r3jha"
      "revision": "02f3fa0374fa13707d42d55d58ecc76b091f223c",
      "url": "https://github.com/NixOS/nixpkgs/archive/02f3fa0374fa13707d42d55d58ecc76b091f223c.tar.gz",
      "hash": "0z8d33c5g0gk9a74ppqq77npisf9xx9c8ai9isxa2hyjx4lv1pki"
    },
    "treefmt-nix": {
      "type": "Git",
@@ -22,9 +22,9 @@
      },
      "branch": "main",
      "submodules": false,
      "revision": "75925962939880974e3ab417879daffcba36c4a3",
      "url": "https://github.com/numtide/treefmt-nix/archive/75925962939880974e3ab417879daffcba36c4a3.tar.gz",
      "hash": "118zlbyzmh21x6rad2vrxjkdfyicd8lx3s0if8b791n51hz1r9ns"
      "revision": "790751ff7fd3801feeaf96d7dc416a8d581265ba",
      "url": "https://github.com/numtide/treefmt-nix/archive/790751ff7fd3801feeaf96d7dc416a8d581265ba.tar.gz",
      "hash": "1zah3dmbpn3ap5acg22kq1j19dg32gj73l43yamjcxhc38sv9kd5"
    }
  },
  "version": 5
+6 −0
Original line number Diff line number Diff line
@@ -9904,6 +9904,12 @@
    name = "Adrian Groh";
    keys = [ { fingerprint = "62BD BF30 83E9 7076 9665 B60B 3AA3 153E 98B0 D771"; } ];
  };
  god464 = {
    github = "god464";
    githubId = 36400459;
    name = "god464";
    keys = [ { fingerprint = "089E 1560 7145 FE93 2C00  2942 D7A7 2706 FC8D E569"; } ];
  };
  goertzenator = {
    email = "daniel.goertzen@gmail.com";
    github = "goertzenator";
+0 −4
Original line number Diff line number Diff line
@@ -72,10 +72,6 @@ in
    systemd = {
      packages = [ pkgs.gamemode ];
      user.services.gamemoded = {
        # The upstream service already defines this, but doesn't get applied.
        # See https://github.com/NixOS/nixpkgs/issues/81138
        wantedBy = [ "default.target" ];

        # Use pkexec from the security wrappers to allow users to
        # run libexec/cpugovctl & libexec/gpuclockctl as root with
        # the the actions defined in share/polkit-1/actions.
+115 −60
Original line number Diff line number Diff line
@@ -45,19 +45,6 @@ in
        default = "glitchtip";
      };

      listenAddress = lib.mkOption {
        type = lib.types.str;
        description = "The address to listen on.";
        default = "127.0.0.1";
        example = "0.0.0.0";
      };

      port = lib.mkOption {
        type = lib.types.port;
        description = "The port to listen on.";
        default = 8000;
      };

      stateDir = lib.mkOption {
        type = lib.types.path;
        description = "State directory of glitchtip.";
@@ -66,7 +53,7 @@ in

      settings = lib.mkOption {
        description = ''
          Configuration of GlitchTip. See <https://glitchtip.com/documentation/install#configuration> for more information.
          Configuration of GlitchTip. See <https://glitchtip.com/documentation/install#configuration> for more information and required settings.
        '';
        default = { };
        defaultText = lib.literalExpression ''
@@ -74,8 +61,14 @@ in
            DEBUG = 0;
            DEBUG_TOOLBAR = 0;
            DATABASE_URL = lib.mkIf config.services.glitchtip.database.createLocally "postgresql://@/glitchtip";
            GLITCHTIP_DOMAIN = lib.mkIf config.services.glitchtip.nginx.createLocally "https://''${config.services.glitchtip.nginx.domain}";
            GLITCHTIP_VERSION = config.services.glitchtip.package.version;
            GRANIAN_HOST = "127.0.0.1";
            GRANIAN_PORT = 8000;
            GRANIAN_STATIC_PATH_MOUNT = "''${config.services.glitchtip.package}/lib/glitchtip/static";
            GRANIAN_WORKERS = 1;
            PYTHONUNBUFFERED = 1;
            REDIS_URL = lib.mkIf config.services.glitchtip.redis.createLocally "unix://''${config.services.redis.servers.glitchtip.unixSocket}";
            CELERY_BROKER_URL = lib.mkIf config.services.glitchtip.redis.createLocally "redis+socket://''${config.services.redis.servers.glitchtip.unixSocket}";
          }
        '';
        example = {
@@ -94,9 +87,28 @@ in

          options = {
            GLITCHTIP_DOMAIN = lib.mkOption {
              type = lib.types.str;
              type = lib.types.nullOr lib.types.str;
              description = "The URL under which GlitchTip is externally reachable.";
              example = "https://glitchtip.example.com";
              default = null;
            };

            GLITCHTIP_ENABLE_MCP = lib.mkOption {
              type = lib.types.bool;
              description = "Whether to enable the MCP api.";
              default = false;
            };

            GRANIAN_WORKERS = lib.mkOption {
              type = lib.types.ints.positive;
              description = "Number of granian workers to start";
              default = 1;
            };

            ENABLE_OBSERVABILITY_API = lib.mkOption {
              type = lib.types.bool;
              description = "Whether to enable the Prometheus metrics endpoint.";
              default = false;
            };

            ENABLE_USER_REGISTRATION = lib.mkOption {
@@ -132,49 +144,74 @@ in
      database.createLocally = lib.mkOption {
        type = lib.types.bool;
        default = true;
        description = ''
          Whether to enable and configure a local PostgreSQL database server.
        '';
        description = "Whether to enable and configure a local PostgreSQL database server.";
      };

      redis.createLocally = lib.mkOption {
      nginx = {
        createLocally = lib.mkOption {
          type = lib.types.bool;
        default = true;
          default = false;
          description = "Whether to enable and configure a local Nginx server.";
        };

        domain = lib.mkOption {
          type = lib.types.str;
          example = "glitchtip.example.com";
          description = ''
          Whether to enable and configure a local Redis instance.
            Domain under which GlitchTip will be reachable.
            In contrast to `settings.GLITCHTIP_DOMAIN` this option has no protocol.
            It will also set `settings.GLITCHTIP_DOMAIN` with the `https://` protocol.
          '';
        };

      gunicorn.extraArgs = lib.mkOption {
        type = lib.types.listOf lib.types.str;
        default = [ ];
        description = "Extra arguments for gunicorn.";
      };

      celery.extraArgs = lib.mkOption {
        type = lib.types.listOf lib.types.str;
        default = [ ];
        description = "Extra arguments for celery.";
      redis.createLocally = lib.mkOption {
        type = lib.types.bool;
        default = true;
        description = "Whether to enable and configure a local Redis instance.";
      };
    };
  };

  imports = [
    (lib.mkRenamedOptionModule
      [ "services" "glitchtip" "listenAddress" ]
      [ "services" "glitchtip" "settings" "GRANIAN_HOST" ]
    )
    (lib.mkRenamedOptionModule
      [ "services" "glitchtip" "port" ]
      [ "services" "glitchtip" "settings" "GRANIAN_PORT" ]
    )
    (lib.mkRemovedOptionModule [ "services" "glitchtip" "celery" "extraArgs" ]
      "GlitchTip 6 migrated away from celery. Please check the upstream docs how to handle your usecase now."
    )
    (lib.mkRemovedOptionModule [ "services" "glitchtip" "gunicorn" "extraArgs" ]
      "GlitchTip 6 migrated away from gunicorn. Please check the upstream docs how to handle your usecase now."
    )
  ];

  config = lib.mkIf cfg.enable {
    services.glitchtip.settings = {
      DEBUG = lib.mkDefault 0;
      DEBUG_TOOLBAR = lib.mkDefault 0;
      PYTHONPATH = "${python.pkgs.makePythonPath pkg.propagatedBuildInputs}:${pkg}/lib/glitchtip";
      DATABASE_URL = lib.mkIf cfg.database.createLocally "postgresql://@/glitchtip";
      REDIS_URL = lib.mkIf cfg.redis.createLocally "unix://${config.services.redis.servers.glitchtip.unixSocket}";
      CELERY_BROKER_URL = lib.mkIf cfg.redis.createLocally "redis+socket://${config.services.redis.servers.glitchtip.unixSocket}";
      GLITCHTIP_VERSION = pkg.version;
      GRANIAN_HOST = lib.mkDefault "127.0.0.1";
      GRANIAN_PORT = lib.mkDefault 8000;
      GRANIAN_STATIC_PATH_MOUNT = "${pkg}/lib/glitchtip/static";
      GRANIAN_WORKERS = lib.mkDefault 1;
      PYTHONPATH = "${python.pkgs.makePythonPath pkg.propagatedBuildInputs}:${pkg}/lib/glitchtip";
      PYTHONUNBUFFERED = lib.mkDefault 1;
    }
    // lib.optionalAttrs cfg.database.createLocally { DATABASE_URL = "postgresql://@/glitchtip"; }
    // lib.optionalAttrs cfg.nginx.createLocally { GLITCHTIP_DOMAIN = "https://${cfg.nginx.domain}"; }
    // lib.optionalAttrs cfg.redis.createLocally {
      REDIS_URL = "unix://${config.services.redis.servers.glitchtip.unixSocket}";
    };

    systemd.services =
      let
        commonService = {
          wantedBy = [ "multi-user.target" ];

          wants = [ "network-online.target" ];
          requires =
            lib.optional cfg.database.createLocally "postgresql.target"
@@ -235,31 +272,51 @@ in
      {
        glitchtip = commonService // {
          description = "GlitchTip";
          environment =
            environment
            // lib.optionalAttrs (cfg.settings.ENABLE_OBSERVABILITY_API && cfg.settings.WORKERS > 1) {
              PROMETHEUS_MULTIPROC_DIR = "/tmp/prometheus_multiproc";
            };
          bindsTo = [ "glitchtip-worker.service" ];
          before = [ "glitchtip-worker.service" ];

          preStart = ''
            ${lib.getExe pkg} migrate
            ${lib.getExe pkg} createcachetable
            ${lib.getExe pkg} maintain_partitions
          '';

          serviceConfig = commonServiceConfig // {
            ExecStart = ''
              ${lib.getExe python.pkgs.gunicorn} \
                --bind=${cfg.listenAddress}:${toString cfg.port} \
                ${lib.concatStringsSep " " cfg.gunicorn.extraArgs} \
                glitchtip.wsgi
              ${lib.getExe python.pkgs.granian} \
                --interface ${if cfg.settings.GLITCHTIP_ENABLE_MCP then "asgi" else "asginl"} \
                glitchtip.asgi:application \
                --host ${cfg.settings.GRANIAN_HOST} \
                --port ${toString cfg.settings.GRANIAN_PORT} \
                --workers ${toString cfg.settings.GRANIAN_WORKERS} \
                --no-ws
            '';
          };
        };

        glitchtip-worker = commonService // {
          description = "GlitchTip Job Runner";

          environment = environment // {
            IS_WORKER = "1";
          };
          serviceConfig = commonServiceConfig // {
            ExecStart = ''
              ${lib.getExe python.pkgs.celery} \
                -A glitchtip worker \
                -B -s /run/glitchtip/celerybeat-schedule \
                ${lib.concatStringsSep " " cfg.celery.extraArgs}
            '';
            ExecStart = "${lib.getExe pkg} runworker --scheduler";
          };
        };
      };

    services.nginx = lib.mkIf cfg.nginx.createLocally {
      enable = true;
      virtualHosts.${cfg.nginx.domain} = {
        forceSSL = lib.mkDefault true;
        locations = {
          "/".proxyPass = "http://${cfg.settings.GRANIAN_HOST}:${toString cfg.settings.GRANIAN_PORT}";
          "/static/".root = "${pkg}/lib/glitchtip";
        };
      };
    };
@@ -289,15 +346,13 @@ in

    systemd.tmpfiles.settings.glitchtip."${cfg.stateDir}/uploads".d = { inherit (cfg) user group; };

    environment.systemPackages =
      let
        glitchtip-manage = pkgs.writeShellScriptBin "glitchtip-manage" ''
    environment.systemPackages = [
      (pkgs.writeShellScriptBin "glitchtip-manage" ''
        set -o allexport
        ${lib.toShellVars environment}
        ${lib.concatMapStringsSep "\n" (f: "source ${f}") cfg.environmentFiles}
        ${config.security.wrapperDir}/sudo -E -u ${cfg.user} ${lib.getExe pkg} "$@"
        '';
      in
      [ glitchtip-manage ];
      '')
    ];
  };
}
+16 −9
Original line number Diff line number Diff line
{ lib, ... }:

let
  domain = "http://glitchtip.local:8000";
  domain = "glitchtip.local";
  url = "http://${domain}";
in

{
@@ -16,8 +17,10 @@ in
    {
      services.glitchtip = {
        enable = true;
        port = 8000;
        settings.GLITCHTIP_DOMAIN = domain;
        nginx.createLocally = true;
        nginx.domain = domain;
        settings.GLITCHTIP_DOMAIN = lib.mkForce url;
        settings.CSRF_TRUSTED_ORIGINS = "${url},http://localhost:8000";
        environmentFiles = [
          (builtins.toFile "glitchtip.env" ''
            SECRET_KEY=8Hz7YCGzo7fiicHb8Qr22ZqwoIB7lSRx
@@ -25,19 +28,23 @@ in
        ];
      };

      services.nginx.virtualHosts.${domain}.forceSSL = false;

      environment.systemPackages = [ pkgs.sentry-cli ];

      networking.hosts."127.0.0.1" = [ "glitchtip.local" ];
      networking.hosts."127.0.0.1" = [ domain ];
    };

  interactive.sshBackdoor.enable = true;
  interactive.defaults.virtualisation.graphics = false;

  interactive.nodes.machine = {
    services.glitchtip.listenAddress = "0.0.0.0";
    networking.firewall.allowedTCPPorts = [ 8000 ];
    networking.firewall.allowedTCPPorts = [ 80 ];
    virtualisation.forwardPorts = [
      {
        from = "host";
        host.port = 8000;
        guest.port = 8000;
        guest.port = 80;
      }
    ];
  };
@@ -53,7 +60,7 @@ in
      machine.wait_for_unit("glitchtip-worker.service")
      machine.wait_for_open_port(8000)

      origin_url = "${domain}"
      origin_url = "${url}"
      cookie_jar_path = "/tmp/cookies.txt"
      curl = f"curl -b {cookie_jar_path} -c {cookie_jar_path} -fS -H 'Origin: {origin_url}'"

@@ -89,7 +96,7 @@ in
      # fetch dsn
      resp = json.loads(machine.succeed(f"{curl} {origin_url}/api/0/projects/main/test/keys/"))
      assert len(resp) == 1
      assert re.match(r"^http://[\da-f]+@glitchtip\.local:8000/\d+$", dsn := resp[0]["dsn"]["public"])
      assert re.match(r"^http://[\da-f]+@glitchtip\.local/\d+$", dsn := resp[0]["dsn"]["public"])

      # send event
      machine.succeed(f"SENTRY_DSN={dsn} sentry-cli send-event -m 'hello world'")
Loading