Automatic schema upgrade on Gerrit startup

In case when Gerrit administrator(s) don't have a direct access to the
file system where the review site is located it gets difficult to
perform a schema upgrade (run the init program). For such cases it is
convenient if Gerrit performs schema upgrade automatically on its
startup.

Since this is a potentially dangerous operation, by default it will not
be performed. Configuration parameter site.upgradeSchemaOnStartup is
used to switch on automatic schema upgrade. It has 3 possible values:

  * OFF - no automatic schema upgrade (default)
  * AUTO - automatic schema upgrade and drop of unused DB objects
  * AUTO_NO_PRUNE - like AUTO but without dropping unused DB objects

Change-Id: Ief1bf1135fde74146e5a5fdd25f510a4eeae0a73
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
Signed-off-by: Sasa Zivkov <sasa.zivkov@sap.com>
This commit is contained in:
Sasa Zivkov
2012-06-14 14:57:53 +02:00
parent 23c571899e
commit de980a4ddd
3 changed files with 130 additions and 0 deletions

View File

@@ -1938,6 +1938,28 @@ If true the deprecated `/query` URL is available to return JSON
and text results for changes. If false, the URL is disabled and
returns 404 to clients. Default is true, enabling `/query`.
[[site.upgradeSchemaOnStartup]]site.upgradeSchemaOnStartup::
+
Control whether schema upgrade should be done on Gerrit startup. The following
values are supported:
+
* `OFF`
+
No automatic schema upgrade on startup.
+
* `AUTO`
+
Perform schema migration on startup, if necessary. If, as a result of
schema migration, there would be any unused database objects they will
be dropped automatically.
+
* `AUTO_NO_PRUNE`
+
Like `AUTO` but unused database objects will not be pruned.
+
The default is `OFF`.
[[ssh-alias]] Section ssh-alias
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -35,12 +35,14 @@ import com.google.gerrit.pgm.util.LogFileCompressor;
import com.google.gerrit.pgm.util.RuntimeShutdown;
import com.google.gerrit.pgm.util.SiteProgram;
import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.cache.h2.DefaultCacheFactory;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.AuthConfigModule;
import com.google.gerrit.server.config.CanonicalWebUrlModule;
import com.google.gerrit.server.config.CanonicalWebUrlProvider;
import com.google.gerrit.server.config.GerritGlobalModule;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.MasterNodeStartup;
import com.google.gerrit.server.contact.HttpContactStoreConnection;
import com.google.gerrit.server.git.ReceiveCommitsExecutorModule;
@@ -49,15 +51,24 @@ import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier;
import com.google.gerrit.server.mail.SmtpEmailSender;
import com.google.gerrit.server.plugins.PluginGuiceEnvironment;
import com.google.gerrit.server.plugins.PluginModule;
import com.google.gerrit.server.schema.SchemaUpdater;
import com.google.gerrit.server.schema.SchemaVersionCheck;
import com.google.gerrit.server.schema.UpdateUI;
import com.google.gerrit.server.ssh.NoSshModule;
import com.google.gerrit.sshd.SshModule;
import com.google.gerrit.sshd.commands.MasterCommandModule;
import com.google.gerrit.sshd.commands.SlaveCommandModule;
import com.google.gwtorm.jdbc.JdbcExecutor;
import com.google.gwtorm.jdbc.JdbcSchema;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.gwtorm.server.StatementExecutor;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.Config;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -145,6 +156,7 @@ public class Daemon extends SiteProgram {
sysInjector = createSysInjector();
sysInjector.getInstance(PluginGuiceEnvironment.class)
.setCfgInjector(cfgInjector);
sysInjector.getInstance(SchemaUpgrade.class).upgradeSchema();
manager.add(dbInjector, cfgInjector, sysInjector);
if (sshd) {
@@ -192,6 +204,74 @@ public class Daemon extends SiteProgram {
}
}
static class SchemaUpgrade {
private final Config config;
private final SchemaUpdater updater;
private final SchemaFactory<ReviewDb> schema;
@Inject
SchemaUpgrade(@GerritServerConfig Config config, SchemaUpdater updater,
SchemaFactory<ReviewDb> schema) {
this.config = config;
this.updater = updater;
this.schema = schema;
}
void upgradeSchema() throws OrmException {
SchemaUpgradePolicy policy =
config.getEnum("site", null, "upgradeSchemaOnStartup",
SchemaUpgradePolicy.OFF);
if (policy == SchemaUpgradePolicy.AUTO
|| policy == SchemaUpgradePolicy.AUTO_NO_PRUNE) {
final List<String> pruneList = new ArrayList<String>();
updater.update(new UpdateUI() {
@Override
public void message(String msg) {
log.info(msg);
}
@Override
public boolean yesno(boolean def, String msg) {
return true;
}
@Override
public boolean isBatch() {
return true;
}
@Override
public void pruneSchema(StatementExecutor e, List<String> prune) {
for (String p : prune) {
if (!pruneList.contains(p)) {
pruneList.add(p);
}
}
}
});
if (!pruneList.isEmpty() && policy == SchemaUpgradePolicy.AUTO) {
log.info("Pruning: " + pruneList.toString());
final JdbcSchema db = (JdbcSchema) schema.open();
try {
final JdbcExecutor e = new JdbcExecutor(db);
try {
for (String sql : pruneList) {
e.execute(sql);
}
} finally {
e.close();
}
} finally {
db.close();
}
}
}
}
}
private String myVersion() {
return com.google.gerrit.common.Version.getVersion();
}

View File

@@ -0,0 +1,28 @@
// Copyright (C) 2012 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;
/** Policy for auto upgrading schema on server startup */
public enum SchemaUpgradePolicy {
/** Perform schema migration if necessary and prune unused objects */
AUTO,
/** Like AUTO but don't prune unused objects */
AUTO_NO_PRUNE,
/** No automatic schema upgrade */
OFF
}