Add option to configure location of marker file

In a setup using the high-availability plugin it can be useful to
put all instances into read-only mode with a single command. To do this
the marker file has to be in the shared directory.

This change allows to configure the directory in which the marker file
will be created and watched. This allows to configure for example the
shared directory in an HA-setup.

Change-Id: I492b2141c697bbe46edf106800d8dfe42275b965
diff --git a/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnlyConfig.java b/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnlyConfig.java
index 28ef6c5..68849e8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnlyConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnlyConfig.java
@@ -19,25 +19,33 @@
 import com.google.common.collect.ImmutableList;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.server.config.PluginConfigFactory;
+import com.google.gerrit.server.config.SitePaths;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
+import java.nio.file.Path;
 import java.util.List;
 import org.eclipse.jgit.lib.Config;
 
 @Singleton
 class ReadOnlyConfig {
   private static final String MESSAGE_KEY = "message";
+  private static final String MARKER_DIR_PATH_KEY = "markerDir";
   private static final String DEFAULT_MESSAGE =
       "Gerrit is under maintenance - all data is READ ONLY";
   private static final String SSH_ALLOW = "allowSshCommand";
 
   private final String message;
+  private final Path markerDir;
   private final List<String> allowSshCommands;
 
   @Inject
-  ReadOnlyConfig(PluginConfigFactory pluginConfigFactory, @PluginName String pluginName) {
+  ReadOnlyConfig(
+      SitePaths sitePaths, PluginConfigFactory pluginConfigFactory, @PluginName String pluginName) {
     Config cfg = pluginConfigFactory.getGlobalPluginConfig(pluginName);
     this.message = firstNonNull(cfg.getString(pluginName, null, MESSAGE_KEY), DEFAULT_MESSAGE);
+    this.markerDir =
+        sitePaths.resolve(
+            firstNonNull(cfg.getString(pluginName, null, MARKER_DIR_PATH_KEY), "etc"));
     this.allowSshCommands = ImmutableList.copyOf(cfg.getStringList(pluginName, null, SSH_ALLOW));
   }
 
@@ -45,6 +53,10 @@
     return message;
   }
 
+  Path markerDir() {
+    return markerDir;
+  }
+
   List<String> allowSshCommands() {
     return allowSshCommands;
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnlyState.java b/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnlyState.java
index b6c4def..9d9d60d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnlyState.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnlyState.java
@@ -14,7 +14,6 @@
 
 package com.googlesource.gerrit.plugins.readonly;
 
-import com.google.gerrit.server.config.SitePaths;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
@@ -26,11 +25,13 @@
 public class ReadOnlyState {
   private static final String GERRIT_READONLY = "gerrit.readonly";
 
+  private final Path markerDir;
   private final Path marker;
 
   @Inject
-  ReadOnlyState(SitePaths sitePaths) {
-    this.marker = sitePaths.etc_dir.resolve(GERRIT_READONLY);
+  ReadOnlyState(ReadOnlyConfig cfg) {
+    this.markerDir = cfg.markerDir();
+    this.marker = markerDir.resolve(GERRIT_READONLY);
   }
 
   public boolean isReadOnly() {
@@ -38,6 +39,7 @@
   }
 
   public void setReadOnly(boolean readOnly) throws IOException {
+    Files.createDirectories(markerDir);
     if (readOnly && !Files.exists(marker)) {
       Files.newOutputStream(marker, StandardOpenOption.CREATE).close();
     } else if (!readOnly && Files.exists(marker)) {
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index f8d7a1f..a5b0a4c 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -20,6 +20,10 @@
     is blocked due to the server being in read-only mode. When not specified,
     the default is "Gerrit is under maintenance - all data is READ ONLY".
 
+```readonly.markerDir```
+:   Directory in which to create the file marking that Gerrit is in readonly mode.
+    By default, this is `$SITE/etc`.
+
 ```readonly.allowSshCommand```
 :   Allow one or more SSH commands to be executed. When the allow value starts
     with a caret '^' then it is interpreted as regex, otherwise as a prefix.