From f16f65741e426b0e58bdf67673aad474cdd5bc7e Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Thu, 26 May 2016 14:10:32 -0400 Subject: [PATCH] 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. --- .../plugins/InstallPluginCommand.java | 4 +++- .../scripts/module_and_plugin_test_cases.bash | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java index 95fc2373766..9e17eec2e93 100644 --- a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java +++ b/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; diff --git a/qa/vagrant/src/test/resources/packaging/scripts/module_and_plugin_test_cases.bash b/qa/vagrant/src/test/resources/packaging/scripts/module_and_plugin_test_cases.bash index 19d9f69ece0..32118fda389 100644 --- a/qa/vagrant/src/test/resources/packaging/scripts/module_and_plugin_test_cases.bash +++ b/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.*