Author: mduerig
Date: Thu Sep  7 11:18:37 2017
New Revision: 1807590

URL: http://svn.apache.org/viewvc?rev=1807590&view=rev
Log:
OAK-6625: Avoid oak-run compact inadvertently upgrading the segment format
Add a strict version check to the file store and control it via a --force flag 
from the compact mode

Modified:
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompactCommand.java
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Compact.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/upgrade/UpgradeIT.java

Modified: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompactCommand.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompactCommand.java?rev=1807590&r1=1807589&r2=1807590&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompactCommand.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompactCommand.java
 Thu Sep  7 11:18:37 2017
@@ -25,13 +25,12 @@ import java.util.Date;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
+import com.google.common.base.Stopwatch;
 import joptsimple.OptionParser;
 import joptsimple.OptionSet;
 import joptsimple.OptionSpec;
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.commons.IOUtils;
-
-import com.google.common.base.Stopwatch;
 import org.apache.jackrabbit.oak.run.commons.Command;
 
 class CompactCommand implements Command {
@@ -47,6 +46,12 @@ class CompactCommand implements Command
                         "and file access is used on 32 bit systems.")
                 .withOptionalArg()
                 .ofType(Boolean.class);
+        OptionSpec<Boolean> forceArg = parser.accepts("force",
+                "Force compaction and ignore a non matching segment store 
version. " +
+                        "CAUTION: this will upgrade the segment store to the 
latest version, " +
+                        "which is incompatible with older versions of Oak.")
+                .withOptionalArg()
+                .ofType(Boolean.class);
 
         OptionSet options = parser.parse(args);
 
@@ -73,6 +78,9 @@ class CompactCommand implements Command
         } else {
             System.out.println("With file access");
         }
+
+        boolean force = isTrue(forceArg.value(options));
+
         System.out.println("    before ");
         beforeLs.addAll(list(directory));
         long sizeBefore = FileUtils.sizeOfDirectory(directory);
@@ -82,7 +90,7 @@ class CompactCommand implements Command
         System.out.println("    -> compacting");
 
         try {
-            SegmentTarUtils.compact(directory, mmap);
+            SegmentTarUtils.compact(directory, mmap, force);
             success = true;
         } catch (Throwable e) {
             System.out.println("Compaction failure stack trace:");
@@ -108,6 +116,10 @@ class CompactCommand implements Command
         }
     }
 
+    private static boolean isTrue(Boolean value) {
+        return value != null && value;
+    }
+
     private static Set<String> list(File directory) {
         Set<String> files = newHashSet();
         for (File f : directory.listFiles()) {

Modified: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java?rev=1807590&r1=1807589&r2=1807590&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java
 Thu Sep  7 11:18:37 2017
@@ -174,10 +174,11 @@ final class SegmentTarUtils {
                 .run();
     }
 
-    static void compact(@Nonnull File directory, @Nullable Boolean mmap) {
+    static void compact(@Nonnull File directory, @Nullable Boolean mmap, 
boolean force) {
         Compact.builder()
                 .withPath(directory)
                 .withMmap(mmap)
+                .withForce(force)
                 .build()
                 .run();
     }

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java?rev=1807590&r1=1807589&r2=1807590&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java
 Thu Sep  7 11:18:37 2017
@@ -89,11 +89,11 @@ public abstract class AbstractFileStore
      */
     private static final int MAX_STORE_VERSION = 2;
 
-    static ManifestChecker newManifestChecker(File directory) {
+    static ManifestChecker newManifestChecker(File directory, boolean 
strictVersionCheck) {
         return ManifestChecker.newManifestChecker(
                 new File(directory, MANIFEST_FILE_NAME),
                 notEmptyDirectory(directory),
-                MIN_STORE_VERSION,
+                strictVersionCheck ? MAX_STORE_VERSION : MIN_STORE_VERSION,
                 MAX_STORE_VERSION
         );
     }

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java?rev=1807590&r1=1807589&r2=1807590&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
 Thu Sep  7 11:18:37 2017
@@ -191,7 +191,7 @@ public class FileStore extends AbstractF
                 builder.getCacheManager(),
                 builder.getStatsProvider());
 
-        newManifestChecker(directory).checkAndUpdateManifest();
+        newManifestChecker(directory, 
builder.getStrictVersionCheck()).checkAndUpdateManifest();
 
         this.stats = new FileStoreStats(builder.getStatsProvider(), this, 0);
         this.tarFiles = TarFiles.builder()

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java?rev=1807590&r1=1807589&r2=1807590&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java
 Thu Sep  7 11:18:37 2017
@@ -121,6 +121,8 @@ public class FileStoreBuilder {
     private SegmentNotFoundExceptionListener snfeListener = LOG_SNFE;
 
     private IOMonitor ioMonitor = new IOMonitorAdapter();
+
+    private boolean strictVersionCheck;
     
     private boolean built;
 
@@ -297,6 +299,20 @@ public class FileStoreBuilder {
         this.ioMonitor = checkNotNull(ioMonitor);
         return this;
     }
+
+    /**
+     * Enable strict version checking. With strict version checking enabled Oak
+     * will fail to start if the store version does not exactly match this Oak 
version.
+     * This is useful to e.g. avoid inadvertent upgrades during when running 
offline
+     * compaction accidentally against an older version of a store.
+     * @param strictVersionCheck  enables strict version checking iff {@code 
true}.
+     * @return this instance
+     */
+    @Nonnull
+    public FileStoreBuilder withStrictVersionCheck(boolean strictVersionCheck) 
{
+        this.strictVersionCheck = strictVersionCheck;
+        return this;
+    }
     
     /**
      * Create a new {@link FileStore} instance with the settings specified in 
this
@@ -448,6 +464,10 @@ public class FileStoreBuilder {
         return ioMonitor;
     }
 
+    boolean getStrictVersionCheck() {
+        return strictVersionCheck;
+    }
+
     @Override
     public String toString() {
         return "FileStoreBuilder{" +

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java?rev=1807590&r1=1807589&r2=1807590&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java
 Thu Sep  7 11:18:37 2017
@@ -63,7 +63,7 @@ public class ReadOnlyFileStore extends A
     ReadOnlyFileStore(FileStoreBuilder builder) throws 
InvalidFileStoreVersionException, IOException {
         super(builder);
 
-        newManifestChecker(directory).checkManifest();
+        newManifestChecker(directory, 
builder.getStrictVersionCheck()).checkManifest();
 
         tarFiles = TarFiles.builder()
                 .withDirectory(directory)

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Compact.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Compact.java?rev=1807590&r1=1807589&r2=1807590&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Compact.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Compact.java
 Thu Sep  7 11:18:37 2017
@@ -58,6 +58,8 @@ public class Compact implements Runnable
         @CheckForNull
         private Boolean mmap;
 
+        private boolean force;
+
         private Builder() {
             // Prevent external instantiation.
         }
@@ -86,6 +88,16 @@ public class Compact implements Runnable
         }
 
         /**
+         * Whether to fail if run on an older version of the store of force 
upgrading its format.
+         * @param force   upgrade iff {@code true}
+         * @return this builder.
+         */
+        public Builder withForce(boolean force) {
+            this.force = force;
+            return this;
+        }
+
+        /**
          * Create an executable version of the {@link Compact} command.
          *
          * @return an instance of {@link Runnable}.
@@ -102,9 +114,12 @@ public class Compact implements Runnable
     @CheckForNull
     private final Boolean mmap;
 
+    private final boolean strictVersionCheck;
+
     private Compact(Builder builder) {
         this.path = builder.path;
         this.mmap = builder.mmap;
+        this.strictVersionCheck = !builder.force;
     }
 
     @Override
@@ -141,6 +156,7 @@ public class Compact implements Runnable
 
     private FileStore newFileStore() throws IOException, 
InvalidFileStoreVersionException {
         FileStoreBuilder fileStoreBuilder = 
fileStoreBuilder(path.getAbsoluteFile())
+                .withStrictVersionCheck(strictVersionCheck)
                 .withGCOptions(defaultGCOptions()
                     .setOffline()
                     .setGCLogInterval(logAt));

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/upgrade/UpgradeIT.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/upgrade/UpgradeIT.java?rev=1807590&r1=1807589&r2=1807590&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/upgrade/UpgradeIT.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/upgrade/UpgradeIT.java
 Thu Sep  7 11:18:37 2017
@@ -100,6 +100,7 @@ public class UpgradeIT {
         Compact.builder()
                 .withPath(fileStoreHome.getRoot())
                 .withMmap(true)
+                .withForce(true)
                 .build()
                 .run();
         checkStoreVersion(2);


Reply via email to