blob: 8300e0afe5e8ca7859da3fd98cb19aca5602573c [file] [log] [blame] [view]
Giorgi Lekveishviliee15ee22024-03-28 12:35:10 +04001# Gerrit on Kubernetes
2
3Gerrit is a web-based code review tool, which acts as a Git server. This helm
4chart provides a Gerrit setup that can be deployed on Kubernetes.
5In addition, the chart provides a CronJob to perform Git garbage collection.
6
7***note
8Gerrit versions before 3.0 are no longer supported, since the support of ReviewDB
9was removed.
10***
11
12## Prerequisites
13
14- Helm (>= version 3.0)
15
16 (Check out [this guide](https://docs.helm.sh/using_helm/#quickstart-guide)
17 how to install and use helm.)
18
19- Access to a provisioner for persistent volumes with `Read Write Many (RWM)`-
20 capability.
21
22 A list of applicaple volume types can be found
23 [here](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes).
24 This project was developed using the
25 [NFS-server-provisioner helm chart](https://github.com/helm/charts/tree/master/stable/nfs-server-provisioner),
26 a NFS-provisioner deployed in the Kubernetes cluster itself. Refer to
27 [this guide](/helm-charts/gerrit/docs/nfs-provisioner.md) of how to
28 deploy it in context of this project.
29
30- A domain name that is configured to point to the IP address of the node running
31 the Ingress controller on the kubernetes cluster (as described
32 [here](http://alesnosek.com/blog/2017/02/14/accessing-kubernetes-pods-from-outside-of-the-cluster/)).
33
34- (Optional: Required, if SSL is configured)
35 A [Java keystore](https://gerrit-review.googlesource.com/Documentation/config-gerrit.html#httpd.sslKeyStore)
36 to be used by Gerrit.
37
38## Installing the Chart
39
40***note
41**ATTENTION:** The value for `ingress.host` is required for rendering
42the chart's templates. The nature of the value does not allow defaults.
43Thus a custom `values.yaml`-file setting this value is required!
44***
45
46To install the chart with the release name `gerrit`, execute:
47
48```sh
49cd $(git rev-parse --show-toplevel)/helm-charts
50helm install \
51 gerrit \ # release name
52 ./gerrit \ # path to chart
53 -f <path-to-custom-values>.yaml
54```
55
56The command deploys the Gerrit instance on the current Kubernetes cluster.
57The [configuration section](#Configuration) lists the parameters that can be
58configured during installation.
59
60## Configuration
61
62The following sections list the configurable values in `values.yaml`. To configure
63a Gerrit setup, make a copy of the `values.yaml`-file and change the parameters
64as needed. The configuration can be applied by installing the chart as described
65[above](#Installing-the-chart).
66
67In addition, single options can be set without creating a custom `values.yaml`:
68
69```sh
70cd $(git rev-parse --show-toplevel)/helm-charts
71helm install \
72 gerrit \ # release name
73 ./gerrit \ # path to chart
74 --set=gitRepositoryStorage.size=100Gi
75```
76
77### Container images
78
79| Parameter | Description | Default |
80|-----------|-------------|---------|
81| `images.busybox.registry` | The registry to pull the busybox container images from | `docker.io` |
82| `images.busybox.tag` | The busybox image tag to use | `latest` |
83| `images.registry.name` | The image registry to pull the container images from | `` |
84| `images.registry.ImagePullSecret.name` | Name of the ImagePullSecret | `image-pull-secret` (if empty no image pull secret will be deployed) |
85| `images.registry.ImagePullSecret.create` | Whether to create an ImagePullSecret | `false` |
86| `images.registry.ImagePullSecret.username` | The image registry username | `nil` |
87| `images.registry.ImagePullSecret.password` | The image registry password | `nil` |
88| `images.version` | The image version (image tag) to use | `latest` |
89| `images.imagePullPolicy` | Image pull policy | `Always` |
90| `images.additionalImagePullSecrets` | Additional image pull policies that pods should use | `[]` |
91
92### Labels
93
94| Parameter | Description | Default |
95|-----------|-------------|---------|
96| `additionalLabels` | Additional labels for resources managed by this Helm chart | `{}` |
97
98### Storage classes
99
100For information of how a `StorageClass` is configured in Kubernetes, read the
101[official Documentation](https://kubernetes.io/docs/concepts/storage/storage-classes/#introduction).
102
103| Parameter | Description | Default |
104|-----------|-------------|---------|
105| `storageClasses.default.name` | The name of the default StorageClass (RWO) | `default` |
106| `storageClasses.default.create` | Whether to create the StorageClass | `false` |
107| `storageClasses.default.provisioner` | Provisioner of the StorageClass | `kubernetes.io/aws-ebs` |
108| `storageClasses.default.reclaimPolicy` | Whether to `Retain` or `Delete` volumes, when they become unbound | `Delete` |
109| `storageClasses.default.parameters` | Parameters for the provisioner | `parameters.type: gp2`, `parameters.fsType: ext4` |
110| `storageClasses.default.mountOptions` | The mount options of the default StorageClass | `[]` |
111| `storageClasses.default.allowVolumeExpansion` | Whether to allow volume expansion. | `false` |
112| `storageClasses.shared.name` | The name of the shared StorageClass (RWM) | `shared-storage` |
113| `storageClasses.shared.create` | Whether to create the StorageClass | `false` |
114| `storageClasses.shared.provisioner` | Provisioner of the StorageClass | `nfs` |
115| `storageClasses.shared.reclaimPolicy` | Whether to `Retain` or `Delete` volumes, when they become unbound | `Delete` |
116| `storageClasses.shared.parameters` | Parameters for the provisioner | `parameters.mountOptions: vers=4.1` |
117| `storageClasses.shared.mountOptions` | The mount options of the shared StorageClass | `[]` |
118| `storageClasses.shared.allowVolumeExpansion` | Whether to allow volume expansion. | `false` |
119
120### Network policies
121
122| Parameter | Description | Default |
123|-----------|-------------|---------|
124| `networkPolicies.enabled` | Whether to enable preconfigured NetworkPolicies | `false` |
125| `networkPolicies.dnsPorts` | List of ports used by DNS-service (e.g. KubeDNS) | `[53, 8053]` |
126
127The NetworkPolicies provided here are quite strict and do not account for all
128possible scenarios. Thus, custom NetworkPolicies have to be added, e.g. for
129allowing Gerrit to replicate to a Gerrit replica. By default, the egress traffic
130of the gerrit pod is blocked, except for connections to the DNS-server.
131Thus, replication which requires Gerrit to perform git pushes to the replica will
132not work. The chart provides the possibility to define custom rules for egress-
133traffic of the gerrit pod under `gerrit.networkPolicy.egress`.
134Depending on the scenario, there are different ways to allow the required
135connections. The easiest way is to allow all egress-traffic for the gerrit
136pods:
137
138```yaml
139gerrit:
140 networkPolicy:
141 egress:
142 - {}
143```
144
145If the remote that is replicated to is running in a pod on the same cluster and
146the service-DNS is used as the remote's URL (e.g. http://gerrit-replica-git-backend-service:80/git/${name}.git),
147a podSelector (and namespaceSelector, if the pod is running in a different
148namespace) can be used to whitelist the traffic:
149
150```yaml
151gerrit:
152 networkPolicy:
153 egress:
154 - to:
155 - podSelector:
156 matchLabels:
157 app: git-backend
158```
159
160If the remote is outside the cluster, the IP of the remote or its load balancer
161can also be whitelisted, e.g.:
162
163```yaml
164gerrit:
165 networkPolicy:
166 egress:
167 - to:
168 - ipBlock:
169 cidr: xxx.xxx.0.0/16
170```
171
172The same principle also applies to other use cases, e.g. connecting to a database.
173For more information about the NetworkPolicy resource refer to the
174[Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/network-policies/).
175
176### Workaround for NFS
177
178Kubernetes will not always be able to adapt the ownership of the files within NFS
179volumes. Thus, a workaround exists that will add init-containers to
180adapt file ownership. Note, that only the ownership of the root directory of the
181volume will be changed. All data contained within will be expected to already be
182owned by the user used by Gerrit. Also the ID-domain will be configured to ensure
183correct ID-mapping.
184
185| Parameter | Description | Default |
186|-----------|-------------|---------|
187| `nfsWorkaround.enabled` | Whether the volume used is an NFS-volume | `false` |
188| `nfsWorkaround.chownOnStartup` | Whether to chown the volume on pod startup | `false` |
189| `nfsWorkaround.idDomain` | The ID-domain that should be used to map user-/group-IDs for the NFS mount | `localdomain.com` |
190
191### Storage for Git repositories
192
193| Parameter | Description | Default |
194|-----------|-------------|---------|
195| `gitRepositoryStorage.externalPVC.use` | Whether to use a PVC deployed outside the chart | `false` |
196| `gitRepositoryStorage.externalPVC.name` | Name of the external PVC | `git-repositories-pvc` |
197| `gitRepositoryStorage.size` | Size of the volume storing the Git repositories | `5Gi` |
198
199If the git repositories should be persisted even if the chart is deleted and in
200a way that the volume containing them can be mounted by the reinstalled chart,
201the PVC claiming the volume has to be created independently of the chart. To use
202the external PVC, set `gitRepositoryStorage.externalPVC.enabled` to `true` and
203give the name of the PVC under `gitRepositoryStorage.externalPVC.name`.
204
205### Storage for Logs
206
207The logs can be stored in a dedicated persistent volume. This volume has to be a
208read-write-many volume to be able to be used by multiple pods.
209
210| Parameter | Description | Default |
211|-----------|-------------|---------|
212| `logStorage.enabled` | Whether to enable persistence of logs | `false` |
213| `logStorage.externalPVC.use` | Whether to use a PVC deployed outside the chart | `false` |
214| `logStorage.externalPVC.name` | Name of the external PVC | `gerrit-logs-pvc` |
215| `logStorage.size` | Size of the volume | `5Gi` |
216| `logStorage.cleanup.enabled` | Whether to regularly delete old logs | `false` |
217| `logStorage.cleanup.schedule` | Cron schedule defining when to run the cleanup job | `0 0 * * *` |
218| `logStorage.cleanup.retentionDays` | Number of days to retain the logs | `14` |
219| `logStorage.cleanup.resources` | Resources the container is allowed to use | `requests.cpu: 100m` |
220| `logStorage.cleanup.additionalPodLabels` | Additional labels for pods | `{}` |
221| | | `requests.memory: 256Mi` |
222| | | `limits.cpu: 100m` |
223| | | `limits.memory: 256Mi` |
224
225Each pod will create a separate folder for its logs, allowing to trace logs to
226the respective pods.
227
228### CA certificate
229
230Some application may require TLS verification. If the default CA built into the
231containers is not enough a custom CA certificate can be given to the deployment.
232Note, that Gerrit will require its CA in a JKS keytore, which is described below.
233
234| Parameter | Description | Default |
235|-----------|-------------|---------|
236| `caCert` | CA certificate for TLS verification (if not set, the default will be used) | `None` |
237
238### Ingress
239
240| Parameter | Description | Default |
241|-----------|-------------|---------|
242| `ingress.enabled` | Whether to enable the Ingress | `false` |
243| `ingress.host` | REQUIRED: Host name to use for the Ingress (required for Ingress) | `nil` |
244| `ingress.additionalAnnotations` | Additional annotations for the Ingress | `nil` |
245| `ingress.tls.enabled` | Whether to enable TLS termination in the Ingress | `false` |
246| `ingress.tls.secret.create` | Whether to create a TLS-secret | `true` |
247| `ingress.tls.secret.name` | Name of an external secret that will be used as a TLS-secret | `nil` |
248| `ingress.tls.cert` | Public SSL server certificate | `-----BEGIN CERTIFICATE-----` |
249| `ingress.tls.key` | Private SSL server certificate | `-----BEGIN RSA PRIVATE KEY-----` |
250
251***note
252For graceful shutdown to work with an ingress, the ingress controller has to be
253configured to gracefully close the connections as well.
254***
255
256### Git garbage collection
257
258| Parameter | Description | Default |
259|-----------|-------------|---------|
260| `gitGC.image` | Image name of the Git-GC container image | `k8sgerrit/git-gc` |
261| `gitGC.schedule` | Cron-formatted schedule with which to run Git garbage collection | `0 6,18 * * *` |
262| `gitGC.resources` | Configure the amount of resources the pod requests/is allowed | `requests.cpu: 100m` |
263| | | `requests.memory: 256Mi` |
264| | | `limits.cpu: 100m` |
265| | | `limits.memory: 256Mi` |
266| `gitGC.logging.persistence.enabled` | Whether to persist logs | `true` |
267| `gitGC.logging.persistence.size` | Storage size for persisted logs | `1Gi` |
268| `gitGC.tolerations` | Taints and tolerations work together to ensure that pods are not scheduled onto inappropriate nodes. For more information, please refer to the following documents. [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration) | [] |
269| `gitGC.nodeSelector` | Assigns a Pod to the specified Nodes. For more information, please refer to the following documents. [Assign Pods to Nodes](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/). [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) | {} |
270| `gitGC.affinity` | Assigns a Pod to the specified Nodes. For more information, please refer to the following documents. [Assign Pods to Nodes using Node Affinity](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/). [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) | {} |
271| `gitGC.additionalPodLabels` | Additional labels for Pods | `{}` |
272
273### Gerrit
274
275***note
276The way the Jetty servlet used by Gerrit works, the Gerrit component of the
277gerrit chart actually requires the URL to be known, when the chart is installed.
278The suggested way to do that is to use the provided Ingress resource. This requires
279that a URL is available and that the DNS is configured to point the URL to the
280IP of the node the Ingress controller is running on!
281***
282
283***note
284Setting the canonical web URL in the gerrit.config to the host used for the Ingress
285is mandatory, if access to Gerrit is required!
286***
287
288***note
289While the chart allows to configure multiple replica for the Gerrit StatefulSet,
290scaling of Gerrit is currently not supported, since no mechanism to guarantee a
291consistent state is currently in place. This is planned to be implemented in the
292future.
293***
294
295| Parameter | Description | Default |
296|-----------|-------------|---------|
297| `gerrit.images.gerritInit` | Image name of the Gerrit init container image | `k8sgerrit/gerrit-init` |
298| `gerrit.images.gerrit` | Image name of the Gerrit container image | `k8sgerrit/gerrit` |
299| `gerrit.tolerations` | Taints and tolerations work together to ensure that pods are not scheduled onto inappropriate nodes. For more information, please refer to the following documents. [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration) | [] |
300| `gerrit.topologySpreadConstraints` | Control how Pods are spread across your cluster among failure-domains. For more information, please refer to the following documents. [Pod Topology Spread Constraints](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints) | {} |
301| `gerrit.nodeSelector` | Assigns a Pod to the specified Nodes. For more information, please refer to the following documents. [Assign Pods to Nodes](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/). [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) | {} |
302| `gerrit.affinity` | Assigns a Pod to the specified Nodes. For more information, please refer to the following documents. [Assign Pods to Nodes using Node Affinity](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/). [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) | {} |
303| `gerrit.additionalAnnotations` | Additional annotations for the Pods | {} |
304| `gerrit.additionalPodLabels` | Additional labels for Pods | `{}` |
305| `gerrit.replicas` | Number of replica pods to deploy | `1` |
306| `gerrit.updatePartition` | Ordinal at which to start updating pods. Pods with a lower ordinal will not be updated. | `0` |
307| `gerrit.resources` | Configure the amount of resources the pod requests/is allowed | `requests.cpu: 1` |
308| | | `requests.memory: 5Gi` |
309| | | `limits.cpu: 1` |
310| | | `limits.memory: 6Gi` |
311| `gerrit.persistence.enabled` | Whether to persist the Gerrit site | `true` |
312| `gerrit.persistence.size` | Storage size for persisted Gerrit site | `10Gi` |
313| `gerrit.probeScheme` | Scheme for probes, for example HTTPS | `nil` |
314| `gerrit.livenessProbe` | Configuration of the liveness probe timings | `{initialDelaySeconds: 30, periodSeconds: 5}` |
315| `gerrit.readinessProbe` | Configuration of the readiness probe timings | `{initialDelaySeconds: 5, periodSeconds: 1}` |
316| `gerrit.startupProbe` | Configuration of the startup probe timings | `{initialDelaySeconds: 10, periodSeconds: 5}` |
317| `gerrit.gracefulStopTimeout` | Time in seconds Kubernetes will wait until killing the pod during termination (has to be longer then Gerrit's httpd.gracefulStopTimeout to allow graceful shutdown of Gerrit) | `90` |
318| `gerrit.networkPolicy.ingress` | Custom ingress-network policy for gerrit pods | `nil` |
319| `gerrit.networkPolicy.egress` | Custom egress-network policy for gerrit pods | `nil` |
320| `gerrit.service.additionalAnnotations` | Additional annotations for the Service | `{}` |
321| `gerrit.service.loadBalancerSourceRanges` | The list of allowed IPs for the Service | `[]` |
322| `gerrit.service.type` | Which kind of Service to deploy | `NodePort` |
323| `gerrit.service.externalTrafficPolicy` | Specify how traffic from external is handled | `Cluster` |
324| `gerrit.service.http.port` | Port over which to expose HTTP | `80` |
325| `gerrit.service.ssh.enabled` | Whether to enable SSH | `false` |
326| `gerrit.service.ssh.port` | Port over which to expose SSH | `29418` |
327| `gerrit.keystore` | base64-encoded Java keystore (`cat keystore.jks \| base64`) to be used by Gerrit, when using SSL | `nil` |
328| `gerrit.index.type` | Index type used by Gerrit (either `lucene` or `elasticsearch`) | `lucene` |
329| `gerrit.pluginManagement.plugins` | List of Gerrit plugins to install | `[]` |
330| `gerrit.pluginManagement.plugins[0].name` | Name of plugin | `nil` |
331| `gerrit.pluginManagement.plugins[0].url` | Download url of plugin. If given the plugin will be downloaded, otherwise it will be installed from the gerrit.war-file. | `nil` |
332| `gerrit.pluginManagement.plugins[0].sha1` | SHA1 sum of plugin jar used to ensure file integrity and version (optional) | `nil` |
333| `gerrit.pluginManagement.plugins[0].installAsLibrary` | Whether the plugin should be symlinked to the lib-dir in the Gerrit site. | `nil` |
334| `gerrit.pluginManagement.libs` | List of Gerrit library modules to install | `[]` |
335| `gerrit.pluginManagement.libs[0].name` | Name of the lib module | `nil` |
336| `gerrit.pluginManagement.libs[0].url` | Download url of lib module. | `nil` |
337| `gerrit.pluginManagement.libs[0].sha1` | SHA1 sum of plugin jar used to ensure file integrity and version | `nil` |
338| `gerrit.pluginManagement.cache.enabled` | Whether to cache downloaded plugins | `false` |
339| `gerrit.pluginManagement.cache.size` | Size of the volume used to store cached plugins | `1Gi` |
340| `gerrit.priorityClassName` | Name of the PriorityClass to apply to the master pod | `nil` |
341| `gerrit.etc.config` | Map of config files (e.g. `gerrit.config`) that will be mounted to `$GERRIT_SITE/etc`by a ConfigMap | `{gerrit.config: ..., replication.config: ...}`[see here](#Gerrit-config-files) |
342| `gerrit.etc.secret` | Map of config files (e.g. `secure.config`) that will be mounted to `$GERRIT_SITE/etc`by a Secret | `{secure.config: ...}` [see here](#Gerrit-config-files) |
343| `gerrit.additionalConfigMaps` | Allows to mount additional ConfigMaps into a subdirectory of `$SITE/data` | `[]` |
344| `gerrit.additionalConfigMaps[*].name` | Name of the ConfigMap | `nil` |
345| `gerrit.additionalConfigMaps[*].subDir` | Subdirectory under `$SITE/data` into which the files should be symlinked | `nil` |
346| `gerrit.additionalConfigMaps[*].data` | Data of the ConfigMap. If not set, ConfigMap has to be created manually | `nil` |
347
348### Gerrit config files
349
350The gerrit chart provides a ConfigMap containing the configuration files
351used by Gerrit, e.g. `gerrit.config` and a Secret containing sensitive configuration
352like the `secure.config` to configure the Gerrit installation in the Gerrit
353component. The content of the config files can be set in the `values.yaml` under
354the keys `gerrit.etc.config` and `gerrit.etc.secret` respectively.
355The key has to be the filename (eg. `gerrit.config`) and the file's contents
356the value. This way an arbitrary number of configuration files can be loaded into
357the `$GERRIT_SITE/etc`-directory, e.g. for plugins.
358All configuration options for Gerrit are described in detail in the
359[official documentation of Gerrit](https://gerrit-review.googlesource.com/Documentation/config-gerrit.html).
360Some options however have to be set in a specified way for Gerrit to work as
361intended with the chart:
362
363- `gerrit.basePath`
364
365 Path to the directory containing the repositories. The chart mounts this
366 directory from a persistent volume to `/var/gerrit/git` in the container. For
367 Gerrit to find the correct directory, this has to be set to `git`.
368
369- `gerrit.serverId`
370
371 In Gerrit-version higher than 2.14 Gerrit needs a server ID, which is used by
372 NoteDB. Gerrit would usually generate a random ID on startup, but since the
373 gerrit.config file is read only, when mounted as a ConfigMap this fails.
374 Thus the server ID has to be set manually!
375
376- `gerrit.canonicalWebUrl`
377
378 The canonical web URL has to be set to the Ingress host.
379
380- `httpd.listenURL`
381
382 This has to be set to `proxy-http://*:8080/` or `proxy-https://*:8080`,
383 depending of TLS is enabled in the Ingress or not, otherwise the Jetty
384 servlet will run into an endless redirect loop.
385
386- `httpd.gracefulStopTimeout` / `sshd.gracefulStopTimeout`
387
388 To enable graceful shutdown of the embedded jetty server and SSHD, a timeout
389 has to be set with this option. This will be the maximum time, Gerrit will wait
390 for HTTP requests to finish before shutdown.
391
392- `container.user`
393
394 The technical user in the Gerrit container is called `gerrit`. Thus, this
395 value is required to be `gerrit`.
396
397- `container.javaHome`
398
399 This has to be set to `/usr/lib/jvm/java-11-openjdk-amd64`, since this is
400 the path of the Java installation in the container.
401
402- `container.javaOptions`
403
404 The maximum heap size has to be set. And its value has to be lower than the
405 memory resource limit set for the container (e.g. `-Xmx4g`). In your calculation,
406 allow memory for other components running in the container.
407
408To enable liveness- and readiness probes, the healthcheck plugin will be installed
409by default. Note, that by configuring to use a packaged or downloaded version of
410the healthcheck plugin, the configured version will take precedence over the default
411version. The plugin is by default configured to disable the `querychanges` and
412`auth` healthchecks, since these would not work on a new and empty Gerrit server.
413The default configuration can be overwritten by adding the `healthcheck.config`
414file as a key-value pair to `gerrit.etc.config` as for every other configuration.
415
416SSH keys should be configured via the helm-chart using the `gerrit.etc.secret`
417map. Gerrit will create its own keys, if none are present in the site, but if
418multiple Gerrit pods are running, each Gerrit instance would have its own keys.
419Users accessing Gerrit via a load balancer would get issues due to changing
420host keys.
421
422### Installing Gerrit plugins
423
424There are several different ways to install plugins for Gerrit:
425
426- **RECOMMENDED: Package the plugins to install into the WAR-file containing Gerrit.**
427 This method provides the most stable way to install plugins, but requires to
428 use a custom built gerrit-war file and container images, if plugins are required
429 that are not part of the official `release.war`-file.
430
431- **Download and cache plugins.** The chart supports downloading the plugin files and
432 to cache them in a separate volume, that is shared between Gerrit-pods. SHA1-
433 sums are used to validate plugin-files and versions.
434
435- **Download plugins, but do not cache them.** This should only be used during
436 development to save resources (the shared volume). Each pod will download the
437 plugin-files on its own. Pods will fail to start up, if the download-URL is
438 not valid anymore at some point in time.
439
440## Upgrading the Chart
441
442To upgrade an existing installation of the gerrit chart, e.g. to install
443a newer chart version or to use an updated custom `values.yaml`-file, execute
444the following command:
445
446```sh
447cd $(git rev-parse --show-toplevel)/helm-charts
448helm upgrade \
449 <release-name> \
450 ./gerrit \ # path to chart
451 -f <path-to-custom-values>.yaml
452```
453
454## Uninstalling the Chart
455
456To delete the chart from the cluster, use:
457
458```sh
459helm delete <release-name>
460```