app/{gerrit,bazel-cache} -> devtools/
Change-Id: I2a98f33c76a59392e644579a1f7064a7c8eaec7c
diff --git a/devtools/gerrit/kube/gerrit.libsonnet b/devtools/gerrit/kube/gerrit.libsonnet
new file mode 100644
index 0000000..e36c7fa
--- /dev/null
+++ b/devtools/gerrit/kube/gerrit.libsonnet
@@ -0,0 +1,212 @@
+local kube = import "../../../kube/kube.libsonnet";
+
+{
+ local gerrit = self,
+ local cfg = gerrit.cfg,
+
+ cfg:: {
+ namespace: error "namespace must be set",
+ appName: "gerrit",
+ prefix: "", # if set, should be 'foo-'
+ domain: error "domain must be set",
+ identity: error "identity (UUID) must be set",
+
+ // The secret must contain a key named 'secure.config' containing (at least):
+ // [auth]
+ // registerEmailPrivateKey = <random>
+ // [plugin "gerrit-oauth-provider-warsawhackerspace-oauth"]
+ // client-id = foo
+ // client-secret = bar
+ // [sendemail]
+ // smtpPass = foo
+ // [receiveemail]
+ // password = bar
+ secureSecret: error "secure secret name must be set",
+
+ storageClass: error "storage class must be set",
+ storageSize: {
+ git: "50Gi", // Main storage for repositories and NoteDB.
+ index: "10Gi", // Secondary Lucene index
+ cache: "10Gi", // H2 cache databases
+ db: "1Gi", // NoteDB is used, so database is basically empty (H2 accountPatchReviewDatabase)
+ etc: "1Gi", // Random site stuff.
+ },
+
+ email: {
+ server: "mail.hackerspace.pl",
+ username: "gerrit",
+ address: "gerrit@hackerspace.pl",
+ },
+
+ tag: "3.0.0-r7",
+ image: "registry.k0.hswaw.net/devtools/gerrit:" + cfg.tag,
+ resources: {
+ requests: {
+ cpu: "100m",
+ memory: "500Mi",
+ },
+ limits: {
+ cpu: "1",
+ memory: "2Gi",
+ },
+ },
+ },
+
+ name(suffix):: cfg.prefix + suffix,
+
+ metadata(component):: {
+ namespace: cfg.namespace,
+ labels: {
+ "app.kubernetes.io/name": cfg.appName,
+ "app.kubernetes.io/managed-by": "kubecfg",
+ "app.kubernetes.io/component": "component",
+ },
+ },
+
+ configmap: kube.ConfigMap(gerrit.name("gerrit")) {
+ metadata+: gerrit.metadata("configmap"),
+ data: {
+ "gerrit.config": |||
+ [gerrit]
+ basePath = git
+ canonicalWebUrl = https://%(domain)s/
+ serverId = %(identity)s
+
+ [sshd]
+ advertisedAddress = %(domain)s
+
+ [container]
+ javaOptions = -Djava.security.edg=file:/dev/./urandom
+
+ [auth]
+ type = OAUTH
+ gitBasicAuthPolicy = HTTP
+
+ [httpd]
+ listenUrl = proxy-http://*:8080
+
+ [sshd]
+ advertisedAddress = %(domain)s
+
+ [user]
+ email = %(emailAddress)s
+
+ [sendemail]
+ enable = true
+ from = MIXED
+ smtpServer = %(emailServer)s
+ smtpServerPort = 465
+ smtpEncryption = ssl
+ smtpUser = %(emailUser)s
+
+ [receiveemail]
+ protocol = IMAP
+ host = %(emailServer)s
+ username = %(emailUser)s
+ encryption = TLS
+ enableImapIdle = true
+
+ ||| % {
+ domain: cfg.domain,
+ identity: cfg.identity,
+ emailAddress: cfg.email.address,
+ emailServer: cfg.email.server,
+ emailUser: cfg.email.username,
+ },
+ },
+ },
+
+ volumes: {
+ [name]: kube.PersistentVolumeClaim(gerrit.name(name)) {
+ metadata+: gerrit.metadata("storage"),
+ spec+: {
+ storageClassName: cfg.storageClassName,
+ accessModes: ["ReadWriteOnce"],
+ resources: {
+ requests: {
+ storage: cfg.storageSize[name],
+ },
+ },
+ },
+ }
+ for name in ["etc", "git", "index", "cache", "db"]
+ },
+
+ local volumeMounts = {
+ [name]: { mountPath: "/var/gerrit/%s" % name }
+ for name in ["etc", "git", "index", "cache", "db"]
+ } {
+ // ConfigMap gets mounted here
+ config: { mountPath: "/var/gerrit-config" },
+ // SecureSecret gets mounted here
+ secure: { mountPath: "/var/gerrit-secure" },
+ },
+ deployment: kube.Deployment(gerrit.name("gerrit")) {
+ metadata+: gerrit.metadata("deployment"),
+ spec+: {
+ replicas: 1,
+ template+: {
+ spec+: {
+ securityContext: {
+ fsGroup: 1000, # gerrit uid
+ },
+ volumes_: {
+ config: kube.ConfigMapVolume(gerrit.configmap),
+ secure: { secret: { secretName: cfg.secureSecret} },
+ } {
+ [name]: kube.PersistentVolumeClaimVolume(gerrit.volumes[name])
+ for name in ["etc", "git", "index", "cache", "db"]
+ },
+ containers_: {
+ gerrit: kube.Container(gerrit.name("gerrit")) {
+ image: cfg.image,
+ ports_: {
+ http: { containerPort: 8080 },
+ ssh: { containerPort: 29418 },
+ },
+ resources: cfg.resources,
+ volumeMounts_: volumeMounts,
+ },
+ },
+ },
+ },
+ },
+ },
+
+ svc: kube.Service(gerrit.name("gerrit")) {
+ metadata+: gerrit.metadata("service"),
+ target_pod:: gerrit.deployment.spec.template,
+ spec+: {
+ ports: [
+ { name: "http", port: 80, targetPort: 8080, protocol: "TCP" },
+ { name: "ssh", port: 22, targetPort: 29418, protocol: "TCP" },
+ ],
+ type: "ClusterIP",
+ },
+ },
+
+ ingress: kube.Ingress(gerrit.name("gerrit")) {
+ metadata+: gerrit.metadata("ingress") {
+ annotations+: {
+ "kubernetes.io/tls-acme": "true",
+ "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
+ "nginx.ingress.kubernetes.io/proxy-body-size": "0",
+ },
+ },
+ spec+: {
+ tls: [
+ { hosts: [cfg.domain], secretName: gerrit.name("acme") },
+ ],
+ rules: [
+ {
+ host: cfg.domain,
+ http: {
+ paths: [
+ { path: "/", backend: gerrit.svc.name_port },
+ ],
+ },
+ }
+ ],
+ },
+ },
+}
diff --git a/devtools/gerrit/kube/prod.jsonnet b/devtools/gerrit/kube/prod.jsonnet
new file mode 100644
index 0000000..565772f
--- /dev/null
+++ b/devtools/gerrit/kube/prod.jsonnet
@@ -0,0 +1,19 @@
+local kube = import "../../../kube/kube.libsonnet";
+local gerrit = import "gerrit.libsonnet";
+{
+ namespace: kube.Namespace("gerrit"),
+
+ gerrit: gerrit {
+ cfg+: {
+ namespace: "gerrit",
+ prefix: "",
+
+ domain: "gerrit.hackerspace.pl",
+ identity: "7b6244cf-e30b-42c5-ba91-c329ef4e6cf1",
+
+ storageClassName: "waw-hdd-redundant-1",
+
+ secureSecret: "gerrit",
+ },
+ },
+}