Merge branch 'stable-3.1' * stable-3.1: ChangeEditModifier: Reject invalid file paths as '400 Bad Request' Remove orphan library downloader facility Fix a bug where _moreChanges is set to the wrong value Don't check conflicting ref names when deleting refs Change-Id: I3eb1d9d4821a1f925ce05f3809e18118e626e419
diff --git a/java/com/google/gerrit/git/RefUpdateUtil.java b/java/com/google/gerrit/git/RefUpdateUtil.java index fa7b98f..bd88962 100644 --- a/java/com/google/gerrit/git/RefUpdateUtil.java +++ b/java/com/google/gerrit/git/RefUpdateUtil.java
@@ -150,6 +150,7 @@ public static void deleteChecked(Repository repo, String refName) throws IOException { RefUpdate ru = repo.updateRef(refName); ru.setForceUpdate(true); + ru.setCheckConflicting(false); switch (ru.delete()) { case FORCED: // Ref was deleted.
diff --git a/java/com/google/gerrit/pgm/init/InitModule.java b/java/com/google/gerrit/pgm/init/InitModule.java index f2fc001..b658675 100644 --- a/java/com/google/gerrit/pgm/init/InitModule.java +++ b/java/com/google/gerrit/pgm/init/InitModule.java
@@ -34,8 +34,6 @@ @Override protected void configure() { bind(SitePaths.class); - bind(Libraries.class); - bind(LibraryDownloader.class); factory(Section.Factory.class); factory(VersionedAuthorizedKeysOnInit.Factory.class);
diff --git a/java/com/google/gerrit/pgm/init/Libraries.java b/java/com/google/gerrit/pgm/init/Libraries.java deleted file mode 100644 index c599e99..0000000 --- a/java/com/google/gerrit/pgm/init/Libraries.java +++ /dev/null
@@ -1,141 +0,0 @@ -// Copyright (C) 2009 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 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; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.List; -import org.eclipse.jgit.errors.ConfigInvalidException; -import org.eclipse.jgit.lib.Config; - -/** Standard {@link LibraryDownloader} instances derived from configuration. */ -@Singleton -class Libraries { - private static final String RESOURCE_FILE = "com/google/gerrit/pgm/init/libraries.config"; - - private final Provider<LibraryDownloader> downloadProvider; - private final List<String> skippedDownloads; - private final boolean skipAllDownloads; - - /* final */ LibraryDownloader db2Driver; - /* final */ LibraryDownloader db2DriverLicense; - /* final */ LibraryDownloader hanaDriver; - /* final */ LibraryDownloader mariadbDriver; - /* final */ LibraryDownloader mysqlDriver; - /* final */ LibraryDownloader oracleDriver; - - @Inject - Libraries( - final Provider<LibraryDownloader> downloadProvider, - @LibraryDownload List<String> skippedDownloads, - @LibraryDownload Boolean skipAllDownloads) { - this.downloadProvider = downloadProvider; - this.skippedDownloads = skippedDownloads; - this.skipAllDownloads = skipAllDownloads; - init(); - } - - private void init() { - final Config cfg = new Config(); - try { - cfg.fromText(read(RESOURCE_FILE)); - } catch (IOException | ConfigInvalidException e) { - throw new RuntimeException(e.getMessage(), e); - } - - for (Field f : Libraries.class.getDeclaredFields()) { - if ((f.getModifiers() & Modifier.STATIC) == 0 && f.getType() == LibraryDownloader.class) { - try { - f.set(this, downloadProvider.get()); - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new IllegalStateException("Cannot initialize " + f.getName()); - } - } - } - - for (Field f : Libraries.class.getDeclaredFields()) { - if ((f.getModifiers() & Modifier.STATIC) == 0 && f.getType() == LibraryDownloader.class) { - try { - init(f, cfg); - } catch (IllegalArgumentException - | IllegalAccessException - | NoSuchFieldException - | SecurityException e) { - throw new IllegalStateException("Cannot configure " + f.getName()); - } - } - } - } - - private void init(Field field, Config cfg) - throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, - SecurityException { - String n = field.getName(); - LibraryDownloader dl = (LibraryDownloader) field.get(this); - dl.setName(get(cfg, n, "name")); - dl.setJarUrl(get(cfg, n, "url")); - dl.setSHA1(getOptional(cfg, n, "sha1")); - dl.setRemove(get(cfg, n, "remove")); - 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) { - return doGet(cfg, name, key, false); - } - - private static String get(Config cfg, String name, String key) { - return doGet(cfg, name, key, true); - } - - private static String doGet(Config cfg, String name, String key, boolean required) { - String val = cfg.getString("library", name, key); - if ((val == null || val.isEmpty()) && required) { - throw new IllegalStateException( - "Variable library." + name + "." + key + " is required within " + RESOURCE_FILE); - } - return val; - } - - private static String read(String p) throws IOException { - try (InputStream in = Libraries.class.getClassLoader().getResourceAsStream(p)) { - if (in == null) { - throw new FileNotFoundException("Cannot load resource " + p); - } - try (Reader r = new InputStreamReader(in, UTF_8)) { - final StringBuilder buf = new StringBuilder(); - final char[] tmp = new char[512]; - int n; - while (0 < (n = r.read(tmp))) { - buf.append(tmp, 0, n); - } - return buf.toString(); - } - } - } -}
diff --git a/java/com/google/gerrit/pgm/init/LibraryDownloader.java b/java/com/google/gerrit/pgm/init/LibraryDownloader.java deleted file mode 100644 index 0b31ee2..0000000 --- a/java/com/google/gerrit/pgm/init/LibraryDownloader.java +++ /dev/null
@@ -1,316 +0,0 @@ -// Copyright (C) 2009 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.common.hash.Funnels; -import com.google.common.hash.Hasher; -import com.google.common.hash.Hashing; -import com.google.common.io.ByteStreams; -import com.google.gerrit.common.Die; -import com.google.gerrit.common.IoUtil; -import com.google.gerrit.pgm.init.api.ConsoleUI; -import com.google.gerrit.server.config.SitePaths; -import com.google.inject.Inject; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.Proxy; -import java.net.ProxySelector; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import org.eclipse.jgit.util.HttpSupport; - -/** Get optional or required 3rd party library files into $site_path/lib. */ -class LibraryDownloader { - private final ConsoleUI ui; - private final Path lib_dir; - private final StaleLibraryRemover remover; - - private boolean required; - private String name; - private String jarUrl; - private String sha1; - private String remove; - private List<LibraryDownloader> needs; - private LibraryDownloader neededBy; - private Path dst; - private boolean download; // download or copy - private boolean exists; - private boolean skipDownload; - - @Inject - LibraryDownloader(ConsoleUI ui, SitePaths site, StaleLibraryRemover remover) { - this.ui = ui; - this.lib_dir = site.lib_dir; - this.remover = remover; - this.needs = new ArrayList<>(2); - } - - void setName(String name) { - this.name = name; - } - - void setJarUrl(String url) { - this.jarUrl = url; - download = jarUrl.startsWith("http"); - } - - void setSHA1(String sha1) { - this.sha1 = sha1; - } - - void setRemove(String remove) { - this.remove = remove; - } - - void addNeeds(LibraryDownloader lib) { - needs.add(lib); - } - - void setSkipDownload(boolean skipDownload) { - this.skipDownload = skipDownload; - } - - void downloadRequired() { - setRequired(true); - download(); - } - - void downloadOptional() { - required = false; - download(); - } - - private void setRequired(boolean r) { - required = r; - for (LibraryDownloader d : needs) { - d.setRequired(r); - } - } - - private void download() { - if (skipDownload) { - return; - } - - if (jarUrl == null || !jarUrl.contains("/")) { - throw new IllegalStateException("Invalid JarUrl for " + name); - } - - final String jarName = jarUrl.substring(jarUrl.lastIndexOf('/') + 1); - if (jarName.contains("/") || jarName.contains("\\")) { - throw new IllegalStateException("Invalid JarUrl: " + jarUrl); - } - - if (name == null) { - name = jarName; - } - - dst = lib_dir.resolve(jarName); - if (Files.exists(dst)) { - exists = true; - } else if (shouldGet()) { - doGet(); - } - - if (exists) { - for (LibraryDownloader d : needs) { - d.neededBy = this; - d.downloadRequired(); - } - } - } - - private boolean shouldGet() { - if (ui.isBatch()) { - return required; - } - final StringBuilder msg = new StringBuilder(); - msg.append("\n"); - msg.append("Gerrit Code Review is not shipped with %s\n"); - if (neededBy != null) { - msg.append(String.format("** This library is required by %s. **\n", neededBy.name)); - } else if (required) { - msg.append("** This library is required for your configuration. **\n"); - } else { - msg.append(" If available, Gerrit can take advantage of features\n"); - msg.append(" in the library, but will also function without it.\n"); - } - msg.append(String.format("%s and install it now", download ? "Download" : "Copy")); - return ui.yesno(true, msg.toString(), name); - } - - private void doGet() { - if (!Files.exists(lib_dir)) { - try { - Files.createDirectories(lib_dir); - } catch (IOException e) { - throw new Die("Cannot create " + lib_dir, e); - } - } - - try { - remover.remove(remove); - if (download) { - doGetByHttp(); - } else { - doGetByLocalCopy(); - } - verifyFileChecksum(); - } catch (IOException err) { - try { - Files.delete(dst); - } catch (IOException e) { - // Delete failed; leave alone. - } - - if (ui.isBatch()) { - throw new Die("error: Cannot get " + jarUrl, err); - } - - System.err.println(); - System.err.println(); - System.err.println("error: " + err.getMessage()); - System.err.println("Please download:"); - System.err.println(); - System.err.println(" " + jarUrl); - System.err.println(); - System.err.println("and save as:"); - System.err.println(); - System.err.println(" " + dst.toAbsolutePath()); - System.err.println(); - System.err.flush(); - - ui.waitForUser(); - - if (Files.exists(dst)) { - verifyFileChecksum(); - - } else if (!ui.yesno(!required, "Continue without this library")) { - throw new Die("aborted by user"); - } - } - - if (Files.exists(dst)) { - exists = true; - IoUtil.loadJARs(dst); - } - } - - private void doGetByLocalCopy() throws IOException { - System.err.print("Copying " + jarUrl + " ..."); - Path p = url2file(jarUrl); - if (!Files.exists(p)) { - StringBuilder msg = - new StringBuilder() - .append("\n") - .append("Can not find the %s at this location: %s\n") - .append("Please provide alternative URL"); - p = url2file(ui.readString(null, msg.toString(), name, jarUrl)); - } - Files.copy(p, dst); - } - - private static Path url2file(String urlString) throws IOException { - final URL url = new URL(urlString); - try { - return Paths.get(url.toURI()); - } catch (URISyntaxException e) { - return Paths.get(url.getPath()); - } - } - - private void doGetByHttp() throws IOException { - System.err.print("Downloading " + jarUrl + " ..."); - System.err.flush(); - try (InputStream in = openHttpStream(jarUrl); - OutputStream out = Files.newOutputStream(dst)) { - ByteStreams.copy(in, out); - System.err.println(" OK"); - System.err.flush(); - } catch (IOException err) { - deleteDst(); - System.err.println(" !! FAIL !!"); - System.err.println(err); - System.err.flush(); - throw err; - } - } - - private static InputStream openHttpStream(String urlStr) throws IOException { - ProxySelector proxySelector = ProxySelector.getDefault(); - URL url = new URL(urlStr); - Proxy proxy = HttpSupport.proxyFor(proxySelector, url); - HttpURLConnection c = (HttpURLConnection) url.openConnection(proxy); - - switch (HttpSupport.response(c)) { - case HttpURLConnection.HTTP_OK: - return c.getInputStream(); - - case HttpURLConnection.HTTP_NOT_FOUND: - throw new FileNotFoundException(url.toString()); - - default: - throw new IOException( - url.toString() + ": " + HttpSupport.response(c) + " " + c.getResponseMessage()); - } - } - - @SuppressWarnings("deprecation") // Use Hashing.sha1 for compatibility. - private void verifyFileChecksum() { - if (sha1 == null) { - System.err.println(); - System.err.flush(); - return; - } - Hasher h = Hashing.sha1().newHasher(); - try (InputStream in = Files.newInputStream(dst); - OutputStream out = Funnels.asOutputStream(h)) { - ByteStreams.copy(in, out); - } catch (IOException e) { - deleteDst(); - throw new Die("cannot checksum " + dst, e); - } - if (sha1.equals(h.hash().toString())) { - System.err.println("Checksum " + dst.getFileName() + " OK"); - System.err.flush(); - } else if (ui.isBatch()) { - deleteDst(); - throw new Die(dst + " SHA-1 checksum does not match"); - - } else if (!ui.yesno( - null /* force an answer */, - "error: SHA-1 checksum does not match\nUse %s anyway", // - dst.getFileName())) { - deleteDst(); - throw new Die("aborted by user"); - } - } - - private void deleteDst() { - try { - Files.delete(dst); - } catch (IOException e) { - System.err.println(" Failed to clean up lib: " + dst); - } - } -}
diff --git a/javatests/com/google/gerrit/pgm/init/LibrariesTest.java b/javatests/com/google/gerrit/pgm/init/LibrariesTest.java deleted file mode 100644 index 5aa4718..0000000 --- a/javatests/com/google/gerrit/pgm/init/LibrariesTest.java +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright (C) 2009 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 static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.verifyZeroInteractions; - -import com.google.gerrit.pgm.init.api.ConsoleUI; -import com.google.gerrit.server.config.SitePaths; -import java.nio.file.Paths; -import java.util.Collections; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.class) -public class LibrariesTest { - @Mock ConsoleUI ui; - @Mock StaleLibraryRemover remover; - - @Test - public void create() throws Exception { - final SitePaths site = new SitePaths(Paths.get(".")); - - Libraries lib = - new Libraries( - () -> new LibraryDownloader(ui, site, remover), Collections.emptyList(), false); - - assertNotNull(lib.mysqlDriver); - verifyZeroInteractions(ui); - verifyZeroInteractions(remover); - } -}
diff --git a/resources/com/google/gerrit/pgm/init/libraries.config b/resources/com/google/gerrit/pgm/init/libraries.config deleted file mode 100644 index 3d3545b..0000000 --- a/resources/com/google/gerrit/pgm/init/libraries.config +++ /dev/null
@@ -1,50 +0,0 @@ -# Copyright (C) 2009 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. - -[library "mysqlDriver"] - name = MySQL Connector/J 5.1.43 - url = https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.43/mysql-connector-java-5.1.43.jar - sha1 = dee9103eec0d877f3a21c82d4d9e9f4fbd2d6e0a - remove = mysql-connector-java-.*[.]jar - -[library "mariadbDriver"] - name = MariaDB Connector/J 2.3.0 - url = https://repo1.maven.org/maven2/org/mariadb/jdbc/mariadb-java-client/2.3.0/mariadb-java-client-2.3.0.jar - sha1 = c2b1a6002a169757d0649449288e9b3b776af76b - remove = mariadb-java-client-.*[.]jar - -[library "oracleDriver"] - name = Oracle JDBC driver 11g Release 2 (11.2.0) - url = file:///u01/app/oracle/product/11.2.0/xe/jdbc/lib/ojdbc6.jar - sha1 = 2f89cd9176772c3a6c261ce6a8e3d0d4425f5679 - remove = ojdbc6.jar - -[library "db2Driver"] - name = DB2 Type 4 JDBC driver (10.5) - url = file:///opt/ibm/db2/V10.5/java/db2jcc4.jar - sha1 = 9344d4fd41d6511f2d1d1deb7759056495b3a39b - needs = db2DriverLicense - remove = db2jcc4.jar - -# Omit SHA-1 for license JAR as it's not stable and depends on the product -# the customer has purchased. -[library "db2DriverLicense"] - name = DB2 Type 4 JDBC driver license (10.5) - url = file:///opt/ibm/db2/V10.5/java/db2jcc_license_cu.jar - remove = db2jcc_license_cu.jar - -[library "hanaDriver"] - name = HANA JDBC driver - url = file:///usr/sap/hdbclient/ngdbc.jar - remove = ngdbc.jar