Dataset versioning

The first feature complete version of my MarkLogic persistence layer for Orbeon Form Runner is available but as far as I know nobody is using it yet and it’s still time to think about what will happen for new versions.

Versioning dataset « schemes » is always hard.

I am using the term « scheme » to refer to both structures and conventions used to store and retrieve information.

I would have used  the term « schema » if it hadn’t different meaning depending on the technology  (SQL database schemas, XML schemas, RDF Schema, …) which are all part of what I am calling a « scheme » in this post.

By « dataset » I mean a set of data isolated by any mean one from each other for the application. Datasets is a logical concept which overlaps the concept of databases as defined by the different database implementations.

It’s a generic issue and if you take the example of WordPress which is powering this blog, most of its plugins include a mechanism to check that their database schemes is up to date with their versions and perform automatic upgrades when needed (see for instance the section called « Store the Plugin Version for Upgrades » and the following one in this article by Dave Donaldson).

This is most needed for applications such as WordPress where there the end user is often the administrator of his blog and enterprise applications usually have system administrators to deal with upgrades but still there might be something to borrow in this approach.

Like in a WordPress plugin, in most database application like my persistence layer, you have on one side the « program » (implemented in XQuery, pipelines or whatever for XML databases) and on the other side one or several « datasets ».

This persistence layer supports storing multiple « datasets » in a single database.

A use case for that could be for a provider to define a common dataset as a persistence layer for form definitions shared by different customers, a dataset per customer, a dataset for demonstration purposes, … All these datasets could be either in separate MarkLogic databases or in a single database.

There is currently a single version of the persistence layer and there is no possible mismatch by the XQuery modules which implement the REST API and the dataset schemes.

The situation might be different in a few months.

There might be for instance a version 2 implementing the optional features which haven’t been implemented yet. These features will likely rely on new documents properties added to the current ones and thus rely on a version 2 of the dataset scheme.

The current scheme relies on URIs to store application and form names and document types in a directory fashion. This seems the natural thing to do because that mirrors the URIs structures in the persistence layer specification. Other options could be to use MarkLogic collections or document properties to store this information and we might have decided to go this way in a version 3.

Our provider could then be in a situation where the dataset with the form definitions would still be in v1 (if it doesn’t use features added in v2, why should he migrate), the datasets with customer data would be in v2 and the dataset used for demo purposes would be testing v3.

Traditional approaches rely on upgrade scripts executed by system administrators which can be run through Roxy  which is the preferred deployment tool for MarkLogic applications such as this persistence layer.

In that case, system administrators need to carefully keep modules and dataset schemes versions synchronized and supporting multiple versions of modules for a single database can be tough even if the modules URIs can be versioned.

This is where the WordPress plugin approach may be useful.

What about adding some kind of metadata to each dataset to determine its version?

The URL rewriter would retrieve this information and choose the REST library options corresponding to a specific version to execute the right version of the modules.

An administrative REST API could easily be added to list datasets, display their metadata and perform datasets upgrades (and downgrades if available) and this REST API could be used by Roxy.

The idea of adding dataset metadata seems really powerful but what should such metadata include?

The minimum would be to identify applications using the datasets and their versions but what about adding more information, such as some kind of user readable documentation, URIs to additional documentation and resources, …

Proposing a vocabulary to define such information is an interesting exercise that I’ll be happy to do if needed but I can’t believe it has never been done…

If you are aware of something similar, please tell us!

Many thanks to Peter Kester (MarkLogic) for sharing his thoughts on the subject.

First steps with MarkLogic

[Edited to take into account Dave Cassel’s comments]

To get started with MarkLogic I have chosen to develop a persistence layer for Orbeon Form Runner.

This is the kind of projects I like, small enough to be done in a few days yet technical enough to see advanced topics and potentially useful to other people.

The project is available on my community site and I’d like to share in this post my feelings during this first contact with MarkLogic.

The first contact with a new product is the installation and I have been really surprised by the simplicity of MarkLogic installation  process. My laptop is running Ubuntu which is not a supported platform but the install went very smoothly after converting the RPM package as documented everywhere on the web and it didn’t took me more than a few minutes to get MarkLogic up and running.

The second contact with the admin interface has been less obvious: MarkLogic comes with a series of different generations of web UIs (admin, configuration manager, monitoring, information studio, application builder and query console) and it’s not always obvious to find your way between these tools.

I must also say that I am an old school administrator who prefers configuration files rather than point and click administration windows!

Fortunately this is well documented and I have rapidly been able to create a new database and servers for my project. The interface with my favorite XML tool, oXygen XML editor has also been very easy to setup.

The feeling that hasn’t left me all over this project is a feeling of stability and robustness: I have never needed to restart the server, all the modifications of configuration have been made while the server was up and running, I have never seen any crash nor any non understandable error message.

In other words, MarkLogic is the kind of software which makes you feel secure and comfortable!

A Form Runner persistence layer is a REST API and such APIs are reasonably easy to implement in MarkLogic thanks to their REST library. I think I have found a bug (I am pretty good for that, all the products I have worked with will tell you that) but that was in a minor function and nothing really blocking.

Something to note if you want to try it by yourself is that paths to documents in a database does not always start with a « / » and « foo/bar » is a different directory than « /foo/bar ». To search all the documents under « foo/bar/ » you’ll write something such as:

cts:search(/, cts:directory-query('foo/bar/', "infinity"))

If you forget the trailing slash in (foo/bar) MarkLogic will raise an error with a self-explanatory message but if you add a leading slash (/foo/bar/) like you’d do for any decent file system you will search in a different directory and your search may  silently result in an empty sequence!

In fact, as pointed out by Dave Cassel, Marklogic considers that « foo/ » is a root directory like « / » and « /foo/ » is a subdirectory of the root directory « / ». A database can thus have as many root directory as you want but you need to be careful and if you insert a document as « foo/bar/bat.xml » you won’t be able to find it as « /foo/bar/bat.xml »!

And as you’ve noticed with this simple snipet you’ll have to use many proprietary functions to develop XQuery applications in MarkLogic. This is not really a problem specific to MarkLogic but XQuery has been defined to be generic and we use it for things which are well beyond its original scope.

The good news is that MarkLogic comes with a very extensive library and that you won’t be blocked in your developments. The bad news is of course that what you’ll develop in MarkLogic won’t be easily portable to other XML databases.

The last thing I want to report is the quality of the online documentation, on MarkLogic Community but also on the web at large and on stackoverflow in particular : during my development I have always been able to find answers for the many questions I had in a very reasonable amount of time.

To summarize, I haven’t had the opportunity to test the support of big data yet but this first contact leaves me with a very positive feeling of a product which is mature, stable, rich of features and well documented and supported by its community.

La musique qui marche au pas

La musique qui marche au pas,
Cela ne me regarde pas

Georges Brassens, La mauvaise réputation

Je suis -faut il le préciser?- atterré par l’attentat contre Charlie Hebdo et profondément attaché à la liberté d’expression et à la république mais je ne participerai pas à la « marche républicaine » du 11 janvier.

La perspective de défiler derrière Sarkozy, Valls, Hollande, Merkel, Cameron, Juncker ou encore Davutoğlu pour ne nommer qu’eux n’a rien de réjouissant mais en tirer prétexte pour ne pas manifester serait puéril.

Par contre je trouve insupportable la manière dont nos dirigeants ont commencé à récupérer l’élan populaire pour justifier des initiatives qui vont à l’encontre même de la liberté d’expression qu’elles sont sensées défendre.

On notera par exemple l’ironie involontaire de Fillon qui ne craint pas d’affirmer qu’ « il ne doit y avoir aucune voix discordante« , montrant une curieuse conception de la liberté d’expression.

Plus sérieusement, le risque d’un Patriot Act à la française est bien réel et nous devons refuser de cautionner cela.

Le gouvernement avait anticipé en faisant passer sa loi renforçant les dispositions relatives à la lutte contre le terrorisme qui limite la liberté d’expression sur internet puisqu’elle permet à la police de faire bloquer l’accès aux sites internet faisant l' »apologie du terrorisme » sans aucun contrôle judiciaire.

Fort de cette unité nationale notre gouvernement va vouloir renforcer ces mesures et pourquoi pas envoyer quelques drones au Yémen.

Ce qui me frappe dans l’itinéraire des frères Kouachi et Coulibaly c’est que leur endoctrinement a débuté au cœur de nos cités et s’est consolidé dans nos prisons.

Plutôt que de restreindre la liberté sur Internet et de bloquer un peu plus nos frontières, ne faudrait il pas nous pencher sur la facette franco-française de ces itinéraires et chercher à résoudre les problèmes de nos cités et de notre système pénitentiaire?

A l’image des camps dans lesquels sont nés l’EI  nos prisons semblent être devenues le meilleur camp de formation au terrorisme, n’est il pas plus urgent de changer cela que de détruire les camps yéménites?

Je crois que je ne fais malheureusement plus suffisamment confiance à nos dirigeants pour défiler avec eux!

Enfin réunis

Il n’est pas toujours facile de choisir ses combats et encore moins d’en mener plusieurs de front mais je suis toujours aussi surpris de voir par exemple les militants anti-OGM utiliser des logiciels ou services propriétaires ou des activistes des logiciels libres ne pas manger bio.

On voit parfois, au mieux, des militants inviter poliment des activistes d’une autre cause mais cela dépasse rarement le temps d’un discours.

Cet après midi au contraire, le rassemblement anti-TAFTA devant l’ambassade de la République Islamique d’Iran (proche de l’hôtel Shangri-La dans lequel le commissaire au commerce de l’Union Européenne Karel De Gucht rencontrait les lobbys industriels et financiers) a été l’occasion de voir réunis pour un même combat des associations telles que :

Espérons que ce projet de traité permettra de rassembler et faire converger ces lutes qui ont tant de points communs!

Encerclés

Notre verger bio et Nature & Progrès fait figure d’îlot de résistance au milieu des cultures « conventionnelles ».

Ce champ a été traité avec un herbicide. Notre verger fait figure d'îlot de verdure.

Un ami m’envoie, sous le titre « tristes news pour la planète » les liens sur deux articles du Monde:

Ces articles font écho au triste état des parcelles de culture dite « conventionnelle » qui entourent notre verger.

Cette année l’hiver a été anormalement clément, le printemps est en avance, les prés sont verts et les arbres en fleurs.

Le contraste est d’autant plus criant entre notre verger bio et ces champs auxquels l’herbicide a donné une teinte orangée. Ces champs ont été laissés nus tout l’hiver – ce qui est une cause bien connue de dégradation des sols – et gorgés d’herbicide au printemps pour tuer tout reste de vie en attendant sans doute un semi de maïs qui ne saurait tarder.

Comme beaucoup de fermes bio, notre verger semble être un îlot de vie au milieu d’une nature dévastée.

Comme Emmanuel Giboulot, le « viticulteur coupable d’avoir dit non aux pesticides » nous refusons tout traitement dans notre verger, préférant recréer un équilibre naturel plutôt que de combattre les déséquilibres avec des produits « miracles ».

Et comme beaucoup d’apiculteurs nous subissions de plein fouet le déclin des abeilles qui dépasse pour nous largement la moyenne de 27,7% observée en France et mentionnée dans l’article du Monde, mais comment pourrait il en être autrement dans ce désert agricole?

Nous entendons parfois les détracteurs du bio dire que le véritable bio n’existe pas et on peut être tenté de leur donner raison en voyant ces photos.

Comme Emmanuel Giboulot, les agriculteurs bio font de leur mieux pour résister. Nos haies semblent de bien faibles protections mais toutes les mesures montrent que le taux de pesticides demeure très faible dans les produits bio.

Ne rendons pas leur résistance encore plus difficile en les obligeant à la désobéissance civile!

 

Objets connectés

Il ne vous a certainement pas échappé que Google s’intéresse aux objets connectés, en vrac :

La lecture de ces articles peut laisser penser que ces objets connectés, contrôlés par Google ou un autre géant du même type vont fatalement rentrer chez nous.

Pourtant, même s’ils arrivent chez nous livrés par les drones d’Amazon, ce sera le résultat de notre choix.

Il est trop facile de nous lamenter de la puissance de Google (vous pouvez remplacer ici Google par Amazon, Microsoft, Apple, Facebook, Carrefour, Intermarché, Leclerc, Casino ou votre bête noire préférée) en oubliant que nous avons le choix et que c’est nous qui faisons la puissance de ces marques.

Libre à nous d’utiliser (ou de ne pas utiliser) le moteur de recherche Google, gmail, Google+, Adsense et Google analytics sur nos sites, Google Maps pour nous déplacer, Google Drive pour partager nos documents, Android et son écosystème sur nos téléphones, tablettes et ordinateurs et bientôt les objets connectés de Google mais ne nous plaignons pas ensuite que Google sait trop de choses sur notre compte.

Personnellement je boycotte autant que possible ces services (et ces marques) mais il m’arrive aussi de les utiliser et je ne me pose pas en moralisateur…

Rappelons nous simplement qu’il existe presque toujours des alternatives, que nous avons toujours le choix et essayons d’exercer nos choix de manière responsable!

 

Un projet e-nov

De:     Valerie P <valeriep@outlook.fr>
À:     vdv@dyomedea.com
Sujet:     informations relatives à notre projet
Date:     Tue, 14 Jan 2014 03:24:19 +0100

Bonjour,

J’ai vu vos coordonnées sur Internet.
Nous recherchons un prestataire et nous souhaitons éventuellement vous consulter concernant un projet.
Merci de me fixer un bref rendez-vous téléphonique à l’heure de votre choix (mardi ou mercredi).
pour un complément d’information.

Bonne réception,
Valerie P
Arcadev

Un prospect qui m’écrit à 3h24 du matin doit avoir un projet particulièrement urgent et je m’empresse de lui répondre.

La plupart de mes clients me contactent de cette manière et je n’ai pas de raison particulière de me méfier mais j’aime bien savoir à qui j’ai à faire et je recherche « arcadev« . Je ne trouve pas grand chose à part les profils LinkedIn et Viadeo de Valérie P. Curieusement, bien que son profil LinkedIn apparaisse en résultat de recherche, aucune mention d’arcadev dans son profil pour lequel elle est « Data Center Sales Specialist at Cisco ». Pas non plus de trace d’arcadev sur societe.com.

Quelqu’un qui écrit des mails à 3h du matin ne se lève peut être pas très tôt, j’essaye donc de trouver une heure raisonnable pour un rendez vous téléphonique :

De:     Eric van der Vlist <vdv@dyomedea.com>
À:     Valerie P<valeriep@outlook.fr>
Sujet:     Re: informations relatives à notre projet
Date:     Tue, 14 Jan 2014 07:45:17 +0100

Bonjour,

Le mardi 14 janvier 2014 à 03:24 +0100, Valerie P a écrit :
> Bonjour,
>
> J’ai vu vos coordonnées sur Internet.
> Nous recherchons un prestataire et nous souhaitons éventuellement vous
> consulter concernant un projet.
> Merci de me fixer un bref rendez-vous téléphonique à l’heure de votre
> choix (mardi ou mercredi).

Est-ce que 11h00 ce matin vous conviendrait?

Bien cordialement,

Eric van der Vlist

> pour un complément d’information.
>
> Bonne réception,
> Valerie P
> Arcadev

La réponse vient un peu plus tard :

De:     E-Nov Développement <valeriep@outlook.fr>
Reply-to:     <contact@e-prog.fr>
À:     Eric van der Vlist <vdv@dyomedea.com>
Sujet:     RE: informations relatives à notre projet
Date:     Tue, 14 Jan 2014 10:18:01 +0100

Merci, entendu c’est noté.
A quel numéro devrais-je vous joindre ?

Cordialement,
Valérie P
Arcadev

Voilà qui me donne un peu plus d’informations. La société E-Nov Développement est connue par societe.com, mais également par les moteurs de recherche :

J’aborde donc ce rendez vous téléphonique avec une certaine prudence. Valérie P marque un point en m’annonçant qu’elle m’envoie un mail décrivant le projet (« cool, un prospect sérieux qui m’envoie des éléments concrets pour que je comprenne ses besoins »).

De:     E-prog vp <contact@cybix.fr>
À:     vdv@dyomedea.com, DEMO <contact@e-prog.fr>
Sujet:     Projet
Date:     Tue, 14 Jan 2014 12:21:13 +0100

Bonjour,

Afin de consulter notre projet, veuillez cliquer sur les liens suivants

————————-Consultation projet ————————-
http://e-prog.fr/z_4647/iph/ok2.asp?tra=http://www.dyomedea.com

————————-Lien 2 ————————-
http://e-prog.fr/z_4647/iph/ok2.asp?tra=http://gossard.cybix.fr

————————-Notre Site ————————-
http://e-prog.fr

Cordialement,
01 49 76 96 26
contact@e-prog.fr

E-Nov
Siret : 40500275900034

Message securise l’antivirus Kapersky

Déception à l’arrivée : en guise de besoins le premier lien pointe sur un montage grossier ajoutant une vidéo standard sure une copie de mon site dyomedea.com en espérant me convaincre de faire appel à leurs services.

Sur son profil, Valérie P annonce avoir un « Master in European Business, International Marketing » de l’ESCP-EAP. Elle sait probablement ce qu’elle fait mais j’ai du mal à croire qu’elle puisse avoir un taux de conversion honorable quand elle décroche des rendez-vous téléphoniques sur la base de courriels mensongers!

On dit souvent qu’Internet est une jungle, un espace de non droit. Il est vrai que sans Internet je n’aurais jamais reçu ce mail. Par contre j’aurais pu recevoir le même type de message par courrier postal et sans Internet je n’aurais pas été capable de recueillir les informations sur la société E-Nov Développement…

Quant au « non droit », E-Nov Développement a déjà été condamné au moins une fois, et ce n’est peut être pas la dernière!

De:     Eric van der Vlist <vdv@dyomedea.com>
À:     abuse@outlook.fr
Sujet:     [Fwd: informations relatives à notre projet]
Date:     Tue, 14 Jan 2014 16:40:13 +0100

Bonjour,

Je souhaite vous signaler l’utilisation d’une adresse mail @outlook.fr
pour l’envoi de messages non sollicités (après contact de cette
personne, il s’avère qu’elle espérait me vendre une vidéo
« personnalisée » pour mon site web).

Il s’avère également que cette personne travaille pour la société « E NOV
DEVELOPPEMENT (E-NOV DEV) » [1] qui a déjà été condamnée pour avoir
utilisé une adresse mail hotmail pour l’envoi de tels messages [2].

[1]http://www.societe.com/societe/e-nov-developpement-405002759.html
[2]http://www.prodimarques.com/documents/gratuit/59/apercus-de-la-jurisprudence-recente.php

Cordialement,

Eric van der Vlist

How to customize GitLab to support OpenID authentication

Rational

While setting my GitLab servers I had to perform a number of customizations, the main one being to support OpenID and the method described here could thus be used to do any kind of customization.

If like me you try to use the software packages that come with your preferred Linux based operating system you’ll find the « official » installation guide for GitLab rather untypical. This installation guide seems to totally ignore Linux good practices such as separating configuration, programs and data into /etc, /usr and /var and installs everything under a standard user directory.

A benefit of this « simplification » is that the whole GitLab installation is a git clone of the GitLab source code (that would probably be more difficult if stuff were spread into multiple locations). And the beauty of using git clones is that updates are basically a matter of pulling a new version from the remote repository.

And if you need to « customize » the code you can take advantage of git and create you own local branch(es) which you can push into you own remote repository if you want to share the same customization between multiple GitLab installations.

Disclaimers

  1. I have been following these principles for an initial installation of GitLab 6.1 and upgrades to 6.2 and 6.3 without any major issues but of course I can’t guarantee that it will be the case for you: use at your own risk!
  2. Many thanks to Stephen Rees-Carter for a most helpful post that got me started.

In Practice

Initial installation

Start by a full installation following the « official » installation guide for GitLab and check that everything is running as expected. You could probably save some time by modifying the source during this initial installation but if anything went wrong you’d be in trouble to determine if this is a consequence of your modifications or anything else.

Stop the server

$ sudo service gitlab stop

Create a local branch

It’s a matter of taste but I tend to prefer running commands as the GitLab user (git if you’ve followed the installation guide to the letter) than prefixing them with sudo -u git -H as shown in the installation guide. Of course gitlab-shell will block you if you try to ssh directly as the GitLab user but you can  become the git-lab user using sudo and su:

$ sudo su - git

To create a local branch called openid and switch to this branch:

~$ cd gitlab
~/gitlab$ git checkout -b openid

 Add the omniauth-openid gem

Edit Gemfile to add gem ‘omniauth-openid‘ after gem ‘omniauth-github‘ so that it looks like:

# Auth
gem "devise", '~> 2.2'
gem "devise-async"
gem 'omniauth', "~> 1.1.3"
gem 'omniauth-google-oauth2'
gem 'omniauth-twitter'
gem 'omniauth-github'
gem 'omniauth-openid'

After this update you’ll need to create a new bundle. To do so you have to run the command bundle install as root (running sudo as a user which has enough rights). This will update the Gemfile.lock file and other resources which should belong to the GitLab:

~/gitlab$sudo bundle install
~/gitlab$sudo chown -R  gitlab.gitlab .

At that point, git status should tell you that you’ve updated both Gemfile and Gemfile.lock and you can commit this first step:

~/gitlab$ git commit -a -m "omniauth-openid gem installed"

Configuration

Update config/gitlab.yml to enable omniauth:

  ## OmniAuth settings
  omniauth:
    # Allow login via Twitter, Google, etc. using OmniAuth providers
    enabled: true

In a perfect world you should be able to configure OpenID as an omniauth provider here but unfortunately, the code that handles these definition (located in config/initializers/devise.rb) requires mandatory app_id and app_secret parameters used by proprietary protocols to lock users. OpenID doesn’t use these parameters and we’ll define OpenID providers directly in the code.

Defining OpenID providers

Update config/initializers/devise.rb to add the definition of the OpenID provider(s) so that it looks like:

...
      name_proc: email_stripping_proc
  end
# Update starts here
#  require "openid/fetchers"
  OpenID.fetcher.ca_file = "/etc/ssl/certs/ca-certificates.crt"

  config.omniauth :open_id,
    :name => 'google',
    :identifier => 'https://www.google.com/accounts/o8/id'

  config.omniauth :open_id,
    :name => 'openid'
# Update ends here
  Gitlab.config.omniauth.providers.each do |provider|
...

(Add the first declaration only if you want to offer OpenID authentication to Google users)

Define how these providers should be handled

Update app/controllers/omniauth_callbacks_controller.rb to include these definitions:

# Update starts here
  def google
     handle_omniauth
  end

  def openid
     handle_omniauth
  end
# Update ends here

  private

  def handle_omniauth

Declare these providers as « enabled social providers »

At that point, users should be able to login using OpenID if the relevant information was available in the database and we need to enable the user interface which will put these info in the database.

Update app/helpers/oauth_helper.rb to add OpenID (and google if you’ve defined it) to the list of « enabled_social_providers« :

  def enabled_social_providers
    enabled_oauth_providers.select do |name|
      [:openid, :google, :twitter, :github, :google_oauth2].include?(name.to_sym)
    end
  end

This list was initially limited to [:twitter, :github, :google_oauth2].

Disable protect_from_forgery in omniauth_callbacks_controller.rb

At that point, profile/account pages should present a list of « social accounts » including Google and OpenID. Unfortunately if you click on one of these buttons the authentication will succeed but the database update will be blocked by the protect_from_forgery feature.

This issue is documented in stackoverflow and GitHub and a workaround is to switch this feature in the controller that handles the authentication.

Update app/controllers/omniauth_callbacks_controller.rb to comment the third line and require to skip this:

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  # Update starts here
  #protect_from_forgery :except => :create
  skip_before_filter :verify_authenticity_token
  # Update ends here

  Gitlab.config.omniauth.providers.each do |provider|

Start the server and test

$ sudo service gitlab start
$ sudo service nginx restart # or sudo service apache2 restart

OpenID authentication should work fine at that point.

Commit

~/gitlab$ git commit -a -m "Ready for OpenID..."

Upgrades

To upgrade your GitLab installation you’ll need to merge the new version into your openid branch before you can follow the upgrade guide. For instance, to upgrade to version 6.3 I have typed:

~/gitlab$ git fetch
~/gitlab$ git checkout 6-3-stable # to have a look at the new version
~/gitlab$ git checkout openid # back to the local branch
~/gitlab$ git merge 6-3-stable

You may run into merge conflicts. During the upgrade to 6.3, the Gemfile had been updated and as a result of this update, Gemfile.lock was in conflict.

To fix this specific issue I have run the bundle install command again:

~/gitlab$sudo bundle install
~/gitlab$sudo chown -R  gitlab.gitlab .

When you’ve fixed your conflicts, you need to add the files in conflict and commit:

~/gitlab$ git add Gemfile.lock 
~/gitlab$ git commit -m "Merging 6.3"

From that point you should be able to follow standards upgrade instructions.

Using your own remote directory

If you need to install several servers with the same customization, you may want to push your branch to a remote directory.

To do so, you must define a new remote and specify whenever you push to that directory, for example:

~/gitlab$ git remote add myremote git@gitlab.example.com:gitlab/custom.git
~/gitlab$ git push myremote openid

Note that of course if you want to pull/push from the GitLab server you are working on it would need to be up and running ;) !

To install new servers you can now follow the standard installation guide just replacing the initial git clone by a clone of your own remote directory.