Add GitLab and GitLab Runner.

Change-Id: Iaf9bbf4567db2ee7c5b36c6be767825093a2881d
diff --git a/gitlab-system/gitlab-runner/.gitignore b/gitlab-system/gitlab-runner/.gitignore
new file mode 100644
index 0000000..91cc9ca
--- /dev/null
+++ b/gitlab-system/gitlab-runner/.gitignore
@@ -0,0 +1 @@
+/config.toml
diff --git a/gitlab-system/gitlab-runner/default.nix b/gitlab-system/gitlab-runner/default.nix
new file mode 100644
index 0000000..e98d43f
--- /dev/null
+++ b/gitlab-system/gitlab-runner/default.nix
@@ -0,0 +1,89 @@
+{ system ? builtins.currentSystem }:
+let
+  pkgs = import <nixpkgs> {
+    inherit system;
+    overlays = [
+      (self: super: {
+        docker = super.docker.override {
+          iptables = self.iptables-legacy;
+        };
+      })
+    ];
+  };
+
+in
+let
+  img = spec: {
+    streamed = pkgs.dockerTools.streamLayeredImage spec;
+    layered = pkgs.dockerTools.buildLayeredImage spec;
+    image = pkgs.dockerTools.buildImage spec;
+  };
+
+in
+let
+  init =
+    pkgs.writeShellScriptBin "init" ''
+      set -xeuo pipefail
+
+      if ! [ -e /vol/docker-data/docker.ext4 ]; then
+          ${pkgs.busybox}/bin/dd if=/dev/zero of=/vol/docker-data/docker.ext4 bs=1G count=0 seek=30
+          ${pkgs.e2fsprogs}/bin/mkfs.ext4 /vol/docker-data/docker.ext4
+      fi
+      ${pkgs.e2fsprogs}/bin/e2fsck -y /vol/docker-data/docker.ext4
+      ${pkgs.busybox}/bin/mkdir -p /var/lib/docker
+      ${pkgs.busybox}/bin/mount -o loop,rw /vol/docker-data/docker.ext4 /var/lib/docker
+
+      ${pkgs.docker}/bin/dockerd --storage-driver=overlay2 &
+      sleep 10s
+
+      ${pkgs.docker}/bin/docker kill $(${pkgs.docker}/bin/docker ps -a -q) || :
+      ${pkgs.docker}/bin/docker system prune --volumes --force || :
+
+      exec ${pkgs.gitlab-runner}/bin/gitlab-runner run
+    '';
+
+  src = ./.;
+
+  extraDeps = with pkgs; [
+    # for Docker
+    cacert
+
+    # for GitLab runner
+    docker
+  ];
+
+  maintenanceDeps = with pkgs; [
+    bash
+    busybox
+    coreutils
+    findutils
+    pxattr
+    strace
+  ];
+
+in
+img {
+  name = "docker.benkard.de/mulk/gitlab-runner";
+  #tag = "latest";
+  maxLayers = 125;
+  contents = extraDeps ++ maintenanceDeps;
+  extraCommands =
+    ''
+      #!${pkgs.runtimeShell}
+
+      install -dm755 etc/gitlab-runner
+      install -dm755 vol/docker-data
+      install -dm755 tmp
+
+      cp -a ${src}/* .
+    '';
+  config = {
+    Entrypoint = [ "${init}/bin/init" ];
+    Cmd = [ ];
+    Workdir = "/";
+    Volumes = {
+      "/etc/gitlab-runner" = { };
+      "/vol/docker-data" = { };
+    };
+  };
+}
diff --git a/gitlab-system/gitlab-runner/gitlab-runner.yaml b/gitlab-system/gitlab-runner/gitlab-runner.yaml
new file mode 100644
index 0000000..c562d69
--- /dev/null
+++ b/gitlab-system/gitlab-runner/gitlab-runner.yaml
@@ -0,0 +1,88 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: gitlab-runner
+  namespace: mulk
+  labels:
+    name: gitlab-runner
+    k8s-app: gitlab-runner
+
+spec:
+  replicas: 1
+
+  strategy:
+    rollingUpdate:
+      maxSurge: 1
+      maxUnavailable: 1
+
+  selector:
+    matchLabels:
+      k8s-app: gitlab-runner
+      name: gitlab-runner
+
+  template:
+    metadata:
+      labels:
+        name: gitlab-runner
+        k8s-app: gitlab-runner
+
+    spec:
+      imagePullSecrets:
+        - name: portus-token
+
+      runtimeClassName: kata
+
+      containers:
+        - name: master
+          image: docker.benkard.de/mulk/gitlab-runner:miyj7qdmgdbbqk7zkj3wdq0ld9zxdk2z
+
+          securityContext:
+            # In a Kata container, this only gives the container full
+            # access to the guest VM rather than the host.  (To ensure
+            # this, it is important to set privileged_without_host_devices
+            # = true in the [plugins.cri.containerd.runtimes.kata] section
+            # of containerd's config.toml.)
+            privileged: true
+
+          volumeMounts:
+            # Configuration data.
+            - name: config
+              mountPath: /etc/gitlab-runner
+
+            # State.
+            - name: docker-data
+              mountPath: /vol/docker-data
+            - name: tmp
+              mountPath: /tmp
+
+          resources:
+            limits:
+              memory: 4G
+
+      volumes:
+        - name: config
+          secret:
+            secretName: gitlab-runner-config
+        - name: docker-data
+          persistentVolumeClaim:
+            claimName: gitlab-runner-docker
+        - name: tmp
+          emptyDir: {}
+
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: gitlab-runner-docker
+  namespace: mulk
+  annotations:
+    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
+    volume.kubernetes.io/selected-node: ifirn
+spec:
+  storageClassName: local-path
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 1Gi
diff --git a/gitlab-system/gitlab.yaml b/gitlab-system/gitlab.yaml
new file mode 100644
index 0000000..a262412
--- /dev/null
+++ b/gitlab-system/gitlab.yaml
@@ -0,0 +1,175 @@
+apiVersion: apps.gitlab.com/v1beta1
+kind: GitLab
+metadata:
+  name: gitlab
+  namespace: gitlab-system
+spec:
+  chart:
+    version: "6.7.1"
+    values:
+      global:
+        appConfig:
+          incomingEmail:
+            enabled: true
+            address: gitlab@benkard.de
+            user: gitlab@benkard.de
+            host: mail.benkard.de
+            startTls: true
+            port: 143
+            ssl: false
+            #host: mailcow.mulk.svc.cluster.local.
+            password:
+              secret: gitlab-infrastructure
+              key: email-password
+          omniauth:
+            enabled: true
+            syncProfileAttributes: ['email']
+            allowSingleSignOn: []
+            blockAutoCreatedUsers: true
+            autoLinkUser: ['openid_connect']
+            externalProviders: ['github']
+            allowBypassTwoFactor: []
+            providers:
+              - secret: gitlab-keycloak
+              - secret: gitlab-github
+        edition: ce
+        #deployment:
+        #  strategy:
+        #    type: Recreate
+        email:
+          display_name: Benkard GitLab
+          from: gitlab@benkard.de
+          reply_to: gitlab@benkard.de
+        smtp:
+          enabled: true
+          address: mail.benkard.de
+          tls: false
+          starttls_auto: true
+          port: 587
+          #address: mailcow.mulk.svc.cluster.local.
+          #tls: false
+          authentication: plain
+          user_name: gitlab@benkard.de
+          password:
+            secret: gitlab-infrastructure
+            key: email-password
+        hosts:
+          domain: gitlab.benkard.de
+          gitlab:
+            name: gitlab.benkard.de
+          ssh: gitlab.benkard.de
+        hpa:
+          minReplicas: 1
+          maxReplicas: 1
+        ingress:
+          configureCertmanager: false
+          #class: nginx
+          class: none
+          annotations:
+            kubernetes.io/tls-acme: true
+            cert-manager.io/cluster-issuer: letsencrypt-prod
+            kubernetes.io/ingress.class: nginx
+          tls:
+            secretName: gitlab-wildcard-tls
+        #object_store:
+        #  enabled: true
+        persistence:
+          storageClass: local-path
+        psql:
+          host: postgresql.system
+          port: 5432
+          username: gitlab
+          database: gitlab
+          password:
+            secret: gitlab-infrastructure
+            key: postgresql-password
+        #redis:
+          #host: redis.system
+          #password:
+          #  secret: gitlab-infrastructure
+          #  key: redis-password
+        shell:
+          port: 22022
+
+      certmanager:
+        install: false
+
+      certmanager-issuer:
+        email: id+acme@mulk.eu
+
+      gitlab:
+        gitaly:
+          persistence:
+            storageClass: local-path
+        gitlab-shell:
+          #replicaCount: 1
+          minReplicas: 1
+          maxReplicas: 1
+          service:
+            type: NodePort
+            nodePort: 22022
+        kas:
+          ingress:
+            tls:
+              secretName: gitlab-kas-tls
+          minReplicas: 1
+          maxReplicas: 1
+        sidekiq:
+          #replicas: 1
+          minReplicas: 1
+          maxReplicas: 1
+        toolbox:
+          backups:
+            cron:
+              persistence:
+                storageClass: local-path
+          persistence:
+            storageClass: local-path
+        webservice:
+          #replicaCount: 1
+          workerProcesses: 1
+          resources:
+            requests:
+              cpu: 1m
+              memory: 100M
+          hpa:
+            minReplicas: 1
+            maxReplicas: 1
+          ingress:
+            tls:
+              secretName: gitlab-gitlab-tls
+#          deployment:
+#            strategy:
+#              type: Recreate
+#          deployments:
+#            default:
+#              hpa:
+#                minReplicas: 1
+#                maxReplicas: 1
+#              workerProcesses: 1
+
+      minio:
+        persistence:
+          storageClass: local-path
+        replicas: 1
+        ingress:
+          tls:
+            secretName: gitlab-minio-tls
+
+      nginx-ingress:
+        enabled: false
+
+      postgresql:
+        install: false
+
+      #redis:
+      #  install: false
+
+      registry:
+        ingress:
+          tls:
+            secretName: gitlab-registry-tls
+        hpa:
+          minReplicas: 1
+          maxReplicas: 1
+
diff --git a/images.nix b/images.nix
index cc6f495..137b4e8 100644
--- a/images.nix
+++ b/images.nix
@@ -54,6 +54,8 @@
 
   mailcow = pkgs.callPackage ./mailcow/default.nix { };
 
+  gitlab-runner = pkgs.callPackage ./gitlab-system/gitlab-runner/default.nix { };
+
   nextcloud = img {
     name = "docker.benkard.de/mulk/nextcloud";
     contents =