diff options
author | Harald Musum <musum@verizonmedia.com> | 2020-06-25 14:02:11 +0200 |
---|---|---|
committer | Harald Musum <musum@verizonmedia.com> | 2020-06-25 14:02:11 +0200 |
commit | b7123aab2704804928d9050a05febf9555bb6e05 (patch) | |
tree | e1a712cf9954b48429f1931ca5ad6b4c6e299497 /configserver | |
parent | c341910e1509d4d607db4baa6fd914d0802e8532 (diff) |
Copy application package atomically
Fix bug where we don't do this atomically, looks like this can happend
when application package is copied at the same time as config server is shut down
Diffstat (limited to 'configserver')
-rw-r--r-- | configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java index 2110e6476b6..8979176b66c 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java @@ -41,6 +41,8 @@ import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.time.Clock; import java.time.Duration; import java.time.Instant; @@ -504,7 +506,7 @@ public class SessionRepository { long sessionId, Optional<Long> currentlyActiveSessionId, boolean internalRedeploy) throws IOException { File userApplicationDir = getSessionAppDir(sessionId); - IOUtils.copyDirectory(applicationFile, userApplicationDir); + copyApp(applicationFile, userApplicationDir); ApplicationPackage applicationPackage = createApplication(applicationFile, userApplicationDir, applicationId, @@ -515,6 +517,20 @@ public class SessionRepository { return applicationPackage; } + private void copyApp(File sourceDir, File destinationDir) throws IOException { + if (destinationDir.exists()) + throw new RuntimeException("Destination dir " + destinationDir + " already exists"); + if (! sourceDir.isDirectory()) + throw new IllegalArgumentException(sourceDir.getAbsolutePath() + " is not a directory"); + + // Copy app it atomically: Copy to default tmp dir and move to destination + java.nio.file.Path tempDestinationDir = Files.createTempDirectory(destinationDir.getParentFile().toPath(), "app-package"); + log.log(Level.FINE, "Copying dir " + sourceDir.getAbsolutePath() + " to " + tempDestinationDir.toFile().getAbsolutePath()); + IOUtils.copyDirectory(sourceDir, tempDestinationDir.toFile()); + log.log(Level.FINE, "Moving " + tempDestinationDir + " to " + destinationDir.getAbsolutePath()); + Files.move(tempDestinationDir, destinationDir.toPath(), StandardCopyOption.ATOMIC_MOVE); + } + /** * Returns a new session instance for the given session id. */ |