diff --git a/cli/parser.py b/cli/parser.py index b109752..04f5b9e 100644 --- a/cli/parser.py +++ b/cli/parser.py @@ -10,6 +10,14 @@ def get_argument_parser(): description="Debian ISO preseeding tool.", ) + # add force flag + mainparser.add_argument( + "-f", + "--force", + action='store_true', + help="Overwrite output file if it already exists", + ) + # add mutually exclusive optional arguments to top-level parser mainparser_group = mainparser.add_mutually_exclusive_group() mainparser_group.add_argument( diff --git a/core/utils.py b/core/utils.py index 871f17b..3859f56 100644 --- a/core/utils.py +++ b/core/utils.py @@ -2,8 +2,9 @@ import hashlib import secrets +import shutil from getpass import getpass -from os import remove, rename +from os import remove from pathlib import Path from subprocess import run, STDOUT, PIPE from sys import exit @@ -168,7 +169,7 @@ def file_is_empty(path_to_input_file): return not file_has_content -def download_and_verify_debian_iso(path_to_output_file, printer=None): +def download_and_verify_debian_iso(path_to_output_file, printer=None, force=False): """Downloads the latest Debian ISO as the specified output file. The file's integrity is validated using a SHA512 checksum. @@ -180,13 +181,15 @@ def download_and_verify_debian_iso(path_to_output_file, printer=None): Path to the file as which the downloaded image will be saved. printer : clibella.Printer A CLI printer to be used for output. + force : bool + If True, overwrite existing files without raising an error. """ if "~" in str(path_to_output_file): path_to_output_file = Path(path_to_output_file).expanduser() path_to_output_file = Path(path_to_output_file).resolve() - if path_to_output_file.is_file(): + if path_to_output_file.is_file() and not force: raise FileExistsError( f"Output file '{path_to_output_file}' already exists." ) @@ -222,28 +225,6 @@ def download_and_verify_debian_iso(path_to_output_file, printer=None): printer=printer, ) - # verify the hash file using gpg - printer.info("Verifying hash file using gpg...") - if not debian_signing_key_is_imported(): - printer.info("Importing Debian public GPG CD signing key...") - import_debian_signing_key() - else: - printer.info("Found Debian public GPG CD signing key.") - try: - assert_detached_signature_is_valid( - path_to_hash_file, - path_to_signature_file, - ) - except VerificationFailedError: - printer.error("PGP signature of the hash file was invalid!") - exit(1) - printer.ok("HASH file PGP authenticity check passed.") - - # remove all lines from hash file not containing the image file name - trim_text_file(path_to_hash_file, files["image_file"]["name"]) - if file_is_empty(path_to_hash_file): - raise RuntimeError("Failed to locate SHA512 hash sum for image.") - # download image file download_file( path_to_image_file, @@ -252,23 +233,51 @@ def download_and_verify_debian_iso(path_to_output_file, printer=None): printer=printer, ) - # validate SHA512 checksum - printer.info("Validating ISO file integrity...") - hash_check_result = run( - [ - "sha512sum", "--check", path_to_hash_file - ], - text=True, - stdout=PIPE, - stderr=STDOUT, - cwd=path_to_image_file.parent, - ) - if hash_check_result.returncode != 0: - raise RuntimeError("SHA512 checksum verification of the ISO failed.") - printer.ok("ISO file integrity check passed.") - # move downloaded file to specified destination - rename(path_to_image_file, path_to_output_file) + shutil.move(path_to_image_file, path_to_output_file) + + +def download_debian_iso_simple(path_to_output_file, printer=None, force=False): + """Downloads the latest Debian ISO without verification. + + Only downloads the ISO file, skips all SHA512 and GPG verification. + + Parameters + ---------- + path_to_output_file : str or pathlike object + Path to the file as which the downloaded image will be saved. + printer : clibella.Printer + A CLI printer to be used for output. + force : bool + If True, overwrite existing files without raising an error. + """ + + if "~" in str(path_to_output_file): + path_to_output_file = Path(path_to_output_file).expanduser() + path_to_output_file = Path(path_to_output_file).resolve() + + if path_to_output_file.is_file() and not force: + raise FileExistsError( + f"Output file '{path_to_output_file}' already exists." + ) + if not path_to_output_file.parent.is_dir(): + raise NotADirectoryError( + f"No such directory: '{path_to_output_file.parent}'." + ) + + if printer is None: + printer = Printer() + + # scrape for URLs and filenames + files = get_debian_iso_urls() + + # download image file directly + download_file( + path_to_output_file, + files["image_file"]["url"], + show_progress=True, + printer=printer, + ) def download_and_verify_debian_testing_iso(path_to_output_file, printer=None): @@ -350,4 +359,47 @@ def download_and_verify_debian_testing_iso(path_to_output_file, printer=None): printer.ok("ISO file integrity check passed.") # move downloaded file to specified destination - rename(path_to_image_file, path_to_output_file) + shutil.move(path_to_image_file, path_to_output_file) + + +def download_debian_testing_iso_simple(path_to_output_file, printer=None, force=False): + """Downloads the latest Debian testing ISO without verification. + + Only downloads the ISO file, skips all SHA512 and GPG verification. + + Parameters + ---------- + path_to_output_file : str or pathlike object + Path to the file as which the downloaded image will be saved. + printer : clibella.Printer + A CLI printer to be used for output. + force : bool + If True, overwrite existing files without raising an error. + """ + + if "~" in str(path_to_output_file): + path_to_output_file = Path(path_to_output_file).expanduser() + path_to_output_file = Path(path_to_output_file).resolve() + + if path_to_output_file.is_file() and not force: + raise FileExistsError( + f"Output file '{path_to_output_file}' already exists." + ) + if not path_to_output_file.parent.is_dir(): + raise NotADirectoryError( + f"No such directory: '{path_to_output_file.parent}'." + ) + + if printer is None: + printer = Printer() + + # scrape for URLs and filenames + files = get_debian_testing_iso_urls() + + # download image file directly + download_file( + path_to_output_file, + files["image_file"]["url"], + show_progress=True, + printer=printer, + ) diff --git a/files_to_inject/preseeds/default.preseed b/files_to_inject/preseeds/default.preseed index 85b8edf..6c13aec 100755 --- a/files_to_inject/preseeds/default.preseed +++ b/files_to_inject/preseeds/default.preseed @@ -4,6 +4,7 @@ d-i debian-installer/locale string fr_CH.UTF-8 # Configuration réseau automatique d-i netcfg/choose_interface select auto d-i netcfg/get_hostname string skylanix +# Forcer la saisie du hostname même si déjà configuré d-i netcfg/get_hostname seen false d-i netcfg/get_domain string unassigned-domain @@ -12,13 +13,19 @@ d-i passwd/root-login boolean false # Partitionnement : manuel uniquement d-i partman-auto/method string manual +# Ne pas demander confirmation pour créer une nouvelle table de partition d-i partman-partitioning/confirm_write_new_label boolean false +# Ne pas demander confirmation avant l'écriture des partitions d-i partman/confirm boolean false +# Ne pas demander confirmation en cas d'écrasement de données d-i partman/confirm_nooverwrite boolean false # Configuration APT : priorité aux dépôts réseau plutôt qu'au CD-ROM d-i apt-setup/cdrom/set-first boolean false +# Configuration des sources Debian +d-i apt-setup/use_mirror boolean true + # Activation des dépôts non-free pour les pilotes propriétaires d-i apt-setup/non-free boolean true d-i apt-setup/non-free-firmware boolean true @@ -26,9 +33,9 @@ d-i apt-setup/non-free-firmware boolean true # Installation minimale de base tasksel tasksel/first multiselect minimal -# Paquets essentiels Skylanix : environnement KDE Plasma et outils système +# Paquets essentiels Skylanix : environnement GNOME et outils système d-i pkgsel/include string \ - kde-plasma-desktop \ + gnome-core \ vim \ fish \ git \ @@ -38,19 +45,14 @@ d-i pkgsel/include string \ htop \ btop \ fastfetch \ - plasma-discover \ flatpak \ - plasma-discover-backend-flatpak \ - gwenview \ - ark \ ffmpeg \ libavcodec-extra \ libavformat-extra \ - zenity \ spice-vdagent \ cmatrix -# kde-plasma-desktop: Bureau KDE Plasma +# gnome: environnement de bureau GNOME # vim: Éditeur de texte # fish: Shell moderne # git: Gestionnaire de versions @@ -60,11 +62,7 @@ d-i pkgsel/include string \ # htop: Moniteur système interactif # btop: Moniteur système moderne # fastfetch: Info système colorée -# plasma-discover: Gestionnaire de logiciels KDE # flatpak: Gestionnaire d'apps universelles -# plasma-discover-backend-flatpak: Support Flatpak dans Discover -# gwenview: Visionneuse d'images KDE -# ark: Gestionnaire d'archives KDE # ffmpeg: Codecs audio/vidéo # libavcodec-extra: Codecs supplémentaires # libavformat-extra: Formats multimédias supplémentaires @@ -105,4 +103,4 @@ d-i preseed/late_command string \ in-target apt-get install -y linux-xanmod-x64v3 ; # Finalisation : redémarrage automatique -d-i finish-install/reboot_in_progress note \ No newline at end of file +d-i finish-install/reboot_in_progress note diff --git a/files_to_inject/preseeds/install_gaming.sh b/files_to_inject/preseeds/install_gaming.sh index 2b14b1c..1311d88 100755 --- a/files_to_inject/preseeds/install_gaming.sh +++ b/files_to_inject/preseeds/install_gaming.sh @@ -422,7 +422,7 @@ show_unified_selection() { FALSE "heroic" "GitHub" "🎮 Heroic Game Launcher - Client Epic Games et GOG" \ FALSE "lutris" "APT" "🎮 Lutris - Gestionnaire de bibliothèque de jeux" \ FALSE "retroarch" "Flatpak" "🕹️ RetroArch - Plateforme d'émulation multi-systèmes" \ - FALSE "utils" "APT" "⚡ Utilitaires gaming - Monitoring des performances (FPS, CPU, GPU)" \ + FALSE "goverlay" "APT" "⚡ GOverlay - Monitoring des performances (FPS, CPU, GPU)" \ FALSE "protonup" "Flatpak" "🔄 ProtonUp-Qt - Gestionnaire de versions Proton" \ FALSE "wine" "APT" "🍷 Wine + Winetricks - Couche de compatibilité Windows" \ FALSE "bottles" "Flatpak" "🍷 Bottles - Gestionnaire Wine moderne" \ @@ -1550,9 +1550,9 @@ install_nvidia() { fi } -# Fonction d'installation des utilitaires gaming -install_utils() { - log_info "Début de l'installation des utilitaires gaming" +# Fonction d'installation des GOverlay +install_GOverlay() { + log_info "Début de l'installation des GOverlay" # Vérifier si les utilitaires sont déjà installés gamemode_installed=$(dpkg -l | grep -q "^ii.*gamemode" && echo "oui" || echo "non") @@ -1560,13 +1560,13 @@ install_utils() { goverlay_installed=$(dpkg -l | grep -q "^ii.*goverlay" && echo "oui" || echo "non") if [ "$gamemode_installed" = "oui" ] && [ "$mangohud_installed" = "oui" ] && [ "$goverlay_installed" = "oui" ]; then - log_info "Tous les utilitaires gaming déjà installés" - zenity 2>/dev/null --info --title="Composants déjà présents" --text="Tous les utilitaires gaming sont déjà installés sur le système." + log_info "Tous les GOverlay déjà installés" + zenity 2>/dev/null --info --title="Composants déjà présents" --text="Tous les GOverlay sont déjà installés sur le système." return fi # Utiliser le mot de passe global ou demander un nouveau - if ! use_global_password_or_ask "utilitaires gaming"; then + if ! use_global_password_or_ask "GOverlay"; then return fi @@ -1597,7 +1597,7 @@ install_utils() { echo "100" ; echo "# Vérification de l'installation..." ) | zenity 2>/dev/null --progress \ - --title="Installation des utilitaires gaming" \ + --title="Installation des GOverlay" \ --text="Initialisation..." \ --percentage=0 \ --width=400 \ @@ -1609,16 +1609,16 @@ install_utils() { goverlay_ok=$(dpkg -l | grep -q "^ii.*goverlay" && echo "✓" || echo "✗") if [ "$gamemode_ok" = "✓" ] && [ "$mangohud_ok" = "✓" ] && [ "$goverlay_ok" = "✓" ]; then - log_info "Installation complète des utilitaires gaming réussie" + log_info "Installation complète des GOverlay réussie" # Le récapitulatif sera affiché à la fin else - log_info "Installation partielle des utilitaires gaming" + log_info "Installation partielle des GOverlay" message="Résultats de l'installation :\n\nGamemode: $gamemode_ok\nMangoHUD: $mangohud_ok\nGOverlay: $goverlay_ok" if [ "$gamemode_ok" = "✗" ] || [ "$mangohud_ok" = "✗" ] || [ "$goverlay_ok" = "✗" ]; then # Afficher d'abord le message puis proposer les logs zenity 2>/dev/null --info --title="Installation partielle" --text="$message" if zenity 2>/dev/null --question --title="Consultation des journaux" --text="Certains utilitaires ont échoué.\nSouhaitez-vous consulter les journaux d'erreur ?"; then - show_error_logs "Installation partielle des utilitaires gaming" + show_error_logs "Installation partielle des GOverlay" fi else zenity 2>/dev/null --info --title="Installation partielle" --text="$message" @@ -3050,9 +3050,9 @@ uninstall_nvidia_silent() { fi } -# Fonction de désinstallation des utilitaires gaming -uninstall_utils() { - log_info "Début de la désinstallation des utilitaires gaming" +# Fonction de désinstallation des GOverlay +uninstall_GOverlay() { + log_info "Début de la désinstallation des GOverlay" # Vérifier si les utilitaires sont installés gamemode_installed=$(dpkg -l | grep -q "^ii.*gamemode" && echo "oui" || echo "non") @@ -3066,12 +3066,12 @@ uninstall_utils() { fi # Demander confirmation - if ! zenity 2>/dev/null --question --title="Confirmation" --text="Êtes-vous sûr de vouloir désinstaller les utilitaires gaming ?"; then + if ! zenity 2>/dev/null --question --title="Confirmation" --text="Êtes-vous sûr de vouloir désinstaller les GOverlay ?"; then return fi # Demander le mot de passe sudo - password=$(zenity 2>/dev/null --password --title="Authentification - Désinstallation utilitaires" --text="Mot de passe sudo requis pour désinstaller les utilitaires gaming:") + password=$(zenity 2>/dev/null --password --title="Authentification - Désinstallation utilitaires" --text="Mot de passe sudo requis pour désinstaller les GOverlay:") if [ $? -eq 1 ]; then @@ -3109,7 +3109,7 @@ uninstall_utils() { echo "100" ; echo "# Vérification de la désinstallation..." ) | zenity 2>/dev/null --progress \ - --title="Désinstallation des utilitaires gaming" \ + --title="Désinstallation des GOverlay" \ --text="Initialisation..." \ --percentage=0 \ --width=400 \ @@ -3121,17 +3121,17 @@ uninstall_utils() { goverlay_ok=$(dpkg -l | grep -q "^ii.*goverlay" && echo "✗" || echo "✓") if [ "$gamemode_ok" = "✓" ] && [ "$mangohud_ok" = "✓" ] && [ "$goverlay_ok" = "✓" ]; then - log_info "Désinstallation complète des utilitaires gaming réussie" - zenity 2>/dev/null --info --title="Succès" --text="Tous les utilitaires gaming ont été désinstallés avec succès !" + log_info "Désinstallation complète des GOverlay réussie" + zenity 2>/dev/null --info --title="Succès" --text="Tous les GOverlay ont été désinstallés avec succès !" elif [ "$gamemode_ok" = "✗" ] || [ "$mangohud_ok" = "✗" ] || [ "$goverlay_ok" = "✗" ]; then - log_info "Échec de désinstallation de certains utilitaires gaming" - show_error_logs "Échec de désinstallation de certains utilitaires gaming" + log_info "Échec de désinstallation de certains GOverlay" + show_error_logs "Échec de désinstallation de certains GOverlay" fi } -uninstall_utils_silent() { +uninstall_GOverlay_silent() { local password="$1" - log_info "Début de la désinstallation des utilitaires gaming (mode silencieux)" + log_info "Début de la désinstallation des GOverlay (mode silencieux)" # Vérifier si les utilitaires sont installés gamemode_installed=$(dpkg -l | grep -q "^ii.*gamemode" && echo "oui" || echo "non") @@ -3172,10 +3172,10 @@ uninstall_utils_silent() { goverlay_ok=$(dpkg -l | grep -q "^ii.*goverlay" && echo "non" || echo "oui") if [ "$gamemode_ok" = "oui" ] && [ "$mangohud_ok" = "oui" ] && [ "$goverlay_ok" = "oui" ]; then - log_info "Désinstallation complète des utilitaires gaming réussie" + log_info "Désinstallation complète des GOverlay réussie" return 0 else - log_info "Échec de désinstallation de certains utilitaires gaming" + log_info "Échec de désinstallation de certains GOverlay" return 1 fi } @@ -3254,7 +3254,7 @@ if [ $exit_code -eq 1 ]; then "mumble") uninstall_display="$uninstall_display\n• Mumble" ;; "flatseal") uninstall_display="$uninstall_display\n• Flatseal" ;; "nvidia") uninstall_display="$uninstall_display\n• Drivers NVIDIA (ATTENTION: peut affecter l'affichage)" ;; - "utils") uninstall_display="$uninstall_display\n• Utilitaires gaming (GameMode, MangoHUD, GOverlay)" ;; + "GOverlay") uninstall_display="$uninstall_display\n• GOverlay (GameMode, MangoHUD, GOverlay)" ;; esac done @@ -3396,11 +3396,11 @@ if [ $exit_code -eq 1 ]; then failed_components="$failed_components\n• Drivers NVIDIA" fi ;; - "utils") - if uninstall_with_progress "$component" "$password" "Utilitaires gaming" "uninstall_utils_silent"; then + "GOverlay") + if uninstall_with_progress "$component" "$password" "GOverlay" "uninstall_GOverlay_silent"; then ((success_count++)) else - failed_components="$failed_components\n• Utilitaires gaming" + failed_components="$failed_components\n• GOverlay" fi ;; esac @@ -3463,7 +3463,7 @@ else "mumble") install_display="$install_display\n• Mumble" ;; "flatseal") install_display="$install_display\n• Flatseal" ;; "nvidia") install_display="$install_display\n• NVIDIA + CUDA" ;; - "utils") install_display="$install_display\n• Goverlay (FPS, CPU, GPU, température)" ;; + "GOverlay") install_display="$install_display\n• Goverlay (FPS, CPU, GPU, température)" ;; esac done @@ -3530,8 +3530,8 @@ else "nvidia") install_nvidia ;; - "utils") - install_utils + "GOverlay") + install_GOverlay ;; esac @@ -3553,7 +3553,7 @@ else "mumble") next_batch_app "Mumble" ;; "flatseal") next_batch_app "Flatseal" ;; "nvidia") next_batch_app "NVIDIA + CUDA" ;; - "utils") next_batch_app "Goverlay (performances)" ;; + "GOverlay") next_batch_app "Goverlay (performances)" ;; esac fi done diff --git a/udib.py b/udib.py index 2e8115e..4990de9 100755 --- a/udib.py +++ b/udib.py @@ -7,7 +7,7 @@ from tempfile import TemporaryDirectory from cli.clibella import Printer from cli.parser import get_argument_parser -from core.utils import assert_system_dependencies_installed, download_and_verify_debian_iso, download_and_verify_debian_testing_iso +from core.utils import assert_system_dependencies_installed, download_debian_iso_simple, download_debian_testing_iso_simple from iso.injection import inject_files_into_iso from net.download import download_file from net.scrape import get_debian_preseed_file_urls, get_debian_iso_urls, get_debian_testing_iso_urls @@ -30,8 +30,8 @@ def main(): path_to_output_file = path_to_output_file.expanduser() path_to_output_file = path_to_output_file.resolve() - if path_to_output_file.exists(): - p.error(f"Output file already exists: '{path_to_output_file}'.") + if path_to_output_file.exists() and not args.force: + p.error(f"Output file already exists: '{path_to_output_file}'. Use --force to overwrite.") exit(1) else: path_to_output_file = None @@ -105,7 +105,7 @@ def main(): else: path_to_output_file = Path.cwd() / output_file_name - download_and_verify_debian_iso(path_to_output_file, printer=p) + download_debian_iso_simple(path_to_output_file, printer=p, force=args.force) p.success(f"Debian ISO saved to '{path_to_output_file}'.") exit(0) @@ -120,10 +120,11 @@ def main(): else: path_to_output_file = Path.cwd() / output_file_name - download_and_verify_debian_testing_iso(path_to_output_file, printer=p) + download_debian_testing_iso_simple(path_to_output_file, printer=p, force=args.force) p.success(f"Debian testing ISO saved to '{path_to_output_file}'.") exit(0) + elif args.subparser_name == "inject": # verify image file path if set by user or download fresh iso if unset