diff options
author | Harald Musum <musum@yahooinc.com> | 2024-06-04 21:18:32 +0200 |
---|---|---|
committer | Harald Musum <musum@yahooinc.com> | 2024-06-04 21:18:32 +0200 |
commit | 83815a2898c6d2972164bf0c496acb3eace7d4a3 (patch) | |
tree | bb445e61ff33c10e1a090b27a7238f5645458911 | |
parent | 3787728612ae929802cb371050ab49be6120c150 (diff) |
Preprocess application package in temp dir, then move atomically to destination
-rw-r--r-- | config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java index 28bf8e10a93..664c5dcd076 100644 --- a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java +++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java @@ -613,24 +613,38 @@ public class FilesApplicationPackage extends AbstractApplicationPackage { @Override public ApplicationPackage preprocess(Zone zone, DeployLogger logger) throws IOException { - IOUtils.recursiveDeleteDir(preprocessedDir); - IOUtils.copyDirectory(appDir, preprocessedDir, -1, + // Note: temp dir needs to be a directory on the same file system as appDir for 'move' to work, + // so using parent dir to create a temp fir if possible. Standalone container does not have a writable + // parent dir, so need to copy directly to preprocessedDir in that case. + java.nio.file.Path parentPath = appDir.getParentFile().toPath(); + if (Files.isWritable(parentPath)) { + var tempDir = Files.createTempDirectory(parentPath, "preprocess-tempdir"); + preprocess(appDir, tempDir.toFile(), zone); + IOUtils.recursiveDeleteDir(preprocessedDir); + // Move to make sure we do this atomically, important to avoid writing only partial content e.g. when shutting down + Files.move(tempDir, preprocessedDir.toPath()); + } else { + preprocess(appDir, preprocessedDir, zone); + } + FilesApplicationPackage preprocessedApp = fromFile(preprocessedDir, includeSourceFiles); + preprocessedApp.copyUserDefsIntoApplication(); + return preprocessedApp; + } + + private void preprocess(File appDir, File dir, Zone zone) throws IOException { + validateServicesFile(); + IOUtils.copyDirectory(appDir, dir, - 1, (__, name) -> ! List.of(preprocessed, SERVICES, HOSTS, CONFIG_DEFINITIONS_DIR).contains(name)); - File servicesFile = validateServicesFile(); - preprocessXML(applicationFile(preprocessedDir, SERVICES), servicesFile, zone); - preprocessXML(applicationFile(preprocessedDir, HOSTS), getHostsFile(), zone); - FilesApplicationPackage preprocessed = fromFile(preprocessedDir, includeSourceFiles); - preprocessed.copyUserDefsIntoApplication(); - return preprocessed; + preprocessXML(applicationFile(dir, SERVICES), getServicesFile(), zone); + preprocessXML(applicationFile(dir, HOSTS), getHostsFile(), zone); } - private File validateServicesFile() throws IOException { + private void validateServicesFile() throws IOException { File servicesFile = getServicesFile(); if ( ! servicesFile.exists()) throw new IllegalArgumentException(SERVICES + " does not exist in application package"); if (IOUtils.readFile(servicesFile).isEmpty()) throw new IllegalArgumentException(SERVICES + " in application package is empty"); - return servicesFile; } private void copyUserDefsIntoApplication() { |