Skip to content

Commit

Permalink
mount parse: Fix matching non-existent directories (#4222)
Browse files Browse the repository at this point in the history
This puts `util.mount_parse()` now on-par with
`util.mount_parse_info()`.
Fix two now failing tests to clarify the new behaviour.

Fixes GH-4193

Sponsored by: The FreeBSD Foundation
  • Loading branch information
igalic committed Jul 5, 2023
1 parent 8836c78 commit e371d63
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 15 deletions.
26 changes: 17 additions & 9 deletions cloudinit/util.py
Expand Up @@ -2677,6 +2677,8 @@ def get_device_info_from_zpool(zpool):


def parse_mount(path, get_mnt_opts=False):
"""Return the mount information for PATH given the lines ``mount(1)``
This function is compatible with ``util.parse_mount_info()``"""
(mountoutput, _err) = subp.subp(["mount"])

# there are 2 types of mount outputs we have to parse therefore
Expand Down Expand Up @@ -2738,21 +2740,27 @@ def parse_mount(path, get_mnt_opts=False):
# continue finding the real device like '/dev/da0'.
# this is only valid for non zfs file systems as a zpool
# can have gpt labels as disk.
# It also doesn't really make sense for NFS.
devm = re.search("^(/dev/.+)[sp]([0-9])$", devpth)
if not devm and is_FreeBSD() and fs_type not in ["zfs", "nfs"]:
devpth = get_freebsd_devpth(path)
# don't duplicate the effort of finding the mountpoint in
# ``get_freebsd_devpth()`` by passing it the ``path``
# instead only resolve the ``devpth``
devpth = get_freebsd_devpth(devpth)
match_devpth = devpth

if match_mount_point == path:
break

if mount_point and path in mount_point:
if get_mnt_opts:
if devpth and fs_type and match_mount_point and mount_options:
return (devpth, fs_type, match_mount_point, mount_options)
else:
if devpth and fs_type and match_mount_point:
return (devpth, fs_type, match_mount_point)
return None
if not match_mount_point or match_mount_point not in path:
# return early here, so we can actually read what's happening below
return None
if get_mnt_opts:
if match_devpth and fs_type and match_mount_point and mount_options:
return (match_devpth, fs_type, match_mount_point, mount_options)
else:
if match_devpth and fs_type and match_mount_point:
return (match_devpth, fs_type, match_mount_point)


def get_mount_info(path, log=LOG, get_mnt_opts=False):
Expand Down
12 changes: 6 additions & 6 deletions tests/unittests/test_util.py
Expand Up @@ -2201,9 +2201,9 @@ def test_parse_mount_with_ext(self, mount_out):
# this one exists in mount_parse_ext.txt
ret = util.parse_mount("/sys/kernel/debug")
self.assertEqual(("none", "debugfs", "/sys/kernel/debug"), ret)
# this one does not even exist in mount_parse_ext.txt
ret = util.parse_mount("/not/existing/mount")
self.assertIsNone(ret)
# this one does not exist in mount_parse_ext.txt
ret = util.parse_mount("/var/tmp/cloud-init")
self.assertEqual(("/dev/mapper/vg00-lv_var", "ext4", "/var"), ret)

@mock.patch("cloudinit.subp.subp")
def test_parse_mount_with_zfs(self, mount_out):
Expand All @@ -2217,9 +2217,9 @@ def test_parse_mount_with_zfs(self, mount_out):
# this one is the root, valid and also exists in mount_parse_zfs.txt
ret = util.parse_mount("/")
self.assertEqual(("vmzroot/ROOT/freebsd", "zfs", "/"), ret)
# this one does not even exist in mount_parse_ext.txt
ret = util.parse_mount("/not/existing/mount")
self.assertIsNone(ret)
# this one does not exist in mount_parse_ext.txt
ret = util.parse_mount("/var/tmp/cloud-init")
self.assertEqual(("vmzroot/var/tmp", "zfs", "/var/tmp"), ret)


class TestIsX86(helpers.CiTestCase):
Expand Down

0 comments on commit e371d63

Please sign in to comment.