summaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2020-06-25 14:02:11 +0200
committerHarald Musum <musum@verizonmedia.com>2020-06-25 14:02:11 +0200
commitb7123aab2704804928d9050a05febf9555bb6e05 (patch)
treee1a712cf9954b48429f1931ca5ad6b4c6e299497 /configserver
parentc341910e1509d4d607db4baa6fd914d0802e8532 (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.java18
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.
*/