Don't use PosixPermission on Windows, when creating temp plugin folders
This commit is contained in:
parent
f71f0d6010
commit
ee95c0a384
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue