Package core plugins in Gerrit war and install them on init
This change adds a new Maven project 'gerrit-package-plugins' which adds the core plugin jars to the Gerrit war file. Inside of the resulting Gerrit war file the plugins are stored under 'WEB-INF/plugins/'. The init command will now look at this folder during the site initialization and offer the plugins for installation. Change-Id: Ia6c28ef13bbbb7a0358c84e785b8422a2e6a47b3
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
Making a Gerrit Sub Project Release
|
Making a Release of a Gerrit Subproject / Core Plugin
|
||||||
===================================
|
=====================================================
|
||||||
|
|
||||||
Preparing a New Gerrit Subproject Snapshot for Publishing
|
Preparing a New Snapshot for Publishing
|
||||||
---------------------------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
* You will need to have the following in the pom.xml to make it
|
* You will need to have the following in the `pom.xml` to make it
|
||||||
deployable to the gerrit-maven storage bucket:
|
deployable to the `gerrit-maven` storage bucket:
|
||||||
|
|
||||||
----
|
----
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
@@ -19,7 +19,7 @@ Preparing a New Gerrit Subproject Snapshot for Publishing
|
|||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
* Add this to the pom.xml to enable the wagon provider:
|
* Add this to the `pom.xml` to enable the wagon provider:
|
||||||
|
|
||||||
----
|
----
|
||||||
<build>
|
<build>
|
||||||
@@ -34,7 +34,7 @@ Preparing a New Gerrit Subproject Snapshot for Publishing
|
|||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
* Add your username and password to your ~/.m2/settings.xml file.
|
* Add your username and password to your `~/.m2/settings.xml` file.
|
||||||
These need to come from the link:https://code.google.com/apis/console/[API Console].
|
These need to come from the link:https://code.google.com/apis/console/[API Console].
|
||||||
|
|
||||||
----
|
----
|
||||||
@@ -52,11 +52,14 @@ Preparing a New Gerrit Subproject Snapshot for Publishing
|
|||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
Making a Gerrit Subproject Snapshot
|
Making a Snapshot
|
||||||
-----------------------------------
|
-----------------
|
||||||
|
|
||||||
* First build and deploy the latest snapshot and ensure that Gerrit builds
|
* Only for plugins: in the `pom.xml` update the Gerrit version under
|
||||||
with this snapshot
|
`properties` > `Gerrit-ApiVersion` to the version of the new Gerrit
|
||||||
|
release
|
||||||
|
* First build and deploy the latest snapshot and ensure that Gerrit
|
||||||
|
builds/runs with this snapshot
|
||||||
|
|
||||||
* Deploy the snapshot:
|
* Deploy the snapshot:
|
||||||
|
|
||||||
@@ -65,15 +68,17 @@ with this snapshot
|
|||||||
====
|
====
|
||||||
|
|
||||||
|
|
||||||
Making a Gerrit Subproject Release
|
Making a Release
|
||||||
----------------------------------
|
----------------
|
||||||
|
|
||||||
* First deploy (and test) the latest snapshot for the subproject
|
* First deploy (and test) the latest snapshot for the subproject/plugin
|
||||||
|
|
||||||
* Update the top level pom.xml in the subproject to reflect the new project
|
* Update the top level `pom.xml` in the subproject/plugin to reflect
|
||||||
version (the exact value of the tag you will create below)
|
the new project version (the exact value of the tag you will create
|
||||||
|
below)
|
||||||
|
|
||||||
* Commit the pom change and push to the project's repo refs/for/<master/stable>
|
* Commit the pom change and push to the project's repo
|
||||||
|
`refs/for/<master/stable>`
|
||||||
|
|
||||||
* Tag the version you just pushed (and push the tag)
|
* Tag the version you just pushed (and push the tag)
|
||||||
|
|
||||||
|
|||||||
@@ -78,16 +78,19 @@ Prepare the Subprojects
|
|||||||
Prepare Gerrit
|
Prepare Gerrit
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* In the 'stable-2.5' branch: Update the top level pom in Gerrit to ensure that
|
* Create a `stable-2.5` branch for making the new release
|
||||||
none of the Subprojects point to snapshot releases
|
|
||||||
|
|
||||||
* In the 'master' branch: Update the poms for the Gerrit version, push for
|
* In the `master` branch: Update the poms for the Gerrit version, push for
|
||||||
review, get merged
|
review, get merged
|
||||||
|
|
||||||
====
|
====
|
||||||
tools/version.sh --snapshot=2.5
|
tools/version.sh --snapshot=2.5
|
||||||
====
|
====
|
||||||
|
|
||||||
|
* Checkout the `stable-2.5` branch
|
||||||
|
* Update the top level `pom.xml` in Gerrit to ensure that none of the
|
||||||
|
Subprojects point to snapshot releases
|
||||||
|
|
||||||
* Tag
|
* Tag
|
||||||
|
|
||||||
====
|
====
|
||||||
@@ -95,14 +98,35 @@ review, get merged
|
|||||||
git tag -a -m "gerrit 2.5" v2.5
|
git tag -a -m "gerrit 2.5" v2.5
|
||||||
====
|
====
|
||||||
|
|
||||||
* Build
|
* Build (without plugins)
|
||||||
|
|
||||||
====
|
====
|
||||||
./tools/release.sh
|
./tools/release.sh
|
||||||
====
|
====
|
||||||
|
|
||||||
* Sanity check WAR
|
Publish the Plugin API JAR File
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* Push JAR to `commondatastorage.googleapis.com`
|
||||||
|
** Run `tools/deploy_api.sh`
|
||||||
|
|
||||||
|
Prepare the Core Plugins
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
* link:dev-release-subproject.html[Release and publish] the core plugins
|
||||||
|
|
||||||
|
Package Gerrit with Plugins
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
* Ensure that the core plugins listed in `gerrit-package-plugins/pom.xml`
|
||||||
|
point to the latest release version (no dependency to snapshot versions)
|
||||||
|
* Include core plugins into WAR
|
||||||
|
====
|
||||||
|
$ ./tools/version.sh --release && mvn clean package -f gerrit-package-plugins/pom.xml
|
||||||
|
$ ./tools/version.sh --reset
|
||||||
|
====
|
||||||
|
|
||||||
|
* Find WAR that includes the core plugins at
|
||||||
|
`gerrit-package-plugins\target\gerrit-v2.5.war`
|
||||||
|
* Sanity check WAR
|
||||||
|
|
||||||
Publish to the Project Locations
|
Publish to the Project Locations
|
||||||
--------------------------------
|
--------------------------------
|
||||||
@@ -118,12 +142,6 @@ WAR File
|
|||||||
** new war: [release-candidate], featured...
|
** new war: [release-candidate], featured...
|
||||||
** old war: deprecated
|
** old war: deprecated
|
||||||
|
|
||||||
Plugin API JAR File
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* Push JAR to commondatastorage.googleapis.com
|
|
||||||
** Run tools/deploy_api.sh
|
|
||||||
|
|
||||||
Tag
|
Tag
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
|||||||
6
gerrit-package-plugins/.gitignore
vendored
Normal file
6
gerrit-package-plugins/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/target
|
||||||
|
/.classpath
|
||||||
|
/.project
|
||||||
|
/.settings/org.maven.ide.eclipse.prefs
|
||||||
|
/.settings/org.eclipse.m2e.core.prefs
|
||||||
|
/gerrit-package-plugins.iml
|
||||||
90
gerrit-package-plugins/pom.xml
Normal file
90
gerrit-package-plugins/pom.xml
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.google.gerrit</groupId>
|
||||||
|
<artifactId>gerrit-package-plugins</artifactId>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<version>2.5-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<name>Gerrit Code Review - Package Plugins</name>
|
||||||
|
<url>http://code.google.com/p/gerrit/</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>
|
||||||
|
UTF-8
|
||||||
|
</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.gerrit</groupId>
|
||||||
|
<artifactId>gerrit-war</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>war</type>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.googlesource.gerrit.plugins.replication</groupId>
|
||||||
|
<artifactId>replication</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>2.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>process-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<includeTypes>jar</includeTypes>
|
||||||
|
<stripVersion>true</stripVersion>
|
||||||
|
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/plugins</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>2.1.1</version>
|
||||||
|
<configuration>
|
||||||
|
<warName>gerrit-${project.version}</warName>
|
||||||
|
<archive>
|
||||||
|
<addMavenDescriptor>false</addMavenDescriptor>
|
||||||
|
<manifestEntries>
|
||||||
|
<Main-Class>Main</Main-Class>
|
||||||
|
<Implementation-Title>Gerrit Code Review</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -43,6 +43,7 @@ public class InitModule extends FactoryModule {
|
|||||||
step().to(InitSshd.class);
|
step().to(InitSshd.class);
|
||||||
step().to(InitHttpd.class);
|
step().to(InitHttpd.class);
|
||||||
step().to(InitCache.class);
|
step().to(InitCache.class);
|
||||||
|
step().to(InitPlugins.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LinkedBindingBuilder<InitStep> step() {
|
protected LinkedBindingBuilder<InitStep> step() {
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
// 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.init;
|
||||||
|
|
||||||
|
import com.google.gerrit.launcher.GerritLauncher;
|
||||||
|
import com.google.gerrit.pgm.util.ConsoleUI;
|
||||||
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
|
import com.google.gerrit.server.plugins.PluginLoader;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.jar.Attributes;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.jar.Manifest;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class InitPlugins implements InitStep {
|
||||||
|
private final static String PLUGIN_DIR = "WEB-INF/plugins/";
|
||||||
|
private final static String JAR = ".jar";
|
||||||
|
|
||||||
|
private final ConsoleUI ui;
|
||||||
|
private final SitePaths site;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
InitPlugins(final ConsoleUI ui, final SitePaths site) {
|
||||||
|
this.ui = ui;
|
||||||
|
this.site = site;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() throws Exception {
|
||||||
|
ui.header("Plugins");
|
||||||
|
|
||||||
|
final File myWar;
|
||||||
|
try {
|
||||||
|
myWar = GerritLauncher.getDistributionArchive();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.err.println("warn: Cannot find gerrit.war");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean foundPlugin = false;
|
||||||
|
try {
|
||||||
|
final ZipFile zf = new ZipFile(myWar);
|
||||||
|
try {
|
||||||
|
final Enumeration<? extends ZipEntry> e = zf.entries();
|
||||||
|
while (e.hasMoreElements()) {
|
||||||
|
final ZipEntry ze = e.nextElement();
|
||||||
|
if (ze.isDirectory()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ze.getName().startsWith(PLUGIN_DIR) && ze.getName().endsWith(JAR)) {
|
||||||
|
if (!foundPlugin) {
|
||||||
|
if (!ui.yesno(false, "Prompt to install core plugins")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
foundPlugin = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String pluginJarName = new File(ze.getName()).getName();
|
||||||
|
final String pluginName = pluginJarName.substring(0, pluginJarName.length() - JAR.length());
|
||||||
|
|
||||||
|
final InputStream in = zf.getInputStream(ze);
|
||||||
|
try {
|
||||||
|
final File tmpPlugin = PluginLoader.storeInTemp(pluginName, in, site);
|
||||||
|
final String pluginVersion = getVersion(tmpPlugin);
|
||||||
|
|
||||||
|
if (!ui.yesno(false, "Install plugin %s version %s", pluginName,
|
||||||
|
pluginVersion)) {
|
||||||
|
tmpPlugin.delete();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final File plugin = new File(site.plugins_dir, pluginJarName);
|
||||||
|
if (plugin.exists()) {
|
||||||
|
final String installedPluginVersion = getVersion(plugin);
|
||||||
|
if (!ui.yesno(false,
|
||||||
|
"version %s is already installed, overwrite it",
|
||||||
|
installedPluginVersion)) {
|
||||||
|
tmpPlugin.delete();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!plugin.delete()) {
|
||||||
|
throw new IOException("Failed to delete plugin " + pluginName
|
||||||
|
+ ": " + plugin.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tmpPlugin.renameTo(plugin)) {
|
||||||
|
throw new IOException("Failed to install plugin " + pluginName
|
||||||
|
+ ": " + tmpPlugin.getAbsolutePath() + " -> "
|
||||||
|
+ plugin.getAbsolutePath());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
zf.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IOException("Failure during plugin installation", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundPlugin) {
|
||||||
|
ui.message("No plugins found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getVersion(final File plugin) throws IOException {
|
||||||
|
final JarFile jarFile = new JarFile(plugin);
|
||||||
|
try {
|
||||||
|
final Manifest manifest = jarFile.getManifest();
|
||||||
|
final Attributes main = manifest.getMainAttributes();
|
||||||
|
return main.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
|
||||||
|
} finally {
|
||||||
|
jarFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,6 +61,9 @@ public abstract class ConsoleUI {
|
|||||||
/** Display a header message before a series of prompts. */
|
/** Display a header message before a series of prompts. */
|
||||||
public abstract void header(String fmt, Object... args);
|
public abstract void header(String fmt, Object... args);
|
||||||
|
|
||||||
|
/** Display a message. */
|
||||||
|
public abstract void message(String fmt, Object... args);
|
||||||
|
|
||||||
/** Request the user to answer a yes/no question. */
|
/** Request the user to answer a yes/no question. */
|
||||||
public abstract boolean yesno(Boolean def, String fmt, Object... args);
|
public abstract boolean yesno(Boolean def, String fmt, Object... args);
|
||||||
|
|
||||||
@@ -215,6 +218,11 @@ public abstract class ConsoleUI {
|
|||||||
fmt = fmt.replaceAll("\n", "\n*** ");
|
fmt = fmt.replaceAll("\n", "\n*** ");
|
||||||
console.printf("\n*** " + fmt + "\n*** \n\n", args);
|
console.printf("\n*** " + fmt + "\n*** \n\n", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void message(String fmt, Object... args) {
|
||||||
|
console.printf(fmt, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Batch extends ConsoleUI {
|
private static class Batch extends ConsoleUI {
|
||||||
@@ -250,5 +258,9 @@ public abstract class ConsoleUI {
|
|||||||
@Override
|
@Override
|
||||||
public void header(String fmt, Object... args) {
|
public void header(String fmt, Object... args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void message(String fmt, Object... args) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,11 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File storeInTemp(String pluginName, InputStream in,
|
||||||
|
SitePaths sitePaths) throws IOException {
|
||||||
|
return asTemp(in, tempNameFor(pluginName), ".jar", sitePaths.tmp_dir);
|
||||||
|
}
|
||||||
|
|
||||||
private static File asTemp(InputStream in,
|
private static File asTemp(InputStream in,
|
||||||
String prefix, String suffix,
|
String prefix, String suffix,
|
||||||
File dir) throws IOException {
|
File dir) throws IOException {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
./tools/version.sh --release &&
|
./tools/version.sh --release &&
|
||||||
mvn clean package $include_docs -P all
|
mvn clean install $include_docs -P all
|
||||||
rc=$?
|
rc=$?
|
||||||
./tools/version.sh --reset
|
./tools/version.sh --reset
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user