Merge "Allow to get single and combined versions from get_version script"
diff --git a/container-images/gerrit-base/Dockerfile b/container-images/gerrit-base/Dockerfile
index 9f42961..77512d7 100644
--- a/container-images/gerrit-base/Dockerfile
+++ b/container-images/gerrit-base/Dockerfile
@@ -29,7 +29,7 @@
 RUN curl -f -k -o /var/plugins/global-refdb.jar ${GLOBAL_REFDB_URL}
 
 # Download high-availability plugin
-ARG HA_JAR_URL=https://gerrit-ci.gerritforge.com/view/Plugins-master/job/plugin-high-availability-bazel-master/lastSuccessfulBuild/artifact/bazel-bin/plugins/high-availability/high-availability.jar
+ARG HA_JAR_URL=https://gerrit-ci.gerritforge.com/view/Plugins-stable-3.9/job/plugin-high-availability-bazel-stable-3.9/lastSuccessfulBuild/artifact/bazel-bin/plugins/high-availability/high-availability.jar
 RUN curl -f -k -o /var/plugins/high-availability.jar ${HA_JAR_URL}
 
 # Download zookeeper-refdb plugin
diff --git a/container-images/gerrit-init/Dockerfile b/container-images/gerrit-init/Dockerfile
index 70da7aa..53ef808 100644
--- a/container-images/gerrit-init/Dockerfile
+++ b/container-images/gerrit-init/Dockerfile
@@ -20,7 +20,6 @@
 COPY config/* /var/config/
 
 RUN mkdir -p /var/mnt/git \
-  && mkdir -p /var/mnt/logs \
   && chown -R gerrit:users /var/mnt
 
 USER gerrit
diff --git a/container-images/gerrit-init/tools/gerrit-initializer/initializer/tasks/init.py b/container-images/gerrit-init/tools/gerrit-initializer/initializer/tasks/init.py
index 4931984..f5cb3f2 100755
--- a/container-images/gerrit-init/tools/gerrit-initializer/initializer/tasks/init.py
+++ b/container-images/gerrit-init/tools/gerrit-initializer/initializer/tasks/init.py
@@ -103,12 +103,16 @@
         LOG.info("No initialization required.")
         return False
 
-    def _ensure_symlink(self, src, target):
-        if not os.path.exists(src):
-            raise FileNotFoundError(f"Unable to find mounted dir: {src}")
+    def _symlink(self, src, target, required=True):
+        if os.path.islink(target) and not os.path.exists(os.readlink(target)):
+            LOG.warn(f"Removing broken symlink {target}")
+            os.unlink(target)
 
-        if os.path.islink(target) and os.path.realpath(target) == src:
-            return
+        if not os.path.exists(src):
+            if required:
+                raise FileNotFoundError(f"Unable to find mounted dir: {src}")
+            else:
+                return
 
         if os.path.exists(target):
             if os.path.isdir(target) and not os.path.islink(target):
@@ -119,16 +123,15 @@
         os.symlink(src, target)
 
     def _symlink_mounted_site_components(self):
-        self._ensure_symlink(f"{MNT_PATH}/git", f"{self.site}/git")
-        self._ensure_symlink(f"{MNT_PATH}/logs", f"{self.site}/logs")
+        self._symlink(f"{MNT_PATH}/git", f"{self.site}/git")
 
         mounted_shared_dir = f"{MNT_PATH}/shared"
         if not self.is_replica and os.path.exists(mounted_shared_dir):
-            self._ensure_symlink(mounted_shared_dir, f"{self.site}/shared")
+            self._symlink(mounted_shared_dir, f"{self.site}/shared")
 
         index_type = self.gerrit_config.get("index.type", default=IndexType.LUCENE.name)
         if IndexType[index_type.upper()] is IndexType.ELASTICSEARCH:
-            self._ensure_symlink(f"{MNT_PATH}/index", f"{self.site}/index")
+            self._symlink(f"{MNT_PATH}/index", f"{self.site}/index")
 
         data_dir = f"{self.site}/data"
         if os.path.exists(data_dir):
@@ -147,7 +150,7 @@
                 abs_path = os.path.join(data_dir, file_or_dir)
                 abs_mounted_path = os.path.join(mounted_data_dir, file_or_dir)
                 if os.path.isdir(abs_mounted_path):
-                    self._ensure_symlink(abs_mounted_path, abs_path)
+                    self._symlink(abs_mounted_path, abs_path)
 
     def _symlink_configuration(self):
         etc_dir = f"{self.site}/etc"
@@ -160,7 +163,7 @@
                     if os.path.isfile(
                         os.path.join(f"{MNT_PATH}/etc/{config_type}", file_or_dir)
                     ):
-                        self._ensure_symlink(
+                        self._symlink(
                             os.path.join(f"{MNT_PATH}/etc/{config_type}", file_or_dir),
                             os.path.join(etc_dir, file_or_dir),
                         )
@@ -176,6 +179,11 @@
                 os.remove(full_path)
 
     def execute(self):
+        # Required for migration away from NFS-based log storage, when using the
+        # Gerrit-Operator and to provide backwards compatibility for the helm-
+        # charts
+        self._symlink(f"{MNT_PATH}/logs", f"{self.site}/logs", required=False)
+
         if not self.is_replica:
             self._symlink_mounted_site_components()
         elif not NoteDbValidator(MNT_PATH).check():
diff --git a/container-images/git-gc/tools/gc.sh b/container-images/git-gc/tools/gc.sh
index 911d3cf..d1b4f15 100755
--- a/container-images/git-gc/tools/gc.sh
+++ b/container-images/git-gc/tools/gc.sh
@@ -119,6 +119,26 @@
   done
 }
 
+delete_stale_gc_lock()
+{
+  local PROJECT_DIR="$1"
+  OUT=$(find "$PROJECT_DIR" -name 'gc.pid' -type f -maxdepth 1 -mmin +720 -delete) && \
+        log "pruning stale 'gc.pid' lock file older than 12 hours:\n$OUT"
+}
+
+delete_empty_ref_dirs()
+{
+  PROJECT_DIR="$1"
+  find "$PROJECT_DIR/refs" -type d -empty -mindepth 2 -mmin +60 -delete
+}
+
+delete_stale_incoming_packs()
+{
+  local PROJECT_DIR="$1"
+  OUT=$(find "$PROJECT_DIR/objects" -maxdepth 1 \( -name 'incoming_*.pack' -o -name 'incoming_*.idx' \) -type f -mtime +1 -delete) && \
+        log "pruning stale 'incoming_*.pack' and 'incoming_*.idx' files older than 24 hours:\n$OUT"
+}
+
 gc_project()
 {
   PROJECT_NAME="$@"
@@ -168,14 +188,15 @@
   git --git-dir="$PROJECT_DIR" config pack.window 250
   git --git-dir="$PROJECT_DIR" config pack.depth 50
 
+  delete_stale_gc_lock "$PROJECT_DIR"
+
   OUT=$(git $GC_CONFIG --git-dir="$PROJECT_DIR" "$GC_COMMAND" --auto --prune $OPTS \
         || date +"%D %r Failed: $PROJECT_NAME") \
     && log "$OUT"
 
   delete_empty_ref_dirs "$PROJECT_DIR"
 
-  OUT=$(find "$PROJECT_DIR/objects" -name 'incoming_*.pack' -type f -mtime +14 -delete) && \
-        log "pruning stale 'incoming_*.pack' files older than 14 days:\n$OUT"
+  delete_stale_incoming_packs "$PROJECT_DIR"
 
   if [ $DONOT_PACK_REFS_OPT -eq 0 ] ; then
     local looseRefCount
@@ -189,12 +210,6 @@
   OUT=$(date +"%D %r Finished: $PROJECT_NAME$LOG_OPTS") && log "$OUT"
 }
 
-delete_empty_ref_dirs()
-{
-  PROJECT_DIR="$1"
-  find "$PROJECT_DIR/refs" -type d -empty -mindepth 2 -mmin +60 -delete
-}
-
 ###########################
 # Main script starts here #
 ###########################
diff --git a/operator/pom.xml b/operator/pom.xml
index aca497c..e5ca845 100644
--- a/operator/pom.xml
+++ b/operator/pom.xml
@@ -20,6 +20,7 @@
 		<guice.version>5.1.0</guice.version>
 		<javaoperatorsdk.version>4.3.3</javaoperatorsdk.version>
 		<jetty.version>11.0.15</jetty.version>
+		<log42.version>2.23.0</log42.version>
 		<lombok.version>1.18.28</lombok.version>
 		<maven.compiler.source>17</maven.compiler.source>
 		<maven.compiler.target>17</maven.compiler.target>
@@ -140,6 +141,20 @@
 		</profile>
 	</profiles>
 
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.apache.logging.log4j</groupId>
+				<artifactId>log4j-api</artifactId>
+				<version>${log42.version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.apache.logging.log4j</groupId>
+				<artifactId>log4j-core</artifactId>
+				<version>${log42.version}</version>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
 	<dependencies>
 		<dependency>
 			<groupId>io.javaoperatorsdk</groupId>
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/api/model/cluster/GerritCluster.java b/operator/src/main/java/com/google/gerrit/k8s/operator/api/model/cluster/GerritCluster.java
index ec4adba..36c0fd9 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/api/model/cluster/GerritCluster.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/api/model/cluster/GerritCluster.java
@@ -142,20 +142,6 @@
   }
 
   @JsonIgnore
-  public static VolumeMount getLogsVolumeMount() {
-    return getLogsVolumeMount("/var/mnt/logs");
-  }
-
-  @JsonIgnore
-  public static VolumeMount getLogsVolumeMount(String mountPath) {
-    return new VolumeMountBuilder()
-        .withName(SHARED_VOLUME_NAME)
-        .withSubPathExpr("logs/$(POD_NAME)")
-        .withMountPath(mountPath)
-        .build();
-  }
-
-  @JsonIgnore
   public static Volume getNfsImapdConfigVolume() {
     return new VolumeBuilder()
         .withName(NFS_IDMAPD_CONFIG_VOLUME_NAME)
@@ -193,7 +179,6 @@
       ContainerImageConfig imageConfig,
       List<VolumeMount> additionalVolumeMounts) {
     List<VolumeMount> volumeMounts = new ArrayList<>();
-    volumeMounts.add(getLogsVolumeMount());
     volumeMounts.add(getGitRepositoriesVolumeMount());
 
     volumeMounts.addAll(additionalVolumeMounts);
@@ -219,7 +204,6 @@
         .withImage(imageConfig.getBusyBox().getBusyBoxImage())
         .withCommand(List.of("sh", "-c"))
         .withArgs(args.toString().trim())
-        .withEnv(getPodNameEnvVar())
         .withVolumeMounts(volumeMounts)
         .build();
   }
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/FluentBitConfigMap.java b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/FluentBitConfigMap.java
deleted file mode 100644
index 4e4757f..0000000
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/FluentBitConfigMap.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (C) 2024 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.k8s.operator.cluster.dependent;
-
-import com.google.gerrit.k8s.operator.api.model.cluster.GerritCluster;
-import com.google.gerrit.k8s.operator.api.model.gerrit.Gerrit;
-import io.fabric8.kubernetes.api.model.ConfigMap;
-import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
-import io.javaoperatorsdk.operator.api.reconciler.Context;
-import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
-import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
-import java.util.Map;
-
-@KubernetesDependent(resourceDiscriminator = FluentBitConfigMapDiscriminator.class)
-public class FluentBitConfigMap extends CRUDKubernetesDependentResource<ConfigMap, Gerrit> {
-
-  public FluentBitConfigMap() {
-    super(ConfigMap.class);
-  }
-
-  public static String getName(Gerrit gerrit) {
-    return String.format("%s-fluentbit-configmap", gerrit.getMetadata().getName());
-  }
-
-  @Override
-  protected ConfigMap desired(Gerrit gerrit, Context<Gerrit> context) {
-    String customConfig = gerrit.getSpec().getFluentBitSidecar().getConfig();
-    String config =
-        """
-        [SERVICE]
-          Parsers_file    parsers-multiline.conf
-        [INPUT]
-          Name            tail
-          Path            /var/mnt/logs/*log
-          Tag             <log_name>
-          Tag_Regex       ^\\/var\\/mnt\\/logs\\/(?<log_name>[^*]+)
-          Multiline.parser   gerrit-multiline
-          Buffer_Chunk_Size  10M
-          Buffer_Max_Size    10M\n
-        """
-            + customConfig;
-    String multilineParser =
-        """
-        [MULTILINE_PARSER]
-          Name          gerrit-multiline
-          Type          regex
-          Flush_timeout 1000
-          Rule  "start_state"  "/\\[\\d{4}-\\d{2}-\\d{2}(.*?)\\](.*)/"  "cont"
-          Rule  "cont"         "^(?!\\[)(.*)"       "cont"
-        """;
-
-    return new ConfigMapBuilder()
-        .withApiVersion("v1")
-        .withNewMetadata()
-        .withName(getName(gerrit))
-        .withNamespace(gerrit.getMetadata().getNamespace())
-        .withLabels(
-            GerritCluster.getLabels(
-                gerrit.getMetadata().getName(), getName(gerrit), this.getClass().getSimpleName()))
-        .endMetadata()
-        .withData(
-            Map.ofEntries(
-                Map.entry("fluent-bit.conf", config),
-                Map.entry("parsers-multiline.conf", multilineParser)))
-        .build();
-  }
-}
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/GerritReconciler.java b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/GerritReconciler.java
index 1ba060e..b5ad4b6 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/GerritReconciler.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/GerritReconciler.java
@@ -19,7 +19,7 @@
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.k8s.operator.api.model.gerrit.Gerrit;
 import com.google.gerrit.k8s.operator.api.model.gerrit.GerritStatus;
-import com.google.gerrit.k8s.operator.cluster.dependent.FluentBitConfigMap;
+import com.google.gerrit.k8s.operator.gerrit.dependent.FluentBitConfigMap;
 import com.google.gerrit.k8s.operator.gerrit.dependent.GerritConfigMap;
 import com.google.gerrit.k8s.operator.gerrit.dependent.GerritInitConfigMap;
 import com.google.gerrit.k8s.operator.gerrit.dependent.GerritService;
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/FluentBitConfigMap.java b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/FluentBitConfigMap.java
new file mode 100644
index 0000000..44c6322
--- /dev/null
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/FluentBitConfigMap.java
@@ -0,0 +1,119 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.k8s.operator.gerrit.dependent;
+
+import com.google.gerrit.k8s.operator.api.model.cluster.GerritCluster;
+import com.google.gerrit.k8s.operator.api.model.gerrit.Gerrit;
+import io.fabric8.kubernetes.api.model.ConfigMap;
+import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
+import io.javaoperatorsdk.operator.api.reconciler.Context;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
+import java.util.Map;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Config;
+
+@KubernetesDependent(resourceDiscriminator = FluentBitConfigMapDiscriminator.class)
+public class FluentBitConfigMap extends CRUDKubernetesDependentResource<ConfigMap, Gerrit> {
+  private static final String FLUENT_BIT_SERVICE_CONFIG =
+      """
+      [SERVICE]
+        Parsers_file parsers.conf
+      """;
+  private static final String FLUENT_BIT_TEXT_LOG_INPUT =
+      """
+      [INPUT]
+        Name tail
+        Path /var/mnt/logs/*_log
+        Tag <log_name>
+        Tag_Regex ^\\/var\\/mnt\\/logs\\/(?<log_name>[^*]+)
+        Multiline.parser gerrit-multiline
+        Buffer_Chunk_Size 10M
+        Buffer_Max_Size 10M\n
+      """;
+  private static final String FLUENT_BIT_JSON_LOG_INPUT =
+      """
+      [INPUT]
+        Name tail
+        Path /var/mnt/logs/*_log.json
+        Tag <log_name>
+        Tag_Regex ^\\/var\\/mnt\\/logs\\/(?<log_name>.+)
+        Parser jsonLog
+        Buffer_Chunk_Size 10M
+        Buffer_Max_Size 10M\n
+      """;
+  private static final String MULTILINE_PARSER_CONFIG =
+      """
+      [MULTILINE_PARSER]
+        Name gerrit-multiline
+        Type regex
+        Flush_timeout 1000
+        Rule "start_state" "/\\[\\d{4}-\\d{2}-\\d{2}(.*?)\\](.*)/" "cont"
+        Rule "cont" "^(?!\\[)(.*)" "cont"
+      """;
+  private static final String JSON_PARSER_CONFIG =
+      """
+      [PARSER]
+        Name jsonLog
+        Format json
+      """;
+
+  public FluentBitConfigMap() {
+    super(ConfigMap.class);
+  }
+
+  public static String getName(Gerrit gerrit) {
+    return String.format("%s-fluentbit-configmap", gerrit.getMetadata().getName());
+  }
+
+  @Override
+  protected ConfigMap desired(Gerrit gerrit, Context<Gerrit> context) {
+    String customConfig = gerrit.getSpec().getFluentBitSidecar().getConfig();
+
+    Config gerritConfig = new Config();
+    try {
+      gerritConfig.fromText(gerrit.getSpec().getConfigFiles().get("gerrit.config"));
+    } catch (ConfigInvalidException e) {
+      throw new IllegalStateException("Failed to parse gerrit.config.", e);
+    }
+
+    String config = FLUENT_BIT_SERVICE_CONFIG;
+    String parserConfig = "";
+    if (gerritConfig.getBoolean("log", "textLogging", true)) {
+      config = config + FLUENT_BIT_TEXT_LOG_INPUT;
+      parserConfig = parserConfig + MULTILINE_PARSER_CONFIG;
+    }
+
+    if (gerritConfig.getBoolean("log", "jsonLogging", false)) {
+      config = config + FLUENT_BIT_JSON_LOG_INPUT;
+      parserConfig = parserConfig + JSON_PARSER_CONFIG;
+    }
+    config = config + customConfig;
+
+    return new ConfigMapBuilder()
+        .withApiVersion("v1")
+        .withNewMetadata()
+        .withName(getName(gerrit))
+        .withNamespace(gerrit.getMetadata().getNamespace())
+        .withLabels(
+            GerritCluster.getLabels(
+                gerrit.getMetadata().getName(), getName(gerrit), this.getClass().getSimpleName()))
+        .endMetadata()
+        .withData(
+            Map.ofEntries(
+                Map.entry("fluent-bit.conf", config), Map.entry("parsers.conf", parserConfig)))
+        .build();
+  }
+}
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/FluentBitConfigMapDiscriminator.java b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/FluentBitConfigMapDiscriminator.java
similarity index 96%
rename from operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/FluentBitConfigMapDiscriminator.java
rename to operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/FluentBitConfigMapDiscriminator.java
index 0c2684b..88e8255 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/dependent/FluentBitConfigMapDiscriminator.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/FluentBitConfigMapDiscriminator.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.k8s.operator.cluster.dependent;
+package com.google.gerrit.k8s.operator.gerrit.dependent;
 
 import com.google.gerrit.k8s.operator.api.model.gerrit.Gerrit;
 import io.fabric8.kubernetes.api.model.ConfigMap;
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/GerritStatefulSet.java b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/GerritStatefulSet.java
index 6cc91b1..3796753 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/GerritStatefulSet.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/gerrit/dependent/GerritStatefulSet.java
@@ -21,7 +21,6 @@
 import com.google.gerrit.k8s.operator.api.model.gerrit.GerritModuleData;
 import com.google.gerrit.k8s.operator.api.model.shared.ContainerImageConfig;
 import com.google.gerrit.k8s.operator.api.model.shared.NfsWorkaroundConfig;
-import com.google.gerrit.k8s.operator.cluster.dependent.FluentBitConfigMap;
 import com.google.gerrit.k8s.operator.gerrit.GerritReconciler;
 import com.google.gerrit.k8s.operator.util.CRUDReconcileAddKubernetesDependentResource;
 import io.fabric8.kubernetes.api.model.Container;
@@ -296,7 +295,6 @@
       volumeMounts.add(GerritCluster.getHAShareVolumeMount());
     }
     volumeMounts.add(GerritCluster.getGitRepositoriesVolumeMount());
-    volumeMounts.add(GerritCluster.getLogsVolumeMount());
     volumeMounts.add(
         new VolumeMountBuilder()
             .withName("gerrit-config")
@@ -351,7 +349,12 @@
             .withMountPath("/fluent-bit/etc/")
             .build());
 
-    volumeMounts.add(GerritCluster.getLogsVolumeMount());
+    volumeMounts.add(
+        new VolumeMountBuilder()
+            .withName(SITE_VOLUME_NAME)
+            .withSubPath("logs")
+            .withMountPath("/var/mnt/logs")
+            .build());
 
     return volumeMounts;
   }
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/dependent/GitGarbageCollectionCronJob.java b/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/dependent/GitGarbageCollectionCronJob.java
index fc1bddb..24364d7 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/dependent/GitGarbageCollectionCronJob.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/dependent/GitGarbageCollectionCronJob.java
@@ -122,7 +122,6 @@
   private Container buildGitGcContainer(GitGarbageCollection gitGc, GerritCluster gerritCluster) {
     List<VolumeMount> volumeMounts = new ArrayList<>();
     volumeMounts.add(GerritCluster.getGitRepositoriesVolumeMount("/var/gerrit/git"));
-    volumeMounts.add(GerritCluster.getLogsVolumeMount("/var/log/git"));
 
     if (gerritCluster.getSpec().getStorage().getStorageClasses().getNfsWorkaround().isEnabled()
         && gerritCluster
@@ -146,7 +145,6 @@
                     .getGerritImages()
                     .getFullImageName("git-gc"))
             .withResources(gitGc.getSpec().getResources())
-            .withEnv(GerritCluster.getPodNameEnvVar())
             .withVolumeMounts(volumeMounts);
 
     ArrayList<String> args = new ArrayList<>();
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/receiver/dependent/ReceiverDeployment.java b/operator/src/main/java/com/google/gerrit/k8s/operator/receiver/dependent/ReceiverDeployment.java
index 9f5fc0c..f1102ae 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/receiver/dependent/ReceiverDeployment.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/receiver/dependent/ReceiverDeployment.java
@@ -106,7 +106,6 @@
                 .getContainerImages()
                 .getGerritImages()
                 .getFullImageName("apache-git-http-backend"))
-        .withEnv(GerritCluster.getPodNameEnvVar())
         .withPorts(getContainerPorts(receiver))
         .withResources(receiver.getSpec().getResources())
         .withReadinessProbe(receiver.getSpec().getReadinessProbe())
@@ -163,7 +162,6 @@
   private Set<VolumeMount> getVolumeMounts(Receiver receiver, boolean isInitContainer) {
     Set<VolumeMount> volumeMounts = new HashSet<>();
     volumeMounts.add(GerritCluster.getGitRepositoriesVolumeMount("/var/gerrit/git"));
-    volumeMounts.add(GerritCluster.getLogsVolumeMount("/var/log/apache2"));
 
     volumeMounts.add(
         new VolumeMountBuilder()
diff --git a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_default.yaml b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_default.yaml
index ebc04e6..7d8b8e1 100644
--- a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_default.yaml
+++ b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_default.yaml
@@ -65,18 +65,10 @@
               limits:
                 cpu: 100m
                 memory: 256Mi
-            env:
-            - name: POD_NAME
-              valueFrom:
-                fieldRef:
-                  fieldPath: metadata.name
             volumeMounts:
             - name: shared
               subPath: git
               mountPath: /var/gerrit/git
-            - name: shared
-              subPathExpr: "logs/$(POD_NAME)"
-              mountPath: /var/log/git
           volumes:
           - name: shared
             persistentVolumeClaim:
diff --git a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_nfs_workaround.yaml b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_nfs_workaround.yaml
index ac30455..38d4c74 100644
--- a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_nfs_workaround.yaml
+++ b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_nfs_workaround.yaml
@@ -62,17 +62,9 @@
             - sh
             - -c
             args:
-            - chown -R 1000:100 /var/mnt/logs /var/mnt/git
-            env:
-            - name: POD_NAME
-              valueFrom:
-                fieldRef:
-                  fieldPath: metadata.name
+            - chown -R 1000:100 /var/mnt/git
             volumeMounts:
             - name: shared
-              subPathExpr: "logs/$(POD_NAME)"
-              mountPath: /var/mnt/logs
-            - name: shared
               subPath: git
               mountPath: /var/mnt/git
             - name: nfs-config
@@ -89,18 +81,10 @@
               limits:
                 cpu: 100m
                 memory: 256Mi
-            env:
-            - name: POD_NAME
-              valueFrom:
-                fieldRef:
-                  fieldPath: metadata.name
             volumeMounts:
             - name: shared
               subPath: git
               mountPath: /var/gerrit/git
-            - name: shared
-              subPathExpr: "logs/$(POD_NAME)"
-              mountPath: /var/log/git
             - name: nfs-config
               subPath: idmapd.conf
               mountPath: /etc/idmapd.conf
diff --git a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_options_enabled.yaml b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_options_enabled.yaml
index b9780f5..e093502 100644
--- a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_options_enabled.yaml
+++ b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_all_options_enabled.yaml
@@ -69,18 +69,10 @@
             - -B
             - -R
             - -P
-            env:
-            - name: POD_NAME
-              valueFrom:
-                fieldRef:
-                  fieldPath: metadata.name
             volumeMounts:
             - name: shared
               subPath: git
               mountPath: /var/gerrit/git
-            - name: shared
-              subPathExpr: "logs/$(POD_NAME)"
-              mountPath: /var/log/git
           volumes:
           - name: shared
             persistentVolumeClaim:
diff --git a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_selected_default.yaml b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_selected_default.yaml
index 68d68ca..a87a216 100644
--- a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_selected_default.yaml
+++ b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_selected_default.yaml
@@ -70,18 +70,10 @@
             - test
             - -p
             - example
-            env:
-            - name: POD_NAME
-              valueFrom:
-                fieldRef:
-                  fieldPath: metadata.name
             volumeMounts:
             - name: shared
               subPath: git
               mountPath: /var/gerrit/git
-            - name: shared
-              subPathExpr: "logs/$(POD_NAME)"
-              mountPath: /var/log/git
           volumes:
           - name: shared
             persistentVolumeClaim:
diff --git a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_selected_options_enabled.yaml b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_selected_options_enabled.yaml
index 7458352..d4519df 100644
--- a/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_selected_options_enabled.yaml
+++ b/operator/src/test/resources/com/google/gerrit/k8s/operator/gitgc/dependent/cronjob_selected_options_enabled.yaml
@@ -73,18 +73,10 @@
             - -B
             - -R
             - -P
-            env:
-            - name: POD_NAME
-              valueFrom:
-                fieldRef:
-                  fieldPath: metadata.name
             volumeMounts:
             - name: shared
               subPath: git
               mountPath: /var/gerrit/git
-            - name: shared
-              subPathExpr: "logs/$(POD_NAME)"
-              mountPath: /var/log/git
           volumes:
           - name: shared
             persistentVolumeClaim:
diff --git a/operator/src/test/resources/com/google/gerrit/k8s/operator/receiver/dependent/deployment.yaml b/operator/src/test/resources/com/google/gerrit/k8s/operator/receiver/dependent/deployment.yaml
index 4857152..2257380 100644
--- a/operator/src/test/resources/com/google/gerrit/k8s/operator/receiver/dependent/deployment.yaml
+++ b/operator/src/test/resources/com/google/gerrit/k8s/operator/receiver/dependent/deployment.yaml
@@ -65,11 +65,6 @@
       - name: apache-git-http-backend
         imagePullPolicy: Always
         image: docker.io/k8sgerrit/apache-git-http-backend:latest
-        env:
-        - name: POD_NAME
-          valueFrom:
-            fieldRef:
-              fieldPath: metadata.name
         ports:
         - name: http
           containerPort: 80
@@ -100,9 +95,6 @@
           failureThreshold: 3
 
         volumeMounts:
-        - name: shared
-          subPathExpr: "logs/$(POD_NAME)"
-          mountPath: /var/log/apache2
         - name: apache-credentials
           mountPath: /var/apache/credentials/.htpasswd
           subPath: .htpasswd
diff --git a/operator/src/test/resources/com/google/gerrit/k8s/operator/receiver/dependent/deployment_minimal.yaml b/operator/src/test/resources/com/google/gerrit/k8s/operator/receiver/dependent/deployment_minimal.yaml
index 92d0752..53b3c87 100644
--- a/operator/src/test/resources/com/google/gerrit/k8s/operator/receiver/dependent/deployment_minimal.yaml
+++ b/operator/src/test/resources/com/google/gerrit/k8s/operator/receiver/dependent/deployment_minimal.yaml
@@ -43,11 +43,6 @@
       - name: apache-git-http-backend
         imagePullPolicy: Always
         image: docker.io/k8sgerrit/apache-git-http-backend:latest
-        env:
-        - name: POD_NAME
-          valueFrom:
-            fieldRef:
-              fieldPath: metadata.name
         ports:
         - name: http
           containerPort: 80
@@ -61,9 +56,6 @@
             port: 80
 
         volumeMounts:
-        - name: shared
-          subPathExpr: "logs/$(POD_NAME)"
-          mountPath: /var/log/apache2
         - name: apache-credentials
           mountPath: /var/apache/credentials/.htpasswd
           subPath: .htpasswd