Je fais des installeurs automatiques pour mes logiciels Windows depuis des années. Là le challenge c’est le serveur PostgreSQL en tant que service Windows. J’utilise InnoSetup. Cet article a été complété
Pour les pressés
La dernière version de l’installateur est téléchargeable ici. Le mot de passe de l’utilisateur (du rôle) postgres se trouve dans le fichier pgpw dans le dossier d’installation.
Copier sur son voisin
Je suis parti de cet article qui mâche déjà pas mal le travail. Je résume :
- Installer Microsoft Visual C++ 2013 Redistributable Package
- Récupérer le ZIP de la distribution binaire de PostgreSQL
- Décompresser le ZIP
- Créer un cluster pour héberger les données
- Démarrer le serveur
Ça c’est la théorie. Enfin non, c’est exactement ça sauf que c’est en mode manuel et ça ne démarre pas le service, ne gère pas les droits ni rien. C’est une proof of concept.
On recommence proprement
D’abord j’ai créé un dossier pour stocker tout ce qui me sera utile pour fabriquer mon installeur et pour le mettre à jour à l’avenir. Il s’appelle K:\Dev\Delphi\PostreSQL
.
Ensuite, j’ai récupéré les 2 fichiers :
- Microsoft Visual C++ 2008 Redistributable Package
- PostgreSQL J’ai pris la version la plus récente en Windows 32 bits.
Et je les ai placés dans mon dossier. Je ne fais qu’une capture d’écran, j’expliquerai au fur et à mesure :
- (1) Le runtime VC++
- (2) Le ZIP de PostgreSQL
- (3) Le ZIP décompressé
- (4) Le mot de passe de
postgres
stocké dans ce fichier - (5) Le résultat final
Donc, ensuite, je décompresse le ZIP de PostgreSQL ce qui crée le sous-dossier pgsql
.
Les mots de passe
C’est un parti pris de ma part : il n’y a pas un grand risque sur le serveur PostgreSQL installé (il sera 90% du temps stocké sur la machine qui fait tourner mon application et dans presque tous les cas l’utilisateur sera administrateur de sa machine). Donc pour simplifier mon travail de maintenance, je force des mots de passe identiques partout. Cela n’empêche pas de les changer dans les cas où ce sera souhaité mais, par défaut, je veux du simple.
Les utilisateurs
On va devoir gérer 2 utilisateurs :
- l’un, interne à postgreSQL, que je vais nommer
postgres
- l’autre, spécifique à Windows, qui sera chargé d’exécuter le serveur, nommé
postgreswinuser
On n’utilise pas n’importe quel compte pour le service Windows, et notamment pas un compte administrateur, pour éviter que quelqu’un qui prendrait le contrôle du serveur PostgreSQL écrase, efface ou modifie des fichiers. Si l’utilisateur qui gère PostgreSQL n’a que des droits limités, il ne peut faire que des dégâts limités.
L’installeur InnoSetup
Je ne rentre pas dans tous les détails, si vous lisez ceci, soit vous connaissez déjà InnoSetup soit vous lirez des docs plus complètes que les banalités que je pourrais écrire ici.
J’ai commencé par créer un nouveau projet et l’ai configuré a minima (un nom, un répertoire, une version, etc.)
Le programme s’installe dans C:\postgresql
pour simplifier au maximum les droits d’écriture sur les Windows Vista, 7, 8.
Puis, j’ai ajouté la plupart des dossiers et sous-dossiers de pgsql dans C:\postgresql
. Je me contente de bin
, lib
, pgAdmin III
et share
. Les autres répertoires servent au debug ou à la doc et je veux un installeur le plus light possible.
Puis quelques fichiers/programmes complémentaires :
- vcredist_x86.exe (à installer dans {tmp})
- pgpw : le mot de passe de l’utilisateur
postgres
- LogOnAsService.exe (dans {tmp}) : un utilitaire de mon crû pour combler un manque hallucinant dans Windows
Il faut enfin créer deux dossiers : un pour les données (data), l’autre pour les logs (log).
Commandes à exécuter
C’est là le seul intérêt de ce tutoriel.
1. D’abord installer le runtime VC++
Nom de fichier : {tmp}\vcredist_x86.exe
Paramètres : /q
/q permet une installation silencieuse
2. Créer l’utilisateur windows
Nom de fichier : {sys}\net.exe
Paramètres : user postgreswinuser m0tdePa55e /add /expires:never
3. Faire en sorte que notre utilisateur puisse se logger en tant que service
Quand on associe un utilisateur à un service manuellement, Windows modifie automatiquement le profil de cet utilisateur pour lui autoriser de se logger en tant que service. Mais je n’ai pas trouvé d’utilitaire intégré pour le faire en ligne de commande. Ni sc
, ni net
, ni subinacl
. Il semblerait qu’un outil NTrights
distribué par Microsoft le fasse mais dans je ne sais quel kit de ressource, qui nécessite une installation particulière, bref, une usine à gaz.
Après de looonnngues recherches, j’ai fini par mettre la main sur un petit bout de code Delphi qui fait ça. J’en ai fait un utilitaire ultra-basic. Ça pèse 100Ko, je le distribue comme je veux et j’ai le source. Vous pouvez le télécharger avec les sources ici.
Remerciements à Hannes Danzl pour ce code qu’on trouve ici. Ironie du sort, ce code sert à installer NexusDB que je remplace aujourd’hui par PostgreSQL.
Nom de fichier : {tmp}\LogOnAsService.exe
Paramètres : postgreswinuser
4. Créer le cluster PostgreSQL
Nom de fichier : {app}\bin\initdb.exe
Paramètres : -U postgres -A password -E utf8 --pwfile {app}\pgpw -D {app}\data
5. Déclarer le service
Nom de fichier : {app}\bin\pg_ctl.exe
Paramètres : register -N "postgresql" -U "postgreswinuser" -P m0tdePa55e -D {app}\data -w
6. Donner les droits sur le répertoire data à l’utilisateur postgreswinuser
Nom de fichier : {sys}\cacls
Paramètres : c:\postgresql /E /T /G postgreswinuser:F
7. Démarrer le service
Nom de fichier : {sys}\sc
Paramètres : start postgresql
Conclusion
Voilà, c’est un début, le plus gros du travail est opérationnel. Je n’ai pas encore testé sur un système 64 bits ou sur différents Windows. Je compléterai au fur et à mesure. Vos commentaires sont les bienvenus.
Astuces complémentaires
- Vous pouvez modifier les fichiers
share\pg_hba.conf.sample
etshare\postgresql.conf.sample
pour personnaliser un peu vos configurations : ces fichiers seront recopiés tel quel lors de la création du cluster.
Ouvrir une session en tant que service
Pour donner à postgres le droit de se connecter en tant que service :
Outils d’administration
Stratégie de sécurité locale
Stratégies locales
Attribution des droits utilisateur
Ouvrir une session en tant que service
Expiration des mots de passe
Attention à l’expiration du mot de passe (Windows 7+ notamment)
Pour les versions familiales :
net accounts /maxpwage:unlimited
Pour les autres :
Outils d’administration
-> Stratégie de sécurité locale
-> Stratégie de comptes
-> Stratégie de mots de passe
-> Durée de vie max du mot de passe -> mettre 0 (zéro) pour illimité
Comme j’ai ajouté le paramètre /expires:never
à la création de l’utilisateur, le problème ne devrait pas se produire mais bon… chat échaudé craint l’eau froide.
Amélioration possibles
Il n’y a que l’embarras du choix :
- Choix des mots de passe pour l’utilisateur Windows
postgreswinuser
et le rôlepostgres
Choix du dossier de stockage des données (levoir iciC:\PostgreSQL\Data
actuel)- Versions 32 et 64 bits
- Gestion des erreurs
Sur un Active Directory, pour donner à postgres le droit de se connecter en tant que service :
* Outils d’administration
* Stratégie de sécurité locale
* Stratégies locales
* Attribution des droits utilisateur
* Ouvrir une session en tant que service
Bonsoir et merci pour le tutoriel.
J’ai utilisé votre .iss avec les fichiers donnés. Toute marche bien sans base de donnes à créer. Mais quad je remplie un champs pour créer une base de donnée, Là il reste bloqué.
Merci de votre aide.