Option to skip library download during init
The init tool offers a mechanism to download a required library like
BouncyCastle during installation, and to remove "stale" versions of
that library from the lib/ folder if specified in libraries.config.
However, init does not check (and in general cannot check) that
the library actually is stale, but forcefully replaces it with the
version stated in libraries.config.
For security critical libraries like BouncyCastle this is dangerous,
especially when doing a batch install. In that case, init may silently
download a potentially vulnerable library version and replace a more
secure version already residing in the lib/ folder.
This patch adds two new options to the init program to disable the
automatic library download altogether, or selectively:
--skip-all-downloads switches the download mechanism off completely;
--skip-download <lib> switches the download off for the given library
(<lib> being the section name of a library in libraries.config).
Change-Id: I1df60b2fd7a4bf519b135e16deebb68a3b9095ef
Signed-off-by: Michael Ochmann <michael.ochmann@sap.com>
diff --git a/Documentation/pgm-init.txt b/Documentation/pgm-init.txt
index 6aa3a74..9fe813b 100644
--- a/Documentation/pgm-init.txt
+++ b/Documentation/pgm-init.txt
@@ -12,6 +12,8 @@
[--list-plugins]
[--install-plugin=<PLUGIN_NAME>]
[--dev]
+ [--skip-all-downloads]
+ [--skip-download=<LIBRARY_NAME>]
--
== DESCRIPTION
@@ -56,6 +58,14 @@
Install in developer mode. Default configuration settings are
chosen to run the Gerrit server as a developer.
+--skip-all-downloads::
+ Do not automatically download and install required libraries. The
+ administrator must provision the required libraries in the lib/ folder.
+
+--skip-download::
+ Do not automatically download and install the library with the given name.
+ The administrator must provision the required library in the lib/ folder.
+
== CONTEXT
This command can only be run on a server which has direct
connectivity to the metadata database, and local access to the
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Init.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Init.java
index e08b7ac..f57f95f 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Init.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Init.java
@@ -40,6 +40,7 @@
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/** Initialize a new Gerrit installation. */
@@ -67,6 +68,12 @@
usage = "Setup site with default options suitable for developers")
private boolean dev;
+ @Option(name = "--skip-all-downloads", usage = "Don't download libraries")
+ private boolean skipAllDownloads;
+
+ @Option(name = "--skip-download", usage = "Don't download given library")
+ private List<String> skippedDownloads;
+
@Inject
Browser browser;
@@ -147,6 +154,18 @@
}
@Override
+ protected boolean skipAllDownloads() {
+ return skipAllDownloads;
+ }
+
+ @Override
+ protected List<String> getSkippedDownloads() {
+ return skippedDownloads != null
+ ? skippedDownloads
+ : Collections.<String> emptyList();
+ }
+
+ @Override
protected String getSecureStoreLib() {
return secureStoreLib;
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java
index b200ed5..2136723 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java
@@ -26,6 +26,7 @@
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.InstallPlugins;
+import com.google.gerrit.pgm.init.api.LibraryDownload;
import com.google.gerrit.pgm.util.SiteProgram;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.config.GerritServerConfigModule;
@@ -147,6 +148,14 @@
return null;
}
+ protected boolean skipAllDownloads() {
+ return false;
+ }
+
+ protected List<String> getSkippedDownloads() {
+ return Collections.emptyList();
+ }
+
/**
* Invoked before site init is called.
*
@@ -252,6 +261,10 @@
bind(String.class).annotatedWith(SecureStoreClassName.class)
.toProvider(Providers.of(secureStoreClassName));
bind(SecureStore.class).toProvider(SecureStoreProvider.class).in(SINGLETON);
+ bind(new TypeLiteral<List<String>>() {}).annotatedWith(
+ LibraryDownload.class).toInstance(getSkippedDownloads());
+ bind(Boolean.class).annotatedWith(
+ LibraryDownload.class).toInstance(skipAllDownloads());
}
});
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/Libraries.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/Libraries.java
index 988d7ef..282e75a 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/Libraries.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/Libraries.java
@@ -16,6 +16,7 @@
import static java.nio.charset.StandardCharsets.UTF_8;
+import com.google.gerrit.pgm.init.api.LibraryDownload;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -30,6 +31,7 @@
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.util.List;
/** Standard {@link LibraryDownloader} instances derived from configuration. */
@Singleton
@@ -38,6 +40,8 @@
"com/google/gerrit/pgm/init/libraries.config";
private final Provider<LibraryDownloader> downloadProvider;
+ private final List<String> skippedDownloads;
+ private final boolean skipAllDownloads;
/* final */LibraryDownloader bouncyCastlePGP;
/* final */LibraryDownloader bouncyCastleProvider;
@@ -49,9 +53,12 @@
/* final */LibraryDownloader oracleDriver;
@Inject
- Libraries(final Provider<LibraryDownloader> downloadProvider) {
+ Libraries(final Provider<LibraryDownloader> downloadProvider,
+ @LibraryDownload List<String> skippedDownloads,
+ @LibraryDownload Boolean skipAllDownloads) {
this.downloadProvider = downloadProvider;
-
+ this.skippedDownloads = skippedDownloads;
+ this.skipAllDownloads = skipAllDownloads;
init();
}
@@ -98,6 +105,7 @@
for (String d : cfg.getStringList("library", n, "needs")) {
dl.addNeeds((LibraryDownloader) getClass().getDeclaredField(d).get(this));
}
+ dl.setSkipDownload(skipAllDownloads || skippedDownloads.contains(n));
}
private static String getOptional(Config cfg, String name, String key) {
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java
index e4cc305..a354376 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java
@@ -58,6 +58,7 @@
private Path dst;
private boolean download; // download or copy
private boolean exists;
+ private boolean skipDownload;
@Inject
LibraryDownloader(ConsoleUI ui, SitePaths site) {
@@ -87,6 +88,10 @@
needs.add(lib);
}
+ void setSkipDownload(boolean skipDownload) {
+ this.skipDownload = skipDownload;
+ }
+
void downloadRequired() {
setRequired(true);
download();
@@ -105,6 +110,10 @@
}
private void download() {
+ if (skipDownload) {
+ return;
+ }
+
if (jarUrl == null || !jarUrl.contains("/")) {
throw new IllegalStateException("Invalid JarUrl for " + name);
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/api/LibraryDownload.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/api/LibraryDownload.java
new file mode 100644
index 0000000..7e46b21
--- /dev/null
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/api/LibraryDownload.java
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 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.api;
+
+import com.google.inject.BindingAnnotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@BindingAnnotation
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LibraryDownload {
+}
diff --git a/gerrit-pgm/src/test/java/com/google/gerrit/pgm/init/LibrariesTest.java b/gerrit-pgm/src/test/java/com/google/gerrit/pgm/init/LibrariesTest.java
index 2198788..48754f1 100644
--- a/gerrit-pgm/src/test/java/com/google/gerrit/pgm/init/LibrariesTest.java
+++ b/gerrit-pgm/src/test/java/com/google/gerrit/pgm/init/LibrariesTest.java
@@ -26,6 +26,7 @@
import org.junit.Test;
import java.nio.file.Paths;
+import java.util.Collections;
public class LibrariesTest {
@Test
@@ -40,7 +41,7 @@
public LibraryDownloader get() {
return new LibraryDownloader(ui, site);
}
- });
+ }, Collections.<String> emptyList(), false);
assertNotNull(lib.bouncyCastleProvider);
assertNotNull(lib.mysqlDriver);