Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: create the tmp dir if it doesn't exist #102599

Merged
merged 5 commits into from Nov 28, 2023

Conversation

jan-elastic
Copy link
Contributor

@jan-elastic jan-elastic commented Nov 24, 2023

@elasticsearchmachine elasticsearchmachine added needs:triage Requires assignment of a team area label v8.12.0 labels Nov 24, 2023
@jan-elastic jan-elastic added >bug :ml Machine learning Team:ML Meta label for the ML team v6.8.12 v8.11.2 and removed needs:triage Requires assignment of a team area label v8.12.0 labels Nov 24, 2023
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/ml-core (Team:ML)

@elasticsearchmachine
Copy link
Collaborator

Hi @jan-elastic, I've created a changelog YAML for you.

@@ -249,6 +251,7 @@ private void buildScheduledEventsConfig(List<String> command) throws IOException
}

private void buildJobConfig(List<String> command) throws IOException {
Files.createDirectories(env.tmpFile());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This simple fix resolves the problem locally.

I don't know if my local environment is close enough to production w.r.t. security, permissions, etc, to judge whether this will also work in production.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: this fix also works in a Dockerized Ubuntu 20.04.

The following flow succeeds:

  • start Elasticsearch
  • open job
  • close job
  • remove tmp dir
  • open job

The deleted tmp dir is successfully recreated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks for testing that. The final thing to confirm is the permissions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: without this fix you get something like

java.nio.file.NoSuchFileException: /tmp/elasticsearch-14675733582508699252/config6396271037101692016.json

@droberts195
Copy link
Contributor

There's one more place that needs changing, in AnalyticsBuilder.java here:

Path configFile = Files.createTempFile(tempDir, "analysis", ".conf");

The place where the temp directory gets created at server startup is here:

Because at that time it's created using Files.createTempDirectory with no attributes provided it defaults to the following (at least in Java 20):

        static final FileAttribute<Set<PosixFilePermission>> dirPermissions =
            PosixFilePermissions.asFileAttribute(EnumSet
                .of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE));

This is what we want for a secure temp directory.

Please check that Files.createDirectories uses those restricted permissions. I have a feeling that it might allow group and other access too if attributes are not supplied. If it does then it will be necessary to explicitly supply attributes. But then there'll be the complication that Windows needs different permission attributes.

At startup we already do something different on Windows here:

So it looks like on Windows we can match the startup behaviour by not supplying any attributes.

In the ML code you can use if (Constants.WINDOWS) to check for Windows, for example like here:

So please wrap all this up into a recreateTempDirectory utility method that can be called from all the places where it's needed. We have a org.elasticsearch.xpack.ml.utils package where it could go. And you can add a unit test for the utility method that asserts that the permissions are 700 if the test is not running on Windows.

@jan-elastic
Copy link
Contributor Author

You're correct: my new directory was created with permissions drwxr-xr-x.

That's fixed now.

Copy link
Member

@davidkyle davidkyle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are 2 situations where the code should ensure the temp directory exists. One is for anomaly detection and DFA jobs where they write config files to the temp directory which is covered here. The other is where the code creates named pipes to talk to those processes. This happens in the ProcessPipes class and that code is used to connect to all the native processes that we deploy.

https://github.com/elastic/elasticsearch/blob/main/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/process/ProcessPipes.java#L101

Before those pipes are created add the same call to FileUtils.recreateTempDirectoryIfNeeded(env.tmpFile());

This can be done in the constructor or in the ProcessPipes::connectLogStream and ProcessPipes::connectOtherStreams methods

This doesn't apply to Windows where named pipes are created differently:
https://github.com/elastic/elasticsearch/blob/main/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/utils/NamedPipeHelper.java#L73

@jan-elastic
Copy link
Contributor Author

Added recreating the tmp dir in ProcessPipes.

I didn't bother to make an exception for Windows: I think recreating the temp dir is a noop in Windows (Windows doesn't clean up), and otherwise it's pretty cheap anyway.

Copy link
Member

@davidkyle davidkyle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jan-elastic jan-elastic added the auto-backport-and-merge Automatically create backport pull requests and merge when ready label Nov 28, 2023
@jan-elastic jan-elastic merged commit 0a71135 into main Nov 28, 2023
15 checks passed
@jan-elastic jan-elastic deleted the create-tmp-dir-if-not-exists branch November 28, 2023 10:47
@elasticsearchmachine
Copy link
Collaborator

💔 Backport failed

You can use sqren/backport to manually backport by running backport --upstream elastic/elasticsearch --pr 102599

elasticsearchmachine pushed a commit that referenced this pull request Nov 28, 2023
* Make sure the tmp dir exists before creating a tmp file

* Correct file permissions

* changelog

* Recreate tmp dir before creating named pipes
timgrein pushed a commit to timgrein/elasticsearch that referenced this pull request Nov 30, 2023
* Make sure the tmp dir exists before creating a tmp file

* Correct file permissions

* changelog

* Recreate tmp dir before creating named pipes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport-and-merge Automatically create backport pull requests and merge when ready >bug :ml Machine learning Team:ML Meta label for the ML team v8.11.2 v8.12.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants