Un poste s'installe en une commande - #33
Merged
Merged
Conversation
… gestes Installer un poste demandait de trouver l'archive, la copier, cocher « Débloquer » dans les propriétés du fichier, extraire, ouvrir PowerShell en administrateur, se placer dans le bon répertoire, puis lancer install.ps1. Trois de ces gestes échouaient en silence chez un bénévole : la case oubliée, que la stratégie d'exécution transforme en refus parlant de « fichier téléchargé depuis Internet » et jamais d'OpenScale ; la console non élevée, dont le refus n'arrivait qu'après le téléchargement ; et le mauvais répertoire, qui faisait accuser l'archive. deploy/windows/bootstrap.ps1 les fait tous. Il vit sur main et ne nomme aucune version : il demande /releases/latest, seul point de l'API qui exclut brouillons et pré-versions par contrat. L'empreinte est vérifiée AVANT l'extraction, jamais après — décompresser une archive non vérifiée écrit sur le disque des fichiers dont la ligne suivante en exécute un en administrateur. Trois questions au lieu de zéro paramètre : mot de passe de la session, type d'installation, ouverture de session automatique. Le mot de passe ne sort pas du processus — install.ps1 le reçoit en [securestring] — et l'auto-élévation est refusée quand -SessionPassword est fourni, parce qu'une relance élevée ferait passer le secret par une ligne de commande, lisible dans la liste des processus. Deux trous rebouchés en chemin. install.ps1 ne copie aucun script : un poste installé depuis %TEMP% n'aurait eu ni désinstalleur ni script de mise à jour, le dossier extrait est donc conservé sous ProgramData\OpenScale\installer\<version>. Et -Version, qui installe une release antérieure, aurait fait échouer l'appel sur un paramètre inconnu après les trois questions : les paramètres sont confrontés à ce qu'install.ps1 déclare. Le plancher du mot de passe est à quatre caractères. Ce mot de passe est déjà en clair dans Winlogon\DefaultPassword et sur la fiche d'installation : sa longueur ne protège pas ce poste. Le refus de connexion réseau (SeDenyNetworkLogonRight) a été proposé et écarté, le réseau du magasin étant de confiance. INSTALLATION.md retombe à 15 minutes comptées, et la voie clé USB reste écrite pour le poste hors ligne. 12 tests de deploy/ ajoutés aux 32 existants.
Les deux branches ont livré le même jour un mot de passe de compte choisi à l'installation, et main l'a fait mieux. Son -AccountPassword conserve le mot de passe d'un poste réinstallé — la règle du code de secours, « la fiche déjà rangée dans le classeur doit rester vraie » —, le vérifie par Test-LocalCredential, et confie la décision à Resolve-AccountPassword, exerçable en test sans droits administrateur. Le -SessionPassword de cette branche ne faisait rien de tout ça. Il est donc retiré, et bootstrap.ps1 se branche sur -AccountPassword. install.ps1 et common.ps1 reprennent la version de main sans un mot de la mienne. Le plancher de quatre caractères disparaît aussi du bootstrap : il vit dans common.ps1, Resolve-AccountPassword en est l'autorité, et la question le lit. Un bootstrap qui l'aurait redit aurait accepté ce que l'installeur refuse trois pas plus loin, devant un bénévole ayant déjà tout répondu. Le test qui gardait la constante garde maintenant son absence. La saisie reste masquée et confirmée. Ce que -AsSecureString achète n'est pas un secret gardé — ce mot de passe finit dans Winlogon\DefaultPassword et sur la fiche — mais un mot de passe qui ne s'affiche pas à l'écran d'un poste posé face aux clients. INSTALLATION.md garde les deux sections, celle de main sur le mot de passe du compte et celle de cette branche sur l'installation hors ligne, renumérotées sur les six étapes et 15 minutes du nouveau parcours.
« Vide = tiré au sort (20 caractères) » puis, deux lignes plus bas, « laisser vide ne touche pas au mot de passe en place ». Les deux sont vraies, mais pas au même moment, et l'écran ne disait pas lequel : c'est install.ps1 qui décide, selon que le poste est neuf ou déjà installé. L'invite le dit maintenant en une seule phrase, et nomme au passage ce que la saisie masquée achète.
« Installer un poste » venait en septième section, après « Développer » : un dépôt dont le produit est un poste de pesée le décrivait à qui vient le compiler, pas à qui vient le poser dans un magasin. La commande unique est maintenant la première chose sous le titre, et la démonstration sans matériel la suit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ce que ça change
Sept gestes disparaissent. Trois d'entre eux échouaient en silence chez un bénévole :
cdqui a manqué.Cette branche ne touche ni
install.ps1nicommon.ps1: elle ajoute un script qui les appelle. La voie clé USB reste entière pour un poste sans Internet.La collision avec
main, et comment elle est résoluemaina livré le même jour, pour un autre défaut,install.ps1 -AccountPassword: un mot de passe de compte choisi à l'installation, plancher à quatre caractères danscommon.ps1, décision confiée àResolve-AccountPassword. Cette branche portait un-SessionPasswordqui faisait le même travail en moins bon — il ne conservait pas le mot de passe d'un poste réinstallé et ne le vérifiait pas parTest-LocalCredential.Il a été retiré. Le bootstrap se branche sur
-AccountPassword, etinstall.ps1/common.ps1reprennent la version demainsans un mot de la mienne. Le plancher de quatre caractères a disparu du bootstrap au passage : il vit danscommon.ps1,Resolve-AccountPassworden est l'autorité, et la question le lit. Un bootstrap qui l'aurait redit aurait accepté ce que l'installeur refuse trois pas plus loin, devant un bénévole ayant déjà tout répondu — le test qui gardait la constante garde maintenant son absence.Cinq points de conception
L'URL pointe
main, pas une release. Le fichier ne porte aucun numéro de version — il demande/releases/latest, seul point de l'API qui exclut brouillons et pré-versions par contrat. Un actif de release le figerait sur son tag ; GitHub Pages en ferait une seconde copie à tenir synchrone avecdeploy/windows/.L'empreinte est vérifiée avant l'extraction.
Expand-Archivesur une archive non vérifiée écrit sur le disque des fichiers dont la ligne suivante en exécute un en administrateur.L'élévation et le mode non-interactif ne se combinent pas. Le one-liner se relance seul par
Start-Process -Verb RunAset pose ses questions dans la fenêtre élevée. Avec-AccountPassword, cette relance est refusée : une relance élevée fait passer ses paramètres par une ligne de commande, lisible dans la liste des processus par tout utilisateur de la machine.Les scripts survivent à l'installation.
install.ps1ne copie aucun script —uninstall.ps1,update.ps1etharden.ps1ne survivaient que parce que l'archive restait sur le Bureau. Le dossier extrait est conservé sousC:\ProgramData\OpenScale\installer\<version>\.-Versionne casse pas après les questions. Ce script vit surmain, les archives sont figées à leur tag : installer une release antérieure aurait fait échouer l'appel sur un paramètre inconnu après le téléchargement, l'extraction et les trois questions. Les paramètres sont confrontés à ce qu'install.ps1déclare, et ce qui manque est retiré et annoncé.Le mot de passe du compte à quatre caractères
Ce mot de passe est déjà en clair dans
Winlogon\DefaultPasswordet sur la fiche d'installation : sa longueur ne protège pas ce poste. Le refus de connexion réseau (SeDenyNetworkLogonRight) a été proposé et écarté — le réseau du magasin est un réseau de confiance. C'est écrit dans le spec pour être rouvrable, pas redécouvert.La saisie est masquée et confirmée. Ce que le masque achète n'est pas un secret gardé, c'est un mot de passe qui ne s'affiche pas à l'écran d'un poste posé face aux clients.
Vérification
pwsh -File ./make.ps1 testvert après le merge demain— vet,boundary,deps, l'ensemble des paquets, passe-race.13 tests ajoutés dans
deploy/bootstrap_test.go: aucune version figée, l'empreinte comparée avant l'extraction,Unblock-Fileappelé, tout paramètre passé déclaré parinstall.ps1, le mot de passe absent de toutWrite-Hostet de tout journal, le plancher lu et non redit, les deux entrées qui nomment la même URL, le dépôt et l'hôte alignés surDefaultUpdateRepositoryetDefaultBaseURL, l'auto-élévation refusée avec un secret, les scripts conservés sur le poste, la compatibilité avec uninstall.ps1plus ancien. Le parsing PowerShell réel (pwshetpowershell.exe5.1) et la marque d'ordre des octets couvrent le nouveau fichier sans une ligne de plus.Le chemin réseau a été éprouvé contre la vraie release
v0.9: API interrogée, archive de 7,2 Mo téléchargée, empreinted33c5d72…conforme, extraction vérifiée. Ce qui reste à la recette de §15.2 : l'invite UAC, le service qui démarre, le redémarrage de recette.Documentation
INSTALLATION.mdretombe à 15 minutes comptées (les deux minutes d'écart étaient le téléchargement et la décompression), garde la section demainsur le mot de passe du compte et gagne « Installer un poste sans Internet », les étapes renumérotées de 1 à 6.README.mdgagne une section « Installer un poste » ;handbook/getting-started.mdrenvoie àINSTALLATION.mdpar URL absolue (ODR-0002).Spec :
docs/superpowers/specs/2026-07-31-installation-en-une-commande-design.md.