Maintaining manual gitlab installation with ansible¶
A long time ago we started using GitLab. It was a greate step forward and definitly the right decision to switch from SVN to a distributed version control system. If you want to try GitLab you should definitly install it using GitLab Omnibus distribution.
Manual installation¶
But this long time ago there was no omnibus installation available so we
installed GitLab with a manual git
checkout. Their monthly release cycle
brought some upgrade effort every month - there was an upgrade tool
available which was marked as discontinued
- so i started to write some anisble scripts to handle the upgrade process.
Dependencies to shell and workhorse¶
GitLab uses now several different modular packages as GitLab workhorse and GitLab shell which have some version dependencies, so it would be great if ansible could determine these versions from GitLab checkout itself.
Ansible gitlab role¶
I’ve created a gitlab role which upgrades all parts of GitLab with just one single command:
data/ansible-roles/gitlab
├── defaults
│ └── main.yml
├── handlers
│ └── main.yml
└── tasks
├── gitlab-shell.yml
├── gitlab-workhorse.yml
├── gitlab.yml
└── main.yml
4 directories, 6 files
Role explained¶
First we have to detect the installed version and compare it to required one, which is set in
gitlab/tasks/defaults.yml
. If version is already installed, we’re finished.1 2 3 4 5 6
# ----------------------------------------------------------------------------- # ATTENTION: Please strip leading `v` from version information # valid: 7.12.2 # invalid: v7.12.2 gitlab_user: git gitlab_version: 8.4.0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
--- - name: compare required to installed version command: chdir=/home/{{ gitlab_user }}/gitlab cat VERSION register: gitlab_installed_version changed_when: gitlab_installed_version.stdout != "{{ gitlab_version }}" - name: fetch remote and checkout required version git: repo=https://github.com/gitlabhq/gitlabhq.git dest=/home/{{ gitlab_user }}/gitlab version=v{{ gitlab_version }} force=yes sudo_user: "{{ gitlab_user }}" - name: upgrade gitlab-shell if required include: gitlab-shell.yml when: gitlab_installed_version.changed - name: upgrade gitlab-workhorse if required include: gitlab-workhorse.yml when: gitlab_installed_version.changed - name: upgrade gitlab if version changed include: gitlab.yml when: gitlab_installed_version.changed notify: - restart gitlab - restart apache
Now fetch GitLab remote repository and checkout required version. installed one. If it is different to current installed one we have multiple tasks to be executed in given order.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
--- - name: copy new init script shell: cp /home/{{ gitlab_user }}/gitlab/lib/support/init.d/gitlab /etc/init.d/gitlab - name: replace socket to tcp listener in init script (apache only) replace: dest=/etc/init.d/gitlab regexp='^(gitlab_workhorse_options=".+ -listenNetwork) unix (-listenAddr) \$socket_path/gitlab-workhorse\.socket (.+) -authSocket \$rails_socket (.+)$' replace='\1 tcp \2 127.0.0.1:8181 \3 \4' backup=no - name: install using bundler shell: chdir=/home/{{ gitlab_user }}/gitlab PATH=$PATH:/usr/pgsql-9.4/bin bundle install --deployment --without development test mysql sudo_user: "{{ gitlab_user }}" - name: run database migration shell: chdir=/home/{{ gitlab_user }}/gitlab bundle exec rake db:migrate RAILS_ENV=production sudo_user: "{{ gitlab_user }}" - name: recompile assets shell: chdir=/home/{{ gitlab_user }}/gitlab bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production sudo_user: "{{ gitlab_user }}"
If the version differs from current installed version, check new required shell version and checkout new shell if required.
1 2 3 4 5 6 7 8 9 10 11 12
--- - name: read required shell version command: chdir=/home/{{ gitlab_user }}/gitlab cat GITLAB_SHELL_VERSION register: gitlab_shell_required_version - name: fetch remote and checkout required shell version git: repo=https://github.com/gitlabhq/gitlab-shell.git dest=/home/{{ gitlab_user }}/gitlab-shell version=v{{ gitlab_shell_required_version.stdout }} force=yes sudo_user: "{{ gitlab_user }}" when: gitlab_shell_required_version.changed
If the version differs from current installed version, check new required workhorse version and checkout new workhorse if required. After checkout compile workhorse.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
--- - name: read required workhorse version command: chdir=/home/{{ gitlab_user }}/gitlab cat GITLAB_WORKHORSE_VERSION register: gitlab_workhorse_required_version # No semantic versioning, see: https://gitlab.com/gitlab-org/gitlab-git-http-server/issues/14 - name: fetch remote and checkout required workhorse version git: repo=https://gitlab.com/gitlab-org/gitlab-workhorse.git dest=/home/{{ gitlab_user }}/gitlab-workhorse version={{ gitlab_workhorse_required_version.stdout }} force=yes sudo_user: "{{ gitlab_user }}" when: gitlab_workhorse_required_version.changed - name: compile workhorse command: make chdir=/home/{{ gitlab_user }}/gitlab-workhorse sudo_user: "{{ gitlab_user }}" when: gitlab_workhorse_required_version.changed
Restart gitlab and apache service if a version has changed.
1 2 3 4 5 6 7 8 9 10 11 12
--- - name: restart gitlab service: name: gitlab state: restarted enabled: yes - name: restart apache service: name: httpd state: restarted enabled: yes
Final words¶
Of course these formulas are specific to your setup, that’s why i did not push them into a public repo. If you use nginx as webserver, these may be different and you could use unix sockets instead of tcp listeners.
But anyway - feel free to submit your comments and reuse parts you need.