Fossil comme alternative à GIT

Fossil, c’est une alternative à GIT pour les petits projets, parfaite pour l’auto-hébergement.

Fossil a été créé par l’équipe en charge de sqlite pour sqlite et il embarque dans un petit exécutable (quelques Mo):

  • un serveur web
  • un wiki
  • un interface web pour visualiser branches, timelines, sources,…
  • un forum
  • une gestion de tickets
  • un serveur emails
  • sans doute encore des trucs que je n’ai pas encore découvert

C’est simple à mettre en place et ça tourne efficacement sur un petit Raspberry PI model B avec ses monstrueux 256M de RAM.

Une fois lancé en tant que serveur Fossil et serveur Web, il ne prend qu’une petite dizaine de Mo et peut servir plusieurs référentiels simultanés.

Pour ce qui est de la gestion de version, il a une autre petite particularité qui fait du bien.

Fossil peut fonctionner de la même manière que GIT c’est à dire un référentiel local autonome que tu push vers le serveur central, ou comme ce bon vieux Subversion où chaque commit et automatiquement remonté au serveur central.

Ce deuxième mode de fonctionnement nommé autosync est celui par défaut et quand tu bosses seul sur ton petit repo, ça suffit très largement et ça repose.

Installation

Sur une Debian que ce soit pour le serveur ou pour le poste de travail rien de plus simple:

sudo apt-get install fossil

Mise en place d’un serveur fossil

Allez, on se lance, on commence par créer un référentiel local (parceque.fossil):

  fossil init parceque.fossil
  project-id: 01ed61dcef6cec575fe1d9f637be53921bdd784f
  server-id:  58cfb5deb5d54e251b27e783e261a6a38947f56a
  admin-user: <utilisateur> (initial password is "effd20")

La commande a créé un fichier nommé parceque.fossil que l’on va pouvoir déplacer sur le serveur pour le rendre dispo sur le réseau.

Un utilisateur administrateur est créé avec un mot de passe dont la complexité est un peu light et par défaut le contenu est en grande partie publique ce que l’on ne veut pas forcément non plus.

Pour modifier tout cela, il suffit de lancer l’interface web en local, de modifier le mot de passe administrateur dans admin/users et de suivre les conseils dans admin/security-audit .

fossil ui parceque.fossil 
Listening for HTTP requests on TCP port 8080

admin/users Interface web d&rsquo;administration/users

admin/security-audit Interface web d&rsquo;administration/security-audit

Cela fait on arrête le serveur local (^C) et on copie simplement le fichier parceque.fossil vers un répertoire utilisateur du serveur. Le serveur fossil peut parfaitement tourner en tant qu’utilisateur non privilégié.

scp parceque.fossil <ip-ou-nom-du-serveur>:
ssh <ip-ou-nom-du-serveur>
mkdir fossil
mv parceque.fossil fossil/

En peut alors créer un service systemd par exemple sudo vi /etc/systemd/system/fossil.service:

==/etc/systemd/system/fossil.service==

[Unit]
Description=Fossil server
After=network.target


[Service]
User=<utilisateur>
Group=<utilisateur>
ExecStart=fossil server -P 8080 /home/<utilisateur>/fossil/
Restart=on-failure

[Install]
WantedBy=multi-user.target

On peut alors activer le service et le démarrer:

sudo systemctl enable fossil.service
sudo systemctl start fossil.service

A ce moment, le ou les référentiels présents dans le répertoire /home/utilisateur/fossil/ sont disponibles à une adresse du type http://ip-ou-nom-du-serveur:8080/référentiel.

Utilisation de fossil

Pour travailler sur le référentiel en mode autosync commence par cloner:

fossil clone http://<utilisateur>@ip-ou-nom-du-serveur:8080/parceque parceque.fossil
Round-trips: 2   Artifacts sent: 0  received: 4
Clone done, sent: 542  received: 1276  ip: 192.168.67.151
Rebuilding repository meta-data...
  100.0% complete...
Extra delta compression... 
Vacuuming the database... 
project-id: 01ed61dcef6cec575fe1d9f637be53921bdd784f
server-id:  0a31e22ffb47ae7afbd98aca5fbcf0a93e862a17
admin-user: <utilisateur>(password is "074f65")

On se retrouve alors avec un fichier parceque.fossil local (une copie du référentiel central).

On peut alors faire un checkout de la branche par défaut:

mkdir parceque
cd parceque/
fossil open ../parceque.fossil 
project-name: <unnamed>
repository:   /home/<utilisateur>/fossil/parceque/../parceque.fossil
local-root:   /home/<utilisateur>/fossil/parceque/
config-db:    /home/<utilisateur>/.fossil
project-code: 01ed61dcef6cec575fe1d9f637be53921bdd784f
checkout:     6343e456aaf52659d8c2ada8b3971d9dd6f335d9 2021-04-01 19:46:13 UTC
tags:         trunk
comment:      initial empty check-in (user: laurentu)
check-ins:    1

Une fois dans ce répertoire de travail l’utilisation reste très classique.

  • Ajouter un nouveau fichier
touch zz.txt

fossil add zz.txt 
ADDED  zz.txt

fossil commit -m "Premier commit"
Autosync:  http://<utilisateur>@192.168.67.151:8080/parceque
Round-trips: 1   Artifacts sent: 0  received: 0
Pull done, sent: 379  received: 339  ip: 192.168.67.151
New_Version: 5bf5fcf4667b757bf940ed693102dfe32d2d7d35d7764050f18caca281a14b5f
Autosync:  http://<utilisateur>@192.168.67.151:8080/parceque
Round-trips: 1   Artifacts sent: 2  received: 0
Sync done, sent: 627  received: 417  ip: 192.168.67.151
  • Modifier un fichier déjà sous le contrôle de fossil
echo 'test' >> zz.txt

fossil status
repository:   /home/<utilisateur>/fossil/parceque/../parceque.fossil
local-root:   /home/<utilisateur>/fossil/parceque/
config-db:    /home/<utilisateur>/.fossil
checkout:     5bf5fcf4667b757bf940ed693102dfe32d2d7d35 2021-04-02 08:50:37 UTC
parent:       539b5ea0898e06ca3e078da93bd0683439580555 2021-04-02 08:48:47 UTC
tags:         trunk
comment:      Premier commit (user: <utilisateur>)
EDITED     zz.txt

fossil commit -m "Deuxième commit"
Autosync:  http://<utilisateur>@192.168.67.151:8080/parceque
Round-trips: 2   Artifacts sent: 0  received: 1
Pull done, sent: 801  received: 1090  ip: 192.168.67.151
New_Version: 8a9306b3d7684c9c3842f49a739485398f82dbd907d9d01c775d442346f20cbc
Autosync:  http://<utilisateur>@192.168.67.151:9091/parceque
Round-trips: 1   Artifacts sent: 2  received: 0
Sync done, sent: 787  received: 561  ip: 192.168.67.151
  • Supprimer un fichier sous contrôle
fossil rm zz.txt
fossil commit -m "Troisième commit"

Attention Le fichier est supprimé du contôle de fossil, mais pas du système de fichier.

  • Status

Comme les autres scm fossil possède la commande status.

fossil status
repository:   /home/<utilisateur>/fossil/parceque/../parceque.fossil
local-root:   /home/<utilisateur>/fossil/parceque/
config-db:    /home/<utilisateur>/.fossil
checkout:     8a9306b3d7684c9c3842f49a739485398f82dbd9 2021-04-02 14:56:49 UTC
parent:       5bf5fcf4667b757bf940ed693102dfe32d2d7d35 2021-04-02 08:50:37 UTC
tags:         trunk
comment:      Deuxième commit (user: <utilisateur>)
DELETED    zz.txt

Par contre cette commande n’affiche pas les fichiers hors de son contrôle, mais la commande fossil extras est faite pour ça.

Publication https sur le web

Là, on sort du champ de fossil, pour ma part j’ai l’habitude d’utiliser nginx comme frontend http/https.

On commence par installer le logiciel:

sudo apt-get install nginx-light certbot

Puis on crée le virtualhost dédié à notre fossil (sudo vi /etc/nginx/sites-available/fossil), dans un premier temps sans https, en attendant de récupérer un certificat Let’s encrypt.

==/etc/nginx/sites-available/fossil==

server {
        listen 80;
        listen [::]:80 ;
        
        server_name <mon-domaine>;
        root /var/www/html;
        
        location /.well-known {
                try_files $uri $uri/ = 404;
        }
        location / {
                return 301 https://$host$request_uri;
        }       
}       

On peut maintenant demander la création d’un certificat Let’s encrypt.

certbot --webroot --webroot-path /var/www/html/ certonly -d <mon-domaine>

Enfin on peut activer la configuration https:

==/etc/nginx/sites-available/fossil==

server {
        listen 443 ssl;
        listen [::]:443 ssl;
        
        client_max_body_size 16M;
        root /var/www/html;
        server_name <mon-domaine>;
        
        ssl_certificate /etc/letsencrypt/live/<mon-domaine>/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/<mon-domaine>/privkey.pem;
                
        location /.well-known {
                try_files $uri $uri/ = 404;
        }
        location / {
                include proxy_params;
                proxy_pass http://127.0.0.1:8080;
        }
}       
        
server {
        listen 80;
        listen [::]:80 ;
        server_name <mon-domaine>;
        root /var/www/html;
        
        location /.well-known {
                try_files $uri $uri/ = 404;
        }
        location / {
                return 301 https://$host$request_uri;
        }       
}       

Une fois le frontend nginx opérationnel, il devient inutile de laisser le service fossil en écoute sur l’ensemble des IP du serveur, localhost suffit.

On modifie donc le fichier fossil.service:

==/etc/systemd/system/fossil.service==

[Unit]
Description=Fossil server
After=network.target


[Service]
User=<utilisateur>
Group=<utilisateur>
ExecStart=fossil server --localhost -P 8080 /home/<utilisateur>/fossil/
Restart=on-failure

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl restart fossil.service