Merge "Add --init option to Daemon to initialize site on daemon start."

This commit is contained in:
Shawn Pearce
2013-06-03 13:19:50 +00:00
committed by Gerrit Code Review
6 changed files with 32 additions and 130 deletions

View File

@@ -2275,28 +2275,6 @@ If true the deprecated `/query` URL is available to return JSON
and text results for changes. If false, the URL is disabled and and text results for changes. If false, the URL is disabled and
returns 404 to clients. Default is true, enabling `/query`. 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 [[ssh-alias]] Section ssh-alias
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -15,6 +15,7 @@ SYNOPSIS
[\--console-log] [\--console-log]
[\--slave] [\--slave]
[\--headless] [\--headless]
[\--init]
DESCRIPTION DESCRIPTION
----------- -----------
@@ -63,6 +64,10 @@ This option automatically implies '\--disable-httpd \--enable-sshd'.
Don't start the default Gerrit UI. May be useful when Gerrit is Don't start the default Gerrit UI. May be useful when Gerrit is
run with an alternative UI. run with an alternative UI.
\--init::
Run init before starting the daemon. This will create a new site or
upgrade an existing site.
CONTEXT CONTEXT
------- -------
This command can only be run on a server which has direct This command can only be run on a server which has direct

View File

@@ -39,14 +39,12 @@ import com.google.gerrit.pgm.util.LogFileCompressor;
import com.google.gerrit.pgm.util.RuntimeShutdown; import com.google.gerrit.pgm.util.RuntimeShutdown;
import com.google.gerrit.pgm.util.SiteProgram; import com.google.gerrit.pgm.util.SiteProgram;
import com.google.gerrit.reviewdb.client.AuthType; 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.cache.h2.DefaultCacheFactory;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.AuthConfigModule; import com.google.gerrit.server.config.AuthConfigModule;
import com.google.gerrit.server.config.CanonicalWebUrlModule; import com.google.gerrit.server.config.CanonicalWebUrlModule;
import com.google.gerrit.server.config.CanonicalWebUrlProvider; import com.google.gerrit.server.config.CanonicalWebUrlProvider;
import com.google.gerrit.server.config.GerritGlobalModule; 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.config.MasterNodeStartup;
import com.google.gerrit.server.contact.HttpContactStoreConnection; import com.google.gerrit.server.contact.HttpContactStoreConnection;
import com.google.gerrit.server.git.ReceiveCommitsExecutorModule; import com.google.gerrit.server.git.ReceiveCommitsExecutorModule;
@@ -58,27 +56,18 @@ import com.google.gerrit.server.mail.SmtpEmailSender;
import com.google.gerrit.server.patch.IntraLineWorkerPool; import com.google.gerrit.server.patch.IntraLineWorkerPool;
import com.google.gerrit.server.plugins.PluginGuiceEnvironment; import com.google.gerrit.server.plugins.PluginGuiceEnvironment;
import com.google.gerrit.server.plugins.PluginModule; 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.SchemaVersionCheck;
import com.google.gerrit.server.schema.UpdateUI;
import com.google.gerrit.server.ssh.NoSshKeyCache; import com.google.gerrit.server.ssh.NoSshKeyCache;
import com.google.gerrit.server.ssh.NoSshModule; import com.google.gerrit.server.ssh.NoSshModule;
import com.google.gerrit.sshd.SshKeyCacheImpl; import com.google.gerrit.sshd.SshKeyCacheImpl;
import com.google.gerrit.sshd.SshModule; import com.google.gerrit.sshd.SshModule;
import com.google.gerrit.sshd.commands.MasterCommandModule; import com.google.gerrit.sshd.commands.MasterCommandModule;
import com.google.gerrit.sshd.commands.SlaveCommandModule; 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.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Module; import com.google.inject.Module;
import com.google.inject.Provider; import com.google.inject.Provider;
import org.eclipse.jgit.lib.Config;
import org.kohsuke.args4j.Option; import org.kohsuke.args4j.Option;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -124,6 +113,10 @@ public class Daemon extends SiteProgram {
@Option(name = "--headless", usage = "Don't start the UI frontend") @Option(name = "--headless", usage = "Don't start the UI frontend")
private boolean headless; private boolean headless;
@Option(name = "--init", aliases = {"-i"},
usage = "Init site before starting the daemon")
private boolean doInit;
private final LifecycleManager manager = new LifecycleManager(); private final LifecycleManager manager = new LifecycleManager();
private Injector dbInjector; private Injector dbInjector;
private Injector cfgInjector; private Injector cfgInjector;
@@ -144,6 +137,13 @@ public class Daemon extends SiteProgram {
@Override @Override
public int run() throws Exception { public int run() throws Exception {
if (doInit) {
try {
new Init(getSitePath()).run();
} catch (Exception e) {
throw die("Init failed", e);
}
}
mustHaveValidSite(); mustHaveValidSite();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override @Override
@@ -179,7 +179,6 @@ public class Daemon extends SiteProgram {
sysInjector = createSysInjector(); sysInjector = createSysInjector();
sysInjector.getInstance(PluginGuiceEnvironment.class) sysInjector.getInstance(PluginGuiceEnvironment.class)
.setCfgInjector(cfgInjector); .setCfgInjector(cfgInjector);
sysInjector.getInstance(SchemaUpgrade.class).upgradeSchema();
manager.add(dbInjector, cfgInjector, sysInjector); manager.add(dbInjector, cfgInjector, sysInjector);
if (sshd) { if (sshd) {
@@ -231,74 +230,6 @@ 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() { private String myVersion() {
return com.google.gerrit.common.Version.getVersion(); return com.google.gerrit.common.Version.getVersion();
} }

View File

@@ -62,6 +62,15 @@ public class Init extends SiteProgram {
@Option(name = "--no-auto-start", usage = "Don't automatically start daemon after init") @Option(name = "--no-auto-start", usage = "Don't automatically start daemon after init")
private boolean noAutoStart; private boolean noAutoStart;
public Init() {
}
public Init(File sitePath) {
super(sitePath);
batchMode = true;
noAutoStart = true;
}
@Override @Override
public int run() throws Exception { public int run() throws Exception {
ErrorLogFile.errorOnlyConsole(); ErrorLogFile.errorOnlyConsole();

View File

@@ -1,28 +0,0 @@
// 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
}

View File

@@ -51,6 +51,13 @@ public abstract class SiteProgram extends AbstractProgram {
@Option(name = "--site-path", aliases = {"-d"}, usage = "Local directory containing site data") @Option(name = "--site-path", aliases = {"-d"}, usage = "Local directory containing site data")
private File sitePath = new File("."); private File sitePath = new File(".");
protected SiteProgram() {
}
protected SiteProgram(File sitePath) {
this.sitePath = sitePath;
}
/** @return the site path specified on the command line. */ /** @return the site path specified on the command line. */
protected File getSitePath() { protected File getSitePath() {
File path = sitePath.getAbsoluteFile(); File path = sitePath.getAbsoluteFile();