Commit 255ac994 authored by Guillaume Girol's avatar Guillaume Girol Committed by pennae
Browse files

nixos/firefox-syncserver: fix setup failure due to duplicate key

in some circumstances, the setup service would fail with:
ERROR 1062 (23000) at line 5: Duplicate entry '1' for key 'PRIMARY'
so let's use an upsert instead of insert. This also simplifies the
script.

Besides, also fix that when the setup script changes, the corresponding
script is not restarted as it is usually not active, so we trigger a
restart of the main systemd service.
parent f2689666
Loading
Loading
Loading
Loading
+40 −50
Original line number Diff line number Diff line
@@ -32,6 +32,44 @@ let
    };
  };
  configFile = format.generate "syncstorage.toml" (lib.recursiveUpdate settings cfg.settings);
  setupScript = pkgs.writeShellScript "firefox-syncserver-setup" ''
        set -euo pipefail
        shopt -s inherit_errexit

        schema_configured() {
          mysql ${cfg.database.name} -Ne 'SHOW TABLES' | grep -q services
        }

        update_config() {
          mysql ${cfg.database.name} <<"EOF"
            BEGIN;

            INSERT INTO `services` (`id`, `service`, `pattern`)
              VALUES (1, 'sync-1.5', '{node}/1.5/{uid}')
              ON DUPLICATE KEY UPDATE service='sync-1.5', pattern='{node}/1.5/{uid}';
            INSERT INTO `nodes` (`id`, `service`, `node`, `available`, `current_load`,
                                 `capacity`, `downed`, `backoff`)
              VALUES (1, 1, '${cfg.singleNode.url}', ${toString cfg.singleNode.capacity},
              0, ${toString cfg.singleNode.capacity}, 0, 0)
              ON DUPLICATE KEY UPDATE node = '${cfg.singleNode.url}', capacity=${toString cfg.singleNode.capacity};

            COMMIT;
        EOF
        }


        for (( try = 0; try < 60; try++ )); do
          if ! schema_configured; then
            sleep 2
          else
            update_config
            exit 0
          fi
        done

        echo "Single-node setup failed"
        exit 1
      '';
in

{
@@ -210,6 +248,7 @@ in
      wantedBy = [ "multi-user.target" ];
      requires = lib.mkIf dbIsLocal [ "mysql.service" ];
      after = lib.mkIf dbIsLocal [ "mysql.service" ];
      restartTriggers = lib.optional cfg.singleNode.enable setupScript;
      environment.RUST_LOG = cfg.logLevel;
      serviceConfig = {
        User = defaultUser;
@@ -255,56 +294,7 @@ in
      requires = [ "firefox-syncserver.service" ] ++ lib.optional dbIsLocal "mysql.service";
      after = [ "firefox-syncserver.service" ] ++ lib.optional dbIsLocal "mysql.service";
      path = [ config.services.mysql.package ];
      script = ''
        set -euo pipefail
        shopt -s inherit_errexit

        schema_configured() {
          mysql ${cfg.database.name} -Ne 'SHOW TABLES' | grep -q services
        }

        services_configured() {
          [ 1 != $(mysql ${cfg.database.name} -Ne 'SELECT COUNT(*) < 1 FROM `services`') ]
        }

        create_services() {
          mysql ${cfg.database.name} <<"EOF"
            BEGIN;

            INSERT INTO `services` (`id`, `service`, `pattern`)
              VALUES (1, 'sync-1.5', '{node}/1.5/{uid}');
            INSERT INTO `nodes` (`id`, `service`, `node`, `available`, `current_load`,
                                 `capacity`, `downed`, `backoff`)
              VALUES (1, 1, '${cfg.singleNode.url}', ${toString cfg.singleNode.capacity},
                      0, ${toString cfg.singleNode.capacity}, 0, 0);

            COMMIT;
        EOF
        }

        update_nodes() {
          mysql ${cfg.database.name} <<"EOF"
            UPDATE `nodes`
              SET `capacity` = ${toString cfg.singleNode.capacity}
              WHERE `id` = 1;
        EOF
        }

        for (( try = 0; try < 60; try++ )); do
          if ! schema_configured; then
            sleep 2
          elif services_configured; then
            update_nodes
            exit 0
          else
            create_services
            exit 0
          fi
        done

        echo "Single-node setup failed"
        exit 1
      '';
      serviceConfig.ExecStart = [ "${setupScript}" ];
    };

    services.nginx.virtualHosts = lib.mkIf cfg.singleNode.enableNginx {