Configure gerrit-init.py script with a config file
The gerrit-init.py script was configured with parameters. That was hard
to track and sharing configuration between scripts was difficult.
This change adds a configmap to the helm charts that contains the
configuration for the gerrit-init script.
Change-Id: Id42b64fce7bdea209067442383b2f06f02d95572
diff --git a/container-images/gerrit-init/Dockerfile b/container-images/gerrit-init/Dockerfile
index a1a6dd1..9049214 100644
--- a/container-images/gerrit-init/Dockerfile
+++ b/container-images/gerrit-init/Dockerfile
@@ -2,13 +2,23 @@
USER root
-COPY tools/* /var/tools/
+COPY dependencies/* /var/tools/
WORKDIR /var/tools
RUN apk update && \
apk add --no-cache \
- python3
+ python3 && \
+ python3 -m ensurepip && \
+ rm -r /usr/lib/python*/ensurepip && \
+ pip3 install --no-cache --upgrade pip setuptools wheel pipenv && \
+ pipenv install --python 3.7.3 --system
+
+COPY tools/* /var/tools/
+COPY config/* /var/config/
+
+COPY tools/* /var/tools/
USER gerrit
ENTRYPOINT ["/var/tools/gerrit_init.py", "-s", "/var/gerrit"]
+CMD ["-c", "/var/config/default.config.yaml"]
diff --git a/container-images/gerrit-init/config/default.config.yaml b/container-images/gerrit-init/config/default.config.yaml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/container-images/gerrit-init/config/default.config.yaml
diff --git a/container-images/gerrit-init/dependencies/Pipfile b/container-images/gerrit-init/dependencies/Pipfile
new file mode 100644
index 0000000..32dcbb1
--- /dev/null
+++ b/container-images/gerrit-init/dependencies/Pipfile
@@ -0,0 +1,12 @@
+[[source]]
+name = "pypi"
+url = "https://pypi.org/simple"
+verify_ssl = true
+
+[dev-packages]
+
+[packages]
+pyyaml = "~=5.1.1"
+
+[requires]
+python_version = "3.7"
diff --git a/container-images/gerrit-init/dependencies/Pipfile.lock b/container-images/gerrit-init/dependencies/Pipfile.lock
new file mode 100644
index 0000000..4196274
--- /dev/null
+++ b/container-images/gerrit-init/dependencies/Pipfile.lock
@@ -0,0 +1,40 @@
+{
+ "_meta": {
+ "hash": {
+ "sha256": "4c5889e94a1b967f4cf238d7c5265e62e03611deb65b66c4a77f1673505436d7"
+ },
+ "pipfile-spec": 6,
+ "requires": {
+ "python_version": "3.7"
+ },
+ "sources": [
+ {
+ "name": "pypi",
+ "url": "https://pypi.org/simple",
+ "verify_ssl": true
+ }
+ ]
+ },
+ "default": {
+ "pyyaml": {
+ "hashes": [
+ "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9",
+ "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4",
+ "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8",
+ "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696",
+ "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34",
+ "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9",
+ "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73",
+ "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299",
+ "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b",
+ "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae",
+ "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681",
+ "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41",
+ "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"
+ ],
+ "index": "pypi",
+ "version": "==5.1.2"
+ }
+ },
+ "develop": {}
+}
diff --git a/container-images/gerrit-init/tools/gerrit_init.py b/container-images/gerrit-init/tools/gerrit_init.py
index 85f4a5d..f4be415 100755
--- a/container-images/gerrit-init/tools/gerrit_init.py
+++ b/container-images/gerrit-init/tools/gerrit_init.py
@@ -20,15 +20,16 @@
import sys
from git_config_parser import GitConfigParser
+from init_config import InitConfig
from log import get_logger
LOG = get_logger("init")
class GerritInit:
- def __init__(self, site, wanted_plugins):
+ def __init__(self, site, config):
self.site = site
- self.wanted_plugins = set(wanted_plugins)
+ self.config = config
self.gerrit_config = self._parse_gerrit_config()
self.is_slave = self._is_slave()
@@ -65,7 +66,7 @@
return installed_plugins
def _remove_unwanted_plugins(self):
- for plugin in self.installed_plugins.difference(self.wanted_plugins):
+ for plugin in self.installed_plugins.difference(self.config.packaged_plugins):
LOG.info("Removing plugin %s", plugin)
os.remove(os.path.join(self.site, "plugins", "%s.jar" % plugin))
@@ -90,7 +91,7 @@
LOG.info("Reinitializing site to perform update.")
return True
- if self.wanted_plugins.difference(self.installed_plugins):
+ if self.config.packaged_plugins.difference(self.installed_plugins):
LOG.info("Reininitializing site to install additional plugins.")
return True
@@ -108,9 +109,13 @@
else:
LOG.info("No gerrit.config found. Initializing default site.")
- if self.wanted_plugins:
+ if self.config.packaged_plugins:
plugin_options = " ".join(
- ["--install-plugin %s" % plugin for plugin in self.wanted_plugins]
+ [
+ "--install-plugin %s" % plugin
+ for plugin in self.config.packaged_plugins
+ if plugin
+ ]
)
else:
plugin_options = ""
@@ -149,14 +154,16 @@
required=True,
)
parser.add_argument(
- "-p",
- "--plugin",
- help="Gerrit plugin to be installed. Can be used multiple times.",
- dest="wanted_plugins",
- action="append",
- default=list(),
+ "-c",
+ "--config",
+ help="Path to configuration file for init process.",
+ dest="config",
+ action="store",
+ required=True,
)
args = parser.parse_args()
- init = GerritInit(args.site, args.wanted_plugins)
+ config = InitConfig().parse(args.config)
+
+ init = GerritInit(args.site, config)
init.execute()
diff --git a/container-images/gerrit-init/tools/init_config.py b/container-images/gerrit-init/tools/init_config.py
new file mode 100644
index 0000000..31d9394
--- /dev/null
+++ b/container-images/gerrit-init/tools/init_config.py
@@ -0,0 +1,37 @@
+# Copyright (C) 2019 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.
+
+import os.path
+
+import yaml
+
+
+class InitConfig:
+ def __init__(self):
+ self.packaged_plugins = set()
+
+ def parse(self, config_file):
+ if not os.path.exists(config_file):
+ raise FileNotFoundError("Could not find config file: %s" % config_file)
+
+ with open(config_file, "r") as f:
+ config = yaml.load(f, Loader=yaml.SafeLoader)
+
+ if config is None:
+ raise ValueError("Invalid config-file: %s" % config_file)
+
+ if "packagedPlugins" in config:
+ self.packaged_plugins = set(config["packagedPlugins"])
+
+ return self
diff --git a/helm-charts/gerrit-master/templates/gerrit-master.configmap.yaml b/helm-charts/gerrit-master/templates/gerrit-master.configmap.yaml
index df7422d..30cddc6 100644
--- a/helm-charts/gerrit-master/templates/gerrit-master.configmap.yaml
+++ b/helm-charts/gerrit-master/templates/gerrit-master.configmap.yaml
@@ -11,4 +11,20 @@
gerrit.config: |-
{{ .Values.gerritMaster.config.gerrit | indent 4 }}
replication.config: |-
-{{ .Values.gerritMaster.config.replication | indent 4 }}
\ No newline at end of file
+{{ .Values.gerritMaster.config.replication | indent 4 }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ .Release.Name }}-gerrit-init-configmap
+ labels:
+ app: gerrit-master
+ chart: {{ template "gerrit-master.chart" . }}
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+data:
+ gerrit-init.yaml: |-
+ {{- if .Values.gerritMaster.plugins.packaged }}
+ packagedPlugins:
+{{ toYaml .Values.gerritMaster.plugins.packaged | indent 6}}
+ {{- end }}
diff --git a/helm-charts/gerrit-master/templates/gerrit-master.stateful-set.yaml b/helm-charts/gerrit-master/templates/gerrit-master.stateful-set.yaml
index 2c05a00..bfae1f6 100644
--- a/helm-charts/gerrit-master/templates/gerrit-master.stateful-set.yaml
+++ b/helm-charts/gerrit-master/templates/gerrit-master.stateful-set.yaml
@@ -73,11 +73,7 @@
fi
/var/tools/gerrit_init.py \
- {{- range .Values.gerritMaster.plugins.packaged }}
- {{- if . }}
- -p {{ . }} \
- {{- end }}
- {{- end }}
+ -c /var/config/gerrit-init.yaml \
-s /var/gerrit
symlink_config_to_site
@@ -86,6 +82,9 @@
mountPath: "/var/gerrit"
- name: git-filesystem
mountPath: "/var/mnt/git"
+ - name: gerrit-init-config
+ mountPath: "/var/config/gerrit-init.yaml"
+ subPath: gerrit-init.yaml
- name: gerrit-config
mountPath: "/var/config/gerrit.config"
subPath: gerrit.config
@@ -147,6 +146,9 @@
{{- else }}
claimName: {{ .Release.Name }}-git-filesystem-pvc
{{- end }}
+ - name: gerrit-init-config
+ configMap:
+ name: {{ .Release.Name }}-gerrit-init-configmap
- name: gerrit-config
configMap:
name: {{ .Release.Name }}-gerrit-master-configmap
diff --git a/helm-charts/gerrit-slave/templates/gerrit-slave.configmap.yaml b/helm-charts/gerrit-slave/templates/gerrit-slave.configmap.yaml
index e4f12c8..9586b6f 100644
--- a/helm-charts/gerrit-slave/templates/gerrit-slave.configmap.yaml
+++ b/helm-charts/gerrit-slave/templates/gerrit-slave.configmap.yaml
@@ -9,4 +9,18 @@
release: {{ .Release.Name }}
data:
gerrit.config: |-
-{{ .Values.gerritSlave.config.gerrit | indent 4 }}
\ No newline at end of file
+{{ .Values.gerritSlave.config.gerrit | indent 4 }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ .Release.Name }}-gerrit-init-configmap
+ labels:
+ app: gerrit-slave
+ chart: {{ template "gerrit-slave.chart" . }}
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+data:
+ gerrit-init.yaml: |-
+ packagedPlugins:
+ - singleusergroup
diff --git a/helm-charts/gerrit-slave/templates/gerrit-slave.deployment.yaml b/helm-charts/gerrit-slave/templates/gerrit-slave.deployment.yaml
index 73fd8e2..3fa2357 100644
--- a/helm-charts/gerrit-slave/templates/gerrit-slave.deployment.yaml
+++ b/helm-charts/gerrit-slave/templates/gerrit-slave.deployment.yaml
@@ -58,14 +58,17 @@
args:
- |
/var/tools/gerrit_init.py \
- -s /var/gerrit \
- -p singleusergroup
+ -c /var/config/gerrit-init.yaml \
+ -s /var/gerrit
# The git repositories will be mounted from a volume
[ -L /var/gerrit/git ] || rm -rf /var/gerrit/git
volumeMounts:
- name: gerrit-site
mountPath: "/var/gerrit"
+ - name: gerrit-init-config
+ mountPath: "/var/config/gerrit-init.yaml"
+ subPath: gerrit-init.yaml
{{- end }}
# If configured, run initialization taking the given Gerrit configuration
# and persisted volumes into account.
@@ -94,8 +97,8 @@
{{ if .Values.gerritSlave.initializeTestSite.enabled -}}
/var/tools/gerrit_init.py \
- -s /var/gerrit \
- -p singleusergroup
+ -c /var/config/gerrit-init.yaml \
+ -s /var/gerrit
symlink_config_to_site
{{- end }}
@@ -106,6 +109,9 @@
mountPath: "/var/gerrit"
- name: git-filesystem
mountPath: "/var/mnt/git"
+ - name: gerrit-init-config
+ mountPath: "/var/config/gerrit-init.yaml"
+ subPath: gerrit-init.yaml
- name: gerrit-config
mountPath: "/var/config/gerrit.config"
subPath: gerrit.config
@@ -152,6 +158,9 @@
- name: git-filesystem
persistentVolumeClaim:
claimName: {{ .Release.Name }}-git-filesystem-pvc
+ - name: gerrit-init-config
+ configMap:
+ name: {{ .Release.Name }}-gerrit-init-configmap
- name: gerrit-config
configMap:
name: {{ .Release.Name }}-gerrit-slave-configmap
diff --git a/tests/container-images/gerrit-init/test_container_integration_gerrit_init.py b/tests/container-images/gerrit-init/test_container_integration_gerrit_init.py
index 057f5ba..082ffa7 100644
--- a/tests/container-images/gerrit-init/test_container_integration_gerrit_init.py
+++ b/tests/container-images/gerrit-init/test_container_integration_gerrit_init.py
@@ -14,11 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import os.path
import re
from docker.errors import NotFound
import pytest
+import yaml
@pytest.fixture(scope="class")
@@ -44,14 +46,28 @@
@pytest.fixture(scope="class")
-def container_run_endless(docker_client, gerrit_init_image, tmp_path_factory):
- tmp_site_dir = tmp_path_factory.mktemp("gerrit_site")
+def init_config_dir(tmp_path_factory):
+ return tmp_path_factory.mktemp("init_config")
+
+
+@pytest.fixture(scope="class")
+def tmp_site_dir(tmp_path_factory):
+ return tmp_path_factory.mktemp("gerrit_site")
+
+
+@pytest.fixture(scope="class")
+def container_run_endless(
+ docker_client, gerrit_init_image, init_config_dir, tmp_site_dir
+):
container_run = docker_client.containers.run(
image=gerrit_init_image.id,
entrypoint="/bin/ash",
command=["-c", "tail -f /dev/null"],
user="gerrit",
- volumes={tmp_site_dir: {"bind": "/var/gerrit", "mode": "rw"}},
+ volumes={
+ tmp_site_dir: {"bind": "/var/gerrit", "mode": "rw"},
+ init_config_dir: {"bind": "/var/config", "mode": "rw"},
+ },
detach=True,
auto_remove=True,
)
@@ -88,52 +104,44 @@
assert container_run_default.attrs["State"]["ExitCode"] == 0
+@pytest.fixture(
+ scope="function",
+ params=[
+ ["replication", "reviewnotes"],
+ ["replication", "reviewnotes", "hooks"],
+ ["download-commands"],
+ [],
+ ],
+)
+def plugins_to_install(request):
+ return request.param
+
+
@pytest.mark.docker
@pytest.mark.incremental
@pytest.mark.integration
class TestGerritInitPluginInstallation:
- def test_gerrit_init_plugins_are_installed(self, container_run_endless):
- exit_code, _ = container_run_endless.exec_run(
- "/var/tools/gerrit_init.py -s /var/gerrit -p replication -p reviewnotes"
- )
- assert exit_code == 0
- cmd = (
- "/bin/ash -c '"
- + "test -f /var/gerrit/plugins/replication.jar && "
- + "test -f /var/gerrit/plugins/reviewnotes.jar'"
- )
- exit_code, _ = container_run_endless.exec_run(cmd)
- assert exit_code == 0
+ def _configure_packaged_plugins(self, file_path, plugins):
+ with open(file_path, "w") as f:
+ yaml.dump({"packagedPlugins": plugins}, f, default_flow_style=False)
- def test_gerrit_init_plugins_are_added_in_existing_site(
- self, container_run_endless
+ def test_gerrit_init_plugins_are_installed(
+ self, container_run_endless, init_config_dir, plugins_to_install, tmp_site_dir
):
+ self._configure_packaged_plugins(
+ os.path.join(init_config_dir, "init.yaml"), plugins_to_install
+ )
+
exit_code, _ = container_run_endless.exec_run(
- "/var/tools/gerrit_init.py -s /var/gerrit -p replication -p reviewnotes -p hooks"
+ "/var/tools/gerrit_init.py -s /var/gerrit -c /var/config/init.yaml"
)
assert exit_code == 0
- cmd = (
- "/bin/ash -c '"
- + "test -f /var/gerrit/plugins/replication.jar && "
- + "test -f /var/gerrit/plugins/reviewnotes.jar && "
- + "test -f /var/gerrit/plugins/hooks.jar'"
- )
- exit_code, _ = container_run_endless.exec_run(cmd)
- assert exit_code == 0
+ plugins_path = os.path.join(tmp_site_dir, "plugins")
- def test_gerrit_init_plugins_are_installed_in_existing_site(
- self, container_run_endless
- ):
- exit_code, _ = container_run_endless.exec_run(
- "/var/tools/gerrit_init.py -s /var/gerrit -p download-commands"
- )
- assert exit_code == 0
+ for plugin in plugins_to_install:
+ assert os.path.exists(os.path.join(plugins_path, "%s.jar" % plugin))
- cmd = "/bin/ash -c '" + "test -f /var/gerrit/plugins/download-commands.jar'"
- exit_code, _ = container_run_endless.exec_run(cmd)
- assert exit_code == 0
-
- cmd = "/bin/ash -c '" + "test -f /var/gerrit/plugins/reviewnotes.jar'"
- exit_code, _ = container_run_endless.exec_run(cmd)
- assert exit_code == 1
+ installed_plugins = os.listdir(plugins_path)
+ for plugin in installed_plugins:
+ assert os.path.splitext(plugin)[0] in plugins_to_install
diff --git a/tests/container-images/gerrit-init/test_container_structure_gerrit_init.py b/tests/container-images/gerrit-init/test_container_structure_gerrit_init.py
index 21249bc..38d37ec 100755
--- a/tests/container-images/gerrit-init/test_container_structure_gerrit_init.py
+++ b/tests/container-images/gerrit-init/test_container_structure_gerrit_init.py
@@ -26,7 +26,11 @@
@pytest.fixture(
scope="function",
- params=["/var/tools/gerrit_init.py", "/var/tools/git_config_parser.py"],
+ params=[
+ "/var/tools/gerrit_init.py",
+ "/var/tools/git_config_parser.py",
+ "/var/tools/init_config.py",
+ ],
)
def expected_script(request):
return request.param
@@ -37,6 +41,11 @@
return request.param
+@pytest.fixture(scope="function", params=["pyyaml"])
+def expected_pip_package(request):
+ return request.param
+
+
# pylint: disable=E1101
@pytest.mark.structure
def test_gerrit_init_inherits_from_gerrit_base(gerrit_init_image):
diff --git a/tests/helm-charts/gerrit-master/test_chart_gerrit_master_plugins.py b/tests/helm-charts/gerrit-master/test_chart_gerrit_master_plugins.py
index 63edd10..d4470ec 100644
--- a/tests/helm-charts/gerrit-master/test_chart_gerrit_master_plugins.py
+++ b/tests/helm-charts/gerrit-master/test_chart_gerrit_master_plugins.py
@@ -121,6 +121,7 @@
chart = gerrit_master_deployment_with_packaged_plugins
chart["removed_plugin"] = chart["installed_plugins"].pop()
plugins_opts_string = "{%s}" % (",".join(chart["installed_plugins"]))
+ plugins_opts_string = plugins_opts_string if plugins_opts_string else "false"
update_chart(
test_cluster.helm,
chart,