Add --init option to Daemon to initialize site on daemon start.
The --init option will also upgrade an already existing site and
is processed in non-interactive (batch) mode.
This is a rework of the automatic schema upgrade feature that was
introduced with de980a4ddd and is
reverted with this change. Running init is more generic and also
supports initialization of a new site on daemon start.
Besides automatic upgrade, this feature also makes developers work
more comfortable as it can eliminate running init as a separate
step before running the daemon.
Change-Id: I6a245172529812e42e573413f41424a0497e9539
			
			
This commit is contained in:
		@@ -2213,28 +2213,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
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,14 +38,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;
 | 
				
			||||||
@@ -55,27 +53,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;
 | 
				
			||||||
@@ -121,6 +110,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;
 | 
				
			||||||
@@ -141,6 +134,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
 | 
				
			||||||
@@ -176,7 +176,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) {
 | 
				
			||||||
@@ -228,74 +227,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();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user