diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 747e768527fec27b63a5d3bb7a99a1905641a9cf..46226f170df3636e5fa8aa302c6e369cd1ab3408 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,6 @@ stages: - - steve - - build_webservice - - test_maxima + - build_server + - build variables: GIT_SUBMODULE_STRATEGY: recursive @@ -9,8 +8,8 @@ variables: # gitlab ci script taken from https://gist.github.com/danielneis/5c6140ec8150c6151a54bccd26950278 -steve_jobs: - stage: steve +build_server_binary: + stage: build_server image: golang tags: - docker @@ -21,12 +20,25 @@ steve_jobs: - bin/web expire_in: 1 week -build_webservice: +build_goemaxima_containers: image: "docker:latest" - stage: build_webservice + stage: build tags: - docker before_script: - docker login -u mathinstitut -p "$DOCKERHUB_PASS" script: - ./build.sh "$REGISTRY" "$CI_COMMIT_TAG" + +build_gitrollout: + image: "docker:latest" + stage: build + tags: + - docker + before_script: + - docker login -u mathinstitut -p "$DOCKERHUB_PASS" + script: + - docker build -t mathinstitut/gitrollout:latest git-rollout + only: + changes: + - git-rollout/** diff --git a/git-rollout/Dockerfile b/git-rollout/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..34b09fae2d8f377fa1e1bdeb3fa640e41645147f --- /dev/null +++ b/git-rollout/Dockerfile @@ -0,0 +1,10 @@ +from alpine:latest +run apk update && apk add git git-daemon jq && \ + wget "https://dl.k8s.io/release/$(wget -q -O- https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && \ + chmod a+x kubectl && \ + cp kubectl /bin/kubectl && \ + mkdir -p /git +copy update.sh /bin/update.sh +workdir /git +entrypoint ["/bin/update.sh"] + diff --git a/git-rollout/README.md b/git-rollout/README.md new file mode 100644 index 0000000000000000000000000000000000000000..bcd515d2c1239eae6361a7e86436512f67546322 --- /dev/null +++ b/git-rollout/README.md @@ -0,0 +1,13 @@ +git-rollout +=========== + +This directory contains git-rollout, a small container and kubernetes config to update +rollout new containers whenever some git repository is updated. + +At the MI, this is used to make the goemaxima containers automatically restart with new +macro files downloaded from git (see also the enableGitRollout and gitRollout values +in helmmaxima). + +It has to be in the same namespace as the goemaxima instances and looks for the label +gitrollout=goemaxima label, which is already added if you use the helmmaxima chart with +enableGitRollout value set to true. diff --git a/git-rollout/git-rollout.yml b/git-rollout/git-rollout.yml new file mode 100644 index 0000000000000000000000000000000000000000..25ed14d7ac068a6a123014340baba209c95688dd --- /dev/null +++ b/git-rollout/git-rollout.yml @@ -0,0 +1,61 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: git-rollout +rules: + - apiGroups: ["apps", "extensions"] + resources: ["deployments"] + verbs: ["get", "patch", "list"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: git-rollout +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: git-rollout +subjects: +- kind: ServiceAccount + name: git-rollout +roleRef: + kind: Role + name: git-rollout + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: git-rollout + labels: + app: git-rollout +spec: + selector: + matchLabels: + app: git-rollout + template: + metadata: + labels: + app: git-rollout + spec: + serviceAccountName: git-rollout + containers: + - name: git-rollout + image: "mathinstitut/git-rollout:latest" + imagePullPolicy: "Always" + args: ['https://github.com/eLearning-TUDarmstadt/maxima-scripts', 'gitrollout=goemaxima'] + ports: + - containerPort: 9418 +--- +apiVersion: v1 +kind: Service +metadata: + name: git-rollout +spec: + selector: + app: git-rollout + ports: + - protocol: TCP + port: 9418 + targetPort: 9418 diff --git a/git-rollout/update.sh b/git-rollout/update.sh new file mode 100755 index 0000000000000000000000000000000000000000..4c8cc353da493f51cf820037cacdc3967d1c32fa --- /dev/null +++ b/git-rollout/update.sh @@ -0,0 +1,27 @@ +#!/bin/sh +SLEEP_TIME=180 +DIR_NAME="git" +rm -rf "$DIR_NAME" +git clone "$1" "$DIR_NAME" +# required for git daemon to work on this repo +touch "$DIR_NAME/.git/git-daemon-export-ok" +git daemon --base-path="$(pwd)" --log-destination=stderr & +cd "$DIR_NAME" +while true; do + git remote update + # check whether there has been any update + if [ "$(git rev-parse @)" = "$(git rev-parse '@{u}')" ]; then + # do nothing if no update + sleep "$SLEEP_TIME" + continue + fi + # checkout latest commit + git reset --hard origin + # names of all deployments that match the labels in $2 + deployments="$(kubectl get deployment -l "$2" -o json | jq -r '.items[].metadata.name')" + # restart all those deployments + for deployment in $deployments; do + kubectl rollout restart "deployment/$deployment" + done + sleep "$SLEEP_TIME" +done diff --git a/helmmaxima/templates/deployment.yaml b/helmmaxima/templates/deployment.yaml index 4af9b554e9c059a3bcedea98a4164e0729bf5094..e44f8690822ea001a2b9a06178ca071e03c73193 100644 --- a/helmmaxima/templates/deployment.yaml +++ b/helmmaxima/templates/deployment.yaml @@ -3,6 +3,9 @@ kind: Deployment metadata: name: {{ include "helmmaxima.fullname" . }} labels: + {{ if .Values.enableGitRollout -}} + gitrollout: goemaxima + {{- end -}} {{- include "helmmaxima.labels" . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} @@ -15,6 +18,7 @@ spec: {{- include "helmmaxima.selectorLabels" . | nindent 8 }} app: {{ include "helmmaxima.fullname" . }} spec: + terminationGracePeriodSeconds: 45 {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} @@ -22,6 +26,20 @@ spec: securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} automountServiceAccountToken: false + {{ if .Values.enableGitRollout }} + initContainers: + - name: "{{ .Chart.Name }}-git" + image: "k8s.gcr.io/git-sync/git-sync:v3.6.1" + args: ['--root=/mnt', '--one-time', '--depth=1'] + volumeMounts: + - mountPath: /mnt + name: git + env: + - name: GIT_SYNC_REPO + value: "{{ .Values.gitRollout.repo }}" + - name: GIT_SYNC_BRANCH + value: "{{ .Values.gitRollout.branch }}" + {{ end }} containers: - name: {{ .Chart.Name }} securityContext: @@ -35,6 +53,10 @@ spec: volumeMounts: - mountPath: /tmp name: tmptmpfs + {{ if .Values.enableGitRollout }} + - mountPath: /mnt + name: git + {{ end }} livenessProbe: httpGet: path: '/maxima?health=1' @@ -49,12 +71,26 @@ spec: initialDelaySeconds: 5 periodSeconds: 5 failureThreshold: 3 + {{ if .Values.enableGitRollout }} + env: + - name: GOEMAXIMA_EXTRA_PACKAGES + value: "{{ .Values.gitRollout.includefile }}" + {{ end }} + lifecycle: + preStop: + exec: + command: ["/bin/sleep", "35"] resources: {{- toYaml .Values.resources | nindent 12 }} volumes: - name: tmptmpfs emptyDir: medium: "Memory" + {{ if .Values.enableGitRollout }} + - name: git + emptyDir: + medium: "Memory" + {{ end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helmmaxima/templates/network.yaml b/helmmaxima/templates/network.yaml index ba84ae6b7c5f64e22c53fb0d975ba7a0517998c6..c967275a21afdbb403172b9f5875f7e430ccebbf 100644 --- a/helmmaxima/templates/network.yaml +++ b/helmmaxima/templates/network.yaml @@ -6,6 +6,16 @@ spec: podSelector: matchLabels: app: {{ include "helmmaxima.fullname" . }} - # block all egress traffic + # block egress traffic policyTypes: - Egress + {{ if .Values.enableGitRollout }} + egress: + - to: + - podSelector: + matchLabels: + app: git-rollout + - ports: + - protocol: TCP + port: 9418 + {{ end }} diff --git a/helmmaxima/values.yaml b/helmmaxima/values.yaml index 1696f035af8239c5b1328a64d13a7634804c4739..ebdf182a4bf425d634edff2a54715b380df9b64c 100644 --- a/helmmaxima/values.yaml +++ b/helmmaxima/values.yaml @@ -12,6 +12,12 @@ image: image_prefix: mathinstitut/goemaxima pullPolicy: Always +enableGitRollout: false +gitRollout: + repo: 'git://$(GIT_ROLLOUT_SERVICE_HOST)/git' + branch: main + includefile: '/mnt/git/main.mac' + imagePullSecrets: [] nameOverride: "" fullnameOverride: ""