Add storage for logs to GerritCluster resource
As in the helm charts, logs will be stored in a shared RWM volume.
Change-Id: If8245b3f83c8ccff8eabd4b809124d6ee788e822
diff --git a/operator/README.md b/operator/README.md
index 6eb95b4..9fd1612 100644
--- a/operator/README.md
+++ b/operator/README.md
@@ -77,6 +77,7 @@
## Name of a StorageClass allowing ReadWriteMany access. (default: shared-storage)
readWriteMany: nfs-client
+ ## Storage for git repositories
gitRepositoryStorage:
## Size of the volume (ReadWriteMany) used to store git repositories. (mandatory)
size: 1Gi
@@ -90,6 +91,21 @@
matchLabels:
volume-type: ssd
aws-availability-zone: us-east-1
+
+ ## Storage for logs
+ gerritLogsStorage:
+ ## Size of the volume (ReadWriteMany) used to store logs. (mandatory)
+ size: 1Gi
+
+ ## Name of a specific persistent volume to claim (optional)
+ volumeName: logs
+
+ ## Selector (https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector)
+ ## to select a specific persistent volume (optional)
+ selector:
+ matchLabels:
+ volume-type: ssd
+ aws-availability-zone: us-east-1
```
### GitGarbageCollection
@@ -126,7 +142,4 @@
limits:
cpu: 100m
memory: 256Mi
-
- ## Name of an existing PVC that will be used to store the logs (mandatory)
- logPVC: logs-pvc
```
diff --git a/operator/k8s/cluster.sample.yaml b/operator/k8s/cluster.sample.yaml
index 0afc40d..52b7759 100644
--- a/operator/k8s/cluster.sample.yaml
+++ b/operator/k8s/cluster.sample.yaml
@@ -8,3 +8,5 @@
readWriteMany: nfs-client
gitRepositoryStorage:
size: 1Gi
+ gerritLogsStorage:
+ size: 1Gi
diff --git a/operator/k8s/gitgc.sample.yaml b/operator/k8s/gitgc.sample.yaml
index 3c2ee00..480f5c6 100644
--- a/operator/k8s/gitgc.sample.yaml
+++ b/operator/k8s/gitgc.sample.yaml
@@ -5,7 +5,6 @@
spec:
image: k8sgerrit/git-gc
schedule: "*/5 * * * *"
- logPVC: logs-pvc
cluster: gerrit
resources:
requests:
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritCluster.java b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritCluster.java
index 693602a..d2a8297 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritCluster.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritCluster.java
@@ -14,6 +14,7 @@
package com.google.gerrit.k8s.operator.cluster;
+import static com.google.gerrit.k8s.operator.cluster.GerritLogsPVC.LOGS_PVC_NAME;
import static com.google.gerrit.k8s.operator.cluster.GitRepositoriesPVC.REPOSITORY_PVC_NAME;
import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -38,6 +39,7 @@
public class GerritCluster extends CustomResource<GerritClusterSpec, Status> implements Namespaced {
private static final long serialVersionUID = 1L;
private static final String GIT_REPOSITORIES_VOLUME_NAME = "git-repositories";
+ private static final String LOGS_VOLUME_NAME = "logs";
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
@@ -75,4 +77,22 @@
.withMountPath("/var/gerrit/git")
.build();
}
+
+ @JsonIgnore
+ public Volume getLogsVolume() {
+ return new VolumeBuilder()
+ .withName(LOGS_VOLUME_NAME)
+ .withNewPersistentVolumeClaim()
+ .withClaimName(LOGS_PVC_NAME)
+ .endPersistentVolumeClaim()
+ .build();
+ }
+
+ @JsonIgnore
+ public VolumeMount getLogsVolumeMount() {
+ return new VolumeMountBuilder()
+ .withName(LOGS_VOLUME_NAME)
+ .withMountPath("/var/gerrit/logs")
+ .build();
+ }
}
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritClusterReconciler.java b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritClusterReconciler.java
index f6e66f4..29d4d73 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritClusterReconciler.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritClusterReconciler.java
@@ -23,6 +23,7 @@
@ControllerConfiguration(
dependents = {
@Dependent(type = GitRepositoriesPVC.class),
+ @Dependent(type = GerritLogsPVC.class),
})
public class GerritClusterReconciler implements Reconciler<GerritCluster> {
@Override
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritClusterSpec.java b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritClusterSpec.java
index e084753..2c0f8c0 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritClusterSpec.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritClusterSpec.java
@@ -17,13 +17,14 @@
public class GerritClusterSpec {
private StorageClassConfig storageClasses;
- private GitRepositoryStorage gitRepositoryStorage;
+ private SharedStorage gitRepositoryStorage;
+ private SharedStorage logsStorage;
public StorageClassConfig getStorageClasses() {
return storageClasses;
}
- public GitRepositoryStorage getGitRepositoryStorage() {
+ public SharedStorage getGitRepositoryStorage() {
return gitRepositoryStorage;
}
@@ -31,7 +32,15 @@
this.storageClasses = storageClasses;
}
- public void setGitRepositoryStorage(GitRepositoryStorage gitRepositoryStorage) {
+ public void setGitRepositoryStorage(SharedStorage gitRepositoryStorage) {
this.gitRepositoryStorage = gitRepositoryStorage;
}
+
+ public SharedStorage getLogsStorage() {
+ return logsStorage;
+ }
+
+ public void setLogsStorage(SharedStorage logsStorage) {
+ this.logsStorage = logsStorage;
+ }
}
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritLogsPVC.java b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritLogsPVC.java
new file mode 100644
index 0000000..bf4dc94
--- /dev/null
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GerritLogsPVC.java
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 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;
+
+import io.fabric8.kubernetes.api.model.PersistentVolumeClaim;
+import io.fabric8.kubernetes.api.model.PersistentVolumeClaimBuilder;
+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(labelSelector = "app.kubernetes.io/component=gerrit-logs-storage")
+public class GerritLogsPVC
+ extends CRUDKubernetesDependentResource<PersistentVolumeClaim, GerritCluster> {
+
+ public static final String LOGS_PVC_NAME = "gerrit-logs-pvc";
+
+ public GerritLogsPVC() {
+ super(PersistentVolumeClaim.class);
+ }
+
+ @Override
+ protected PersistentVolumeClaim desired(
+ GerritCluster gerritCluster, Context<GerritCluster> context) {
+ PersistentVolumeClaim gerritLogsPvc =
+ new PersistentVolumeClaimBuilder()
+ .withNewMetadata()
+ .withName(LOGS_PVC_NAME)
+ .withNamespace(gerritCluster.getMetadata().getNamespace())
+ .withLabels(
+ gerritCluster.getLabels("gerrit-logs-storage", this.getClass().getSimpleName()))
+ .endMetadata()
+ .withNewSpec()
+ .withAccessModes("ReadWriteMany")
+ .withNewResources()
+ .withRequests(Map.of("storage", gerritCluster.getSpec().getLogsStorage().getSize()))
+ .endResources()
+ .withStorageClassName(gerritCluster.getSpec().getStorageClasses().getReadWriteMany())
+ .withSelector(gerritCluster.getSpec().getLogsStorage().getSelector())
+ .withVolumeName(gerritCluster.getSpec().getLogsStorage().getVolumeName())
+ .endSpec()
+ .build();
+
+ return gerritLogsPvc;
+ }
+}
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GitRepositoriesPVC.java b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GitRepositoriesPVC.java
index 30c7582..bde8797 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GitRepositoriesPVC.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GitRepositoriesPVC.java
@@ -21,7 +21,7 @@
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
import java.util.Map;
-@KubernetesDependent
+@KubernetesDependent(labelSelector = "app.kubernetes.io/component=git-repositories-storage")
public class GitRepositoriesPVC
extends CRUDKubernetesDependentResource<PersistentVolumeClaim, GerritCluster> {
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GitRepositoryStorage.java b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/SharedStorage.java
similarity index 97%
rename from operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GitRepositoryStorage.java
rename to operator/src/main/java/com/google/gerrit/k8s/operator/cluster/SharedStorage.java
index 57c1fc6..5f8dba1 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/GitRepositoryStorage.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/cluster/SharedStorage.java
@@ -17,7 +17,7 @@
import io.fabric8.kubernetes.api.model.LabelSelector;
import io.fabric8.kubernetes.api.model.Quantity;
-public class GitRepositoryStorage {
+public class SharedStorage {
private Quantity size;
private String volumeName;
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionCronJob.java b/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionCronJob.java
index 4c473dc..ae68a83 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionCronJob.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionCronJob.java
@@ -20,10 +20,6 @@
import io.fabric8.kubernetes.api.model.ContainerBuilder;
import io.fabric8.kubernetes.api.model.EnvVar;
import io.fabric8.kubernetes.api.model.EnvVarBuilder;
-import io.fabric8.kubernetes.api.model.Volume;
-import io.fabric8.kubernetes.api.model.VolumeBuilder;
-import io.fabric8.kubernetes.api.model.VolumeMount;
-import io.fabric8.kubernetes.api.model.VolumeMountBuilder;
import io.fabric8.kubernetes.api.model.batch.v1.CronJob;
import io.fabric8.kubernetes.api.model.batch.v1.CronJobBuilder;
import io.fabric8.kubernetes.api.model.batch.v1.JobTemplateSpec;
@@ -39,8 +35,6 @@
extends CRUDKubernetesDependentResource<CronJob, GitGarbageCollection> {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
- private static final String LOGS_VOLUME_NAME = "logs";
-
public GitGarbageCollectionCronJob() {
super(CronJob.class);
}
@@ -64,16 +58,6 @@
Map<String, String> gitGcLabels =
gerritCluster.getLabels("GitGc", this.getClass().getSimpleName());
- Volume gitRepositoriesVolume = gerritCluster.getGitRepositoriesVolume();
-
- Volume logsVolume =
- new VolumeBuilder()
- .withName(LOGS_VOLUME_NAME)
- .withNewPersistentVolumeClaim()
- .withClaimName(gitGc.getSpec().getLogPVC())
- .endPersistentVolumeClaim()
- .build();
-
JobTemplateSpec gitGcJobTemplate =
new JobTemplateSpecBuilder()
.withNewSpec()
@@ -93,7 +77,8 @@
.withFsGroup(100L)
.endSecurityContext()
.addToContainers(buildGitGcContainer(gitGc, gerritCluster))
- .withVolumes(List.of(gitRepositoriesVolume, logsVolume))
+ .withVolumes(
+ List.of(gerritCluster.getGitRepositoriesVolume(), gerritCluster.getLogsVolume()))
.endSpec()
.endTemplate()
.endSpec()
@@ -123,13 +108,6 @@
}
private Container buildGitGcContainer(GitGarbageCollection gitGc, GerritCluster gerritCluster) {
- VolumeMount logsVolumeMount =
- new VolumeMountBuilder()
- .withName(LOGS_VOLUME_NAME)
- .withSubPathExpr("git-gc/$(POD_NAME)")
- .withMountPath("/var/log/git")
- .build();
-
EnvVar podNameEnvVar =
new EnvVarBuilder()
.withName("POD_NAME")
@@ -147,7 +125,9 @@
.withResources(gitGc.getSpec().getResources())
.withEnv(podNameEnvVar)
.withVolumeMounts(
- List.of(gerritCluster.getGitRepositoriesVolumeMount(), logsVolumeMount));
+ List.of(
+ gerritCluster.getGitRepositoriesVolumeMount(),
+ gerritCluster.getLogsVolumeMount()));
ArrayList<String> args = new ArrayList<>();
for (String project : gitGc.getSpec().getProjects()) {
diff --git a/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionSpec.java b/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionSpec.java
index 80f46d4..86c8f11 100644
--- a/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionSpec.java
+++ b/operator/src/main/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionSpec.java
@@ -25,7 +25,6 @@
private String schedule;
private Set<String> projects;
private ResourceRequirements resources;
- private String logPVC;
public GitGarbageCollectionSpec() {
image = "k8s-gerrit/git-gc";
@@ -73,17 +72,9 @@
return resources;
}
- public void setLogPVC(String logPVC) {
- this.logPVC = logPVC;
- }
-
- public String getLogPVC() {
- return logPVC;
- }
-
@Override
public int hashCode() {
- return Objects.hash(cluster, image, logPVC, projects, resources, schedule);
+ return Objects.hash(cluster, image, projects, resources, schedule);
}
@Override
@@ -92,7 +83,6 @@
GitGarbageCollectionSpec other = (GitGarbageCollectionSpec) obj;
return Objects.equals(cluster, other.cluster)
&& Objects.equals(image, other.image)
- && Objects.equals(logPVC, other.logPVC)
&& Objects.equals(projects, other.projects)
&& Objects.equals(resources, other.resources)
&& Objects.equals(schedule, other.schedule);
diff --git a/operator/src/test/java/com/google/gerrit/k8s/operator/cluster/GerritClusterE2E.java b/operator/src/test/java/com/google/gerrit/k8s/operator/cluster/GerritClusterE2E.java
index 2f85a3a..436bcf6 100644
--- a/operator/src/test/java/com/google/gerrit/k8s/operator/cluster/GerritClusterE2E.java
+++ b/operator/src/test/java/com/google/gerrit/k8s/operator/cluster/GerritClusterE2E.java
@@ -43,30 +43,7 @@
@Test
void testGitRepositoriesPvcCreated() {
- GerritCluster cluster = new GerritCluster();
-
- cluster.setMetadata(
- new ObjectMetaBuilder()
- .withName("test-cluster")
- .withNamespace(operator.getNamespace())
- .build());
-
- GitRepositoryStorage repoStorage = new GitRepositoryStorage();
- repoStorage.setSize(Quantity.parse("1Gi"));
-
- StorageClassConfig storageClassConfig = new StorageClassConfig();
- storageClassConfig.setReadWriteMany(System.getProperty("rwmStorageClass", "nfs-client"));
-
- GerritClusterSpec clusterSpec = new GerritClusterSpec();
- clusterSpec.setGitRepositoryStorage(repoStorage);
- clusterSpec.setStorageClasses(storageClassConfig);
-
- cluster.setSpec(clusterSpec);
-
- client
- .resources(GerritCluster.class)
- .inNamespace(operator.getNamespace())
- .createOrReplace(cluster);
+ GerritCluster cluster = createGerritCluster();
logger.atInfo().log("Waiting max 1 minutes for the git repositories pvc to be created.");
await()
@@ -85,4 +62,59 @@
logger.atInfo().log("Deleting test cluster object: %s", cluster);
client.resource(cluster).delete();
}
+
+ @Test
+ void testGerritLogsPvcCreated() {
+ GerritCluster cluster = createGerritCluster();
+
+ logger.atInfo().log("Waiting max 1 minutes for the gerrit logs pvc to be created.");
+ await()
+ .atMost(1, MINUTES)
+ .untilAsserted(
+ () -> {
+ PersistentVolumeClaim pvc =
+ client
+ .persistentVolumeClaims()
+ .inNamespace(operator.getNamespace())
+ .withName(GerritLogsPVC.LOGS_PVC_NAME)
+ .get();
+ assertThat(pvc, is(notNullValue()));
+ });
+
+ logger.atInfo().log("Deleting test cluster object: %s", cluster);
+ client.resource(cluster).delete();
+ }
+
+ private GerritCluster createGerritCluster() {
+ GerritCluster cluster = new GerritCluster();
+
+ cluster.setMetadata(
+ new ObjectMetaBuilder()
+ .withName("test-cluster")
+ .withNamespace(operator.getNamespace())
+ .build());
+
+ SharedStorage repoStorage = new SharedStorage();
+ repoStorage.setSize(Quantity.parse("1Gi"));
+
+ SharedStorage logStorage = new SharedStorage();
+ logStorage.setSize(Quantity.parse("1Gi"));
+
+ StorageClassConfig storageClassConfig = new StorageClassConfig();
+ storageClassConfig.setReadWriteMany(System.getProperty("rwmStorageClass", "nfs-client"));
+
+ GerritClusterSpec clusterSpec = new GerritClusterSpec();
+ clusterSpec.setGitRepositoryStorage(repoStorage);
+ clusterSpec.setLogsStorage(logStorage);
+ clusterSpec.setStorageClasses(storageClassConfig);
+
+ cluster.setSpec(clusterSpec);
+
+ client
+ .resources(GerritCluster.class)
+ .inNamespace(operator.getNamespace())
+ .createOrReplace(cluster);
+
+ return cluster;
+ }
}
diff --git a/operator/src/test/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionE2E.java b/operator/src/test/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionE2E.java
index 5debf29..d4c51b0 100644
--- a/operator/src/test/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionE2E.java
+++ b/operator/src/test/java/com/google/gerrit/k8s/operator/gitgc/GitGarbageCollectionE2E.java
@@ -28,7 +28,7 @@
import com.google.gerrit.k8s.operator.cluster.GerritCluster;
import com.google.gerrit.k8s.operator.cluster.GerritClusterReconciler;
import com.google.gerrit.k8s.operator.cluster.GerritClusterSpec;
-import com.google.gerrit.k8s.operator.cluster.GitRepositoryStorage;
+import com.google.gerrit.k8s.operator.cluster.SharedStorage;
import com.google.gerrit.k8s.operator.cluster.StorageClassConfig;
import com.google.gerrit.k8s.operator.gitgc.GitGarbageCollectionStatus.GitGcState;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
@@ -203,14 +203,18 @@
.withNamespace(operator.getNamespace())
.build());
- GitRepositoryStorage repoStorage = new GitRepositoryStorage();
+ SharedStorage repoStorage = new SharedStorage();
repoStorage.setSize(Quantity.parse("1Gi"));
+ SharedStorage logStorage = new SharedStorage();
+ logStorage.setSize(Quantity.parse("1Gi"));
+
StorageClassConfig storageClassConfig = new StorageClassConfig();
storageClassConfig.setReadWriteMany(System.getProperty("rwmStorageClass", "nfs-client"));
GerritClusterSpec clusterSpec = new GerritClusterSpec();
clusterSpec.setGitRepositoryStorage(repoStorage);
+ clusterSpec.setLogsStorage(logStorage);
clusterSpec.setStorageClasses(storageClassConfig);
cluster.setSpec(clusterSpec);
@@ -244,7 +248,6 @@
.build());
GitGarbageCollectionSpec spec = new GitGarbageCollectionSpec();
spec.setSchedule(GITGC_SCHEDULE);
- spec.setLogPVC("log-pvc");
spec.setCluster(CLUSTER_NAME);
gitGc.setSpec(spec);
@@ -260,7 +263,6 @@
new ObjectMetaBuilder().withName(name).withNamespace(operator.getNamespace()).build());
GitGarbageCollectionSpec spec = new GitGarbageCollectionSpec();
spec.setSchedule(GITGC_SCHEDULE);
- spec.setLogPVC("log-pvc");
spec.setCluster(CLUSTER_NAME);
spec.setProjects(projects);
gitGc.setSpec(spec);