Skip to content

Commit 68be24a

Browse files
committed
[GR-44870] Ensure bundle temp directory gets deleted in case of SIGTERM.
PullRequest: graal/14100
2 parents 12ddc84 + 27bffb1 commit 68be24a

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/BundleSupport.java

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.util.ArrayList;
4242
import java.util.Arrays;
4343
import java.util.Collections;
44+
import java.util.Enumeration;
4445
import java.util.HashMap;
4546
import java.util.HashSet;
4647
import java.util.List;
@@ -50,6 +51,7 @@
5051
import java.util.Optional;
5152
import java.util.Properties;
5253
import java.util.Set;
54+
import java.util.concurrent.atomic.AtomicBoolean;
5355
import java.util.function.Predicate;
5456
import java.util.jar.Attributes;
5557
import java.util.jar.JarEntry;
@@ -194,7 +196,7 @@ private BundleSupport(NativeImage nativeImage) {
194196
loadBundle = false;
195197
writeBundle = true;
196198
try {
197-
rootDir = Files.createTempDirectory(BUNDLE_TEMP_DIR_PREFIX);
199+
rootDir = createBundleRootDir();
198200
bundleProperties = new BundleProperties();
199201

200202
Path inputDir = rootDir.resolve("input");
@@ -223,15 +225,17 @@ private BundleSupport(NativeImage nativeImage, String bundleFilenameArg) {
223225
updateBundleLocation(Path.of(bundleFilenameArg), false);
224226

225227
try {
226-
rootDir = Files.createTempDirectory(BUNDLE_TEMP_DIR_PREFIX);
228+
rootDir = createBundleRootDir();
227229
bundleProperties = new BundleProperties();
228230

229231
outputDir = rootDir.resolve("output");
230232
String originalOutputDirName = outputDir.getFileName().toString() + ORIGINAL_DIR_EXTENSION;
231233

232234
Path bundleFilePath = bundlePath.resolve(bundleName + BUNDLE_FILE_EXTENSION);
233235
try (JarFile archive = new JarFile(bundleFilePath.toFile())) {
234-
archive.stream().forEach(jarEntry -> {
236+
Enumeration<JarEntry> jarEntries = archive.entries();
237+
while (jarEntries.hasMoreElements() && !deleteBundleRoot.get()) {
238+
JarEntry jarEntry = jarEntries.nextElement();
235239
Path bundleEntry = rootDir.resolve(jarEntry.getName());
236240
if (bundleEntry.startsWith(outputDir)) {
237241
/* Extract original output to different path */
@@ -246,12 +250,17 @@ private BundleSupport(NativeImage nativeImage, String bundleFilenameArg) {
246250
} catch (IOException e) {
247251
throw NativeImage.showError("Unable to copy " + jarEntry.getName() + " from bundle " + bundleEntry + " to " + bundleEntry, e);
248252
}
249-
});
253+
}
250254
}
251255
} catch (IOException e) {
252256
throw NativeImage.showError("Unable to expand bundle directory layout from bundle file " + bundleName + BUNDLE_FILE_EXTENSION, e);
253257
}
254258

259+
if (deleteBundleRoot.get()) {
260+
/* Abort image build request without error message and exit with 0 */
261+
throw NativeImage.showError(null, null, 0);
262+
}
263+
255264
bundleProperties.loadAndVerify();
256265

257266
try {
@@ -280,10 +289,12 @@ private BundleSupport(NativeImage nativeImage, String bundleFilenameArg) {
280289
throw NativeImage.showError("Failed to read bundle-file " + pathSubstitutionsFile, e);
281290
}
282291
Path environmentFile = stageDir.resolve("environment.json");
283-
try (Reader reader = Files.newBufferedReader(environmentFile)) {
284-
new EnvironmentParser(nativeImage.imageBuilderEnvironment).parseAndRegister(reader);
285-
} catch (IOException e) {
286-
throw NativeImage.showError("Failed to read bundle-file " + environmentFile, e);
292+
if (Files.isReadable(environmentFile)) {
293+
try (Reader reader = Files.newBufferedReader(environmentFile)) {
294+
new EnvironmentParser(nativeImage.imageBuilderEnvironment).parseAndRegister(reader);
295+
} catch (IOException e) {
296+
throw NativeImage.showError("Failed to read bundle-file " + environmentFile, e);
297+
}
287298
}
288299

289300
Path buildArgsFile = stageDir.resolve("build.json");
@@ -296,6 +307,17 @@ private BundleSupport(NativeImage nativeImage, String bundleFilenameArg) {
296307
}
297308
}
298309

310+
private final AtomicBoolean deleteBundleRoot = new AtomicBoolean();
311+
312+
private Path createBundleRootDir() throws IOException {
313+
Path bundleRoot = Files.createTempDirectory(BUNDLE_TEMP_DIR_PREFIX);
314+
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
315+
deleteBundleRoot.set(true);
316+
nativeImage.deleteAllFiles(bundleRoot);
317+
}));
318+
return bundleRoot;
319+
}
320+
299321
public List<String> getNativeImageArgs() {
300322
return nativeImageArgs;
301323
}
@@ -486,9 +508,9 @@ private void copyFile(Path sourceFile, Path target, boolean overwrite) {
486508
void complete() {
487509
boolean writeOutput;
488510
try (Stream<Path> pathOutputFiles = Files.list(imagePathOutputDir); Stream<Path> auxiliaryOutputFiles = Files.list(auxiliaryOutputDir)) {
489-
writeOutput = pathOutputFiles.findAny().isPresent() || auxiliaryOutputFiles.findAny().isPresent();
511+
writeOutput = (pathOutputFiles.findAny().isPresent() || auxiliaryOutputFiles.findAny().isPresent()) && !deleteBundleRoot.get();
490512
} catch (IOException e) {
491-
throw NativeImage.showError("Unable to determine if bundle output should be written.");
513+
writeOutput = false;
492514
}
493515

494516
/*
@@ -517,7 +539,6 @@ void complete() {
517539
}
518540
} finally {
519541
nativeImage.showNewline();
520-
nativeImage.deleteAllFiles(rootDir);
521542
}
522543
}
523544

substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,12 @@ private static void sanitizeJVMEnvironment(Map<String, String> environment, Map<
15601560
} else {
15611561
environment.forEach((key, val) -> {
15621562
if (keyMapper.apply(key).equals(keyMapper.apply(entry.getKey()))) {
1563+
/*
1564+
* Record key as it was given by -E<key-name> (by using `entry.getKey()`
1565+
* instead of `key`) to allow creating bundles on Windows that will also
1566+
* work on Linux. `System.getEnv(val)` is case-insensitive on Windows but
1567+
* not on Linux.
1568+
*/
15631569
restrictedEnvironment.put(entry.getKey(), val);
15641570
/* Capture found value for storing vars in bundle */
15651571
entry.setValue(val);

0 commit comments

Comments
 (0)