Skip to content

Commit 308d072

Browse files
committed
Fix race condition by memoizing Tempfile objects
Previously, the `certificate` and `private_key` methods created `Tempfile` objects without maintaining references after the methods exited. This allowed the Ruby garbage collector to collect and delete these temporary files at any time. As a result, there was a race condition where the `keytool` binary could fail with a `java.io.FileNotFoundException` if the temporary files were deleted before `keytool` accessed them. This commit resolves the issue by memoizing the `Tempfile` objects using instance variables (`@temp_certificate_file` and `@temp_private_key_file`). By caching these objects, we prevent them from being garbage collected prematurely, ensuring that the temporary files remain available for the duration of the provider instance. Fixes #425
1 parent 5dc91d7 commit 308d072

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

Diff for: lib/puppet/provider/java_ks/keytool.rb

+21-14
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,17 @@ def certificate
284284
# When no certificate file is specified, we infer the usage of
285285
# certificate content and create a tempfile containing this value.
286286
# we leave it to to the tempfile to clean it up after the pupet run exists.
287-
file = Tempfile.new('certificate')
288-
# Check if the specified value is a Sensitive data type. If so, unwrap it and use
289-
# the value.
290-
content = @resource[:certificate_content].respond_to?(:unwrap) ? @resource[:certificate_content].unwrap : @resource[:certificate_content]
291-
file.write(content)
292-
file.close
293-
file.path
287+
@temp_certificate_file ||= begin
288+
file = Tempfile.new('certificate')
289+
# Check if the specified value is a Sensitive data type. If so, unwrap it and use
290+
# the value.
291+
content = @resource[:certificate_content].respond_to?(:unwrap) ? @resource[:certificate_content].unwrap : @resource[:certificate_content]
292+
file.write(content)
293+
file.close
294+
file
295+
end
296+
297+
@temp_certificate_file.path
294298
end
295299

296300
def private_key
@@ -300,13 +304,16 @@ def private_key
300304
# When no private key file is specified, we infer the usage of
301305
# private key content and create a tempfile containing this value.
302306
# we leave it to to the tempfile to clean it up after the pupet run exists.
303-
file = Tempfile.new('private_key')
304-
# Check if the specified value is a Sensitive data type. If so, unwrap it and use
305-
# the value.
306-
content = @resource[:private_key_content].respond_to?(:unwrap) ? @resource[:private_key_content].unwrap : @resource[:private_key_content]
307-
file.write(content)
308-
file.close
309-
file.path
307+
@temp_private_key_file ||= begin
308+
file = Tempfile.new('private_key')
309+
# Check if the specified value is a Sensitive data type. If so, unwrap it and use
310+
# the value.
311+
content = @resource[:private_key_content].respond_to?(:unwrap) ? @resource[:private_key_content].unwrap : @resource[:private_key_content]
312+
file.write(content)
313+
file.close
314+
file
315+
end
316+
@temp_private_key_file.path
310317
end
311318

312319
def private_key_type

0 commit comments

Comments
 (0)