Revert "Further improvements to dnf robustness and repo discovery for offline installs"

This reverts commit 5df00a5814.
This commit is contained in:
2026-02-05 19:43:12 +01:00
parent 5df00a5814
commit 74fedf9001

View File

@@ -79,8 +79,7 @@ def mount_pseudo_fs(mount_root):
Context manager to bind mount /dev, /proc, /sys, /run, and efivarfs into mount_root. Context manager to bind mount /dev, /proc, /sys, /run, and efivarfs into mount_root.
""" """
logger.info(f"Mounting pseudo-filesystems to {mount_root}...") logger.info(f"Mounting pseudo-filesystems to {mount_root}...")
# dev/pts and dev/shm are often needed by scriptlets mounts = ["dev", "proc", "sys", "run"]
mounts = ["dev", "proc", "sys", "run", "dev/pts", "dev/shm"]
mounted_paths = [] mounted_paths = []
try: try:
@@ -90,14 +89,6 @@ def mount_pseudo_fs(mount_root):
run_command(["mount", "--bind", f"/{fs}", target]) run_command(["mount", "--bind", f"/{fs}", target])
mounted_paths.append(target) mounted_paths.append(target)
# Bind mount RPM GPG keys from host
gpg_keys_host = "/etc/pki/rpm-gpg"
if os.path.exists(gpg_keys_host):
gpg_keys_target = os.path.join(mount_root, "etc/pki/rpm-gpg")
os.makedirs(gpg_keys_target, exist_ok=True)
run_command(["mount", "--bind", gpg_keys_host, gpg_keys_target])
mounted_paths.append(gpg_keys_target)
# Mount efivarfs if it exists on the host # Mount efivarfs if it exists on the host
efivars_path = "/sys/firmware/efi/efivars" efivars_path = "/sys/firmware/efi/efivars"
if os.path.exists(efivars_path): if os.path.exists(efivars_path):
@@ -144,19 +135,14 @@ def find_iso_repo():
"/run/initramfs/isoscan", "/run/initramfs/isoscan",
] ]
def check_path(p): # 1. Check known paths for repodata or media.repo
if os.path.exists(os.path.join(p, "repodata")) or os.path.exists(os.path.join(p, "media.repo")):
return p
for sub in ["os", "Packages", "BaseOS", "AppStream"]:
sub_p = os.path.join(p, sub)
if os.path.exists(os.path.join(sub_p, "repodata")) or os.path.exists(os.path.join(sub_p, "media.repo")):
return sub_p
return None
# 1. Check known paths
for path in possible_paths: for path in possible_paths:
res = check_path(path) if os.path.exists(os.path.join(path, "repodata")) or os.path.exists(os.path.join(path, "media.repo")):
if res: return res return path
for sub in ["os", "Packages", "BaseOS", "AppStream"]:
sub_path = os.path.join(path, sub)
if os.path.exists(os.path.join(sub_path, "repodata")) or os.path.exists(os.path.join(sub_path, "media.repo")):
return sub_path
# 2. Check all mounted filesystems # 2. Check all mounted filesystems
try: try:
@@ -165,35 +151,48 @@ def find_iso_repo():
for mount in res.stdout.splitlines(): for mount in res.stdout.splitlines():
if mount.startswith("/proc") or mount.startswith("/sys") or mount.startswith("/dev"): if mount.startswith("/proc") or mount.startswith("/sys") or mount.startswith("/dev"):
continue continue
res = check_path(mount) if os.path.exists(os.path.join(mount, "repodata")) or os.path.exists(os.path.join(mount, "media.repo")):
if res: return res return mount
for sub in ["os", "Packages", "BaseOS", "AppStream"]:
if os.path.exists(os.path.join(mount, sub, "repodata")) or os.path.exists(os.path.join(mount, sub, "media.repo")):
return os.path.join(mount, sub)
except Exception as e: except Exception as e:
logger.debug(f"Error searching mount points: {e}") logger.debug(f"Error searching mount points: {e}")
# 3. Try to mount /dev/sr0 or /dev/cdrom # 3. Try to mount /dev/sr0 or /dev/cdrom if not already mounted
for dev in ["/dev/sr0", "/dev/cdrom"]: for dev in ["/dev/sr0", "/dev/cdrom"]:
try: try:
if os.path.exists(dev): if os.path.exists(dev):
res = subprocess.run(["findmnt", "-n", dev], capture_output=True) res = subprocess.run(["findmnt", "-n", dev], capture_output=True)
if res.returncode != 0: if res.returncode != 0:
logger.info(f"Found {dev} but not mounted. Attempting to mount to /mnt...")
try: try:
os.makedirs("/mnt/iso", exist_ok=True) subprocess.run(["mount", "-o", "ro", dev, "/mnt"], check=True)
subprocess.run(["mount", "-o", "ro", dev, "/mnt/iso"], check=True) if os.path.exists("/mnt/repodata") or os.path.exists("/mnt/media.repo"):
res = check_path("/mnt/iso") return "/mnt"
if res: return res for sub in ["os", "Packages", "BaseOS", "AppStream"]:
except Exception: pass if os.path.exists(os.path.join("/mnt", sub, "repodata")) or os.path.exists(os.path.join("/mnt", sub, "media.repo")):
except Exception: pass return os.path.join("/mnt", sub)
except Exception as e:
logger.debug(f"Failed to mount {dev}: {e}")
except Exception:
pass
# 4. Check /run/media deeper # 4. Check /run/media
if os.path.exists("/run/media"): if os.path.exists("/run/media"):
try: try:
for root, dirs, files in os.walk("/run/media"): for user in os.listdir("/run/media"):
if "repodata" in dirs or "media.repo" in files: user_path = os.path.join("/run/media", user)
return root if os.path.isdir(user_path):
# Limit depth for performance for label in os.listdir(user_path):
if root.count(os.sep) > 5: label_path = os.path.join(user_path, label)
del dirs[:] if os.path.exists(os.path.join(label_path, "repodata")) or os.path.exists(os.path.join(label_path, "media.repo")):
except Exception: pass return label_path
for sub in ["os", "Packages", "BaseOS", "AppStream"]:
if os.path.exists(os.path.join(label_path, sub, "repodata")) or os.path.exists(os.path.join(label_path, sub, "media.repo")):
return os.path.join(label_path, sub)
except Exception:
pass
# 5. Last resort: any directory with .rpm files # 5. Last resort: any directory with .rpm files
for path in possible_paths: for path in possible_paths:
@@ -244,26 +243,14 @@ def install_minimal_os(mount_root, releasever=None):
# Offline installation logic # Offline installation logic
iso_repo = find_iso_repo() iso_repo = find_iso_repo()
# Create a temporary dnf.conf to be strictly local if repo found dnf_args = []
dnf_conf_path = "/tmp/iridium_dnf.conf"
with open(dnf_conf_path, "w") as f:
f.write("[main]\ngpgcheck=0\ninstallroot_managed_by_dnf=True\n")
dnf_args = [
f"--config={dnf_conf_path}",
"--setopt=cachedir=/tmp/dnf-cache",
"--setopt=install_weak_deps=False",
"--nodocs",
]
if iso_repo: if iso_repo:
logger.info(f"Found ISO repository at {iso_repo}. Using strictly offline mode.") logger.info(f"Found ISO repository at {iso_repo}. Using strictly offline mode.")
dnf_args += [ dnf_args = [
"--disablerepo=*", "--disablerepo=*",
f"--repofrompath=iridium-iso,{iso_repo}", f"--repofrompath=iridium-iso,{iso_repo}",
"--enablerepo=iridium-iso", "--enablerepo=iridium-iso",
"--nogpgcheck", "--nogpgcheck",
"--offline", # Supported by dnf5
"--setopt=iridium-iso.gpgcheck=0", "--setopt=iridium-iso.gpgcheck=0",
"--setopt=metadata_expire=-1", "--setopt=metadata_expire=-1",
] ]
@@ -272,9 +259,10 @@ def install_minimal_os(mount_root, releasever=None):
if os.path.exists("/run/initramfs/live/LiveOS/squashfs.img"): if os.path.exists("/run/initramfs/live/LiveOS/squashfs.img"):
logger.warning("Detected Fedora Live environment, but no RPM repository was found on the media.") logger.warning("Detected Fedora Live environment, but no RPM repository was found on the media.")
logger.warning("Workstation Live ISOs usually do not contain a DNF repository for offline installation.") logger.warning("Workstation Live ISOs usually do not contain a DNF repository for offline installation.")
logger.warning("Consider using an 'Everything' or 'Server' ISO for offline package-based install.")
logger.warning("ISO repository not found. DNF will attempt to use network.") logger.warning("ISO repository not found. DNF will attempt to use network.")
dnf_args.append("--use-host-config") dnf_args = []
cmd = [ cmd = [
"dnf", "dnf",
@@ -282,17 +270,13 @@ def install_minimal_os(mount_root, releasever=None):
"-y", "-y",
f"--installroot={mount_root}", f"--installroot={mount_root}",
f"--releasever={releasever}", f"--releasever={releasever}",
"--use-host-config",
"--setopt=install_weak_deps=False",
"--nodocs",
] ]
cmd += dnf_args + packages cmd += dnf_args + packages
# Copy resolv.conf if it exists (some scriptlets might need it for UID/GID lookups)
try:
os.makedirs(os.path.join(mount_root, "etc"), exist_ok=True)
if os.path.exists("/etc/resolv.conf"):
subprocess.run(["cp", "/etc/resolv.conf", os.path.join(mount_root, "etc/resolv.conf")])
except Exception: pass
with mount_pseudo_fs(mount_root): with mount_pseudo_fs(mount_root):
run_command(cmd) run_command(cmd)