Bonjour tout le monde ! (si il reste quelqu'un... 😉 )

Je me suis enfin occupé du script en python ! Il a pour l'instant un certain nombre de défaut, notamment l’absence d'interface graphique (c'est super long à coder ces trucs ! :mad: )

Sinon à part ça le fonctionnement est assez simple : je vous affiche le résultat d'un GRUBEnhancer.py -h :
usage: GRUB Enhancer [-h] -i FILE -l FILE [--grub-rep DIRECTORY]

Modifie les fichiers de configuration de GRUB afin de démarrer l'ordi sur une
image iso.

optional arguments:
  -h, --help            show this help message and exit
  -i FILE, --iso FILE   L'image iso destinée à être bootée
  -l FILE, --loop FILE  Le fichier loopback qui y est associé
  --grub-rep DIRECTORY  Un éventuel répertoire alternatif pour GRUB.
                        Default=/boot/grub/
Je pense que c'est clair... :lol:
J'ai de plus créé un autre script (en bash celui-là, mais je vais probablement le transcrire en python) qui va chercher dans l'iso le fichier loopback.cfg pour le copier à côté de l'iso. Pas de fichier d'aide (c'est en partie pour ça que je veux le transcrire en python), donc la syntaxe est :
LoopbackCreator.sh fichier.iso
Seul problème, il ne rajoute pas les instructions pour l'interface en français, je rajoute ça dès que j'ai un peu de temps.

Bien sûr les deux scripts nécessitent les droits root... 😛

Pour pouvoir s'en servir il faut mettre dans un même dossier :

Le fichier GRUBEnhancer.py
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import sys
import os
from os.path import join, basename
import argparse
import subprocess


def check_grub_config(rep):
    """Vérifie la configuration par défaut de GRUB"""
    content = open("grub.cfg", 'r').read()
    grub_config = open(join(rep, "grub.cfg"), 'r').read()
    if content not in grub_config:
        open(join(rep, "grub.cfg"), 'a').write(content)

def write_function(rep):
    """Écrit le fichier de fonctions de boot"""
    content = open("fonctions_iso.cfg", 'r').read()
    try:
        os.mkdir(join(rep, "greffons"))
    except: pass
    open(join(rep, "greffons/fonctions_iso.cfg"), 'w').write(content)

def modify_custom(rep, iso, loop):
    """Modifie le fichier contenant les entrées du menu"""
    incipit = "source ${prefix}/greffons/fonctions_iso.cfg\n"
    # Ici on tente d'ouvrir le fichier custom.cfg pour y écrire l'incipit
    # Si on n'y arrive pas, il n'existe pas : on le crée,
    # Sinon on vérifie que l'incipit n'est pas déjà présent et on le rajoute le cas échéant.
    try:
        custom = open(join(rep, 'custom.cfg'), 'r').read()
    except IOError:
        open(join(rep, 'custom.cfg'), 'w').write(incipit)
    else:
        if incipit in custom: pass
        else:
            content = incipit + custom
            open(join(rep, 'custom.cfg'), 'w').write(content)
    # Le chemin d'accès à l'iso à partir de / n'est pas forcément le même
    # que celui à partir de la racine de la partition.
    iso = find_path(iso)
    loop = find_path(loop)

    iso_name = basename(iso)
    config = '\tsubmenu "'+ iso_name + '" {iso_boot "' + iso + '" "' + loop + '"}\n'
    open(join(rep, 'custom.cfg'), 'a').write(config)

def find_path(path):
    """Retrouve le chemin d'accès d'un fichier à partir de la racine de sa partition"""
    # On utilise le programme df pour retrouver le point de montage de la partition
    subprocess.call(["bash", "-c", "df " + path + " > partition"])
    resultat = open("partition", "r").read()
    partition = resultat.split()[-1]
    os.remove("partition")
    # On ne supprime que la première occurence de la partition (des fois que l'utilisateur
    # toto se soit amusé à créer un dossier home/toto et à mettre ses isos dedans...
    path = path.replace(partition, "", 1)
    return path


### Programme principal ###
parser = argparse.ArgumentParser(description='''Modifie les fichiers de configuration de GRUB afin de démarrer l'ordi sur une image iso.''', prog='GRUB Enhancer')

parser.add_argument('-i', '--iso', required=True, metavar='FILE', help="L'image iso destinée à être bootée")
parser.add_argument('-l', '--loop', required=True, metavar='FILE', help="Le fichier loopback qui y est associé")
parser.add_argument('--grub-rep', metavar='DIRECTORY', dest='rep', default='/boot/grub/', help="Un éventuel répertoire alternatif pour GRUB. Default=/boot/grub/")

args = parser.parse_args()

print("Vérification de la configuration de GRUB...")
check_grub_config(args.rep)
print("Écriture des fonctions nécessaire aux démarrage sur une image iso...")
write_function(args.rep)
print("Modification du fichier de menu...")
modify_custom(args.rep, args.iso, args.loop)
ainsi que les deux fichier grub.cfg et fonctions_iso.cfg contenant respectivement :
### BEGIN /etc/grub.d/41_custom ###
if [ -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###
et
#######################################################################################################################
# Avertissement présenté à l'utilisateur si le fichier iso est introuvable, ou n'a pas été donné en paramètre de la commande iso_boot
#   Iso file missing
function no_iso_file {
  if [ -n "${1}" ] ; then
    echo L\'image à partir de laquelle il faut amorcer le PC, ${1}, ne se trouve sur aucun des supports actuellement raccordés à l\'ordinateur.
  else 
    echo Aucune image iso n\'a été attachée au libellé ${chosen} que vous venez de choisir.
  fi
}
#######################################################################################################################
# Avertissement présenté à l'utilisateur si le fichier de configuration est introuvable
#   Grub configuration file missing
function no_cfg_file {
  echo Le fichier de configuration, ${1}, ne se trouve sur aucun des supports actuellement raccordés à l\'ordinateur.
 }
#######################################################################################################################
function iso_boot  {
#
# Cette procédure crée un periphérique virtuel qui donne accès aux répertoires et fichiers contenu dans le fichier iso
# et cherche le fichier contenant le menu correspondant à l'image iso considérée et l'introduit dans le menu Grub
# paramètre ${1} : le nom du fichier iso, chemin d'accès compris, dans la partition où il se trouve, en commençant par /
# paramètre ${2}, facultatif : idem pour le fichier contenant les entrées de menu pour l'image iso considérée
#    quand il est omis, il s'agit du fichier /boot/grub/loopback.cfg de l'image iso
  set image_iso=
  set iso_path="${1}"
#  recherche du fichier iso
  if [ -n "${1}" ]; then
# si le fichier ${1} de nom /..../nom existe, alors cela signifie qu'il est sur la partition ${root}
     if [ -e "${1}" ]; then set image_iso=${root}; else search --file --set=image_iso --no-floppy "${1}"; fi
  fi
  if [ -z "${image_iso}" ]; then no_iso_file "${1}";  sleep -v 10; fi
# création du périphérique virtuel qui donne accès au fichier iso
#    creation of the virtual device holding the iso file and paths initialisation
   loopback iso (${image_iso})${1}
   set root=iso
   set loopcfg=
# recherche et introduction du menu spécifique à l'image iso considérée
   if [ -z "${2}" ]; then set sourcefile=/boot/grub/loopback.cfg; else set sourcefile="${2}"; fi
# si le fichier se trouve sur le périphérique $root, il n'est pas utile de le chercher
   if [ -e "${sourcefile}" ]; then set loopcfg=${root} ; else search --file --set=loopcfg --no-floppy "${sourcefile}" ; fi
   if [ -z "${loopcfg}" ]; then no_cfg_file "${sourcefile}"; sleep -v 10; else source "(${loopcfg})${sourcefile}"; fi
}
function amorce_iso {
########################################################################################
#
# amorçage par le script shell iso_boot.sh
#
#######################################################################################
# pour éviter le bouclage sur la procédure
    if ${amorceiso}; then
        set amorceiso=false
        save_env amorceiso
        if ! keystatus --ctrl; then
            if ! keystatus --shift; then
                set image_iso=
                set iso_path="${1}"
                set iso_file="${1}"
                if [ -e "${1}" ]; then set image_iso="${root}"; else search --file --set=image_iso --no-floppy "${1}"; fi
                loopback iso (${image_iso})${1}
                set root=iso
                if [ -e "${2}" ]; then set loopcfg=${root} ; else search --file --set=loopcfg --no-floppy "${2}" ; fi
                export iso_path
                export iso_file
                export root
                configfile "(${loopcfg})${2}"
                fi
            fi
        fi
}
Ces trois fichier doivent être impérativement dans le même dossier, le script GRUBEnhancer.py ne fonctionnera pas sinon, puisqu'il y lit le contenu qui doit être utilisé pour modifier GRUB !

Enfin le script LoopbackCreator.sh qui est plus modeste :
#!/bin/bash

# Vérification des droits root
if [ $EUID -ne 0 ];
then
    echo "Ce script nécessite les droits administrateur."
    exit
fi

# Vérification de la présence d'une iso existante
if [ $# -eq 1 ];
then
    if [ -f $1 ];
    then
        iso=$1
    else
        echo "$1 : Ce fichier n'existe pas."
        exit
    fi
else
    echo "Il faut préciser un fichier iso !"
    exit
fi

# On monte l'iso dans un emplacement temporaire pour aller voir le contenu
echo "Montage de l'iso..."
mkdir /tmp/iso
mount $1 /tmp/iso > /dev/null 2>&1
# On copie le fichier loopback dans le dossier de l'iso
echo "Récupération du fichier loopback..."
if [ -e /tmp/iso/boot/grub/loopback.cfg ];
then
    cp /tmp/iso/boot/grub/loopback.cfg ${iso%.*}.loopback.cfg
else
    cp /tmp/iso/isolinux/live.cfg ${iso%.*}.live.cfg
    echo -e "\033[31mAttention ce fichier est un fichier pour Isolinux ! Il convient de le traduire avant de l'utiliser.\033[0m"
fi
# On supprime les fichiers temporaires
echo "Supression des fichiers temporaires..."
umount /tmp/iso
rmdir /tmp/iso
Ce script récupère, s'il ne trouve pas le fichier loopback.cfg, le fichier live.cfg, qui semble être l'équivalent pour Isolinux. Dès qu'on aura trouvé comment booter des isos créées avec isolinux ce sera probablement ce fichier qu'on devra utiliser.

Voilà !

N'hésitez pas si vous avez des questions ou trouvez des bugs !
C'est encore moi !

J'ai décidé d'être productif aujourd'hui, donc voici mon deuxième script (celui en bash) traduit en python. Il est même plus complet encore, dans le sens ou il gère les erreurs de nom de fichier (le précédent copiait mais ne précisait pas s'il avait bien trouvé un fichier ou pas... :/ )

Et j'ai enfin l'aide en ligne de commande !
usage: Loopback Creator [-h] iso

Extrait d'une image iso le fichier loopback permettant de la booter.

positional arguments:
  iso         L'image iso dont va être extraite le fichier loopback.

optional arguments:
  -h, --help  show this help message and exit
Donc voilà, la syntaxe est la même que précédemment, rien ne change. Sauf que je vais pouvoir l'intégrer dans l'autre plus facilement une fois que j'aurais codé l'interface graphique. 🙂

Petite précision quand même : aucun des deux scripts python ne gère les tildes ( ~ ) dans les noms de fichier. Il faut préciser le chemin complet à chaque fois. Bien sûr, les chemins relatifs sont pris en charge (par python).

Voici le script :
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import subprocess
import os
import shutil
import argparse

# Vérification des droits root
if os.geteuid() != 0:
    print("Ce script nécessite les droits administrateur.")
    exit()

# Initialisation des paramêtres

parser = argparse.ArgumentParser(description="Extrait d'une image iso le fichier loopback permettant de la booter.", prog="Loopback Creator")

parser.add_argument('iso', help="L'image iso dont va être extraite le fichier loopback.")

args = parser.parse_args()

# Montage de l'iso dans un emplacement temporaire pour y avoir accès
print("Montage de l'iso...")
os.mkdir("/tmp/iso")
subprocess.call("mount {} /tmp/iso".format(args.iso).split())
# Copie du fichier loopback dans le dossier de l'iso
print("Récupération du fichier loopback...")
loopback_location = "/tmp/iso/boot/grub/loopback.cfg"
live_location = "/tmp/iso/isolinux/live.cfg"
if os.access(loopback_location, os.F_OK):
    copy = shutil.copy2(loopback_location, "{}.loopback.cfg".format(args.iso[:-4]))
    print("Copie réalisée dans {} avec succès !".format(copy))
elif os.access(live_location, os.F_OK):
    copy = copy = shutil.copy2(live_location, "{}.live.cfg".format(args.iso[:-4]))
    print("Fichier loopback non trouvé. Copie du fichier live dans {} à la place.".format(copy))
    print("*** Attention ! Ce fichier est un fichier pour Isolinux ! Il n'est pas utilisable en l'état avec GRUB ! ***")
else:
    print("Aucun fichier trouvé.")
# Suppression des fichiers temporaires
print("Suppression des fichiers temporaires...")
subprocess.call("umount /tmp/iso".split())
os.rmdir("/tmp/iso")
Voilà ! ^^
Bonjour

je vais chipoter un peu, mais je remplacerai bien, par exemple
subprocess.call("umount /tmp/iso".split())
par
code_de_retour = subprocess.call("umount /tmp/iso".split())
et on regarde si ce code_de_retour vaut 0

La doc
https://docs.python.org/2/library/subprocess.html#subprocess.call

De manière générale, c'est bien de tester le code de retour d'une opération
@k3c : Tu as raison tu chipotes 😃 Mais il n'y a pas de mauvais moment pour prendre de bonnes habitudes. J'ai corrigé ma version locale, je posterai peut-être plus tard la nouvelle version (qui ajoute entre autre le support du tilde...)

Merci pour ton retour sur mon code !
C'est quoi l’intérêt de tous ces scripts par rapport à grub-imageboot ?
@bruno :

Excellente question... Je ne connaissais pas grub-imageboot... Je dirais que la grosse différence c'est que les scripts peuvent fonctionner avec un répertoire grub installé sur une clef usb ou un hdd, ce qui permet une utilisation nomade de Linux. Enfin, la plus grosse partie reste à faire, à savoir ajouter une interface graphique, afin de les rendre accessibles aux débutants (ceux qui ne savent pas ce qu'est un chargeur de démarrage par exemple... 🙂 )
@bruno

Le plaisir de comprendre comment ça marche et écrire son code ?
Oui, enfin grub + syslinux (grâce à memdisk) permet depuis longtemps d'amorcer sur une image disque sans qu'il y ait besoin d’écrire de script, juste quelques lignes de configuration pour grub.
Et avec le paquet grub-imageboot c'est encore plus simple puisqu'il suffit de placer ses images dans /boot/images (ou un autre emplacement si on modifie /etc/default/grub-imageboot) et de mettre à jour grub. Cela marchera aussi parfaitement sur une clé usb ou sur n'importe quel disque où grub est installé.
Après effectivement chacun est libre de réinventer la roue 😉
Bonsoir

@bruno

Je ne sais si nous avons réinventé la roue comme tu le laisses entendre car la commande grub-imageboot n'est documentée ni dans la documentation française, ni dans les "manpages" anglo-saxones, ni dans le paquet une fois installé. La commande
grub-imageboot
reste inconnue après installation du paquet, évidemment.

Si tu as la gentillesse d'indiquer où se trouve la documentation et comment la commande se met en œuvre, je pourrai alors t'indiquer les éventuelles différences avec ce que propose Laerte, qui est la traduction en python, à titre d'exercice, d'un script bash, Celui-ci propose une interface graphique pour redémarrer le PC à partir d'une image iso, avec une éventuelle modification, à la main, du menu contenu dans l'image en question (traduction en français, adaptation du clavier). Le menu grub ainsi obtenu peut être inséré dans le menu grub initial ou au contraire n'être utilisé qu'au premier redémarrage, sans venir perturber les redémarrages ultérieurs.

grub-imageboot m'était évidemment inconnue lorsque j'ai commencé à travailler sur le sujet.

@Laërte

Je ne connais pas python. Je ne sais donc pas exactement ce que tu fais.

Il faut utiliser la fonction amorce_iso, et simplifier le fichier fonctions_iso.cfg comme indiqué ci-dessous
function amorce_iso {
########################################################################################
#
# amorçage à partir d'une image iso
# le chemin d'accès au fichier contenant l'image est passé en premier paramètre
# le chemin d'accès au fichier contenant le menu à afficher est passé en deuxième paramètre
# rappel : si le fichier "menu" ne contient pas l'ordre "menuentry", ne pas oublier de le terminer par un ordre boot
#
#######################################################################################
# pour éviter le bouclage sur la procédure
    if ${amorceiso}; then
        set amorceiso=false
        save_env amorceiso
        if ! keystatus --ctrl; then
            if ! keystatus --shift; then
                set image_iso=
                set iso_path="${1}"
                set iso_file="${1}"
                if [ -e "${1}" ]; then set image_iso="${root}"; else search --file --set=image_iso --no-floppy "${1}"; fi
                loopback iso (${image_iso})${1}
                set root=iso
                if [ -e "${2}" ]; then set loopcfg=${root} ; else search --file --set=loopcfg --no-floppy "${2}" ; fi
                export iso_path
                export iso_file
                export root
                configfile "(${loopcfg})${2}"
                fi
            fi
        fi
}
Les tests sur les touches "Maj" et "Ctrl" servent à éviter le lancement de l'image iso, au cas où l'utilisateur changerait d'avis après avoir demandé le redémarrage du PC ce qui n'est pas indispensable. Tu peux alors simplifier encore un peu fonctions_iso.cfg
function amorce_iso {
########################################################################################
#
# amorçage à partir d'une image iso
# le chemin d'accès au fichier contenant l'image est passé en premier paramètre
# le chemin d'accès au fichier contenant le menu à afficher est passé en deuxième paramètre
# rappel : si le fichier "menu" ne contient pas l'ordre "menuentry", ne pas oublier de le terminer par un ordre boot
#
#######################################################################################
# pour éviter le bouclage sur la procédure
    if ${amorceiso}; then
        set amorceiso=false
        save_env amorceiso
        set image_iso=
         set iso_path="${1}"
         set iso_file="${1}"
         if [ -e "${1}" ]; then set image_iso="${root}"; else search --file --set=image_iso --no-floppy "${1}"; fi
          loopback iso (${image_iso})${1}
          set root=iso
          if [ -e "${2}" ]; then set loopcfg=${root} ; else search --file --set=loopcfg --no-floppy "${2}" ; fi
          export iso_path
          export iso_file
           export root
           configfile "(${loopcfg})${2}"
           fi
}
Enfin, pour effectivement lancer l'image iso, il faut que ton script effectue la commande
grub-editenv /boot/grub/grubenv set amorceiso=true
Enfin, le fichier grub.cfg que tu proposes est beaucoup trop particulier et n'est valable que dans le cas de la clé USB que tu as créée. Dans le cas général dans lequel il convient que tu te places, le fichier grub.cfg contient déjà l'appel de custom.cfg si celui-ci existe. S'il n'existe pas, il faut que tu le crées.

Arbiel
Abriel, je ne nie pas la qualité du travail effectué, je trouve simplement curieuse la méthode utilisée. Comme je l'ai déjà dit Grub permet de démarrer sur image disque grâce à memdisk. grub-imageboot n'est pas une commande mais un paquet qui permet d'utiliser cela très simplement en fournissant un script pour grub dans /etc/grub.d (là on l'on place les éléments de configuration pour grub2).
@ Arbiel:

Voici ce que fais mon script :
Il vérifie que GRUB contient bien les lignes :
### BEGIN /etc/grub.d/41_custom ###
if [ -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###
Si ce n'est pas le cas il les ajoute.

Ensuite il crée un fichier greffons/fonctions_iso.cfg qui contient ce que Babdu m'avait donné au post 35 :
#######################################################################################################################
# Avertissement présenté à l'utilisateur si le fichier iso est introuvable, ou n'a pas été donné en paramètre de la commande iso_boot
#   Iso file missing
function no_iso_file {
  if [ -n "${1}" ] ; then
    echo L\'image à partir de laquelle il faut amorcer le PC, ${1}, ne se trouve sur aucun des supports actuellement raccordés à l\'ordinateur.
  else 
    echo Aucune image iso n\'a été attachée au libellé ${chosen} que vous venez de choisir.
  fi
}
#######################################################################################################################
# Avertissement présenté à l'utilisateur si le fichier de configuration est introuvable
#   Grub configuration file missing
function no_cfg_file {
  echo Le fichier de configuration, ${1}, ne se trouve sur aucun des supports actuellement raccordés à l\'ordinateur.
 }
#######################################################################################################################
function iso_boot  {
#
# Cette procédure crée un periphérique virtuel qui donne accès aux répertoires et fichiers contenu dans le fichier iso
# et cherche le fichier contenant le menu correspondant à l'image iso considérée et l'introduit dans le menu Grub
# paramètre ${1} : le nom du fichier iso, chemin d'accès compris, dans la partition où il se trouve, en commençant par /
# paramètre ${2}, facultatif : idem pour le fichier contenant les entrées de menu pour l'image iso considérée
#    quand il est omis, il s'agit du fichier /boot/grub/loopback.cfg de l'image iso
  set image_iso=
  set iso_path="${1}"
#  recherche du fichier iso
  if [ -n "${1}" ]; then
# si le fichier ${1} de nom /..../nom existe, alors cela signifie qu'il est sur la partition ${root}
     if [ -e "${1}" ]; then set image_iso=${root}; else search --file --set=image_iso --no-floppy "${1}"; fi
  fi
  if [ -z "${image_iso}" ]; then no_iso_file "${1}";  sleep -v 10; fi
# création du périphérique virtuel qui donne accès au fichier iso
#    creation of the virtual device holding the iso file and paths initialisation
   loopback iso (${image_iso})${1}
   set root=iso
   set loopcfg=
# recherche et introduction du menu spécifique à l'image iso considérée
   if [ -z "${2}" ]; then set sourcefile=/boot/grub/loopback.cfg; else set sourcefile="${2}"; fi
# si le fichier se trouve sur le périphérique $root, il n'est pas utile de le chercher
   if [ -e "${sourcefile}" ]; then set loopcfg=${root} ; else search --file --set=loopcfg --no-floppy "${sourcefile}" ; fi
   if [ -z "${loopcfg}" ]; then no_cfg_file "${sourcefile}"; sleep -v 10; else source "(${loopcfg})${sourcefile}"; fi
}
function amorce_iso {
########################################################################################
#
# amorçage par le script shell iso_boot.sh
#
#######################################################################################
# pour éviter le bouclage sur la procédure
    if ${amorceiso}; then
        set amorceiso=false
        save_env amorceiso
        if ! keystatus --ctrl; then
            if ! keystatus --shift; then
                set image_iso=
                set iso_path="${1}"
                set iso_file="${1}"
                if [ -e "${1}" ]; then set image_iso="${root}"; else search --file --set=image_iso --no-floppy "${1}"; fi
                loopback iso (${image_iso})${1}
                set root=iso
                if [ -e "${2}" ]; then set loopcfg=${root} ; else search --file --set=loopcfg --no-floppy "${2}" ; fi
                export iso_path
                export iso_file
                export root
                configfile "(${loopcfg})${2}"
                fi
            fi
        fi
}
Enfin, il crée le fichier custom.cfg (s'il n'existe pas) et y ajoute :
 source ${prefix}/greffons/fonctions_iso.cfg
Puis une ligne du type :
submenu "file.iso" { iso_boot "path/to/file.iso" "path/to/loopback.cfg" }
Le second script fait exactement la même chose que le script bash que j'avais donné, donc tu devrais pouvoir comprendre.

Voilà ! (je vais probablement poster une nouvelle version dans la journée, je t'expliquerai de nouveau ce que ça fait.)

Je n'ai pas tout compris pour la fonction amorce_iso... Ce n'était pas la fonction iso_boot qu'il fallait utiliser ?
Quant aux commandes grub-env, est-ce que tu pourrais m'expliquer précisément ce qu'elle fait, que je comprenne ce qui se passe ? Je me souviens effectivement que ton script permettait de n'enregistrer le menu de boot de l'iso qu'une seule fois, ce que le mien ne permet pas, puisqu'il écrit l'entrée de manière permanente à chaque fois... Pourrais-tu m'expliquer comment ça marchait ?

Merci !
Bonsoir laerte

Je n'ai pas vu l'alerte indiquant ta nouvelle intervention. J'espère que tu ne t'es pas désespéré de mon silence.

J'ai fait une erreur en te disant de supprimer une partie du code de "fonctions_iso.cfg". Cette erreur provient de ce que j'avais oublié que j'avais prévu deux méthodes pour démarrer à partir d'une image iso et je n'ai gardé en mémoire que celle que j'utilise systématiquement, et qui n'est pas celle qui est mise en œuvre avec ta clé. Comme souvent, je n'ai pas assez réfléchi avant d'intervenir.

Pour démarrer à partir d'une image iso, il faut en quelque sorte intervenir sur le fichier grub.cfg. Ce fichier est créé par la commande grub-mkconfig (update-grub n'est autre chose que l'invocation de cette commande, avec l'indication du fichier de sortie : "grub-mkconfig -o /boot/grub/grub.cfg") à partir du fichier /etc/default/grub et des fichiers contenus dans le répertoire /etc/grub.d. Pour modifier le comportement de grub, beaucoup recommandent de modifier ces fichiers, éventuellement d'en créer de nouveaux dans /etc/grub.d et d'exécuter ensuite la commande update-grub.

Les distributions Ubuntu permettent d'utiliser une seconde méthode qui consiste à créer un fichier /boot/grub/custom.cfg, ou, s'il existe, à le modifier. Cette méthode présente l'avantage de ne pas nécessiter l'exécution de la commande update-grub. Elle se traduit par la présence à la fin du fichier grub.cfg de lignes créées par le fichier /etc/grub.d/41_custom
### BEGIN /etc/grub.d/41_custom ###
if [ -f  ${config_directory}/custom.cfg ]; then
  source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
ou, dans les versions plus anciennes
### BEGIN /etc/grub.d/41_custom ###
if [ -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg
fi
Pour les distributions dans lesquelles le fichier grub.cfg ne contient pas ces lignes, il suffit de créer un fichier /etc/grub.d/41_custom, ou au delà (je veux dire par là /etc/grub.d/nn_custom, avec nn > 41) pour les créer :
#!/bin/sh
cat <<EOF
if [ -f  \${config_directory}/custom.cfg ]; then
  source \${config_directory}/custom.cfg
elif [ -z "\${config_directory}" -a -f  \$prefix/custom.cfg ]; then
  source \$prefix/custom.cfg;
fi
EOF
Lorsque j'ai décidé d'écrire un script grub pour faciliter le démarrage à partir d'un fichier iso, j'ai choisi d'utiliser le fichier custom.cfg. J'ai alors défini la commande "iso_boot" qui attend comme arguments la référence (le chemin d'accès) au fichier iso et, optionnellement, au fichier de configuration servant à créer les lignes du menu grub relatives au démarrage à partir du fichier iso. Cette fonction utilise les deux fonctions "no_iso_file" et "no_cfg_file" pour afficher les messages d'erreur correspondants. La ligne
   if [ -z "${2}" ]; then set sourcefile=/boot/grub/loopback.cfg; else set sourcefile="${2}"; fi
signifie qu'en l'absence du 2e paramètre, le fichier de configuration est le fichier loopback.cfg contenu dans le fichier.

Ces références devaient être données dans le "langage" grub, semblable à celui de GNU/Linux, mais néanmoins suffisamment différent pour présenter des difficultés pour quiconque n'en était pas familier. J'ai alors entrepris d'écrire le script bash pour créer automatiquement les lignes amorce_iso dans le fichier custom.cfg. Ce script étant exécuté sous GNU/Linux, j'ai introduit, outre l'introduction "permanente" dans le menu grub des lignes spécifiques à l'image iso choisie lors de l'exécution du script bash, la possibilité de réamorcer immédiatement, et une seule fois, à partir du fichier iso, sans afficher le menu grub correspondant au système en cours d'exécution, mais en affichant directement celui qui correspond à l'image iso. Ces deux options, introduction dans le menu grub ou substitution d'un nouveau menu, correspondent à deux commandes grub différentes : source et configfile. J'ai alors défini la commande "amorce_iso" pour ce second mode de fonctionnement.

La ligne "amorce_iso" introduite dans le fichier custom.cfg n'est pas effacée par grub. Il faut au redémarrage à partir de l'image la neutraliser pour éviter de boucler indéfiniment sur le démarrage à partir de l'image iso. Cette neutralisation est effectuée par la variable d'environnement "amorceiso" qui est remise à la valeur "false" lors du démarrage à partir de l'image iso, et qui doit être "true" pour activer le démarrage à partir du fichier iso.

Je n'ai pas encore eu le temps d'analyser "grub-imageboot". J'ai constaté qu'un nouveau fichier "60_grub-imageboot" dans le répertoire /etc/grub.d a été créé, mais je n'en ai pas compris le fonctionnement.

Arbiel
J'ai bien vu ton message. Je comprends mieux comment fonctionne ton script maintenant (pas très bon en bash... ^^ )

Je continue de l'étudier en détail pour recréer son fonctionnement histoire d'avoir des fonctions python équivalentes à tes fonctions bash, ça me permettra de les incorporer à l'interface graphique par la suite.

Je vais essayer de poster une nouvelle version bientôt.

Merci pour tes explications !
Ok, mises à jour du script finies !

Il fonctionne maintenant en deux fichiers séparés : grubenhancer.py et fonctions.py
grubenhancer.py est le script qui doit être appelé en ligne de commande et fonctions.py celui qui contient les fonctions utilisées par le script.
La principale différence avec la précédente version est l'utilisation du module path.py qu'il faut installer avec pip :
sudo pip-3.2 install path.py
À adapter en fonction de votre version de python (peut être pip-3.2, pip-3.3 ou pip-3.4)

Ensuite créer un fichier grubenhancer.py comme suit :
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from os.path import expanduser
import argparse
import fonctions
import subprocess

### Programme principal ###
# Initialisation des arguments à passer au programme
parser = argparse.ArgumentParser(description='''Modifie les fichiers de configuration de GRUB afin de démarrer l'ordi sur une image iso.''', prog='GRUB Enhancer')

parser.add_argument('-i', '--iso', required=True, metavar='FILE', help="L'image iso destinée à être bootée")
parser.add_argument('-l', '--loop', metavar='FILE', default="", help="Le fichier loopback qui y est associé")
parser.add_argument('--grub-rep', metavar='DIRECTORY', dest='rep', default='/boot/grub/', help="Un éventuel répertoire alternatif pour GRUB. Default=/boot/grub/")
parser.add_argument('-r', '--reboot', const=True, default=False, action='store_const', dest='reboot', help="Redémarre l'ordinateur après les modifications")
parser.add_argument('-t', '--temporary', const=True, default=False, action='store_const', dest='temp', help="N'effectue la modification que pour le prochain redémarrage")

args = parser.parse_args()
# Support du tilde ( ~ )
args.iso = expanduser(args.iso)
args.rep = expanduser(args.rep)
if args.loop: args.loop = expanduser(args.loop)
else: args.loop = None

# Vérification des droits root
if fonctions.check_root(): pass
else:
    print("Ce programme demande les droits root.")
    exit()

print("Vérification de la configuration de GRUB...")
fonctions.check_grub_config()
fonctions.update_grub(args.rep)

print("Écriture des fonctions nécessaire aux démarrage sur une image iso...")
fonctions.write_function(args.rep)

print("Modification du fichier de menu...")
fonctions.update_custom(args.iso, args.rep, args.loop, args.temp)

if args.reboot: subprocess.call("shutdown -r now".split())
et un fichier fonctions.py :
#! /usr/bin/env pyhton3
# -*- coding:utf-8 -*-

import path
import subprocess
import os
import shlex
from os.path import basename

def search(dir, pattern, rec=1):
    """Fonction de recherche de répertoire selon un «pattern».
    <rec> indique le niveau de récursivité.
    Renvoie une liste contenant les chemins correspondant au pattern."""
    dir = path.Path(dir)
    result = list()
    for i in range(rec):
        result += dir.glob('*/'*i + pattern)
    return result

def check_grub_config(rep="/etc/grub.d/", custom_conf="custom.cfg"):
    """Vérifie la présence du fichier «41_custom» dans le
    répertoire "/etc/grub.d". Le crée sinon avec le contenu
    de custom.cfg"""
    grub_dir = path.Path(rep)
    files = grub_dir.files()
    if "41_custom" in files: return True
    else:
        custom_content = open(custom_conf, 'r').read()
        custom = grub_dir.joinpath("41_custom")
        custom = custom.open('w')
        custom.write(custom_content)
        custom.close()
        return True

def update_grub(rep="/boot/grub/"):
    """Met à jour la configuration de grub"""
    grub_dir = path.Path(rep)
    config_file = grub_dir.joinpath("grub.cfg")
    commande = "grub-mkconfig -o {}".format(config_file)
    subprocess.call(commande.split())
    return True

def check_root():
    """Vérifie que le programme a les droits root.
    Renvoie True si c'est le cas, False sinon."""
    if os.geteuid() == 0:
        return True
    else:
        return False

def write_function(rep, file="fonctions_iso.cfg"):
    """Écrit les fonctions nécessaires au démarrage
    sur iso dans le répertoire grub. Les fonctions sont
    lues à partir de «file»"""
    grub_dir = path.Path(rep)
    fonctions = open(file, 'r').read()
    try:
        grub_dir.joinpath("greffons").mkdir()
    except OSError: pass
    fonctions_file = grub_dir.joinpath("greffons/fonctions_iso.cfg")
    fonctions_file = fonctions_file.open('w')
    fonctions_file.write(fonctions)
    fonctions_file.close()
    return True

def update_custom(iso, rep="/boot/grub", loop=None, temp=False):
    """Modifie le fichier contenant les entrées du menu"""
    incipit = "source ${prefix}/greffons/fonctions_iso.cfg\n"
    grub_dir = path.Path(rep)
    custom = grub_dir.joinpath("custom.cfg")
    try: custom_content = custom.open('r').readlines()
    except OSError: custom_content = []
    
    # Rajout de l'incipit
    if incipit not in custom_content:
        custom_content[:0] = [incipit]
    
    # Suppression des instructions «amorce_iso»
    for line in custom_content:
        if "amorce_iso" in line:
            custom_content.remove(line)
    
    # Calcul des chemins depuis la racine de la partition
    iso = find_path(iso)
    if loop: loop = find_path(loop)
    
    # Obtention du nom de l'iso
    iso_name = basename(iso)
    
    if temp:
        if loop:
            config = 'amorce_iso "{}" "{}"\n'.format(iso, loop)
        elif not loop:
            config = 'amorce_iso "{}"\n'.format(iso)
        subprocess.call('grub-editenv /boot/grub/grubenv set amorceiso=true'.split())
    elif not temp:
        if loop:
            config = '\tsubmenu "'+iso_name+'" {iso_boot "'+iso+'" "'+loop+'"}\n'
        elif not loop:
            config = '\tsubmenu "'+iso_name+'" {iso_boot "'+iso+'"}\n'
    
    custom_content.append(config)
    custom_content = "".join(custom_content)
    
    custom = custom.open('w')
    custom.write(custom_content)
    custom.close()
    
    return True
    
def find_path(path):
    """Retrouve le chemin d'accès d'un fichier à partir de la racine
    de sa partition et non du système. Utilise le programme df"""
    # Redirection du retour du programme df dans un fichier que l'on va 
    # ensuite lire puis supprimer
    commande = shlex.split('bash -c "df {} > partition"'.format(path))
    subprocess.call(commande)
    resultat = open('partition', 'r').read()
    partition = resultat.split()[-1]
    os.remove("partition")
    # Puis suppression dans le chemin donné de la partition
    path = path.replace(partition, "", 1)
    return path
Ainsi qu'un fichier custom.cfg contenant :
#!/bin/sh
cat <<EOF
if [ -f  \${config_directory}/custom.cfg ]; then
  source \${config_directory}/custom.cfg
elif [ -z "\${config_directory}" -a -f  \$prefix/custom.cfg ]; then
  source \$prefix/custom.cfg;
fi
EOF

Le script peut être appelé avec les paramètres suivants:
--iso permet de sélectionner un fichier iso
--loop permet de sélectionner un fichier loopback
--grub-rep permet de sélectionner un répertoire grub (/boot/grub/ par défaut)
--reboot permet de redémarrer l'ordi après l'exécution du script
--temporary permet de rendre la modification effective seulement pour le prochain redémarrage

Seule l'option --iso est obligatoire normalement mais le script ne fonctionnera pas si l'option --temporary est précisée sans --loop. Cette limitation est due aux fonctions grub d'Arbiel (la fonctions amorce_iso attend obligatoirement deux paramètres et ne permet pas d'utiliser le fichier loopback de l'iso)

@Arbiel:

Le script fonctionne normalement (j'ai testé certaines options) selon tes directives (pas de modification directe du fichier grub.cfg mais de /etc/grub.d.41_custom, permet les entrées temporaires et rend le fichier loopback facultatif parfois).
Si jamais tu avais prévu un autre comportement qui n'est pas présenté ici, précise-le moi et je le créerai. En attendant il ne me reste plus qu'à créer l'interface graphique. Est-ce que tu as trouvée une solution pour booter des isos qui ne sont pas basées sur Ubuntu ?

Voilà c'est tout !

Si tu pouvais juste rendre facultatif la précision du fichier loopback avec amorce_iso ce serait parfait ! (Pourquoi ne pas avoir fait que amorce_iso appelle iso_boot ? )

Merci pour ton travail !
Bonjour Laërte

J'ai modifié le script grub pour permettre l'appel de "amorce_iso" avec un seul paramètre. J'ai rapidement testé, mais je n'ai pas testé l'absence de régression pour "iso_boot".

Je suis surpris que tu aies fractionné le code de ton script en deux fichiers. Il me semblerait plus facile, pour les utilisateurs, que tout soit regroupé et qu'il n'y ait pas à enregistrer quoi que ce soit ici ou là. En poursuivant dans cette idée, j'ai constaté que Python (Python3.4, pour les versions antérieures, je ne sais pas) permet, plutôt que de lire le script grub à partir d'un fichier, d'en affecter le contenu à une variable, par exemple "fonctions", ce qui donnerait, dans ta fonction "update_custom"
fonctions = """# fonctions_iso_V2-1.cfg
# 2015_01_26
#######################################################################################################################
# Redémarrage en cas d'absence ou d'indisponibilité des fichiers (fichier image iso ou fichier de configuration)
function rdmge {
	echo Le PC va redémarrer dans quelques secondes
	sleep -v 10
	reboot
}
#######################################################################################################################
# Avertissement présenté à l'utilisateur si le fichier iso est introuvable, ou n'a pas été donné en paramètre de la commande iso_boot
#   Iso file missing
function no_iso_file {
	if [ -n "${1}" ] ; then
		echo L\'image à partir de laquelle il faut amorcer le PC, ${1}, ne se trouve sur aucun des supports actuellement raccordés à l\'ordinateur.
	else 
		echo Aucune image iso n\'a été attachée au libellé ${chosen} que vous venez de choisir.
	fi
	rdmge
}
#######################################################################################################################
# Avertissement présenté à l'utilisateur si le fichier de configuration est introuvable
#   Grub configuration file missing
function no_cfg_file {
	echo Le fichier de configuration, ${1}, ne se trouve sur aucun des supports actuellement raccordés à l\'ordinateur.
	rdmge
 }
#######################################################################################################################
# Contrôle de l'existence des fichiers
#
function existent_fichiers {
#  recherche du fichier iso
	if [ -n "${iso_file}" ]; then
# si grub trouve le fichier ${iso_file}, alors ce fichier est sur la partition ${root} ; sinon il faut chercher où il est.
		if [ -e "${iso_file}" ]; then set image_iso=${root}; else search --file --set=image_iso --no-floppy "${iso_file}"; fi
	fi
	if [ -z "${image_iso}" ]; then no_iso_file "${iso_file}"; fi
# création du périphérique virtuel qui donne accès au fichier iso
#    creation of the virtual device holding the iso file and paths initialisation
	loopback iso (${image_iso})${iso_file}
	set root=iso
	set loopcfg=
# recherche et introduction du menu spécifique à l'image iso considérée
	if [ -z "${sourcefile}" ]; then set sourcefile=/boot/grub/loopback.cfg; fi
# si le fichier se trouve sur le périphérique $root, il n'est pas utile de le chercher
	if [ -e "${sourcefile}" ]; then set loopcfg=${root} ; else search --file --set=loopcfg --no-floppy "${sourcefile}" ; fi
	if [ -z "${loopcfg}" ]; then no_cfg_file "${sourcefile}";  fi
}
#######################################################################################################################
# Cette procédure crée un periphérique virtuel qui donne accès aux répertoires et fichiers contenu dans le fichier iso
# et cherche le fichier contenant le menu correspondant à l'image iso considérée et l'introduit dans le menu Grub
# paramètre ${1} : le chemin d'accès au fichier iso
# paramètre ${2}, facultatif : le chemin d'accès au fichier contenant les entrées de menu pour l'image iso considérée
#    quand il est omis, il s'agit du fichier /boot/grub/loopback.cfg de l'image iso
function iso_boot  {
	set image_iso=
	set iso_file="${1}"
	set iso_path="${1}"
	set sourcefile="${2}"
	existent_fichiers
	source "(${loopcfg})${sourcefile}"
}
function amorce_iso {
########################################################################################
#
# amorçage par le script shell iso_boot.sh
#
#######################################################################################
# pour éviter le bouclage sur la procédure
    if ${amorceiso}; then
		set amorceiso=false
		save_env amorceiso
		set image_iso=
		set iso_path="${1}"
		set iso_file="${1}"
		set sourcefile="${2}"
		existent_fichiers
		export iso_path
		export iso_file
		export root
		configfile "(${loopcfg})${sourcefile}"
        fi
}"""
Tu remarqueras que la première ligne porte un numéro de mise à jour, que je vais faire évoluer à chaque modification, même minime. Je te conseille de nommer ainsi le fichier que tu enregistres dans /boot/grub/greffons, ce qui te permet facilement de décider s'il convient ou non de l'enregistrer dans /boot/grub/greffons.

J'ai compris que ton script n'avait pas d'interface graphique. À quoi sert alors le paramètre "help=" dans les commandes "parser.add_argument" ? J'y ai relevé quelques "imperfections" mineures, dont je te fais part ci-dessous, au cas où ces commentaires apparaîtrait néanmoins aux yeux des utilisateurs :
parser.add_argument('-i', '--iso', required=True, metavar='FILE', help="L'image iso à utiliser pour redémarrer le PC")
parser.add_argument('-l', '--loop', metavar='FILE', default="", help="Le fichier de configuration pour l'affichage du menu")
parser.add_argument('--grub-rep', metavar='DIRECTORY', dest='rep', default='/boot/grub/', help="Le répertoire utilisé par grub au démarrage si celui-ci n'est pas /boot/grub/")
parser.add_argument('-r', '--reboot', const=True, default=False, action='store_const', dest='reboot', help="Redémarrer immédiatement l'ordinateur")
parser.add_argument('-t', '--temporary', const=True, default=False, action='store_const', dest='temp', help="N'effectuer la modification que pour le prochain redémarrage")
Je crois qu'il faut envisager la possibilité de lancer ton script à partir d'un lanceur sur lequel l'utilisateur pourrait faire glisser l'image iso, ou même par un menu contextuel obtenu par clic sur le bouton droit de la souris lorsqu'elle est positionnée sur une image iso, ou son fichier loopback. Ta fonction "fonctions.check_root" n'est pas appropriée pour ce mode de lancement. Dans cette idée, j'ai écrit il y a quelque temps un petit script bash que tu pourrais peut-être essayer de traduire en Python.

C'est ton interface graphique qui va donner à ton script toute sa valeur. Il faut donc la définir avec précaution.

Le script bash que j'ai écrit utilise zenity. Or zenity présente l'inconvénient de ne permettre la saisie que d'un seul élément à la fois, ce qui n'est pas assez ergonomique . À mon avis, il faudrait pouvoir saisir les informations dans un écran unique, contenant vraisemblablement plusieurs onglets, ou plusieurs parties parfaitement bien identifiées. Dans ces onglets, on peut penser à un regroupement des informations par nature ou par complexité. Par complexité, je veux dire ce qui demande une plus ou moins grande compréhension du démarrage d'un PC et qui pourrait être intitulé "Mode expert".

Les tests effectués par Babdu89 ont montré que certaines distributions n'acceptent pas d'espaces dans le chemin d'accès à l'image iso. La solution que j'avais l'intention d'introduire dans le script bash était de définir un lien physique à la racine de la partition, nommé par la concaténation d'un libellé, par exemple "amorce_iso" et de l'inode du fichier (ou tout autre procédé, par exemple un uuid, permettant de s'assurer que deux images iso de même nom, mais enregistrées dans deux répertoires différents, ne conduisent pas à deux liens physiques de même nom). En allant dans ce sens, il faudra probablement ajouter des paramètres pour l'appel de "iso-boot" pour présenter un libellé compréhensible par l'utilisateur.

Certaines distributions, et vraisemblablement celle qui t'intéressait quand tu as commencé à t'intéresser à ce sujet, ne sont pas compatibles avec le script grub. La solution tourne autour de l'utilisation de "memdisk", mais je n'ai pas encore approfondi.

Babdu89 avait également souhaiter qu'au démarrage l'image iso bascule en français et le clavier en "azerty". Le plus simple, dans un premier temps est que tu prévois deux nouveaux paramètres. Le clavier "azerty" n'est pas le seul utilisé en français. J'utilise "bépo". Mais tu peux certainement obtenir cette information dans le système et te passer des paramètres. Nous verrons plus tard comment passer ces informations au lancement de l'image.

Bon courage

Arbiel
Ça fait beaucoup tout ça... ^^

Pour le numéro de version, je note ça dans mon fichier TODO histoire de gérer les prochaines versions avec le script.

Pour le paramètre help='TEXT' des parser.add_argument, il définit le texte qui s'affiche lorsqu'on lance la fonction avec l'argument -h ou --help. C'est dans ces cas-là rt uniquement ceux-ci que le message écrit s'affiche.

Pour le clavier azerty c'est déjà rajouté dans ma version locale, je pensais l'avoir mis en ligne. Le script qui extrait le fichier loopback y ajoute la traduction francophone dans la foulée. Je ne le poste pas tout de suite il est en cours de modification et n'est pas utilisable pour le moment. Concrètement il rajoute dans le fichier loopback, à toutes les lignes commençant par linux :
locale=fr_FR bootkbd=fr console-setup/layoutcode=fr console-setup/variantcode=oss
Pour la séparation en plusieurs fichiers, je pense que ça reste une bonne idée de séparer les fonctions utilisées par le script du fonctionnement de celui-ci. Pareil pour le fait de mettre tes fonctions dans des fichiers au lieu de dans des variables. Lors de modifications ultérieures, ça évite que tout soit fait sur le même fichier, ce qui augmenterait les risques d'erreur. D'autant qu'avec l'ajout de l'interface graphique, le script risque de se compliquer, je préfère donc que tout soit bien compartimenté. Après, pour l'utilisateur, le seul côté gênant pour l'instant vient du fait qu'il doive créer tous ces fichiers lui-même, puisque leur contenu est posté dans le forum. Je pense d'ailleurs créer un dépôts sur github (dès que j'aurais compris comment fonctionne git...), de cette manière il sera possible de télécharger directement une archive et d’exécuter le script qu'il faut, sans se prendre la tête avec les fichiers autour...

Pour l'exécution du script par un menu contextuel ou autre, là ça ne relève plus de l'appli en elle-même mais d'un module de gestionnaire de fichier qu'il faudra que l'on crée à part. je sais que Dolphin peut faire ça avec un fichier .desktop placé dans le bon dossier, j'imagine qu'il y a un équivalent pour Nautilus. Mais là, je pense que pour l'instant c'est du bonus, on va déjà essayer de faire une appli qui marche. 😃 Parce qu'il reste du boulot en ce qui me concerne.

D'ailleurs tu mets le doigt dessus : pas d'interface graphique encore. Pour celle-ci je ne sais pas si tu vois bien à quoi ressemble une interface faite avec tkinter (exemple : https://3.bp.blogspot.com/-9GGOzb7SUzg/UBBeLFQzXFI/AAAAAAAAA3M/yyxfNFNhigU/s1600/themes_2.PNG ) mais on peut faire des trucs assez complexes. Ça demande juste du temps... Pour l'instant je vais essayer de faire un truc assez simple mais qui reprend toutes les fonctions de mon script en ligne de commande.

Pour memdisk, j'ai testé chez moi avec grubimage-boot, et bah ça ne marche pas ! ^^ Le kernel commence à démarrer et s'arrête en cours de root route.

Et enfin, la création d'un lien logique, qui me plaît bien comme idée. 😃 Faut que je vois comment je peux rajouter ça.

Bref, beaucoup de choses, pas dit que j'aille très vite en plus (je débute toujours dans la programmation python et je fais régulièrement des recherches encore pour trouver comment faire ceci ou cela), donc je ne sais pas si je vais poster de nouvelles versions avant un moment, mais vous en faîtes pas, j'y travaille ! ^^

Juste une question : est-ce que quelqu'un teste les scripts à part moi ? Histoire de faire des retours de bugs... Je sais pas si Babdu a vu qu'on avait repris le post...
Bonsoir Laërte

Pour ma part, je n'ai pas testé ton script. Je le testerai peut-être si j'en trouve le temps et en ai l'occasion, mais j'attends plutôt l'interface graphique car c'est vraiment cette interface qui lui donnera toute sa valeur.

C'est bien sûr à toi qu'il revient de définir l'organisation de tes fichiers et j'ai compris que tu as l'intention de les distribuer sous la forme d'une archive avec un script pour les copier à leur place. C'est effectivement une solution intéressante.

J'ai néanmoins quelques remarques à formuler sur ce que tu as présenté

1) le contrôle de l'exécution en mode root : à mon avis, elle dépend de ton application car si l'on veut envisager de la lancer à partir d'un lanceur ou par un élément de menu contextuel, c'est bien ton application qui doit gérer le dialogue

2) le passage de paramètres au lancement du noyau : il me semblerait préférable de les mémoriser dans une variable et ce qui te permettra de tester beaucoup plus facilement s'il faut l'insérer ou si elle est déjà présente sur la ligne linux

3) pour ce qui est de la langue et du clavier, je crois qu'il est nécessaire de les prévoir dans les paramètres, et dans ton interface graphique.

Arbiel
Bonjour.
Juste une question : est-ce que quelqu'un teste les scripts à part moi ? Histoire de faire des retours de bugs... Je sais pas si Babdu a vu qu'on avait repris le post...
Oui, oui, bien sur que je suis toujours le sujet.

Mais ce qui est intéressant pour le "novice" que je m'efforce de rester, c'est d'avoir le script "presque"final à tester, et de retourner au dev, ce qui ne va pas. Je ne pense pas qu'on en soit arrivé là.

Alors, si je peux me permettre d'intervenir en cours de dev. Voila ce que j'aimerais souligné.

Remarque et rappel.
Sur mes vieilles machines.
Je n'ai fais que tester des iso en 32 bit. Des iso Ubuntu et leurs variantes officielles.
Je lance les 12.04, 14.04, et 14.10 .
Mais dès que l'on s'en écarte, le script ne les lance plus.
Exemple, j'ai tenté de lancer des iso d'Hybryde (basées sur Ubuntu) . Çà ne marche pas . Le script bash me demande de choisir le Grub lanceur de l'iso, me demande d'indiquer le chemin de l'iso, trouve l'iso et la monte.
Soit çà ne va pas plus loin et redemande d'indiquer l'iso a nouveau.
Soit çà va un peut plus loin . Mais il y a un souci avec le "loopback.iso" , et çà en reste là.

Donc pour lancer une variété d'iso comme on peut le faire avec le "MultiSystem" de frafa, on en est encore loin...
Il y a peut-être des idées à reprendre dans les script de cet outils, par une lecture approfondie.
Je dis çà. Je ne suis pas codeur, ni même capable de faire le moindre script, alors...

Maintenant, avec les nouvelles machines, dont je ne suis pas possesseur, donc pas de tests possibles. Les iso vont surtout être en 64 bit et en UEFI. Et là, çà change beaucoup de choses . Il faudrait que ce qui est écrit soit aussi utilisable en ce mode.

Pour en revenir au MultiSystem, frafa l'a fait évoluer en ce sens, ce qui fait que les iso en UEFI sont maintenant lancées par le MultiSystem.

Je ne sais pas si ce que vous écrivez actuellement va dans ce sens?...

Grub2 et Grub/efi . Il y a pas mal de différence il me semble.

Si on veut que ce soit utilisable, pour "tout" , la prise en compte de l'UEFI va devenir incontournable. Sinon les script deviendront rapidement obsolètes, et il y a un risque de voir de moins en moins de contributeurs pour tester.

Bonne continuation, je continue de suivre en silence pour le moment.

@+. Babdu89 .
3 mois plus tard
J'ai fini ! (enfin) 😃

Normalement ça devrait marcher.

Le script est ici : https://github.com/schyzophrene-asynchrone/grub-enhancer

Au programme, la rédaction d'un README, éventuellement l'ajout du support de memdisk, pour supporter autre chose que juste les isos basées sur Ubuntu.

Au niveau des dépendances, il faut avoir installé python3, python3-pyqt5, et avoir fait un
sudo pip3 install path.py
Cette dernière commande pourra être évitée plus tard.

J'attend les retours de bug pour corriger, l'appli doit être lancée en tant que root pour pouvoir appliquer les modifications.

Voilà ! ^^

PS : le script à éxécuter est main.py.
7 jours plus tard
Bonsoir Laërte

Je viens, en migrant mon système vers LVM, de trouver une limitation à l'utilisation de ton script. Dans l'immédiat, il faut refuser (ne pas exécuter la commande grub-editenv) si /boot/grub est un volume logique LVM, ou si le système de fichier est l'un des suivants
btrfs
cpiofs
newc
odc
romfs
squash4
tarfs
zfs

Des explications sont disponibles dans cette page (en anglais)

Je ne suis pour l'instant pas en mesure de tester ton travail.

Par contre, à la lecture de l'intervention de Babdu89, j'ai réfléchi à l'impact potentiel de l'UEFI et il me semble qu'il n'y en a pas. Tout repose sur grub et grub fonctionne avec BIOS et UEFI. Mais il s'agit là d'une analyse qui ne permet pas de négliger la confirmation par des tests.

Arbiel

Arbiel