Don't use PosixPermission on Windows, when creating temp plugin folders

This commit is contained in:
Boaz Leskes 2016-03-19 11:35:05 +01:00
parent f71f0d6010
commit ee95c0a384
1 changed files with 53 additions and 47 deletions

View File

@ -21,6 +21,7 @@ package org.elasticsearch.plugins;
import joptsimple.OptionSet; import joptsimple.OptionSet;
import joptsimple.OptionSpec; import joptsimple.OptionSpec;
import org.apache.lucene.util.Constants;
import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.IOUtils;
import org.elasticsearch.Build; import org.elasticsearch.Build;
import org.elasticsearch.Version; import org.elasticsearch.Version;
@ -68,9 +69,9 @@ import static org.elasticsearch.common.util.set.Sets.newHashSet;
* *
* The install command takes a plugin id, which may be any of the following: * The install command takes a plugin id, which may be any of the following:
* <ul> * <ul>
* <li>An official elasticsearch plugin name</li> * <li>An official elasticsearch plugin name</li>
* <li>Maven coordinates to a plugin zip</li> * <li>Maven coordinates to a plugin zip</li>
* <li>A URL to a plugin zip</li> * <li>A URL to a plugin zip</li>
* </ul> * </ul>
* *
* Plugins are packaged as zip files. Each packaged plugin must contain a * Plugins are packaged as zip files. Each packaged plugin must contain a
@ -79,9 +80,9 @@ import static org.elasticsearch.common.util.set.Sets.newHashSet;
* The installation process first extracts the plugin files into a temporary * The installation process first extracts the plugin files into a temporary
* directory in order to verify the plugin satisfies the following requirements: * directory in order to verify the plugin satisfies the following requirements:
* <ul> * <ul>
* <li>Jar hell does not exist, either between the plugin's own jars, or with elasticsearch</li> * <li>Jar hell does not exist, either between the plugin's own jars, or with elasticsearch</li>
* <li>The plugin is not a module already provided with elasticsearch</li> * <li>The plugin is not a module already provided with elasticsearch</li>
* <li>If the plugin contains extra security permissions, the policy file is validated</li> * <li>If the plugin contains extra security permissions, the policy file is validated</li>
* </ul> * </ul>
* <p> * <p>
* A plugin may also contain an optional {@code bin} directory which contains scripts. The * A plugin may also contain an optional {@code bin} directory which contains scripts. The
@ -99,34 +100,34 @@ class InstallPluginCommand extends Command {
// TODO: make this a resource file generated by gradle // TODO: make this a resource file generated by gradle
static final Set<String> MODULES = unmodifiableSet(newHashSet( static final Set<String> MODULES = unmodifiableSet(newHashSet(
"ingest-grok", "ingest-grok",
"lang-expression", "lang-expression",
"lang-groovy", "lang-groovy",
"lang-painless", "lang-painless",
"reindex")); "reindex"));
// TODO: make this a resource file generated by gradle // TODO: make this a resource file generated by gradle
static final Set<String> OFFICIAL_PLUGINS = unmodifiableSet(new LinkedHashSet<>(Arrays.asList( static final Set<String> OFFICIAL_PLUGINS = unmodifiableSet(new LinkedHashSet<>(Arrays.asList(
"analysis-icu", "analysis-icu",
"analysis-kuromoji", "analysis-kuromoji",
"analysis-phonetic", "analysis-phonetic",
"analysis-smartcn", "analysis-smartcn",
"analysis-stempel", "analysis-stempel",
"delete-by-query", "delete-by-query",
"discovery-azure", "discovery-azure",
"discovery-ec2", "discovery-ec2",
"discovery-gce", "discovery-gce",
"ingest-attachment", "ingest-attachment",
"ingest-geoip", "ingest-geoip",
"lang-javascript", "lang-javascript",
"lang-python", "lang-python",
"mapper-attachments", "mapper-attachments",
"mapper-murmur3", "mapper-murmur3",
"mapper-size", "mapper-size",
"repository-azure", "repository-azure",
"repository-hdfs", "repository-hdfs",
"repository-s3", "repository-s3",
"store-smb"))); "store-smb")));
private final Environment env; private final Environment env;
private final OptionSpec<Void> batchOption; private final OptionSpec<Void> batchOption;
@ -136,7 +137,7 @@ class InstallPluginCommand extends Command {
super("Install a plugin"); super("Install a plugin");
this.env = env; this.env = env;
this.batchOption = parser.acceptsAll(Arrays.asList("b", "batch"), this.batchOption = parser.acceptsAll(Arrays.asList("b", "batch"),
"Enable batch mode explicitly, automatic confirmation of security permission"); "Enable batch mode explicitly, automatic confirmation of security permission");
this.arguments = parser.nonOptions("plugin id"); this.arguments = parser.nonOptions("plugin id");
} }
@ -182,10 +183,10 @@ class InstallPluginCommand extends Command {
final String url; final String url;
if (System.getProperty(PROPERTY_SUPPORT_STAGING_URLS, "false").equals("true")) { if (System.getProperty(PROPERTY_SUPPORT_STAGING_URLS, "false").equals("true")) {
url = String.format(Locale.ROOT, "https://download.elastic.co/elasticsearch/staging/%1$s-%2$s/org/elasticsearch/plugin/%3$s/%1$s/%3$s-%1$s.zip", url = String.format(Locale.ROOT, "https://download.elastic.co/elasticsearch/staging/%1$s-%2$s/org/elasticsearch/plugin/%3$s/%1$s/%3$s-%1$s.zip",
version, Build.CURRENT.shortHash(), pluginId); version, Build.CURRENT.shortHash(), pluginId);
} else { } else {
url = String.format(Locale.ROOT, "https://download.elastic.co/elasticsearch/release/org/elasticsearch/plugin/%1$s/%2$s/%1$s-%2$s.zip", url = String.format(Locale.ROOT, "https://download.elastic.co/elasticsearch/release/org/elasticsearch/plugin/%1$s/%2$s/%1$s-%2$s.zip",
pluginId, version); pluginId, version);
} }
terminal.println("-> Downloading " + pluginId + " from elastic"); terminal.println("-> Downloading " + pluginId + " from elastic");
return downloadZipAndChecksum(url, tmpDir); return downloadZipAndChecksum(url, tmpDir);
@ -195,7 +196,7 @@ class InstallPluginCommand extends Command {
String[] coordinates = pluginId.split(":"); String[] coordinates = pluginId.split(":");
if (coordinates.length == 3 && pluginId.contains("/") == false) { if (coordinates.length == 3 && pluginId.contains("/") == false) {
String mavenUrl = String.format(Locale.ROOT, "https://repo1.maven.org/maven2/%1$s/%2$s/%3$s/%2$s-%3$s.zip", String mavenUrl = String.format(Locale.ROOT, "https://repo1.maven.org/maven2/%1$s/%2$s/%3$s/%2$s-%3$s.zip",
coordinates[0].replace(".", "/") /* groupId */, coordinates[1] /* artifactId */, coordinates[2] /* version */); coordinates[0].replace(".", "/") /* groupId */, coordinates[1] /* artifactId */, coordinates[2] /* version */);
terminal.println("-> Downloading " + pluginId + " from maven central"); terminal.println("-> Downloading " + pluginId + " from maven central");
return downloadZipAndChecksum(mavenUrl, tmpDir); return downloadZipAndChecksum(mavenUrl, tmpDir);
} }
@ -241,15 +242,20 @@ class InstallPluginCommand extends Command {
private Path unzip(Path zip, Path pluginsDir) throws IOException, UserError { private Path unzip(Path zip, Path pluginsDir) throws IOException, UserError {
// unzip plugin to a staging temp dir // unzip plugin to a staging temp dir
Set<PosixFilePermission> perms = new HashSet<>(); final Path target;
perms.add(PosixFilePermission.OWNER_EXECUTE); if (Constants.WINDOWS) {
perms.add(PosixFilePermission.OWNER_READ); target = Files.createTempDirectory(pluginsDir, ".installing-");
perms.add(PosixFilePermission.OWNER_WRITE); } else {
perms.add(PosixFilePermission.GROUP_READ); Set<PosixFilePermission> perms = new HashSet<>();
perms.add(PosixFilePermission.GROUP_EXECUTE); perms.add(PosixFilePermission.OWNER_EXECUTE);
perms.add(PosixFilePermission.OTHERS_READ); perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OTHERS_EXECUTE); perms.add(PosixFilePermission.OWNER_WRITE);
Path target = Files.createTempDirectory(pluginsDir, ".installing-", PosixFilePermissions.asFileAttribute(perms)); perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.GROUP_EXECUTE);
perms.add(PosixFilePermission.OTHERS_READ);
perms.add(PosixFilePermission.OTHERS_EXECUTE);
target = Files.createTempDirectory(pluginsDir, ".installing-", PosixFilePermissions.asFileAttribute(perms));
}
Files.createDirectories(target); Files.createDirectories(target);
boolean hasEsDir = false; boolean hasEsDir = false;
@ -279,7 +285,7 @@ class InstallPluginCommand extends Command {
if (entry.isDirectory() == false) { if (entry.isDirectory() == false) {
try (OutputStream out = Files.newOutputStream(targetFile)) { try (OutputStream out = Files.newOutputStream(targetFile)) {
int len; int len;
while((len = zipInput.read(buffer)) >= 0) { while ((len = zipInput.read(buffer)) >= 0) {
out.write(buffer, 0, len); out.write(buffer, 0, len);
} }
} }
@ -408,7 +414,7 @@ class InstallPluginCommand extends Command {
perms.add(PosixFilePermission.OTHERS_EXECUTE); perms.add(PosixFilePermission.OTHERS_EXECUTE);
} }
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpBinDir)) { try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpBinDir)) {
for (Path srcFile : stream) { for (Path srcFile : stream) {
if (Files.isDirectory(srcFile)) { if (Files.isDirectory(srcFile)) {
throw new UserError(ExitCodes.DATA_ERROR, "Directories not allowed in bin dir for plugin " + info.getName() + ", found " + srcFile.getFileName()); throw new UserError(ExitCodes.DATA_ERROR, "Directories not allowed in bin dir for plugin " + info.getName() + ", found " + srcFile.getFileName());
@ -442,7 +448,7 @@ class InstallPluginCommand extends Command {
Files.getFileAttributeView(destConfigDir.getParent(), PosixFileAttributeView.class).readAttributes(); Files.getFileAttributeView(destConfigDir.getParent(), PosixFileAttributeView.class).readAttributes();
setOwnerGroup(destConfigDir, destConfigDirAttributes); setOwnerGroup(destConfigDir, destConfigDirAttributes);
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpConfigDir)) { try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpConfigDir)) {
for (Path srcFile : stream) { for (Path srcFile : stream) {
if (Files.isDirectory(srcFile)) { if (Files.isDirectory(srcFile)) {
throw new UserError(ExitCodes.DATA_ERROR, "Directories not allowed in config dir for plugin " + info.getName()); throw new UserError(ExitCodes.DATA_ERROR, "Directories not allowed in config dir for plugin " + info.getName());