Skip to content

Commit

Permalink
Correct file permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-elastic committed Nov 27, 2023
1 parent e1e9d6f commit 9e8e297
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 5 deletions.
3 changes: 2 additions & 1 deletion x-pack/plugin/ml/build.gradle
Expand Up @@ -103,6 +103,7 @@ dependencies {
changing = true
}
testImplementation 'org.ini4j:ini4j:0.5.2'
testImplementation "com.google.jimfs:jimfs:${versions.jimfs}"
}

artifacts {
Expand Down Expand Up @@ -133,4 +134,4 @@ tasks.named("dependencyLicenses").configure {
mapping from: /lucene-.*/, to: 'lucene'
}

addQaCheckDependencies(project)
addQaCheckDependencies(project)
Expand Up @@ -12,6 +12,7 @@
import org.elasticsearch.xcontent.json.JsonXContent;
import org.elasticsearch.xpack.ml.process.NativeController;
import org.elasticsearch.xpack.ml.process.ProcessPipes;
import org.elasticsearch.xpack.ml.utils.FileUtils;

import java.io.IOException;
import java.io.OutputStreamWriter;
Expand Down Expand Up @@ -80,6 +81,7 @@ private List<String> buildAnalyticsCommand() throws IOException {

private void addConfigFile(List<String> command) throws IOException {
Path tempDir = tempDirPathSupplier.get();
FileUtils.recreateTempDirectoryIfNeeded(tempDir);
Path configFile = Files.createTempFile(tempDir, "analysis", ".conf");
filesToDelete.add(configFile);
try (
Expand Down
Expand Up @@ -23,6 +23,7 @@
import org.elasticsearch.xpack.ml.job.process.autodetect.writer.ScheduledEventToRuleWriter;
import org.elasticsearch.xpack.ml.process.NativeController;
import org.elasticsearch.xpack.ml.process.ProcessPipes;
import org.elasticsearch.xpack.ml.utils.FileUtils;

import java.io.BufferedWriter;
import java.io.IOException;
Expand Down Expand Up @@ -208,7 +209,7 @@ public static Path writeNormalizerInitState(String jobId, String state, Environm
// createTempFile has a race condition where it may return the same
// temporary file name to different threads if called simultaneously
// from multiple threads, hence add the thread ID to avoid this
Files.createDirectories(env.tmpFile());
FileUtils.recreateTempDirectoryIfNeeded(env.tmpFile());
Path stateFile = Files.createTempFile(
env.tmpFile(),
jobId + "_quantiles_" + Thread.currentThread().getId(),
Expand All @@ -226,7 +227,7 @@ private void buildScheduledEventsConfig(List<String> command) throws IOException
if (scheduledEvents.isEmpty()) {
return;
}
Files.createDirectories(env.tmpFile());
FileUtils.recreateTempDirectoryIfNeeded(env.tmpFile());
Path eventsConfigFile = Files.createTempFile(env.tmpFile(), "eventsConfig", JSON_EXTENSION);
filesToDelete.add(eventsConfigFile);

Expand All @@ -251,7 +252,7 @@ private void buildScheduledEventsConfig(List<String> command) throws IOException
}

private void buildJobConfig(List<String> command) throws IOException {
Files.createDirectories(env.tmpFile());
FileUtils.recreateTempDirectoryIfNeeded(env.tmpFile());
Path configFile = Files.createTempFile(env.tmpFile(), "config", JSON_EXTENSION);
filesToDelete.add(configFile);
try (
Expand All @@ -270,7 +271,7 @@ private void buildFiltersConfig(List<String> command) throws IOException {
if (referencedFilters.isEmpty()) {
return;
}
Files.createDirectories(env.tmpFile());
FileUtils.recreateTempDirectoryIfNeeded(env.tmpFile());
Path filtersConfigFile = Files.createTempFile(env.tmpFile(), "filtersConfig", JSON_EXTENSION);
filesToDelete.add(filtersConfigFile);

Expand Down
@@ -0,0 +1,41 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.ml.utils;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.EnumSet;

/**
* Some utility functions for managing files.
*/
public final class FileUtils {

private static final FileAttribute<?>[] POSIX_TMP_DIR_PERMISSIONS = new FileAttribute<?>[] {
PosixFilePermissions.asFileAttribute(
EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE)
) };

/**
* Recreates the Elasticsearch temporary directory if it doesn't exist.
* The operating system may have cleaned it up due to inactivity, which
* causes some (machine learning) processes to fail.
* @param tmpDir the path to the temporary directory
*/
public static void recreateTempDirectoryIfNeeded(Path tmpDir) throws IOException {
if (tmpDir.getFileSystem().supportedFileAttributeViews().contains("posix")) {
Files.createDirectories(tmpDir, POSIX_TMP_DIR_PERMISSIONS);
} else {
Files.createDirectories(tmpDir);
}
}
}
@@ -0,0 +1,58 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.ml.utils;

import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;

import org.elasticsearch.core.PathUtilsForTesting;
import org.elasticsearch.test.ESTestCase;

import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;

public class FileUtilsTests extends ESTestCase {

public void test_recreateTempDirectoryIfNeeded_forWindows() throws IOException {
FileSystem fileSystem = Jimfs.newFileSystem(Configuration.windows());
PathUtilsForTesting.installMock(fileSystem);

Path tmpDir = fileSystem.getPath("c:\\tmp\\elasticsearch");

assertFalse(Files.exists(tmpDir));
FileUtils.recreateTempDirectoryIfNeeded(tmpDir);
assertTrue(Files.exists(tmpDir));

BasicFileAttributes attributes = Files.readAttributes(tmpDir, BasicFileAttributes.class);
assertTrue(attributes.isDirectory());
}

public void test_recreateTempDirectoryIfNeeded_forPosix() throws IOException {
FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix().toBuilder().setAttributeViews("posix").build());
PathUtilsForTesting.installMock(fileSystem);

Path tmpDir = fileSystem.getPath("/tmp/elasticsearch-1234567890");

assertFalse(Files.exists(tmpDir));
FileUtils.recreateTempDirectoryIfNeeded(tmpDir);
assertTrue(Files.exists(tmpDir));

PosixFileAttributes attributes = Files.readAttributes(tmpDir, PosixFileAttributes.class);
assertTrue(attributes.isDirectory());
assertEquals(
attributes.permissions(),
Set.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE)
);
}
}

0 comments on commit 9e8e297

Please sign in to comment.