summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2020-09-28 12:24:58 +0200
committerSimon Rettberg2020-09-28 12:24:58 +0200
commitfe9c0cc3445485221b12118c2f5e34cccde82105 (patch)
tree989def6112ca970ab6df06393e0739a1a4c4ad2d
parent[server] Abort orphan scan/delete if known image list is empty (diff)
downloadtutor-module-fe9c0cc3445485221b12118c2f5e34cccde82105.tar.gz
tutor-module-fe9c0cc3445485221b12118c2f5e34cccde82105.tar.xz
tutor-module-fe9c0cc3445485221b12118c2f5e34cccde82105.zip
[server] Up the safety game even more: Don't delete if disjoint
If non of the files in the known image list matches the list of files we find on the vmstore, don't delete anything. It's possible we mounted the wrong vmstore (test server vs. production system) and would totally ruin the day for someone.
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java53
1 files changed, 35 insertions, 18 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java
index 1d5b27e7..3a6f39ad 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebRpc.java
@@ -7,13 +7,16 @@ import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.security.auth.login.LoginException;
@@ -88,14 +91,33 @@ public class WebRpc {
if (known.isEmpty()) {
return WebServer.internalServerError("SAFTY CHECK: Known image list empty, aborting");
}
+ AtomicInteger matches = new AtomicInteger();
try {
// Consider only regular files, call checkFile for each one
Files.find(Configuration.getVmStoreProdPath().toPath(), 8,
(filePath, fileAttr) -> fileAttr.isRegularFile())
- .forEach((fileName) -> checkFile(fileName, orphanedFiles, baseLen, known, del));
+ .forEach((fileName) -> checkFile(fileName, orphanedFiles, baseLen, known, matches));
} catch (IOException e) {
return WebServer.internalServerError(e.toString());
}
+ if (del) {
+ for (Entry<String, DeleteResult> it : orphanedFiles.entrySet()) {
+ if (matches.get() == 0) {
+ // Don't delete anything if the set of known files and the set of files we actually
+ // found are disjoint
+ it.setValue(DeleteResult.SAFETY_ABORT);
+ continue;
+ }
+ Path filePath = Paths.get(baseDir + "/" + it.getKey());
+ try {
+ Files.delete(filePath);
+ it.setValue(DeleteResult.DELETED);
+ } catch (Exception e) {
+ LOGGER.warn("Cannot delete " + filePath, e);
+ it.setValue(DeleteResult.ERROR);
+ }
+ }
+ }
return new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK, "application/json; charset=utf-8",
Json.serialize(orphanedFiles));
}
@@ -103,20 +125,23 @@ public class WebRpc {
private static enum DeleteResult {
EXISTS,
DELETED,
- ERROR;
+ ERROR,
+ SAFETY_ABORT;
}
/**
- * Function called for each file found on the VMstore to determine if it's orphaned.
+ * Function called for each file found on the VMstore to determine if it's
+ * orphaned.
*
* @param filePath File to check
* @param result Map to add the check result to
- * @param baseLen length of the base path we need to strip from the absolute path
+ * @param baseLen length of the base path we need to strip from the absolute
+ * path
* @param known list of known images from the db
- * @param doDelete whether to delete all files we found to be orphaned
+ * @param matches counter for files that match a DB entry
*/
private static void checkFile(Path filePath, Map<String, DeleteResult> result, int baseLen,
- Set<String> known, boolean doDelete) {
+ Set<String> known, AtomicInteger matches) {
if (filePath.endsWith("dozmod.lock"))
return;
final String relativeFileName;
@@ -135,18 +160,10 @@ public class WebRpc {
} else {
compareFileName = relativeFileName;
}
- if (!known.contains(compareFileName)) {
- DeleteResult code = DeleteResult.EXISTS;
- if (doDelete) {
- try {
- Files.delete(filePath);
- code = DeleteResult.DELETED;
- } catch (Exception e) {
- LOGGER.warn("Cannot delete " + filePath, e);
- code = DeleteResult.ERROR;
- }
- }
- result.put(relativeFileName, code);
+ if (known.contains(compareFileName)) {
+ matches.incrementAndGet();
+ } else {
+ result.put(relativeFileName, DeleteResult.EXISTS);
}
}