Migration et upgrade d’un serveur GitLab-ce

Tous les 5 ans c’est la même musique. La version de Debian LTS arrive à expiration et il faut mettre à jour le serveur. Et du coup, on en profite pour prendre une machine récente pour bénéficier des meilleurs performances.
Si on a un disque dur SATA, il vaut mieux repartir sur de nouveaux disques quoi qu’il arrive. Leurs durée de vie étant limitées.

Nous allons donc procéder à une série de backups sur l’ancien serveur, les rapatrier sur le nouveau et tout réinstaller à l’identique.

Dans notre cas, nous étions sur une Debian 8, laquelle supporte GitLab 13.3.9.
Nous changeons de machine pour une Debian 10, laquelle supporte GitLab 14.x.x

Installer GitLab-ce est simple, tant que nous n’avons pas de repository à migrer. Là ou ça se complique, c’est qu’il ne faut rien perdre de l’ancienne instance. Chez partITech nous avons plus de 100 repository qui représentent à peu près 20 Go d’archives.

Les archives ne sont pas compatibles entre les versions. Donc si nous avons une archive faite avec la version 13.3.9, il faudra installer cette même version et faire l’import. La dernière étape consistera à faire la migration de la 13.3.9 vers la dernière version 14.x
Mais pour procéder à cette montée de version majeur, il nous faudra impérativement installer la dernière version en date de la branche 13.x soit la version 13.12.0

Installation des packages de base

apt-get install vim curl backup-manager mlocate libcurl4-openssl-dev libexpat1-dev gettext libz-dev libssl-dev libpcre2-dev build-essential git-core graphicsmagick libimage-exiftool-perl htop

On installe vim et on désactive la souris.

vi ~/.vimrc
#on ajoute set mouse-=a

On dé-commente les alias.

vi ~/.bashrc
.   ~/.bashrc

Sur l’ancien serveur

On stoppe les services.

sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq

On crée un backup.

sudo gitlab-rake gitlab:backup:create

On prépare un répertoire dans lequel on met l’ensemble de nos fichiers à rapatrier.

mkdir ~/gitlab-old

On copie nos fichiers de configuration de notre répertoire. /etc/gitlab (gitlab.rb and gitlab-secrets.json) ainsi que le répertoire /etc/gitlab/ssl

sudo cp /etc/gitlab/gitlab.rb ~/gitlab-old
sudo cp /etc/gitlab/gitlab-secrets.json ~/gitlab-old
sudo cp -R /etc/gitlab/ssl ~/gitlab-old
sudo cp /etc/backup-manager.conf ~/gitlab-old/
sudo cp /etc/backup-manager.sh ~/gitlab-old/

Sur le nouveau serveur

On installe la source apt de GitLab.

curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh |  bash

On installe la version de GitLab à l’identique de l’ancienne pour ne pas avoir de problèmes d’installations. Puis on mettra à jour avec la dernière version.

sudo apt-get install gitlab-ce=13.3.9-ce.0

On installe nos fichiers de configuration de notre ancienne instance.

sudo mv /etc/gitlab/gitlab.rb /etc/gitlab/_gitlab.rb
sudo cp gitlab-old/gitlab* /etc/gitLab

On copie le répertoire SSL de notre ancienne instance.

cp -R gitlab-old/ssl /etc/gitlab/

On lance la reconfiguration de GitLab.

sudo gitlab-ctl reconfigure

On éteint les services.

sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq

On place notre premier backup dans le répertoire de backup par défaut de GitLab (nous avons modifié notre répertoire par défaut.

sudo cp gitlab-old/1624870826_2021_06_28_13.3.9_gitlab_backup.tar ~/gitlab-backups

Et on l’importe.

sudo gitlab-rake gitlab:backup:restore BACKUP=1624870826_2021_06_28_13.3.9

On fixe les permissions.

  sudo find /data/gitlab-storage -type f -exec chmod 0644 {} \;
  sudo find /data/gitlab-storage/uploads -type d -not -path /data/gitlab-storage/uploads -exec chmod 0700 {} \;

On convertit nos repository en hash si besoin.

gitlab-rake gitlab:storage:migrate_to_hashed

On ouvre les ports 80 et 443 dans le firewall si besoin.

iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

L’interface devrait répondre normalement maintenant sur notre nouveau serveur.

Upgrade des versions

Il nous faut maintenant mettre à jour GitLab.
Première étape, on passe sous la version 13.5.0

apt-get install gitlab-ce=13.5.0-ce.0

Et là on a l’erreur suivante : PG::DuplicateTable: ERROR: relation « postgres_indexes » already exists

Selection_865

Pour faire passer le script, nous devrons modifier la procédure d’upgrade pour ajouter un drop des indexes dans le fichier : /opt/gitlab/embedded/service/gitlab-rails/db/migrate/20200922093004_add_postgres_index_view.rb

# frozen_string_literal: true

class AddPostgresIndexView < ActiveRecord::Migration[6.0]
  DOWNTIME = false

  def up
    execute(<<~SQL)
       DROP VIEW IF EXISTS postgres_indexes;
        CREATE VIEW postgres_indexes AS
      SELECT
        pg_namespace.nspname || '.' || pg_class.relname as identifier,
        pg_index.indexrelid,
        pg_namespace.nspname as schema,
        pg_class.relname as name,
        pg_index.indisunique as unique,
        pg_index.indisvalid as valid_index,
        pg_class.relispartition as partitioned,
        pg_index.indisexclusion as exclusion,
        pg_indexes.indexdef as definition,
        pg_relation_size(pg_class.oid) as ondisk_size_bytes
      FROM pg_index
      INNER JOIN pg_class ON pg_class.oid = pg_index.indexrelid
      INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
      INNER JOIN pg_indexes ON pg_class.relname = pg_indexes.indexname
      WHERE pg_namespace.nspname <> 'pg_catalog'
    SQL
  end

  def down
    execute(<<~SQL)
      DROP VIEW postgres_indexes
    SQL
  end
end

Une fois le script de migration modifié, on relance le reconfigure.

gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure
Selection_866

On peut maintenant passer à l’upgrade suivante. Upgrader à la version 13.6.0 et incrémenter les installations jusqu’à la version 13.12.0

apt-get install gitlab-ce=13.6.0-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure
apt-get install gitlab-ce=13.7.0-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure
apt-get install gitlab-ce=13.8.0-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure
apt-get install gitlab-ce=13.9.0-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure
apt-get install gitlab-ce=13.10.0-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure
apt-get install gitlab-ce=13.11.0-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure
apt-get install gitlab-ce=13.12.5-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure

Sur la version 13.7.0 il faudra corriger le script de migration.

/opt/gitlab/embedded/service/gitlab-rails/db/migrate/20201127170848_add_index_bloat_estimate_view.rb

# frozen_string_literal: true

class AddIndexBloatEstimateView < ActiveRecord::Migration[6.0]
  DOWNTIME = false

  def up
    execute(<<~SQL)
      DROP VIEW IF EXISTS postgres_index_bloat_estimates;
      CREATE VIEW postgres_index_bloat_estimates AS
      -- Originally from: https://github.com/ioguix/pgsql-bloat-estimation/blob/master/btree/btree_bloat.sql
      -- WARNING: executed with a non-superuser role, the query inspect only index on tables you are granted to read.
      -- WARNING: rows with is_na = 't' are known to have bad statistics ("name" type is not supported).
      -- This query is compatible with PostgreSQL 8.2 and after
      SELECT nspname || '.' || idxname as identifier,
        CASE WHEN relpages > est_pages_ff
          THEN bs*(relpages-est_pages_ff)
          ELSE 0
        END::bigint AS bloat_size_bytes
      FROM (
        SELECT
            coalesce(1 +
              ceil(reltuples/floor((bs-pageopqdata-pagehdr)*fillfactor/(100*(4+nulldatahdrwidth)::float))), 0
            ) AS est_pages_ff,
            bs, nspname, tblname, idxname, relpages, is_na
        FROM (
            SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, idxoid, fillfactor,
                  ( index_tuple_hdr_bm +
                      maxalign - CASE -- Add padding to the index tuple header to align on MAXALIGN
                        WHEN index_tuple_hdr_bm%maxalign = 0 THEN maxalign
                        ELSE index_tuple_hdr_bm%maxalign
                      END
                    + nulldatawidth + maxalign - CASE -- Add padding to the data to align on MAXALIGN
                        WHEN nulldatawidth = 0 THEN 0
                        WHEN nulldatawidth::integer%maxalign = 0 THEN maxalign
                        ELSE nulldatawidth::integer%maxalign
                      END
                  )::numeric AS nulldatahdrwidth, pagehdr, pageopqdata, is_na
            FROM (
       

On installe maintenant la version 14.0.0.

apt-get install gitlab-ce=13.12.0-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure

Depuis la version 14, il faut impérativement utiliser le systeme de fichier par hash. L’installation affichera une alerte et stoppera le processus.

root@git-partitech-sd-47766:/opt/gitlab# apt-get install gitlab-ce=14.0.0-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be upgraded:
  gitlab-ce
1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/923 MB of archives.
After this operation, 14.5 MB of additional disk space will be used.
Reading changelogs... Done
(Reading database ... 119998 files and directories currently installed.)
Preparing to unpack .../gitlab-ce_14.0.0-ce.0_amd64.deb ...
gitlab preinstall: Checking for unmigrated data on legacy storage
gitlab preinstall: 
gitlab preinstall: Legacy storage is no longer supported. Please migrate your data to hashed storage.
gitlab preinstall: Check https://docs.gitlab.com/ee/administration/raketasks/storage.html#migrate-to-hashed-storage for details.
gitlab preinstall: 
gitlab preinstall: If you want to skip this check, run the following command and try again:
gitlab preinstall: 
gitlab preinstall:  sudo touch /etc/gitlab/skip-unmigrated-data-check
gitlab preinstall: 
dpkg: error processing archive /var/cache/apt/archives/gitlab-ce_14.0.0-ce.0_amd64.deb (--unpack):
 new gitlab-ce package pre-installation script subprocess returned error exit status 1
Errors were encountered while processing:
 /var/cache/apt/archives/gitlab-ce_14.0.0-ce.0_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

Il faudra donc convertir vos repository si ce n’est pas déjà fait.

gitlab-rake gitlab:storage:migrate_to_hashed

Et ensuite lancer l’installe en spécifiant de ne plus afficher l’alerte.

sudo touch /etc/gitlab/skip-unmigrated-data-check
apt-get install gitlab-ce=14.0.0-ce.0 && gitlab-ctl stop unicorn && gitlab-ctl stop sidekiq && gitlab-ctl reconfigure
Selection_871

L’étape la plus critique est passée. On peut mettre à jour sur la toute dernière version. De notre coté c’est la version 14.0.1

apt-get upgrade

Dernière opération. Si comme nous vous utilisiez les notifications Slack, il vous faudra migrer la configuration. Les services templates sont retirés depuis la version 14.x.x

Vous pouvez réintégrer les notifications projet par projet, ou faire comme nous, le mettre au global.
Pour cela, vous devrez aller dans Admin Area >> System Hooks

Selection_874