diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py index 4654cd0..1bcce9d 100644 --- a/archinstall/lib/disk/blockdevice.py +++ b/archinstall/lib/disk/blockdevice.py @@ -52,12 +52,26 @@ class BlockDevice: self._block_info = self._fetch_information(self.info) self._partitions: Dict[str, 'Partition'] = {} + self.tips = "" + self._make_tips() + self._load_partitions() # TODO: Currently disk encryption is a BIT misleading. # It's actually partition-encryption, but for future-proofing this # I'm placing the encryption password on a BlockDevice level. + def _make_tips(self): + tip_list = [] + # 1 Ventoy check + output = SysCommand(f'lsblk -o+LABEL {self._path}').decode('UTF-8') + if output: + for line in output.splitlines(): + if "Ventoy" in line: + tip_list.append("Ventoy Disk") + + self.tips = ";".join(tip_list) + def __repr__(self, *args :str, **kwargs :str) -> str: return self._str_repr @@ -67,7 +81,10 @@ class BlockDevice: @property def _str_repr(self) -> str: - return f"BlockDevice({self._device_or_backfile}, size={self.size}GB, free_space={self._safe_free_space()}, bus_type={self.bus_type})" + addtion = "" + if self.tips: + addtion = f", tips='{self.tips}'" + return f"BlockDevice({self._device_or_backfile}, size={self.size}GB, free_space={self._safe_free_space()}, bus_type={self.bus_type}{addtion})" def as_json(self) -> Dict[str, Any]: return { diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index 8e7b23a..161dd0f 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -152,6 +152,11 @@ def blkid(cmd :str) -> Dict[str, Any]: if "PTUUID" not in result[devname]: if "dos" == result[devname]["PTTYPE"]: result[devname]["PTUUID"] = devname + if "filesystem" == result[devname].get('USAGE', None): + if result[devname].get('UUID', None) is not None: + result[devname]["PTUUID"] = result[devname]["UUID"] + # if result[devname].get('TYPE', None) in ("squashfs", ): + # pass return result def get_loop_info(path :str) -> Dict[str, Any]: diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 042c2b4..b6c133e 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -174,7 +174,7 @@ class Installer: # self.sync_log_to_install_medium() # return False - self.log('Installation completed without any errors. You may now reboot.', fg='green', level=logging.INFO) + self.log('Installation completed with some errors. You may try again.', fg='yellow', level=logging.INFO) return True @property diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index cb8a96a..eabd66a 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -27,7 +27,7 @@ from ..user_interaction import select_additional_repositories from ..user_interaction import select_disk_layout from ..user_interaction import select_encrypted_partitions from ..user_interaction import select_harddrives -from ..user_interaction import select_kernel +from ..user_interaction import select_kernel, select_base_image from ..user_interaction import select_language from ..user_interaction import select_locale_enc from ..user_interaction import select_locale_lang @@ -158,6 +158,11 @@ class GlobalMenu(GeneralMenu): _('Kernels'), lambda preset: select_kernel(preset), default=['linux']) + self._menu_options['base_image'] = \ + Selector( + _('Base Image'), + func=lambda preset: select_base_image(preset), + default='runtime') self._menu_options['packages'] = \ Selector( _('Additional packages'), diff --git a/archinstall/lib/user_interaction/__init__.py b/archinstall/lib/user_interaction/__init__.py index a1ca265..031f2a2 100644 --- a/archinstall/lib/user_interaction/__init__.py +++ b/archinstall/lib/user_interaction/__init__.py @@ -1,3 +1,6 @@ +''' +Author: l +''' from .save_conf import save_config from .manage_users_conf import ask_for_additional_users from .backwards_compatible_conf import generic_select, generic_multi_select @@ -7,6 +10,6 @@ from .network_conf import ask_to_configure_network from .partitioning_conf import select_partition, select_encrypted_partitions from .general_conf import (ask_ntp, ask_for_a_timezone, ask_for_audio_selection, select_language, select_mirror_regions, select_profile, select_archinstall_language, ask_additional_packages_to_install, - select_additional_repositories, ask_hostname, add_number_of_parrallel_downloads) + select_additional_repositories, ask_hostname, add_number_of_parrallel_downloads, select_base_image) from .disk_conf import ask_for_main_filesystem_format, select_individual_blockdevice_usage, select_disk_layout, select_disk from .utils import get_password, do_countdown diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index b79de2b..f0cedbe 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -225,6 +225,39 @@ def select_profile(preset) -> Optional[Profile]: storage['arguments']['gfx_driver_packages'] = None return None +def select_base_image(preset: str) -> str: + """ + Asks the user to select a image for system. + + :return: The string as a selected image + :rtype: string + """ + allnames = ["runtime", "develop"] + + default_val = "runtime" + + warning = str(_('Are you sure you want to reset this setting?')) + + choice = Menu( + _('Choose which base image to use or leave blank for default "{}"').format(default_val), + allnames, + sort=False, + multi=False, + preset_values=preset, + raise_error_on_interrupt=True, + raise_error_warning_msg=warning + ).run() + + # match choice.type_: + # case MenuSelectionType.Esc: return preset + # case MenuSelectionType.Ctrl_c: return [] + # case MenuSelectionType.Selection: return choice.value + if choice.type_ == MenuSelectionType.Esc: + return preset + elif choice.type_ == MenuSelectionType.Ctrl_c: + return [] + elif choice.type_ == MenuSelectionType.Selection: + return choice.value def ask_additional_packages_to_install(pre_set_packages: List[str] = []) -> List[str]: # Additional packages (with some light weight error handling for invalid package names) diff --git a/examples/guided.py b/examples/guided.py index 00e4ac4..f9030d9 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -150,7 +150,9 @@ def ask_user_questions(): # Ask or Call the helper function that asks the user to optionally configure a network. # global_menu.enable('nic') - global_menu.enable('timezone') + # global_menu.enable('timezone') + + global_menu.enable("base_image") # global_menu.enable('ntp') @@ -193,40 +195,79 @@ def install_grub(installation): target = installation.target installation.log("Installing grub...", level=logging.INFO) - archinstall.SysCommand('mkdir -p {}/run'.format(target)) - archinstall.SysCommand('mkdir -p {}/proc'.format(target)) - archinstall.SysCommand('mkdir -p {}/sys'.format(target)) - archinstall.SysCommand('mkdir -p {}/dev'.format(target)) - archinstall.SysCommand('mount -t proc proc {}/proc'.format(target)) - archinstall.SysCommand('mount -t sysfs sys {}/sys'.format(target)) - archinstall.SysCommand('mount -o bind /dev {}/dev'.format(target)) - archinstall.SysCommand('mount -t efivarfs none {}/sys/firmware/efi/efivars/'.format(target)) - archinstall.SysCommand('grub-installer {}'.format(target)) + if archinstall.has_uefi(): + archinstall.SysCommand('mount -t efivarfs none {}/sys/firmware/efi/efivars/'.format(target)) + archinstall.SysCommand('mount -t efivarfs none /sys/firmware/efi/efivars/') + + archinstall.SysCommand('chroot {} bash -c "grub-install"'.format(target)) + archinstall.SysCommand('chroot {} bash -c "grub-mkconfig >> /boot/grub/grub.cfg"'.format(target)) + + # if archinstall.has_uefi(): + # installation.log("Installing finish", level=logging.INFO) + installation.log("Installing finish", level=logging.INFO) def extract_rootfs(installation): target = installation.target + + image_name = archinstall.arguments.get('base_image') + syspack = "" filenames = os.listdir("/mnt/images") for fname in filenames: - if fname.startswith("rootfs"): + if fname.startswith("rootfs") and image_name in fname: syspack = fname break if syspack: installation.log("Installing system: {}".format(syspack), level=logging.INFO) archinstall.SysCommand('sh -c "xz -d -c {} | tar -x -C {}"'.format("/mnt/images/" + syspack, target)) installation.log("Installing system finish.", level=logging.INFO) + else: + installation.log("Can't find base image: {}".format(image_name), level=logging.ERROR) + raise ValueError("[Installer] Can't find base image: {}".format(image_name)) + +def mount_target_paths(installation): + target = installation.target + archinstall.SysCommand('mkdir -p {}/run'.format(target)) + archinstall.SysCommand('mkdir -p {}/proc'.format(target)) + archinstall.SysCommand('mkdir -p {}/sys'.format(target)) + archinstall.SysCommand('mkdir -p {}/dev'.format(target)) + archinstall.SysCommand('mount -t tmpfs none {}/run'.format(target)) + archinstall.SysCommand('mount -t proc proc {}/proc'.format(target)) + archinstall.SysCommand('mount -t sysfs sys {}/sys'.format(target)) + archinstall.SysCommand('mount -o bind /dev {}/dev'.format(target)) def install_kernel(installation): + target = installation.target - installation.log("Installing Kenel: {}".format("..."), level=logging.INFO) - archinstall.SysCommand('cp -ar /mnt/pool/other/kernel {}/tmp'.format(target)) - archinstall.SysCommand('chroot {} bash -c "dpkg -i /tmp/kernel/linux-*.deb"'.format(target)) - archinstall.SysCommand('chroot {} bash -c "dpkg -i /tmp/kernel/mwv207-*.deb"'.format(target)) - archinstall.SysCommand('chroot {} bash -c "depmod 5.15.0-5-arm64"'.format(target)) - archinstall.SysCommand('rm -fr {}/tmp/kernel'.format(target)) + try: + installation.log("Installing Kenel: {}".format("..."), level=logging.INFO) + archinstall.SysCommand('mkdir {}/tmp'.format(target)) + archinstall.SysCommand('cp -ar /mnt/pool/other/kernel {}/tmp'.format(target)) + archinstall.SysCommand('chroot {} bash -c "dpkg -i /tmp/kernel/linux-*.deb"'.format(target)) + cmdline = "" + with open("/proc/cmdline", "r") as cmdfs: + cmdline = cmdfs.read() + if False and "nomwv" not in cmdline: + archinstall.SysCommand('chroot {} bash -c "dpkg -i /tmp/kernel/mwv207-*.deb"'.format(target)) + archinstall.SysCommand("chroot {} bash -c 'depmod `ls /lib/modules | tail -n 1`'".format(target)) + archinstall.SysCommand('rm -fr {}/tmp/kernel'.format(target)) + except SysCallError as error: + installation.log(f"install_kernel error: {error!r}", level=logging.ERROR, fg="red") + raise error installation.log("Installing Kenel finish.", level=logging.INFO) +def do_config(installation): + target = installation.target + + ############ + # config apt sources + with open(f"{target}/etc/apt/sources.list", "w") as fw: + fw.write("""deb http://mirrors.huaweicloud.com/debian/ bullseye main +deb-src http://mirrors.huaweicloud.com/debian/ bullseye main +""") + + def perform_installation2(mountpoint): with archinstall.Installer(mountpoint, kernels=archinstall.arguments.get('kernels', ['linux'])) as installation: @@ -250,18 +291,22 @@ def perform_installation2(mountpoint): # 1 extract root files extract_rootfs(installation) - # 2 reinstall kernel + # 2 update fstab + installation.genfstab() + + # 3 reinstall kernel + mount_target_paths(installation) install_kernel(installation) - # 3 grub-install + # 4 grub-install install_grub(installation) - # 4 add user/passwd + # 5 add user/passwd if (root_pw := archinstall.arguments.get('!root-password', None)) and len(root_pw): installation.user_set_pw('root', root_pw) - - # 5 update fstab - installation.genfstab() + + # 6 do config + do_config(installation) input(str(_('Install finished, user:[acosail] password is [ ].\nPress Enter to reboot.'))) reboot()