From 17548898bde9e5c641e4394f1f663f27eba33529 Mon Sep 17 00:00:00 2001 From: N0VA Date: Tue, 10 Feb 2026 14:09:16 +0100 Subject: [PATCH] Switch to rsync-based offline installation from live system --- iridium_installer/backend/os_install.py | 123 ++++++++---------------- 1 file changed, 41 insertions(+), 82 deletions(-) diff --git a/iridium_installer/backend/os_install.py b/iridium_installer/backend/os_install.py index 12140c5..16a941e 100644 --- a/iridium_installer/backend/os_install.py +++ b/iridium_installer/backend/os_install.py @@ -126,96 +126,46 @@ def is_uefi(): def install_minimal_os(mount_root, releasever="43"): """ - Installs minimal Fedora packages to mount_root. + Installs the OS by rsyncing from the live environment (fully offline). """ - logger.info(f"Installing minimal Fedora {releasever} to {mount_root}...") - log_os_install("INSTALL", "start", f"Target: {mount_root}, Release: {releasever}") + logger.info(f"Installing Iridium OS to {mount_root} via rsync...") + log_os_install("INSTALL", "start", f"Target: {mount_root}") - uefi = is_uefi() - - packages = [ - "basesystem", - "bash", - "coreutils", - "kernel", - "systemd", - "dnf", - "shadow-utils", - "util-linux", - "passwd", - "rootfiles", - "vim-minimal", + # Exclude list for rsync to avoid copying pseudo-filesystems and temporary data + excludes = [ + "/dev/*", + "/proc/*", + "/sys/*", + "/tmp/*", + "/run/*", + "/mnt/*", + "/media/*", + "/lost+found", + "/home/*/.gvfs", + "/home/*/.cache", + "/home/*/.local/share/Trash", + "/var/lib/dnf/*", + "/var/cache/dnf/*", + "/etc/fstab", + "/etc/hostname", + # Avoid copying the installer data itself if it's in home + "domek_na_skale", ] - if uefi: - packages += ["systemd-boot-unsigned", "efibootmgr"] - else: - packages += ["grub2-pc", "grub2-tools", "grubby"] - - # Offline installation logic - possible_repos = [ - "/run/install/repo", - "/run/install/source", - "/mnt/install/repo", - "/run/initramfs/live", - "/run/initramfs/isoscan", - ] + exclude_args = [f"--exclude={ex}" for ex in excludes] - iso_repo = None - for path in possible_repos: - if os.path.exists(os.path.join(path, "repodata")): - iso_repo = path - break - elif os.path.exists(os.path.join(path, "Packages")): - iso_repo = path - break - - # Try searching in /run/media if not found - if not iso_repo and os.path.exists("/run/media"): - try: - for user in os.listdir("/run/media"): - user_path = os.path.join("/run/media", user) - if os.path.isdir(user_path): - for label in os.listdir(user_path): - label_path = os.path.join(user_path, label) - if os.path.exists(os.path.join(label_path, "repodata")): - iso_repo = label_path - break - if iso_repo: break - except Exception: pass + # We use -a (archive), -H (hard links), -A (acls), -X (xattrs), -v (verbose), -x (one file system) + # --info=progress2 gives a nice summary for logging + cmd = ["rsync", "-aHAXvx", "--info=progress2"] + exclude_args + ["/", mount_root] - dnf_args = [] - if iso_repo: - logger.info(f"Found ISO repository at {iso_repo}. Using strictly offline mode.") - dnf_args = [ - "--disablerepo=*", - f"--repofrompath=iridium-iso,{iso_repo}", - "--enablerepo=iridium-iso", - "--cacheonly", - ] - else: - logger.warning("ISO repository not found. DNF might try to use network.") - dnf_args = [] + logger.info("Starting rsync operation...") + run_command(cmd) - cmd = [ - "dnf", - "install", - "-y", - f"--installroot={mount_root}", - f"--releasever={releasever}", - "--setopt=install_weak_deps=False", - "--nodocs", - ] - - if not iso_repo: - cmd.append("--use-host-config") - - cmd += dnf_args + packages + # Ensure essential directories exist + for d in ["dev", "proc", "sys", "run", "mnt", "tmp"]: + os.makedirs(os.path.join(mount_root, d), exist_ok=True) - with mount_pseudo_fs(mount_root): - run_command(cmd) - - logger.info("Base system installation complete.") + logger.info("Base system rsync complete.") log_os_install("INSTALL", "complete", f"Installed to {mount_root}") @@ -263,6 +213,15 @@ def configure_system(mount_root, partition_info, user_info=None, disk_device=Non # 2. Configure User if user_info: logger.info(f"Creating user {user_info['username']}...") + + # Since we rsync from live, we might have a 'liveuser' or similar. + # We should probably clear /home and /etc/passwd entries that are non-system + # but for now, let's just make sure we can create the new one. + try: + # Remove liveuser if it exists (common in Fedora live) + run_command(["chroot", mount_root, "userdel", "-r", "liveuser"], check=False) + except: pass + run_command(["chroot", mount_root, "useradd", "-m", "-G", "wheel", user_info["username"]]) # Set hostname