diff options
author | Jon Marius Venstad <jonmv@users.noreply.github.com> | 2024-06-05 10:14:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-05 10:14:58 +0200 |
commit | cdcad090eece54a38fd2869cee8a2cbe639faa79 (patch) | |
tree | 1ebc91088bcc7d7243e7e5625afc08f30d5077d1 | |
parent | 2247ffea60c982d8c370aa5e88f5be256455f139 (diff) | |
parent | 83815a2898c6d2972164bf0c496acb3eace7d4a3 (diff) |
Merge pull request #31432 from vespa-engine/hmusum/preprocess-and-move-atomically-take-3
Preprocess application package in temp dir, then move atomically to d…
-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() { |