Add init step for enabling experimental features

This is intended for features that are experimental enough that we want
to hide them behind some warning text, but not so experimental that we
want them to be enabled only with obscure or undocumented commands.

The two current features, to nobody's surprise, are NoteDb and
PolyGerrit.

Enabling NoteDb sets all NotesMigration options to enabled, in
particular disabling ReviewDb for changes, although the tables are
still created since they're still in the schema.

For PolyGerrit, the main question is what the default UI is, as PG has
been part of the WAR for a while now. It is also possible to disable
the GWT UI, although this is not the suggested default option since
there are still some missing features that make switching back
worthwhile.

Change-Id: I419d73eb5944b7c4c8651b86c6efd25a969e60b5
This commit is contained in:
Dave Borowitz 2017-04-24 11:57:47 +02:00
parent ca1c967a68
commit c561858c13
9 changed files with 116 additions and 16 deletions

View File

@ -43,6 +43,9 @@ config snippet in your `gerrit.config`:
disableReviewDb = true
----
This is the configuration that will be produced if you enable experimental
NoteDb support on a new site with `init`.
For an example NoteDb change, poke around at this one:
----

View File

@ -129,6 +129,7 @@ public class BaseInit extends SiteProgram {
init.flags.dev = isDev() && init.site.isNew;
init.flags.skipPlugins = skipPlugins();
init.flags.deleteCaches = getDeleteCaches();
init.flags.isNew = init.site.isNew;
final SiteRun run;
try {

View File

@ -0,0 +1,83 @@
// Copyright (C) 2017 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.pgm.init;
import static com.google.gerrit.server.notedb.ConfigNotesMigration.SECTION_NOTE_DB;
import static com.google.gerrit.server.notedb.NoteDbTable.CHANGES;
import com.google.gerrit.extensions.client.UiType;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.InitStep;
import com.google.gerrit.pgm.init.api.Section;
import com.google.gerrit.server.notedb.ConfigNotesMigration;
import com.google.inject.Inject;
import java.util.Locale;
import javax.inject.Singleton;
import org.eclipse.jgit.lib.Config;
@Singleton
class InitExperimental implements InitStep {
private final ConsoleUI ui;
private final InitFlags flags;
private final Section noteDbChanges;
private final Section gerrit;
@Inject
InitExperimental(ConsoleUI ui, InitFlags flags, Section.Factory sections) {
this.ui = ui;
this.flags = flags; // Don't grab any flags yet; they aren't initialized until BaseInit#run.
this.noteDbChanges = sections.get(SECTION_NOTE_DB, CHANGES.key());
this.gerrit = sections.get("gerrit", null);
}
@Override
public void run() {
ui.header("Experimental features");
if (!ui.yesno(false, "Enable any experimental features")) {
return;
}
if (flags.isNew) {
initNoteDb();
}
initUis();
}
private void initNoteDb() {
ui.message(
"Use experimental NoteDb for change metadata?\n"
+ " NoteDb is not recommended for production servers."
+ " Please familiarize yourself with the documentation:\n"
+ " https://gerrit-review.googlesource.com/Documentation/dev-note-db.html\n");
if (!ui.yesno(false, "Enable")) {
return;
}
Config defaultConfig = ConfigNotesMigration.allEnabledConfig();
for (String name : defaultConfig.getNames(SECTION_NOTE_DB, CHANGES.key())) {
noteDbChanges.set(name, defaultConfig.getString(SECTION_NOTE_DB, CHANGES.key(), name));
}
}
private void initUis() {
boolean pg = ui.yesno(true, "Default to PolyGerrit UI");
UiType uiType = pg ? UiType.POLYGERRIT : UiType.GWT;
gerrit.set("ui", uiType.name().toLowerCase(Locale.US));
if (pg) {
gerrit.set("enableGwtUi", Boolean.toString(ui.yesno(true, "Enable GWT UI")));
}
}
}

View File

@ -15,7 +15,6 @@
package com.google.gerrit.pgm.init;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.InitStep;
import com.google.gerrit.pgm.init.api.Section;
import com.google.gerrit.server.config.SitePaths;
@ -37,7 +36,6 @@ public class InitModule extends FactoryModule {
@Override
protected void configure() {
bind(SitePaths.class);
bind(InitFlags.class);
bind(Libraries.class);
bind(LibraryDownloader.class);
factory(Section.Factory.class);
@ -64,6 +62,7 @@ public class InitModule extends FactoryModule {
step().to(InitCache.class);
step().to(InitPlugins.class);
step().to(InitDev.class);
step().to(InitExperimental.class);
}
protected LinkedBindingBuilder<InitStep> step() {

View File

@ -31,6 +31,9 @@ public class InitFlags {
/** Recursively delete the site path if initialization fails. */
public boolean deleteOnFailure;
/** Site is being newly created */
public boolean isNew;
/** Run the daemon (and open the web UI in a browser) after initialization. */
public boolean autoStart;

View File

@ -44,7 +44,7 @@ public class ConfigNotesMigration extends NotesMigration {
}
}
private static final String NOTE_DB = "noteDb";
public static final String SECTION_NOTE_DB = "noteDb";
// All of these names must be reflected in the allowed set in checkConfig.
private static final String DISABLE_REVIEW_DB = "disableReviewDb";
@ -62,9 +62,9 @@ public class ConfigNotesMigration extends NotesMigration {
READ.toLowerCase(),
WRITE.toLowerCase(),
SEQUENCE.toLowerCase());
for (String t : cfg.getSubsections(NOTE_DB)) {
for (String t : cfg.getSubsections(SECTION_NOTE_DB)) {
checkArgument(keys.contains(t.toLowerCase()), "invalid NoteDb table: %s", t);
for (String key : cfg.getNames(NOTE_DB, t)) {
for (String key : cfg.getNames(SECTION_NOTE_DB, t)) {
checkArgument(allowed.contains(key.toLowerCase()), "invalid NoteDb key: %s.%s", t, key);
}
}
@ -72,8 +72,11 @@ public class ConfigNotesMigration extends NotesMigration {
public static Config allEnabledConfig() {
Config cfg = new Config();
cfg.setBoolean(NOTE_DB, CHANGES.key(), WRITE, true);
cfg.setBoolean(NOTE_DB, CHANGES.key(), READ, true);
cfg.setBoolean(SECTION_NOTE_DB, CHANGES.key(), WRITE, true);
cfg.setBoolean(SECTION_NOTE_DB, CHANGES.key(), READ, true);
cfg.setBoolean(SECTION_NOTE_DB, CHANGES.key(), SEQUENCE, true);
cfg.setString(SECTION_NOTE_DB, CHANGES.key(), PRIMARY_STORAGE, PrimaryStorage.NOTE_DB.name());
cfg.setBoolean(SECTION_NOTE_DB, CHANGES.key(), DISABLE_REVIEW_DB, true);
return cfg;
}
@ -87,18 +90,19 @@ public class ConfigNotesMigration extends NotesMigration {
public ConfigNotesMigration(@GerritServerConfig Config cfg) {
checkConfig(cfg);
writeChanges = cfg.getBoolean(NOTE_DB, CHANGES.key(), WRITE, false);
readChanges = cfg.getBoolean(NOTE_DB, CHANGES.key(), READ, false);
writeChanges = cfg.getBoolean(SECTION_NOTE_DB, CHANGES.key(), WRITE, false);
readChanges = cfg.getBoolean(SECTION_NOTE_DB, CHANGES.key(), READ, false);
// Reading change sequence numbers from NoteDb is not the default even if
// reading changes themselves is. Once this is enabled, it's not easy to
// undo: ReviewDb might hand out numbers that have already been assigned by
// NoteDb. This decision for the default may be reevaluated later.
readChangeSequence = cfg.getBoolean(NOTE_DB, CHANGES.key(), SEQUENCE, false);
readChangeSequence = cfg.getBoolean(SECTION_NOTE_DB, CHANGES.key(), SEQUENCE, false);
changePrimaryStorage =
cfg.getEnum(NOTE_DB, CHANGES.key(), PRIMARY_STORAGE, PrimaryStorage.REVIEW_DB);
disableChangeReviewDb = cfg.getBoolean(NOTE_DB, CHANGES.key(), DISABLE_REVIEW_DB, false);
cfg.getEnum(SECTION_NOTE_DB, CHANGES.key(), PRIMARY_STORAGE, PrimaryStorage.REVIEW_DB);
disableChangeReviewDb =
cfg.getBoolean(SECTION_NOTE_DB, CHANGES.key(), DISABLE_REVIEW_DB, false);
checkArgument(
!(disableChangeReviewDb && changePrimaryStorage != PrimaryStorage.NOTE_DB),

View File

@ -14,11 +14,11 @@
package com.google.gerrit.server.notedb;
enum NoteDbTable {
public enum NoteDbTable {
ACCOUNTS,
CHANGES;
String key() {
public String key() {
return name().toLowerCase();
}

View File

@ -50,7 +50,10 @@ public class SchemaUpdater {
@Inject
SchemaUpdater(
SchemaFactory<ReviewDb> schema, SitePaths site, SchemaCreator creator, Injector parent) {
@ReviewDbFactory SchemaFactory<ReviewDb> schema,
SitePaths site,
SchemaCreator creator,
Injector parent) {
this.schema = schema;
this.site = site;
this.creator = creator;

View File

@ -38,6 +38,7 @@ import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.gwtorm.server.StatementExecutor;
import com.google.inject.Guice;
import com.google.inject.Key;
import com.google.inject.ProvisionException;
import com.google.inject.TypeLiteral;
import java.io.FileNotFoundException;
@ -82,7 +83,10 @@ public class SchemaUpdaterTest {
new FactoryModule() {
@Override
protected void configure() {
bind(new TypeLiteral<SchemaFactory<ReviewDb>>() {}).toInstance(db);
TypeLiteral<SchemaFactory<ReviewDb>> schemaFactory =
new TypeLiteral<SchemaFactory<ReviewDb>>() {};
bind(schemaFactory).to(NotesMigrationSchemaFactory.class);
bind(Key.get(schemaFactory, ReviewDbFactory.class)).toInstance(db);
bind(SitePaths.class).toInstance(paths);
Config cfg = new Config();