diff options
author | Simon Rettberg | 2020-09-28 12:24:58 +0200 |
---|---|---|
committer | Simon Rettberg | 2020-09-28 12:24:58 +0200 |
commit | fe9c0cc3445485221b12118c2f5e34cccde82105 (patch) | |
tree | 989def6112ca970ab6df06393e0739a1a4c4ad2d | |
parent | [server] Abort orphan scan/delete if known image list is empty (diff) | |
download | tutor-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.java | 53 |
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); } } |