Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Quickstart Official documentation Setuphelpers Changelog FAQ
Back to top
View this page
Toggle table of contents sidebar

# 1. Créer des paquets WAPT

## 1.1. Créer son environnement de développement de paquets WAPT

### 1.1.1. Pré-requis

Attention

- Il est impératif d’être en possession d’un compte Administrateur Local de la machine pour cette opération.

- Nous vous conseillons de créer / éditer vos paquets dans un environnement maîtrisé, sain et jetable.

- L’utilisation d’une machine virtuelle autonome (type Virtualbox ou équivalent) est vivement recommandée.

- Importer le paquet tis-waptdev dans votre dépôt local et l’installer sur votre machine de développement.

### 1.1.2. Préconisations concernant l’environnement de test

La méthode préconisée pour tester correctement vos paquets est d’utiliser un échantillon de machines représentatif de votre parc. Donc plus votre parc est hétérogène, plus votre échantillon devra être large.

Cette démarche vise à confronter le paquet WAPT à une multitude de plateformes et environnements afin qu’il devienne le plus abouti possible en régime de test, avant d’être basculé en production.

Pour expliquer le fonctionnement des maturités de paquets, vous pouvez vous référer à cette vidéo.

### 1.1.3. Démarche de test

#### 1.1.3.1. Systèmes d’exploitation et architectures

Systèmes d’exploitation de bureau

Windows XP | Windows 7 | Windows 10
Windows 10 | Redhat et dérivés | Debian et dérivés

Systèmes d’exploitation pour serveurs

Windows Serveur 2008 R2 | Windows Serveur 2012 | Windows Serveur 2008 R2

Architectures

x86 | x64 | arm64 (tech preview)

Environnements de déploiement

Machine physique et virtuelle | Des ordinateurs portables

On testera si possible les versions RC / Beta des OS si elles sont disponibles (exemple : Windows 10 Creators Update).

#### 1.1.3.2. L’état des mises à jour Windows

- Un poste Microsoft Windows sans aucune mise à jour Windows Update : l’objectif est de détecter les mises à jour indispensables au bon fonctionnement du logiciel et adapter le paquet en conséquence ;

- Un poste Microsoft Windows à jour avec les toutes dernières MàJ Windows Update : l’objectif est de détecter les mise à jour en conflit avec le logiciel et d’adapter le paquet en conséquence ;

#### 1.1.3.3. État des installations des logiciels

- Un poste avec peu de logiciels déjà installés : l’objectif est de détecter une dépendance possible à Java ou autre framework applicatif ;

- Les postes avec beaucoup de logiciels déjà installés: l’objectif est de détecter un conflit avec une application existante ;

- Installer les anciennes versions du logiciel : il est possible que l’installeur ne supporte pas l’écrasement d’une installation précédente, dans ce cas il faudra prévoir la désinstallation des anciennes versions avant d’installer la nouvelle version ;

## 1.2. Les principes de création d’un paquet WAPT à partir d’un modèle depuis la console

Attention

Pour créer des paquets à partir de la console, il faut d’abord avoir installé l’environnement de développement WAPT tis-pyscripter3 ou tis-vscode. Il n’est PAS recommandé d’utiliser tis-pyscripter4.

Nous vous recommandons de télécharger le paquet tis-waptdev et de l’installer sur votre ordinateur où vous créerez les paquets WAPT.

Si vous ne savez plus comment télécharger un paquet depuis le store Tranquil IT, veuillez consulter comment télécharger un paquet dans votre dépôt privé.

Si vous ne savez plus comment installer un paquet, veuillez consulter comment installer un paquet sur un hôte.

### 1.2.1. Créer un paquet WAPT depuis la Console WAPT

Nous utilisons l’installation MSI de 7-zip téléchargée depuis le site officiel de 7-zip.

- Télécharger tis-7zip for x64.

- Créer le modèle de paquet depuis l’installeur.

  In the WAPT Console, click on Packages –> Make package from setup from file:

  Les principes de création d’un paquet WAPT à partir d’un modèle depuis la console

  Sélectionnez le fichier d’installation MSI téléchargé (Windows installer(.msi/.msix/.exe)) et remplissez les champs obligatoires. Vérifiez que le nom du paquet ne contient pas de numéro de version.

  Boîte de dialogue demandant des informations lors de la création du packaging WAPT dans la Console WAPT

- Deux solutions sont proposées :

  - Click on Make and edit (recommended) to verify the WAPT package and customize it to your Organization’s specific needs.

  - Click on Make and upload to directly build and upload the package into your private repository.

  Avertissement

  Le bouton Build and upload envoi directement le paquet dans le dépôt privé sans tester l’installation.

  Cette méthode fonctionne assez bien avec les MSI car leur installation est standard.

  Cependant la deuxième méthode qui consiste à tester localement le paquet d’abord puis à l’uploader est la méthode recommandée.

Note

Si vous préférez utiliser la ligne de commande, vous pouvez utiliser cette méthode.

### 1.2.2. Personnaliser le paquet avant de le téléverser dans votre dépôt

La méthode conseillée avant l’upload d’un paquet est de personnaliser son comportement en l’éditant avec PyScripter.

Lors de la création du modèle de paquet, cliquez sur Editer manuellement.

« Modifier manuellement » dans la boîte de dialogue

Fenêtre de message indiquant dans la Console WAPT que le packaging WAPT a été téléchargé dans le dépôt WAPT.

Informations sur la création du paquet

L’IDE PyScripter se lance et permet d’éditer les fichiers du paquet.

PyScripter - Personnalisation du paquet avec PyScripter

### 1.2.3. Présentation de PyScripter

#### 1.2.3.1. L’explorateur de projets PyScripter

C’est la vue initiale de l’explorateur Pyscripter lorsque vous ouvrez un paquet WAPT.

PyScripter - Navigation d’un projet dans l’explorateur de fichiers de PyScrypter

L’explorateur de projets PyScripter liste les différents fichiers dont vous pouvez avoir besoin, notamment le fichier `control` et le fichier `setup.py`.

#### 1.2.3.2. Zone d’édition

Le panneau d’édition en orange dans l’image ci-dessus.

Le panneau d’édition dans PyScripter permet d’éditer le fichier `setup.py` et le fichier `control`.

#### 1.2.3.3. Run Configurations

Dans l’image ci-dessus, la boîte la box verte affiche les configurations préinstallées.

Les options de Run dans l’explorateur de projets de PyScripter vont vous permettre de lancer des actions de votre paquet en cours d’édition.

Ses fonctions sont expliqués dans le tableau ci-dessous.

Liste de fonctions pour la création de paquet.
Fonction | Description
--- | ---
install | Permet d’installer le paquet sur le système de notre machine de test.
remove | Utilisé pour désinstaller le paquet du système de la machine de test.
uninstall | Permet d’exécuter une désinstallation personnalisée du package de la machine de test.
session_setup | Permet d’installer le paquet via le contexte utilisateur de la machine de test.
session_cleanup | Permet de nettoyer les changements effectués dans le contexte de l’utilisateur
audit | Permet d’auditer le paquet.
update-package-source | Automatiser la mise à jour d’un paquet logiciel.

#### 1.2.3.4. Console Python

PyScripter - console python de PyScripter

C’est la console python visible dans PyScripter, elle va vous permettre d’afficher la sortie python lorsque vous exécuterez des commandes run.

Vous pouvez également l’utiliser pour tester / déboguer des portions de votre script `setup.py`.

Pour en savoir plus sur la composition d’un paquet WAPT, consultez la documentation sur la structure détaillée d’un paquet.

#### 1.2.3.5. Tester localement l’installation du paquet WAPT

Vous pouvez ensuite tester le lancement d’une installation sur votre station de développement.

La Console PyScripter vous permet de vérifier si l’installation s’est bien déroulée.

#### 1.2.3.6. Tester localement la désinstallation du paquet WAPT

Vous pouvez ensuite tester le lancement d’une installation sur votre station de développement.

La Console PyScripter vous permet de vérifier si l’installation s’est bien déroulée.

### 1.2.4. Explorer les fichiers du paquet depuis la Console WAPT

Pour explorer tous les fichiers d’un paquet WAPT via la Console WAPT, vous devez activer l’option Afficher les fonctionnalités de développeur. Pour ce faire :

- Aller dans le menu `Affichage` de la Console WAPT.

- Sélectionner Préférences d’affichage et cocher Afficher les fonctionnalités de développeur.

Comment explorer les fichiers du paquet ? Naviguez dans la section WAPT Packages, sélectionnez votre paquet et faites un clic droit sur `Edit_package`

Une fois activé, vous pouvez accéder à l’explorateur de fichiers du paquet.

Console WAPT mode développeur

## 1.3. Créer vos premiers paquets WAPT

### 1.3.1. Packager des .msi (exemple)

Pour cet exemple, nous prendrons tightvnc.

Vous pouvez le télécharger ici.

Maintenant, vous pouvez générer votre modèle de paquet, veuillez vous référer à la documentation pour la création de paquets à partir de la Console WAPT.

Editer le fichier `control` (`architecture`, `impacted_process`, `target_os`, `description`, `maintainer` …), veuillez vous référer à la structure du fichier documentation du fichier control.

Votre pyscripter s’ouvre, allez dans votre `setup.py` :

    # -*- coding: utf-8 -*-
    from setuphelpers import *

    uninstallkey = []

    def install():
        print('installing tis-tightvnc')
        install_msi_if_needed('tightvnc-2.8.5-setup-64bit.msi')

- La fonction testera également si une version du logiciel est déjà installée sur la machine avec la clé de désinstallation.

- Si présence il y a, l’installation sera enclenchée uniquement si la version actuellement installée est plus ancienne.

- Après installation, la fonction testera finalement la présence de la clé de désinstallation et sa version pour vérifier que tout s’est bien passé.

Liste des arguments disponibles avec install_exe_if_need
Options (Option par défaut) | Description
--- | ---
`min_version` (par défaut `None`) | Définit la version minimale au dessus de laquelle le logiciel se mettra à jour.
`killbefore` (par défaut `None`) | Liste des programmes à tuer avant de lancer l’installation.
`accept_returncodes` (par défaut `[0,3010]`) | Définit les codes de retour autres que 0 ou 3010 acceptés en retour par la fonction.
`timeout` (par défaut `300`) | Définit la durée d’attente maximale d’installation (en secondes).
`propriétés` (par défaut `None`) | Définit les propriétés supplémentaires à passer en argument au MSI pour l’installation.
`get_version` (par défaut `None`) | Définit la valeur passée en paramètre pour le contrôle de version au lieu de celle retournée par la fonction installed_softwares.
`remove_old_version` (défaut `False`) | Supprime automatiquement une ancienne version d’un logiciel dont la clé de désinstallation est identique.
`force` (par défaut `False`) | Force l’installation du logiciel même si une clé de désinstallation avec une version identique est trouvée.

La fonction install_msi_if_needed récupère la clé de désinstallation depuis le MSI, il n’est pas nécessaire de l’écrire dans le fichier `setup.py`.

Vous n’avez pas non plus à remplir le champ `killbefore` si la valeur indiquée dans le champ `impacted_process` du fichier `control` est correcte.

Note

Le `setup.py` aurait pu ressembler à cela, mais la méthode est moins élégante car elle fait moins de vérifications.

>     # -*- coding: utf-8 -*-
>     from setuphelpers import *

>     uninstallkey = ["{8B9896FC-B4F2-44CD-8B6E-78A0B1851B59}"]

>     def install():
>         print('installing tis-tightvnc')
>         run('msiexec /norestart /q /i "tightvnc-2.8.5-setup-64bit.msi"')

Lancez l’installation et voyez ce qui se passe lorsque le logiciel est déjà installé.

    wapt-get -ldebug install C:\waptdev\tis-tightvnc-wapt
    Installing WAPT file C:\waptdev\tis-tightvnc-wapt
    MSI tightvnc-2.8.5-gpl-setup-64bit.msi already installed. Skipping msiexec

    Results:

    === install packages ===
    C:\waptdev\tis-tightvnc-wapt | tis-tightvnc (2.8.5.0-1)

#### 1.3.1.1. Ajouter des propriétés supplémentaires en argument

Pour ajouter des propriétés supplémentaires on va les stocker dans un élément dict.

    # -*- coding: utf-8 -*-
    from setuphelpers import *

    uninstallkey = []

    properties = {
        'SERVER_REGISTER_AS_SERVICE': 0,
        'SERVER_ADD_FIREWALL_EXCEPTION': 0,
        'ADDLOCAL': 'Server,Viewer'

        }

    def install():
        print(u'Installation en cours de TightVNC')
        install_msi_if_needed('tightvnc-2.8.5-setup-64bit.msi', properties = properties )

Note

Le `setup.py` aurait pu ressembler à cela, mais la méthode est moins élégante car elle fait moins de vérifications.

>     # -*- coding: utf-8 -*-
>     from setuphelpers import *

>     uninstallkey = ["{8B9896FC-B4F2-44CD-8B6E-78A0B1851B59}"]

>     def install():
>         print('installing tis-tightvnc')
>         run('msiexec /norestart /q /i "tightvnc-2.8.5-setup-64bit.msi" SERVER_REGISTER_AS_SERVICE=0 SERVER_ADD_FIREWALL_EXCEPTION=0')

#### 1.3.1.2. Vidéo de démonstration

### 1.3.2. Packager des .exe (exemple)

- Télécharger l’installateur .exe à partir d’une source fiable.

  Télécharger l’installateur au format exe Firefox ESR x64 sur https://download.mozilla.org/?product=firefox-esr-latest-ssl&os=win64.

- Rechercher la documentation associée pour les flags silencieux :

  - Sur le site de la Fondation Mozilla .

  - Autres méthodes pour récupérer le flag silencieux :

    - Dépôt de paquets WPKG ;

    - Dépôt de paquets Chocolatey ;

    - Recherche Internet avec le terme Firefox silent install.

- Puis générer votre modèle de paquet, veuillez vous référer à la documentation pour la création de paquets à partir de la Console WAPT. PyScripter se charge et ouvre le projet de paquet .exe.

  PyScripter - Ouverture du paquet WAPT de FirefoxESR

- Editer le fichier `control` (`architecture`, `impacted_process`, `target_os`, `description`, `maintainer` …), veuillez vous référer à la structure du fichier documentation du fichier control.

- Vérifier le contenu du fichier `control`. Mozilla Firefox-ESR ne répond pas aux standards et retourne un numéro de version erroné (il s’agit du numéro de version du logiciel qui créé l’installeur).

  - Fichier `control` d’origine.

        package           : tis-firefox-esr
        version           : 4.42.0.0-0
        architecture      : all
        section           : base
        priority          : optional
        maintainer        : user
        description       : automatic package for firefox setup 52.6.0esr
        impacted_process  :

  - Fichier `control` modifié.

        package           : tis-firefox-esr
        version           : 52.6.0-1
        architecture      : all
        section           : base
        priority          : optional
        maintainer        : Tranquil-IT Systems
        description       : Mozilla Firefox 52.6.0 ESR
        impacted_process  : firefox.exe

  Il est à noter qu’une sous-version -1 a été ajoutée au numéro de version du logiciel ; il s’agit de la version de packaging du paquet WAPT.

  Il permet au développeur de paquets de publier plusieurs versions de paquets WAPT d’un même logiciel, ce qui est très utile pour un développement très rapide et itératif.

Utiliser install_exe_if_needed

La fonction est sensiblement la même que celle utilisée pour les installeurs .msi, avec quelques différences :

- La fonction nécessite l’ajout des flags silencieux en paramètre.

- La fonction nécessite l’ajout de la clé de désinstallation en paramètre.

    # -*- coding: utf-8 -*-
    from setuphelpers import *

    uninstallkey = []

    def install():
        print('installing tis-firefox-esr')
        install_exe_if_needed("Firefox Setup 45.5.0esr.exe",silentflags="-ms",key='',min_version="4.42.0.0")

Liste des arguments disponibles avec install_exe_if_need
Options (Option par défaut) | Description
--- | ---
`silentflags` (par défaut `None`) | Paramètres silencieux à passer en argument à l’installeur.
`key` (par défaut `None`) | Clé de désinstallation du programme.
`min_version` (par défaut `None`) | Définit la version minimale au dessus de laquelle le logiciel se mettra à jour.
`killbefore` (par défaut `None`) | Liste des programmes à tuer avant de lancer l’installation.
`accept_returncodes` (par défaut `[0,3010]`) | Définit les codes de retour autres que 0 ou 3010 acceptés en retour par la fonction.
`timeout` (par défaut `300`) | Définit la durée d’attente maximale d’installation (en secondes).
`get_version` (par défaut `None`) | Définit la valeur passée en paramètre pour le contrôle de version au lieu de celle retournée par la fonction installed_softwares. Exemple https://forum.tranquil.it/viewtopic.php?t=1337.
`remove_old_version` (défaut `False`) | Supprime automatiquement une ancienne version d’un logiciel dont la clé de désinstallation est identique.
`force` (par défaut `False`) | Force l’installation du logiciel même si une clé de désinstallation avec une version identique est trouvée.

Le paquet aura alors ce comportement :

- Le logiciel Firefox s’installera uniquement si le logiciel n’est pas installé et si la version est strictement inférieure à 45.5.0, sauf si l’option `--force` est indiquée lors de l’installation du paquet.

- A l’installation, les processus firefox.exe en cours d’exécution seront tués (avec la valeur indiquée dans `impacted_process` du fichier `control`).

- La fonction ajoutera elle-même la clé de désinstallation, donc laisser l’argument clé de désinstallation vide.

- A la fin de l’installation, la fonction ira vérifier si la clé de désinstallation est bien présente sur le poste et si la version est bien égale ou supérieure à 45.5.0, si ce n’est pas le cas, elle basculera le paquet en ERREUR.

#### 1.3.2.1. Trouver la clé de désinstallation

Contrairement aux fichiers .msi, la clé pour désinstaller un .exe n’est pas dans les propriétés du fichier.

Vous devez donc d’abord installer le logiciel pour connaître la clé de désinstallation.

Vous devez donc démarrer une fois l’installation à partir de pyscripter avec le run configuration et ensuite install.

Une fois le logiciel installé, allez à la Console WAPT, puis trouvez votre machine de développement.

Dans l’onglet inventaire des logiciels, trouvez votre logiciel et copiez la valeur indiquée dans la colonne clé de désinstallation.

Récupérer une clé de désinstallation depuis la Console WAPT

Vous devez également vérifier la valeur de la version avec la valeur indiquée dans `min_version` dans votre `setup.py`.

Modifier votre fichier `setup.py` avec les nouveaux paramètres :

    # -*- coding: utf-8 -*-
    from setuphelpers import *

    uninstallkey = []

    def install():
        print('installing tis-firefox-esr')
        install_exe_if_needed("Firefox Setup 45.5.0esr.exe",silentflags="-ms",key='Mozilla Firefox 45.5.0 ESR (x64 fr)',min_version="45.5.0")

Pour tester que votre clé fonctionne correctement, vous DEVEZ relancer une installation dans pyscripter.

WAPT ne tentera pas d’installer le logiciel car il est déjà présent, le message suivant devrait donc s’afficher :

    >>>
    *** Remote Interpreter Reinitialized ***
    Command Line : install "c:\waptdev\tis-firefox-esr_x64_PROD_fr-wapt\WAPT\.."
    Using config file: C:\Program Files (x86)\wapt\wapt-get.ini
    Installing WAPT files c:\waptdev\tis-firefox-esr_x64_PROD_fr-wapt
    Exe setup Firefox_Setup_78.7.1esr.exe already installed. Skipping

    Results:

    === install packages ===
    c:\waptdev\tis-firefox-esr_x64_PROD_fr-wapt | tis-firefox-esr (78.7.1-102)

Vous pouvez maintenant tester la désinstallation :

Vous pouvez maintenant construire et envoyer votre paquet, veuillez vous référer à la documentation pour construire et envoyer des paquets depuis la Console WAPT.

Note

Si vous laissez la clé de désinstallation vide, la désinstallation de votre paquet ne fonctionnera pas.

#### 1.3.2.2. Cas particulier d’un dé-installeur non-silencieux

Dans certains cas particuliers, un paquet utilisant install_exe_if_needed remplit la clé de désinstallation, mais la clé de désinstallation pointe vers un désinstalleur non silencieux.

Il nous faut contourner le problème en utilisant une fonction qui va supprimer la clé de désinstallation à la fin de l’installation.

    :emphasize-lines: 13

    # -*- coding: utf-8 -*-
    from setuphelpers import *

    uninstallkey = []

    def install():
        install_exe_if_needed("setup.exe",
                              silentflags="/s",
                              key='{D9E87643-0005-447E-9111-78697A9C1595}',
                              min_version="14.0")
        uninstallkey.remove('{D9E87643-0005-447E-9111-78697A9C1595')

    def uninstall():
        run(r'"C:\Program Files\Kutl\uninstall.exe" /supersilent')

Indication

La fonction de désinstallation peut également être utilisée pour exécuter du code en plus de la désinstallation de logiciels, ex : supprimer un dossier, supprimer un raccourci …

#### 1.3.2.3. Vidéo de démonstration

### 1.3.3. Packager des paquets linux simples

### 1.3.4. Construire le paquet et l’envoyer au Serveur WAPT

- Une fois que le paquet est prêt, le construire et l’envoyer au Serveur WAPT, dans la Console WAPT.

- Sélectionner le paquet dans le dossier `c:\waptdev`.

Fenêtre du navigateur permettant de sélectionner le paquet WAPT à importer dans le dépôt privé

- Confirmer le paquet sélectionné.

Boîte de dialogue de la Console WAPT pour confirmer l’importation d’un paquet WAPT dans le dépôt privé

Vous venez de charger votre premier paquet wapt.

Note

Une ancienne méthode en ligne de commande est disponible ici.

Avertissement

Une fois que votre paquet est téléversé, rafraîchissez la liste des paquets en utilisant le bouton Actualiser les paquets disponibles ou en appuyant sur la touche `F5` de votre clavier.

#### 1.3.4.1. Travailler avec des codes de retour non standard

Les codes de retour sont utilisés pour indiquer si un logiciel a été correctement installé.

Avec Windows, le code standard de retour pour une installation réussie est [0].

Si vous savez que vos paquets WAPT s’installent correctement, mais que vous obtenez quand même un code de retour différent de [0], alors vous pouvez explicitement dire à WAPT d’ignorer le code d’erreur en utilisant le paramètre `accept_returncodes`.

Vous pouvez découvrir comment utiliser le paramètre `accept_returncodes` en explorant le code de ce paquet.

    # -*- coding: utf-8 -*-
    from setuphelpers import *
    import re

    uninstallkey = []

    def is_kb_installed(hotfixid):
        installed_update = installed_windows_updates()
        if [kb for kb in installed_update if kb['HotFixID' ].upper() == hotfixid.upper()]:
            return True
        return False

    def waiting_for_reboot():
        # Query WUAU from the registry
        if reg_key_exists(HKEY_LOCAL_MACHINE,r"SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") or \
            reg_key_exists(HKEY_LOCAL_MACHINE,r"SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending") or \
            reg_key_exists(HKEY_LOCAL_MACHINE,r'SOFTWARE\Microsoft\Updates\UpdateExeVolatile'):
            return True
        return False

    def install():
        kb_files = [
            'windows10.0-kb4522355-x64_af588d16a8fbb572b70c3b3bb34edee42d6a460b.msu',
            ]
        with EnsureWUAUServRunning():
          for kb_file in kb_files:
              kb_guess = re.findall(r'^.*-(KB.*)-',kb_file)
              if not kb_guess or not is_kb_installed(kb_guess[0]):
                  print('Installing {}'.format(kb_file))
                  run('wusa.exe "{}" /quiet /norestart'.format(kb_file),accept_returncodes=[0,3010,2359302,-2145124329],timeout=3600)
              else:
                  print('{} already installed'.format(kb_file))

          if waiting_for_reboot():
              print('A reboot is needed!')

Indication

La liste complète des messages d’erreur de l’installeur Windows peut être consultée sur cette page <https://docs.microsoft.com/en-us/windows/win32/msi/windows-installer-error-messages>`_.