瀏覽代碼

Fix when plugins directory is symlink

This commit fixes an issue with the plugins directory being a symbolic
link. Namely, the install plugins command attempts to always create the
plugins directory just in case it does not exist. The JDK method used
here guarantees that the directory is created, and an exception is not
thrown if the directory could not be created because it already
exists. The problem is that this JDK method does not respect symlinks so
its internal existence checks fails, it proceeds to attempt to create
the directory, but the directory creation fails because the symlink
exists. This is documented as being not an issue. We work around this by
checking if there is a symlink where we expect the plugins directory to
be, and only attempt to create if not. We add a unit test that plugin
installation to a symlinked plugins directory works as expected.
Jason Tedor 9 年之前
父節點
當前提交
f16f65741e

+ 3 - 1
core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java

@@ -304,7 +304,9 @@ class InstallPluginCommand extends SettingCommand {
 
                 // be on the safe side: do not rely on that directories are always extracted
                 // before their children (although this makes sense, but is it guaranteed?)
-                Files.createDirectories(targetFile.getParent());
+                if (!Files.isSymbolicLink(targetFile.getParent())) {
+                    Files.createDirectories(targetFile.getParent());
+                }
                 if (entry.isDirectory() == false) {
                     try (OutputStream out = Files.newOutputStream(targetFile)) {
                         int len;

+ 22 - 0
qa/vagrant/src/test/resources/packaging/scripts/module_and_plugin_test_cases.bash

@@ -113,6 +113,28 @@ fi
     fi
 }
 
+@test "[$GROUP] install jvm-example plugin with a symlinked plugins path" {
+    # Clean up after the last time this test was run
+    rm -rf /tmp/plugins.*
+    rm -rf /tmp/old_plugins.*
+
+    rm -rf "$ESPLUGINS"
+    local es_plugins=$(mktemp -d -t 'plugins.XXXX')
+    chown -R elasticsearch:elasticsearch "$es_plugins"
+    ln -s "$es_plugins" "$ESPLUGINS"
+
+    install_jvm_example
+    start_elasticsearch_service
+    # check that symlinked plugin was actually picked up
+    curl -s localhost:9200/_cat/configured_example | sed 's/ *$//' > /tmp/installed
+    echo "foo" > /tmp/expected
+    diff /tmp/installed /tmp/expected
+    stop_elasticsearch_service
+    remove_jvm_example
+
+    unlink "$ESPLUGINS"
+}
+
 @test "[$GROUP] install jvm-example plugin with a custom CONFIG_DIR" {
     # Clean up after the last time we ran this test
     rm -rf /tmp/config.*