Add InstanceId configuration in gerrit.config

When Gerrit is setup in a multi-master / multi-site scenario,
the serverId must be the same for all Gerrit masters.
However, it may still be needed to name the different masters
with a configured stable string value, so that it is possible
to identify the different servers across the cluster.

Introduce a new configuration setting called 'gerrit.instanceId'
so that servers can be assigned with a stable-id.

Example of gerrit.config:

[gerrit]
  instanceId = foo-instance-1

The value is optional because it is redundant for single Gerrit
master. The configured instanceId value is injected via the
@GerritInstanceId annotation.

Reference design: https://gerrit-review.googlesource.com/c/homepage/+/263710

Feature: Issue 12684
Change-Id: I9caa4e2faee4c0f8b9cdec8bc661fa0fa3299b91
This commit is contained in:
Fabio Ponciroli
2020-05-06 13:59:20 +02:00
committed by Luca Milanesio
parent c17859c52c
commit 829be0db79
8 changed files with 142 additions and 0 deletions

View File

@@ -2224,6 +2224,12 @@ Path prefix for PolyGerrit's static resources if using a CDN.
Path for PolyGerrit's favicon after link:#gerrit.canonicalWebUrl[default URL],
including icon name and extension (.ico should be used).
[[gerrit.instanceId]]gerrit.instanceId::
+
Optional identifier for this Gerrit instance.
Used to identify a specific instance within a group of Gerrit instances with the
same `serverId` (i.e.: a Gerrit cluster).
Unlike `instanceName` this value is not available in the email templates.
[[gerrit.instanceName]]gerrit.instanceName::
+

View File

@@ -108,6 +108,7 @@ import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.GerritInstanceId;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.config.SitePaths;
@@ -245,6 +246,7 @@ public abstract class AbstractDaemonTest {
@Inject @CanonicalWebUrl protected Provider<String> canonicalWebUrl;
@Inject @GerritPersonIdent protected Provider<PersonIdent> serverIdent;
@Inject @GerritServerConfig protected Config cfg;
@Inject @GerritInstanceId @Nullable protected String instanceId;
@Inject protected AcceptanceTestRequestScope atrScope;
@Inject protected AccountCache accountCache;
@Inject protected AccountCreator accountCreator;

View File

@@ -72,6 +72,7 @@ import com.google.gerrit.server.config.CanonicalWebUrlProvider;
import com.google.gerrit.server.config.DefaultUrlFormatter;
import com.google.gerrit.server.config.DownloadConfig;
import com.google.gerrit.server.config.GerritGlobalModule;
import com.google.gerrit.server.config.GerritInstanceIdModule;
import com.google.gerrit.server.config.GerritInstanceNameModule;
import com.google.gerrit.server.config.GerritOptions;
import com.google.gerrit.server.config.GerritRuntime;
@@ -446,6 +447,7 @@ public class Daemon extends SiteProgram {
modules.add(new GpgModule(config));
modules.add(new StartupChecks.Module());
modules.add(new GerritInstanceNameModule());
modules.add(new GerritInstanceIdModule());
if (MoreObjects.firstNonNull(httpd, true)) {
modules.add(
new CanonicalWebUrlModule() {

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.config;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.google.inject.BindingAnnotation;
import java.lang.annotation.Retention;
/**
* Marker on a {@link String} holding the instance id for this server.
*
* <p>Note that the String may be null, if the administrator has not configured the value. Clients
* must handle such cases explicitly.
*/
@Retention(RUNTIME)
@BindingAnnotation
public @interface GerritInstanceId {}

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.config;
import static com.google.inject.Scopes.SINGLETON;
import com.google.inject.AbstractModule;
/** Supports binding the {@link GerritInstanceId} annotation. */
public class GerritInstanceIdModule extends AbstractModule {
@Override
protected void configure() {
bind(String.class)
.annotatedWith(GerritInstanceId.class)
.toProvider(GerritInstanceIdProvider.class)
.in(SINGLETON);
}
}

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.config;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.Config;
/** Provides {@link GerritInstanceId} from {@code gerrit.instanceId}. */
@Singleton
public class GerritInstanceIdProvider implements Provider<String> {
private final String instanceId;
@Inject
public GerritInstanceIdProvider(@GerritServerConfig Config cfg) {
instanceId = cfg.getString("gerrit", null, "instanceId");
}
@Override
public String get() {
return instanceId;
}
}

View File

@@ -49,6 +49,7 @@ import com.google.gerrit.server.config.CanonicalWebUrlModule;
import com.google.gerrit.server.config.CanonicalWebUrlProvider;
import com.google.gerrit.server.config.DefaultUrlFormatter;
import com.google.gerrit.server.config.GerritGlobalModule;
import com.google.gerrit.server.config.GerritInstanceIdModule;
import com.google.gerrit.server.config.GerritInstanceNameModule;
import com.google.gerrit.server.config.GerritOptions;
import com.google.gerrit.server.config.GerritRuntime;
@@ -189,6 +190,7 @@ public class InMemoryModule extends FactoryModule {
install(new InMemorySchemaModule());
install(NoSshKeyCache.module());
install(new GerritInstanceNameModule());
install(new GerritInstanceIdModule());
install(
new CanonicalWebUrlModule() {
@Override

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.acceptance.config;
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import org.junit.Test;
public class GerritInstanceIdIT extends AbstractDaemonTest {
@Test
@GerritConfig(name = "gerrit.instanceId", value = "testInstanceId")
public void shouldReturnInstanceIdWhenDefined() {
assertThat(instanceId).isEqualTo("testInstanceId");
}
@Test
public void shouldReturnNullWhenNotDefined() {
assertThat(instanceId).isNull();
}
}