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:
parent
88531176ec
commit
67e09dc69e
@ -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
|
||||
deployable to the gerrit-maven storage bucket:
|
||||
* You will need to have the following in the `pom.xml` to make it
|
||||
deployable to the `gerrit-maven` storage bucket:
|
||||
|
||||
----
|
||||
<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>
|
||||
@ -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].
|
||||
|
||||
----
|
||||
@ -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
|
||||
with this snapshot
|
||||
* Only for plugins: in the `pom.xml` update the Gerrit version under
|
||||
`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:
|
||||
|
||||
@ -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
|
||||
version (the exact value of the tag you will create below)
|
||||
* Update the top level `pom.xml` in the subproject/plugin to reflect
|
||||
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)
|
||||
|
||||
|
@ -78,16 +78,19 @@ Prepare the Subprojects
|
||||
Prepare Gerrit
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
* In the 'stable-2.5' branch: Update the top level pom in Gerrit to ensure that
|
||||
none of the Subprojects point to snapshot releases
|
||||
* Create a `stable-2.5` branch for making the new release
|
||||
|
||||
* 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
|
||||
|
||||
====
|
||||
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
|
||||
|
||||
====
|
||||
@ -95,14 +98,35 @@ review, get merged
|
||||
git tag -a -m "gerrit 2.5" v2.5
|
||||
====
|
||||
|
||||
* Build
|
||||
* Build (without plugins)
|
||||
|
||||
====
|
||||
./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
|
||||
--------------------------------
|
||||
@ -118,12 +142,6 @@ WAR File
|
||||
** new war: [release-candidate], featured...
|
||||
** old war: deprecated
|
||||
|
||||
Plugin API JAR File
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Push JAR to commondatastorage.googleapis.com
|
||||
** Run tools/deploy_api.sh
|
||||
|
||||
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(InitHttpd.class);
|
||||
step().to(InitCache.class);
|
||||
step().to(InitPlugins.class);
|
||||
}
|
||||
|
||||
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. */
|
||||
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. */
|
||||
public abstract boolean yesno(Boolean def, String fmt, Object... args);
|
||||
|
||||
@ -215,6 +218,11 @@ public abstract class ConsoleUI {
|
||||
fmt = fmt.replaceAll("\n", "\n*** ");
|
||||
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 {
|
||||
@ -250,5 +258,9 @@ public abstract class ConsoleUI {
|
||||
@Override
|
||||
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,
|
||||
String prefix, String suffix,
|
||||
File dir) throws IOException {
|
||||
|
@ -25,7 +25,7 @@ then
|
||||
fi
|
||||
|
||||
./tools/version.sh --release &&
|
||||
mvn clean package $include_docs -P all
|
||||
mvn clean install $include_docs -P all
|
||||
rc=$?
|
||||
./tools/version.sh --reset
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user