Einleitung

Diese Einleitung beschreibt das Einrichten einer CI für GitLab auf ARM64. Als Hardware kommt ein ODROID-C2 mit Arch Linux zum Einsatz. Da es keine vorkompilierte ARM64 Version des GitLab Runners gibt, muss dieses Werkzeug manuell kompiliert werden. Darüberhinaus wird eine systemd-Einheit verwendet, um den GitLab Runner u.a. starten zu können.

Kompilieren des GitLab Runners für ARM64

Folgende Abhängigkeiten müssen installiert sein, um den GitLab Runner erfolgreich kompilieren zu können:

  pacman -Sy git-core go gcc make
  

Hinweis: Es wird kein Docker installiert, da als "Executor" später nur die "Shell" verwendet werden soll. Eine erfolgreiche Kompilierung ist aber auch ohne Docker möglich; diverse Fehlermeldung des GitLab Runners können ignoriert werden.

Folgende Befehle sind dann zur Erzeugung des ARM64-Binaries notwendig:

  export GOPATH=$HOME/Go
  export PATH=$PATH:$GOPATH/bin:/usr/local/go/bin
  go get gitlab.com/gitlab-org/gitlab-ci-multi-runner
  cd $HOME/Go/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner
  make deps
  

Die Ausgabe für den letzten Befehl sollte in etwa so aussehen:

  make: docker: Command not found
  make: docker: Command not found
  # Installing dependencies...
  go get -u github.com/golang/lint/golint
  go get github.com/mitchellh/gox
  go get golang.org/x/tools/cmd/cover
  go get github.com/fzipp/gocyclo
  go get -u github.com/jteeuwen/go-bindata/...
  go install cmd/vet
  

Danach kann die eigentliche Kompilierung gestartet werden. Durch Setzen der BUILD_PLATFORMS Variable wird nur ein einziges Binärpaket für ARM64 gebaut und nicht - wie standardmässig - für diverse andere Plattformen zusätzlich:

  make BUILD_PLATFORMS='-osarch linux/arm64' build
  

Die Ausgabe dieses Befehls sollte in etwa so aussehen:

  make: docker: Command not found
  make: docker: Command not found
  Makefile:89: =============================================
  Makefile:90: WARNING: downloading prebuilt docker images that will be embedded in gitlab-runner
  Makefile:91: WARNING: to use images compiled from your code install Docker Engine
  Makefile:92: WARNING: and remove out/docker/prebuilt-x86_64.tar.xz
  Makefile:93: =============================================
  # Create directory
  mkdir -p out/docker
  curl -o out/docker/prebuilt-x86_64.tar.xz \
    https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/master/docker/prebuilt-x86_64.tar.xz
    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                   Dload  Upload   Total   Spent    Left  Speed
  100 8154k  100 8154k    0     0   550k      0  0:00:14  0:00:14 --:--:--  560k
  Makefile:117: =============================================
  Makefile:118: WARNING: downloading prebuilt docker images that will be embedded in gitlab-runner
  Makefile:119: WARNING: to use images compiled from your code install Docker Engine
  Makefile:120: WARNING: and remove out/docker/prebuilt-arm.tar.xz
  Makefile:121: =============================================
  # Create directory
  mkdir -p out/docker
  curl -o out/docker/prebuilt-arm.tar.xz \
    https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/master/docker/prebuilt-arm.tar.xz
    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                   Dload  Upload   Total   Spent    Left  Speed
  100 9096k  100 9096k    0     0   566k      0  0:00:16  0:00:16 --:--:--  602k
  # Generating embedded data
  go-bindata \
    -pkg docker \
    -nocompress \
    -nomemcopy \
    -nometadata \
    -prefix out/docker/ \
    -o executors/docker/bindata.go \
    out/docker/prebuilt-x86_64.tar.xz \
    out/docker/prebuilt-arm.tar.xz
  go fmt executors/docker/bindata.go
  executors/docker/bindata.go
  # Building gitlab-ci-multi-runner in version 1.7.0~beta.27.g184ec68 for -osarch linux/arm64
  gox -osarch linux/arm64 \
    -ldflags "-X gitlab.com/gitlab-org/gitlab-ci-multi-runner/common.NAME=gitlab-ci-multi-runner \
    -X gitlab.com/gitlab-org/gitlab-ci-multi-runner/common.VERSION=1.7.0~beta.27.g184ec68 \
    -X gitlab.com/gitlab-org/gitlab-ci-multi-runner/common.REVISION=184ec68 \
    -X gitlab.com/gitlab-org/gitlab-ci-multi-runner/common.BUILT=2016-10-14T15:08:34+00:00 \
    -X gitlab.com/gitlab-org/gitlab-ci-multi-runner/common.BRANCH=master" \
    -output="out/binaries/gitlab-ci-multi-runner-{{.OS}}-{{.Arch}}"
  Number of parallel builds: 3

  -->     linux/arm64: gitlab.com/gitlab-org/gitlab-ci-multi-runner
  

Einrichten des GitLab Runners

Nachdem das Binärpaket für den GitLab Runner gebaut wurde, muss der Runner sich bei der GitLab Instanz registrieren. Im folgenden Beispiel wird die GitLab.com Installation verwendet, da der Runner dort für meine Repositories zuständig ist. Ein typischer Registrierungsverlauf sieht wie folgt aus:

  $ ./gitlab-ci-multi-runner-linux-arm64 register
  WARNING: Running in user-mode.
  WARNING: The user-mode requires you to manually start builds processing:
  WARNING: $ gitlab-runner run
  WARNING: Use sudo for system-mode:
  WARNING: $ sudo gitlab-runner...

  Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
  https://gitlab.com/ci
  Please enter the gitlab-ci token for this runner:
  SECRET_TOKEN
  Please enter the gitlab-ci description for this runner:
  [alarm]: Arch Linux ARM64 (ODROID-C2)
  Please enter the gitlab-ci tags for this runner (comma separated):
  arm64
  

Die Registrierungsurl und der geheime Token findet man in den "Runner" Einstellungen eines jeden Projektes einer GitLab Installation:

GitLab Runner ARM64

systemd: Einrichtung eines eigenen Benutzerdienstes

Alle Befehle, die der GitLab Runner entgegennimmt, sollen als lokaler Benutzer ausgeführt werden. Dazu wird ein systemd Dienst für einen lokalen Benutzer eingerichtet. Damit kann der Dienst beispielsweise gestartet oder gestoppt werden. Folgende Verzeichnisstruktur wird vorher angelegt:

Sobald diese Verzeichnisstruktur angelegt wurde, kann die systemd-Einheit für den Dienst geschrieben werden. Hinweis: es müssen in der systemd-Einheit absolute Pfade angegeben werden. In unserem Beispiel wird als Heimatverzeichnis /home/builder verwendet. Alle systemd-Einheiten für lokale Benutzer werden in $HOME/.config/systemd/user erwartet. Das Verzeichnis muss ggf. angelegt werden mit:


  mkdir -p ~/.config/systemd/user
  

Als systemd-Einheit wird der Name gitlab-ci-multi-runner-gitlab-com.service vergeben. Der Inhalt sieht dann so aus:

  [Unit]
  Description=GitLab CI Multi Runner GitLab.com

  [Service]
  Type=simple
  RemainAfterExit=yes

  ExecStart=/home/builder/gitlab-ci-multi-runner-gitlab-com/gitlab-ci-multi-runner-linux-arm64 run --config /home/builder/gitlab-ci-multi-runner-gitlab-com/config.toml --working-directory /home/builder/builds-gitlab-com

  [Install]
  WantedBy=default.target
  

Wie oben angemerkt müssen die Pfadangaben ggf. angepasst werden. Nun kann die neue systemd-Einheit aktiviert und gestartet werden:

  systemctl --user enable gitlab-ci-multi-runner-gitlab-com
  systemctl --user start gitlab-ci-multi-runner-gitlab-com
  

Eine Statusabfrage, ob der Dienst korrekt gestartet wurde ist wie folgt möglich:

  systemctl --user status -l gitlab-ci-multi-runner-gitlab-com
  

Beispielsweise könnte eine Ausgabe so aussehen:

  [builder@alarm user]$ systemctl --user status -l gitlab-ci-multi-runner-gitlab-com
  * gitlab-ci-multi-runner-gitlab-com.service - GitLab CI Multi Runner GitLab.com
     Loaded: loaded (/home/builder/.config/systemd/user/gitlab-ci-multi-runner-gitlab-com.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2016-10-14 15:25:54 UTC; 2s ago
   Main PID: 5518 (gitlab-ci-multi)
     CGroup: /user.slice/user-1002.slice/user@1002.service/gitlab-ci-multi-runner-gitlab-com.service
             `-5518 /home/builder/gitlab-ci-multi-runner-gitlab-com/gitlab-ci-multi-runner-linux-arm64 run --config /home/builder/gitlab-ci-mult

  Oct 14 15:25:54 alarm systemd[5453]: Started GitLab CI Multi Runner GitLab.com.
  Oct 14 15:25:55 alarm gitlab-ci-multi-runner-linux-arm64[5518]: Starting multi-runner from /home/builder/gitlab-ci-multi-runner-gitlab-com/con
  Oct 14 15:25:55 alarm gitlab-ci-multi-runner-linux-arm64[5518]: WARNING: Running in user-mode.
  Oct 14 15:25:55 alarm gitlab-ci-multi-runner-linux-arm64[5518]: WARNING: Use sudo for system-mode:
  Oct 14 15:25:55 alarm gitlab-ci-multi-runner-linux-arm64[5518]: WARNING: $ sudo gitlab-runner...
  Oct 14 15:25:55 alarm gitlab-ci-multi-runner-linux-arm64[5518]:
  Oct 14 15:25:55 alarm gitlab-ci-multi-runner-linux-arm64[5518]: Configuration loaded                                builds=0
  

Damit ist die Konfiguration der systemd-Einheit fast abgeschlossen. Als Superbenutzer muss unbedingt folgender ausgeführt werden, damit der systemd Dienst des lokalen Benutzers auch nach einem Ausloggen noch weiterläuft:

    loginctl enable-linger builder
  

Der Benutzername muss ggf. angepasst werden. Die Ausgabe von:

  $ loginctl show-user builder
  UID=1002
  GID=100
  Name=builder
  Timestamp=Fri 2016-10-14 15:17:23 UTC
  TimestampMonotonic=4895972543
  RuntimePath=/run/user/1002
  Service=user@1002.service
  Slice=user-1002.slice
  Display=c4
  State=active
  Sessions=c4
  IdleHint=no
  IdleSinceHint=0
  IdleSinceHintMonotonic=0
  Linger=yes
  

sollte am Ende ein Linger=yes zeigen.

Anmerkungen

Es ist nun möglich den GitLab Runner für ARM64 zu verwenden. Ein offizielles Binärpaket für ARM64 ist noch nicht verfügbar, ein entsprechender Feature Request ist dafür hier zu finden.

Historie