Allow replication of project creation/deletion/HEAD update

The apache-git-http-backend now simulates the Gerrit REST API to
the extend that it allows the replication of creation/deletion/HEAD
updates.

The /new path is deprecated but can still be used for now.

Change-Id: I30fb156cfe1bb7ddbd0a9d4cb47e2c887f4668b0
diff --git a/container-images/apache-git-http-backend/Dockerfile b/container-images/apache-git-http-backend/Dockerfile
index 756cd9d..cee6f40 100644
--- a/container-images/apache-git-http-backend/Dockerfile
+++ b/container-images/apache-git-http-backend/Dockerfile
@@ -20,6 +20,7 @@
 
 COPY tools/start /var/tools/start
 COPY tools/create_repo.sh /var/cgi/create_repo.sh
+COPY tools/project_admin.sh /var/cgi/project_admin.sh
 
 RUN mkdir -p /var/gerrit/git && \
     mkdir -p /var/log/apache2 && \
diff --git a/container-images/apache-git-http-backend/README.md b/container-images/apache-git-http-backend/README.md
index bb31024..4e66244 100644
--- a/container-images/apache-git-http-backend/README.md
+++ b/container-images/apache-git-http-backend/README.md
@@ -10,7 +10,9 @@
 * Apache configurations for http
 * git (via base image) and git-deamon for git-http-backend
 * `tools/create_repo.sh`: cgi script to enable remote creation of new git
- repository over http.
+ repository over http. (deprecated)
+* `tools/project_admin.sh`: cgi script to enable remote creation/deletion/HEAD update
+  of git repositories. Compatible with replication plugin.
 * `tools/start`: start script, configures and starts Apache
  webserver
 
@@ -18,7 +20,7 @@
 
 * install Apache webserver, additional Apache tools and git daemon
 * configure Apache
-* install cgi script
+* install cgi scripts
 * map volumes
 
 ## Start
diff --git a/container-images/apache-git-http-backend/config/git-http-backend.conf b/container-images/apache-git-http-backend/config/git-http-backend.conf
index e16ebe5..b3fa53b 100644
--- a/container-images/apache-git-http-backend/config/git-http-backend.conf
+++ b/container-images/apache-git-http-backend/config/git-http-backend.conf
@@ -15,6 +15,7 @@
   SetEnv GIT_HTTP_EXPORT_ALL
   ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
   ScriptAliasMatch "(?i)^/new/(.*)" "/var/cgi/create_repo.sh"
+  ScriptAliasMatch "(?i)^/a/projects/(.*)" "/var/cgi/project_admin.sh"
   ScriptLog logs/cgi.log
 
   Alias /git /var/gerrit/git
@@ -49,4 +50,10 @@
     AuthUserFile /var/apache/credentials/.htpasswd
     Require valid-user
   </Files>
+  <Files "project_admin.sh">
+    AuthType Basic
+    AuthName "Restricted Content"
+    AuthUserFile /var/apache/credentials/.htpasswd
+    Require valid-user
+  </Files>
 </VirtualHost>
diff --git a/container-images/apache-git-http-backend/tools/create_repo.sh b/container-images/apache-git-http-backend/tools/create_repo.sh
index 080d9e4..e136b9f 100755
--- a/container-images/apache-git-http-backend/tools/create_repo.sh
+++ b/container-images/apache-git-http-backend/tools/create_repo.sh
@@ -1,5 +1,10 @@
 #!/bin/ash
 
+#####################################################################################
+# DEPRECATED
+# Use project_admin.sh instead, which is fully compatible with the replciation plugin
+#####################################################################################
+
 echo "Content-type: text/html"
 REPO=${REQUEST_URI##/new/}
 
diff --git a/container-images/apache-git-http-backend/tools/project_admin.sh b/container-images/apache-git-http-backend/tools/project_admin.sh
new file mode 100755
index 0000000..abb4bcf
--- /dev/null
+++ b/container-images/apache-git-http-backend/tools/project_admin.sh
@@ -0,0 +1,65 @@
+#!/bin/ash
+
+delete() {
+    rm -rf /var/gerrit/git/${REPO}.git
+
+    if ! test -f /var/gerrit/git/${REPO}.git; then
+        STATUS_CODE="204 No Content"
+        MESSAGE="Repository ${REPO} deleted."
+    else
+        MESSAGE="Repository ${REPO} could not be deleted."
+    fi
+}
+
+new() {
+    if test -d /var/gerrit/git/${REPO}.git; then
+        STATUS_CODE="200 OK"
+        MESSAGE="Repository already available."
+    else
+        git init --bare /var/gerrit/git/${REPO}.git > /dev/null
+        if test -f /var/gerrit/git/${REPO}.git/HEAD; then
+            STATUS_CODE="201 Created"
+            MESSAGE="Repository ${REPO} created."
+        else
+            MESSAGE="Repository ${REPO} could not be created."
+        fi
+    fi
+}
+
+update_head(){
+    read -n ${CONTENT_LENGTH} POST_STRING
+    NEW_HEAD=$(echo ${POST_STRING} | jq .ref - | tr -d '"')
+
+    git --git-dir /var/gerrit/git/${REPO}.git symbolic-ref HEAD ${NEW_HEAD}
+
+    if test "ref: ${NEW_HEAD}" == "$(cat /var/gerrit/git/${REPO}.git/HEAD)"; then
+        STATUS_CODE="200 OK"
+        MESSAGE="Repository HEAD updated to ${NEW_HEAD}."
+    else
+        MESSAGE="Repository HEAD could not be updated to ${NEW_HEAD}."
+    fi
+}
+
+echo "Content-type: text/html"
+REPO=${REQUEST_URI##/a/projects/}
+REPO="${REPO%%.git}"
+
+if test "${REQUEST_METHOD}" == "PUT"; then
+    if [[ ${REQUEST_URI} == */HEAD ]]; then
+        REPO=${REPO%"/HEAD"}
+        update_head
+    else
+        new
+    fi
+elif test "${REQUEST_METHOD}" == "DELETE"; then
+    delete
+else
+    STATUS_CODE="400 Bad Request"
+    MESSAGE="Unknown method."
+fi
+
+test -z ${STATUS_CODE} && STATUS_CODE="500 Internal Server Error"
+
+echo "Status: ${STATUS_CODE}"
+echo ""
+echo "${MESSAGE}"
diff --git a/helm-charts/gerrit-replica/README.md b/helm-charts/gerrit-replica/README.md
index 31ca693..c7f6e6b 100644
--- a/helm-charts/gerrit-replica/README.md
+++ b/helm-charts/gerrit-replica/README.md
@@ -335,6 +335,10 @@
 At least one endpoint (HTTP and/or HTTPS) has to be enabled in the service!
 ***
 
+Project creation, project deletion and HEAD update can also replicated. To enable
+this feature configure the replication plugin to use an adminUrl using the format
+`gerrit+https://<apache-git-http-backend host>`.
+
 ### Git garbage collection
 
 | Parameter | Description | Default |
diff --git a/helm-charts/gerrit-replica/templates/ingress.yaml b/helm-charts/gerrit-replica/templates/ingress.yaml
index ee36cdf..d34af05 100644
--- a/helm-charts/gerrit-replica/templates/ingress.yaml
+++ b/helm-charts/gerrit-replica/templates/ingress.yaml
@@ -29,6 +29,13 @@
     http:
       paths:
       - pathType: Prefix
+        path: /a/projects
+        backend:
+          service:
+            name: {{ .Release.Name }}-git-backend-service
+            port:
+              number: {{ .Values.gitBackend.service.http.port }}
+      - pathType: Prefix
         path: /new
         backend:
           service:
diff --git a/helm-charts/gerrit-replica/templates/istio.ingressgateway.yaml b/helm-charts/gerrit-replica/templates/istio.ingressgateway.yaml
index 02a2ebd..fae7e6b 100644
--- a/helm-charts/gerrit-replica/templates/istio.ingressgateway.yaml
+++ b/helm-charts/gerrit-replica/templates/istio.ingressgateway.yaml
@@ -84,6 +84,8 @@
         prefix: /git/
     - uri:
         prefix: /new/
+    - uri:
+        prefix: /a/projects/
     route:
     - destination:
         host: {{ .Release.Name }}-git-backend-service.{{ .Release.Namespace }}.svc.cluster.local