[RESOLU] Paquet Arduino-IDE v2.0.2

Questions about WAPT Packaging / Requêtes et aides autour des paquets Wapt.
Règles du forum
Règles du forum communautaire
* English support on www.reddit.com/r/wapt
* Le support communautaire en français se fait sur ce forum
* Merci de préfixer le titre du topic par [RESOLU] s'il est résolu.
* Merci de ne pas modifier un topic qui est taggé [RESOLU]. Ouvrez un nouveau topic en référençant l'ancien
* Préciser version de WAPT installée, version complète ET numéro de build (2.2.1.11957 / 2.2.2.12337 / etc.) AINSI QUE l'édition Enterprise / Discovery
* Les versions 1.8.2 et antérieures ne sont plus maintenues. Les seules questions acceptées vis à vis de la version 1.8.2 sont liés à la mise à jour vers une version supportée (2.1, 2.2, etc.)
* Préciser OS du serveur (Linux / Windows) et version (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019)
* Préciser OS de la machine d'administration/création des paquets et de la machine avec l'agent qui pose problème le cas échéant (Windows 7 / 10 / 11 / Debian 11 / etc.)
* Eviter de poser plusieurs questions lors de l'ouverture de topic, sinon il risque d'être ignorer. Si plusieurs sujet, ouvrir plusieurs topic, et de préférence les uns après les autres et pas tous en même temps (ie ne pas spammer le forum).
* Inclure directement les morceaux de code, les captures d'écran et autres images directement dans le post. Les liens vers les pastebin, les bitly et autres sites tierces seront systématiquement supprimés.
* Comme tout forum communautaire, le support est fait bénévolement par les membres. Si vous avez besoin d'un support commercial, vous pouvez contacter le service commercial Tranquil IT au 02.40.97.57.55
olaplanche
Messages : 173
Inscription : 26 janv. 2017 - 11:11

04 oct. 2022 - 11:38

Bonjour,

- Le 24/11/2022 : Mise à jour du code pour la version 2.0.2 avec fonction uninstall pour désintaller proprement et modification du fichier de conf session-setup pour langue fr par défaut.

Je vous partage mon paquet Arduino-IDE v2.0.0 qui a demandé pas mal d'adaptation par rapport à la version 1.8.19...

Premièrement il faut savoir que la nouvelle version crée un dossier de donnée dans %localappdata% de chaque utilisateur. Il faut impérativement que l'utilisateur ait le contrôle total en lecture, écriture et exécution sur ce dossier pour le bon fonctionnement du logiciel.
Mon problème : J'utilise une SRP (Stratégie de restriction logiciel) qui interdit l'exécution de certains type de fichier depuis le profil utilisateur.
Il faut savoir également qu'à chaque première ouverture du logiciel par un utilisateur, une dossier Arduino15 va être créé dans %localappdata% et des librairies seront téléchargées. Ce dossier fait 346Mo, si un grand nombre d'utilisateurs utilise le logiciel, ça peut vite devenir la pagaille.
Et dernière chose, les pilotes arduino ne sont plus inclus dans cette version, il s'agit d'un téléchargement séparé. J'ai donc créé un paquet en dépendance : viewtopic.php?t=3222

Je vous propose donc un code qui copie le dossier Arduino15 (récupéré en amont dans le paquet) dans le dossier c:\ProgramData\Arduino15, modifie les droits sur ce dossier pour répondre aux prérequis. Il modifie également le fichier de conf du logiciel via la fonction session-setup afin de pointer vers le seul et unique dossier Arduino15 pour tous les utilisateurs.

Les utilisateurs auront donc les droits en écriture, lecture et exécution sur ce dossier qui est caché dans le dossier ProgramData et inaccessible aux utilisateurs via l'explorateur Windows et autorisé en exécution dans ma SRP.
J'ai également ajouté une fonction d'audit afin de détecter si la version précédente (<=1.8.19) est installée car cette version s'installe séparément.


Setup.py :

Code : Tout sélectionner

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

"""
Usable WAPT package functions: install(), uninstall(), session_setup(), audit(), update_package()

"""
# Declaring global variables - Warnings: 1) WAPT context is only available in package functions; 2) Global variables are not persistent between calls
bin_name_string = 'arduino-ide_%s_Windows_64bit.msi'
app_uninstallkey = "{547C91EB-BA23-4620-83BA-3E850277CD61}"


def install():
    # Declaring local variables
    package_version = control.get_software_version()
    bin_name = bin_name_string % package_version
    impacted_process = control.impacted_process.split(",")
    all_user_data = makepath(programdata,'Arduino15')

    # Installing the software
    print("Installing: %s" % bin_name)
    install_msi_if_needed(bin_name,
        properties='/qn ALLUSERS=1',
        killbefore=impacted_process,
        timeout=900
    )
    uninstallkey.remove(app_uninstallkey)
    copytree2('Arduino15',all_user_data)
    print('Restricting permissions on %s' % all_user_data)
    run(r'icacls "%s" /t /grant *S-1-5-21-3299883279-2723331061-3856246482-1728:(OI)(CI)M' % all_user_data) # groupe AD ELEVES (Get-ADGroup -Identity ELEVES | select Name, SID)
    run(r'icacls "%s" /t /grant *S-1-5-21-3299883279-2723331061-3856246482-1732:(OI)(CI)M' % all_user_data) # groupe AD PROFESSEUR (Get-ADGroup -Identity PROFESSEUR | select Name, SID)
    run(r'icacls "%s\\package_index.json" /inheritance:e /t /c' % all_user_data)
    run(r'icacls "%s\\package_index.json.sig" /inheritance:e /t /c' % all_user_data)

def session_setup():
    import tempfile
    pathparamsfile = makepath(tempfile.gettempdir(),'arduino-cli.yaml')
    currentuser = os.getlogin()
    configpath = makepath(r'c:\users',currentuser,'.arduinoIDE')
    data = r"""board_manager:
  additional_urls: []
daemon:
  port: "50051"
directories:
  data: C:\ProgramData\Arduino15
  downloads: C:\Users\%s\AppData\Local\Arduino15\staging
  user: C:\Users\%s\Documents\Arduino
library:
  enable_unsafe_install: false
locale: fr
logging:
  file: ""
  format: text
  level: info
metrics:
  addr: :9090
  enabled: true
output:
  no_color: false
sketch:
  always_export_binaries: false
updater:
  enable_notification: true
""" % (currentuser,currentuser)
    fichier = open(pathparamsfile, "w")
    fichier.write(data)
    fichier.close()
    mkdirs(configpath)
    filecopyto(pathparamsfile,configpath)
    remove_file(pathparamsfile)

def audit():
    if isfile(r'%s\Arduino\uninstall.exe' % programfiles32):
        print('Version précédente détectée')
        return "WARNING"
    else:
        return "OK"

def update_package():
    # Declaring local variables
    result = False
    proxies = get_proxies()
    if not proxies:
        proxies = get_proxies_from_wapt_console()
    app_name = control.name
    url = control.sources

    # Getting latest version from official website
    version_temp = bs_find_all(url, 'span', 'class', 'download-title',proxies=proxies)[0].string
    version = version_temp.split(' ')[+2]
    latest_bin = bin_name_string % version
    download_url = 'https://downloads.arduino.cc/arduino-ide/arduino-ide_%s_Windows_64bit.msi' % version

    print("Latest %s version is: %s" % (app_name, version))
    print("Download URL is: %s" % download_url)

    # Downloading latest binaries
    if not isfile(latest_bin):
        print("Downloading: %s" % latest_bin)
        wget(download_url, latest_bin, proxies=proxies)

        # Checking version from file
        version_from_file = get_version_from_binary(latest_bin)
        if not version_from_file.startswith(version) and version_from_file != '':
            print("Changing version to the version number of the binary (from: %s to: %s)" % (version, version_from_file))
            os.rename(latest_bin, bin_contains + version_from_file + ends_bin_name)
            version = version_from_file
        else:
            print("Binary file version corresponds to online version")

    # Changing version of the package
    if Version(version) > Version(control.get_software_version()):
        print("Software version updated (from: %s to: %s)" % (control.get_software_version(), Version(version)))
        result = True
    else:
        print("Software version up-to-date (%s)" % Version(version))
    control.version = '%s-%s' % (Version(version), control.version.split('-', 1)[-1])
    #control.set_software_version(version)
    control.save_control_to_wapt()

    # Deleting outdated binaries
    remove_outdated_binaries(version)

    # Validating update-package-sources
    return result

def get_proxies():
    if platform.python_version_tuple()[0] == '3':
        from urllib.request import getproxies
    else:
        from urllib import getproxies
    return getproxies()


def get_version_from_binary(filename):
    if filename.endswith('.msi'):
        return get_msi_properties(filename)['ProductVersion']
    else:
        return get_file_properties(filename)['ProductVersion']


def remove_outdated_binaries(version, list_extensions=['exe','msi','deb','rpm','dmg','pkg'], list_filename_contain=None):
    if type(list_extensions) != list:
        list_extensions = [list_extensions]
    if list_filename_contain:
        if type(list_filename_contain) != list:
            list_filename_contain = [list_filename_contain]
    list_extensions = ['.' + ext for ext in list_extensions if ext[0] != '.']
    for file_ext in list_extensions:
        for bin_in_dir in glob.glob('*%s' % file_ext):
            if not version in bin_in_dir:
                remove_file(bin_in_dir)
            if list_filename_contain:
                for filename_contain in list_filename_contain:
                    if not filename_contain in bin_in_dir:
                        remove_file(bin_in_dir)

def get_proxies_from_wapt_console():
    proxies = {}
    if platform.system() == 'Windows':
        waptconsole_ini_path = makepath(user_local_appdata(), 'waptconsole', 'waptconsole.ini')
    else:
        waptconsole_ini_path = makepath(user_home_directory(), '.config', 'waptconsole', 'waptconsole.ini')
    if isfile(waptconsole_ini_path):
        proxy_wapt = inifile_readstring(waptconsole_ini_path, 'global', 'http_proxy')
        if proxy_wapt:
            proxies = {'http': proxy_wapt, 'https': proxy_wapt}
    return proxies

def uninstall():
    run(r'"MsiExec.exe" /X%s /quiet' % app_uninstallkey,timeout=900)
    print(r'Uninstalling all_user_data')
    remove_tree(makepath(programdata,'Arduino15'))
control :

Code : Tout sélectionner

package           : wapt-arduino
version           : 2.0.0-1
architecture      : x64
section           : base
priority          : optional
name              : Arduino IDE
categories        : 
maintainer        : olaplanche
description       : The Arduino Integrated Development Environment is a cross-platform application that is written in functions from C and C++. It is used to write and upload programs to Arduino compatible boards, but also, with the help of third-party cores, other vendor development boards.
depends           : wapt-ftdi-vcp-drivers,wapt-arduino-drivers
conflicts         : 
maturity          : PROD
locale            : fr
target_os         : windows
min_wapt_version  : 
sources           : https://www.arduino.cc/en/software
installed_size    : 
impacted_process  : arduino
description_fr    : 
description_pl    : 
description_de    : 
description_es    : 
description_pt    : 
description_it    : 
description_nl    : 
description_ru    : 
audit_schedule    : 
editor            : Arduino.cc
keywords          : 
licence           : Free
homepage          : www.arduino.cc
- Version de WAPT installée : 2.3.0.13516 Enterprise
- OS du serveur : Linux / Debian Buster
- OS de la machine d'administration/création des paquets : Windows 10
Verrouillé