From 1abacde9c76752aa94044eb4b38d5c4854f21e1a Mon Sep 17 00:00:00 2001 From: Radek Vykydal Date: Wed, 23 Oct 2024 11:02:32 +0200 Subject: [PATCH] network: add warning for kickstart network configuration when running from nfs Resolves: RHEL-35250 --- pyanaconda/core/util.py | 12 ++++- pyanaconda/network.py | 6 +++ .../pyanaconda_tests/core/test_util.py | 47 ++++++++++++++++++- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/pyanaconda/core/util.py b/pyanaconda/core/util.py index 6d745b6ba39..fef3cf0a759 100644 --- a/pyanaconda/core/util.py +++ b/pyanaconda/core/util.py @@ -39,7 +39,7 @@ from pyanaconda.core.configuration.anaconda import conf from pyanaconda.core.path import make_directories, open_with_perm, join_paths from pyanaconda.core.constants import DRACUT_SHUTDOWN_EJECT, \ - IPMI_ABORTED, PACKAGES_LIST_FILE + IPMI_ABORTED, PACKAGES_LIST_FILE, DRACUT_REPO_DIR from pyanaconda.core.live_user import get_live_user from pyanaconda.errors import RemovedModuleError @@ -911,3 +911,13 @@ def get_image_packages_info(max_string_chars=0): break info_lines.append(' '.join(line.strip() for line in lines)) return info_lines + + +def is_stage2_on_nfs(): + """Is the installation running from image mounted via NFS?""" + for line in open("/proc/mounts").readlines(): + values = line.split() + if len(values) > 2: + if values[1] == DRACUT_REPO_DIR and values[2] in ("nfs", "nfs4"): + return True + return False diff --git a/pyanaconda/network.py b/pyanaconda/network.py index a56db151f89..41487b931d4 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -258,6 +258,12 @@ def initialize_network(): log.debug("Devices found: %s", [dev.device_name for dev in get_supported_devices()]) + if util.is_stage2_on_nfs() and network_proxy.Kickstarted: + msg = "Using kickstart network configuration with installer image (stage2) provided " \ + "via nfs server can freeze the installation." + log.warning(msg) + print("WARNING:", msg) + run_network_initialization_task(network_proxy.ApplyKickstartWithTask()) run_network_initialization_task(network_proxy.DumpMissingConfigFilesWithTask()) diff --git a/tests/unit_tests/pyanaconda_tests/core/test_util.py b/tests/unit_tests/pyanaconda_tests/core/test_util.py index 84ee4aa82f6..a37c66ecefe 100644 --- a/tests/unit_tests/pyanaconda_tests/core/test_util.py +++ b/tests/unit_tests/pyanaconda_tests/core/test_util.py @@ -26,12 +26,14 @@ from threading import Lock from unittest.mock import Mock, patch from timer import timer +from io import StringIO +from textwrap import dedent from pyanaconda.core.path import make_directories from pyanaconda.errors import ExitError from pyanaconda.core.process_watchers import WatchProcesses from pyanaconda.core import util -from pyanaconda.core.util import synchronized, LazyObject +from pyanaconda.core.util import synchronized, LazyObject, is_stage2_on_nfs from pyanaconda.core.configuration.anaconda import conf from pyanaconda.core.live_user import User @@ -815,6 +817,49 @@ def test_dracut_eject(self): file_contents = "\n".join(f.readlines()) assert "eject " + devname in file_contents + @patch("pyanaconda.core.util.open") + def test_is_stage2_on_nfs(self, mock_open): + """Test check for installation running on nfs.""" + nfs_source_mounts = """ + LiveOS_rootfs / overlay rw,seclabel,relatime,lowerdir=/run/rootfsbase,upperdir=/run/overlayfs,workdir=/run/ovlwork,uuid=on 0 0 + proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 + tmpfs /run tmpfs rw,seclabel,nosuid,nodev,size=401324k,nr_inodes=819200,mode=755,inode64 0 0 + 10.43.136.2:/mnt/data/trees/rawhide /run/install/repo nfs ro,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=10.43.136.2,mountvers=3,mountport=20 + 048,mountproto=udp,local_lock=all,addr=10.43.136.2 0 0 + mqueue /dev/mqueue mqueue rw,seclabel,nosuid,nodev,noexec,relatime 0 0 + tmpfs /run/credentials/systemd-vconsole-setup.service tmpfs ro,seclabel,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap 0 0 + 10.43.136.2:/mnt/data/trees/rawhide /run/install/sources/mount-0000-nfs-device nfs rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=10.43.136.2 + ,mountvers=3,mountport=20048,mountproto=udp,local_lock=all,addr=10.43.136.2 0 0 + """ + nfs_stage2_mounts = """ + LiveOS_rootfs / overlay rw,seclabel,relatime,lowerdir=/run/rootfsbase,upperdir=/run/overlayfs,workdir=/run/ovlwork,uuid=on 0 0 + proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 + tmpfs /run tmpfs rw,seclabel,nosuid,nodev,size=401324k,nr_inodes=819200,mode=755,inode64 0 0 + 10.43.136.2:/mnt/data/users/rv/s2/rvm /run/install/repo nfs ro,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=10.43.136.2,mountvers=3,mountport= + mqueue /dev/mqueue mqueue rw,seclabel,nosuid,nodev,noexec,relatime 0 0 + tmpfs /run/credentials/systemd-vconsole-setup.service tmpfs ro,seclabel,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap 0 0 + """ + no_nfs_mounts = """ + LiveOS_rootfs / overlay rw,seclabel,relatime,lowerdir=/run/rootfsbase,upperdir=/run/overlayfs,workdir=/run/ovlwork,uuid=on 0 0 + rpc_pipefs /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0 + mqueue /dev/mqueue mqueue rw,seclabel,nosuid,nodev,noexec,relatime 0 0 + tmpfs /run/credentials/systemd-vconsole-setup.service tmpfs ro,seclabel,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,inode64,noswap 0 0 + """ + nfs4_mounts = """ + 10.43.136.2:/mnt/data/users/rv/s2/rvm /run/install/repo nfs4 ro,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=10.43.136.2,mountvers=3,mountport= + """ + mock_open.return_value = StringIO(dedent(nfs_stage2_mounts)) + assert is_stage2_on_nfs() is True + + mock_open.return_value = StringIO(dedent(nfs_source_mounts)) + assert is_stage2_on_nfs() is True + + mock_open.return_value = StringIO(dedent(nfs4_mounts)) + assert is_stage2_on_nfs() is True + + mock_open.return_value = StringIO(dedent(no_nfs_mounts)) + assert is_stage2_on_nfs() is False + class LazyObjectTestCase(unittest.TestCase):