def test_invalid_mountinfo(self):
        self.fake_logger = fixtures.FakeLogger(level=logging.WARN)
        self.useFixture(self.fake_logger)

        mountinfo.MountInfo(
            mountinfo_file=self._write_mountinfo(dedent("I'm invalid")))

        # Assert that a warning was logged
        self.assertThat(self.fake_logger.output,
                        Equals("Unable to parse mountinfo row: I'm invalid\n"))
Beispiel #2
0
    def test_mountinfo_by_mount_point(self):
        mounts = mountinfo.MountInfo(
            mountinfo_file=self._write_mountinfo(
                dedent(
                    """\
                23 28 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:14 - proc proc rw
                1341 28 7:6 / /snap/snapcraft/1 ro,nodev,relatime shared:39 - squashfs /dev/loop6 ro
                1455 28 253:0 /test-snap/prime /snap/test-snap/x1 ro,relatime shared:1 - ext4 /dev/mapper/foo rw,errors=remount-ro,data=ordered
                """
                )
            )
        )  # noqa

        mount = mounts.for_mount_point("/proc")
        self.assertThat(mount.mount_id, Equals("23"))
        self.assertThat(mount.parent_id, Equals("28"))
        self.assertThat(mount.st_dev, Equals("0:4"))
        self.assertThat(mount.root, Equals("/"))
        self.assertThat(mount.mount_point, Equals("/proc"))
        self.assertThat(mount.mount_options, Equals("rw,nosuid,nodev,noexec,relatime"))
        self.assertThat(mount.optional_fields, Equals(["shared:14"]))
        self.assertThat(mount.filesystem_type, Equals("proc"))
        self.assertThat(mount.mount_source, Equals("proc"))
        self.assertThat(mount.super_options, Equals("rw"))

        mount = mounts.for_mount_point("/snap/snapcraft/1")
        self.assertThat(mount.mount_id, Equals("1341"))
        self.assertThat(mount.parent_id, Equals("28"))
        self.assertThat(mount.st_dev, Equals("7:6"))
        self.assertThat(mount.root, Equals("/"))
        self.assertThat(mount.mount_point, Equals("/snap/snapcraft/1"))
        self.assertThat(mount.mount_options, Equals("ro,nodev,relatime"))
        self.assertThat(mount.optional_fields, Equals(["shared:39"]))
        self.assertThat(mount.filesystem_type, Equals("squashfs"))
        self.assertThat(mount.mount_source, Equals("/dev/loop6"))
        self.assertThat(mount.super_options, Equals("ro"))

        mount = mounts.for_mount_point("/snap/test-snap/x1")
        self.assertThat(mount.mount_id, Equals("1455"))
        self.assertThat(mount.parent_id, Equals("28"))
        self.assertThat(mount.st_dev, Equals("253:0"))
        self.assertThat(mount.root, Equals("/test-snap/prime"))
        self.assertThat(mount.mount_point, Equals("/snap/test-snap/x1"))
        self.assertThat(mount.mount_options, Equals("ro,relatime"))
        self.assertThat(mount.optional_fields, Equals(["shared:1"]))
        self.assertThat(mount.filesystem_type, Equals("ext4"))
        self.assertThat(mount.mount_source, Equals("/dev/mapper/foo"))
        self.assertThat(
            mount.super_options, Equals("rw,errors=remount-ro,data=ordered")
        )
Beispiel #3
0
def _cleanup_common_directories_for_step(step, project_options, parts=None):
    if not parts:
        parts = []

    being_tried = False
    if step <= steps.PRIME:
        # Remove the priming area. Only remove the actual 'prime' directory if
        # it's NOT being used in 'snap try'. We'll know that if it's
        # bind-mounted somewhere.
        mounts = mountinfo.MountInfo()
        try:
            mounts.for_root(project_options.prime_dir)
        except errors.RootNotMountedError:
            remove_dir = True
            message = "Cleaning up priming area"
        else:
            remove_dir = False
            message = (
                "Cleaning up priming area, but not removing as it's in "
                "use by 'snap try'"
            )
            being_tried = True
        _cleanup_common(
            project_options.prime_dir,
            steps.PRIME,
            message,
            parts,
            remove_dir=remove_dir,
        )

    if step <= steps.STAGE:
        # Remove the staging area.
        _cleanup_common(
            project_options.stage_dir, steps.STAGE, "Cleaning up staging area", parts
        )

    if step <= steps.PULL:
        # Remove the parts directory (but leave local plugins alone).
        _cleanup_parts_dir(
            project_options.parts_dir, project_options.local_plugins_dir, parts
        )
        _cleanup_internal_snapcraft_dir()

    if not being_tried:
        _remove_directory_if_empty(project_options.prime_dir)
    _remove_directory_if_empty(project_options.stage_dir)
    _remove_directory_if_empty(project_options.parts_dir)
Beispiel #4
0
def _cleanup_common_directories_for_step(step, project: "Project", parts=None):
    if not parts:
        parts = []

    being_tried = False
    message: Optional[str] = None
    if step <= steps.PRIME:
        # Remove the priming area. Only remove the actual 'prime' directory if
        # it's NOT being used in 'snap try'. We'll know that if it's
        # bind-mounted somewhere.
        mounts = mountinfo.MountInfo()
        try:
            mounts.for_root(project.prime_dir)
        except errors.RootNotMountedError:
            remove_dir = True
            message = "Cleaning up priming area"
        else:
            remove_dir = False
            message = ("Cleaning up priming area, but not removing as it's in "
                       "use by 'snap try'")
            being_tried = True
        finally:
            # It does not matter if prime is being tried inside the managed-host
            # or not, we cannot delete prime as it is really a mount from the
            # outside host.
            if project._is_managed_host:
                remove_dir = False
                message = None
        _cleanup_common(project.prime_dir,
                        steps.PRIME,
                        message,
                        parts,
                        remove_dir=remove_dir)

    if step <= steps.STAGE:
        # Remove the staging area.
        _cleanup_common(project.stage_dir, steps.STAGE,
                        "Cleaning up staging area", parts)

    if step <= steps.PULL:
        # Remove the parts directory (but leave local plugins alone).
        _cleanup_parts_dir(project.parts_dir, project.local_plugins_dir, parts)

    if not being_tried and not project._is_managed_host:
        _remove_directory_if_empty(project.prime_dir)
    _remove_directory_if_empty(project.stage_dir)
    _remove_directory_if_empty(project.parts_dir)
    def test_mountinfo_by_mount_point(self):
        mounts = mountinfo.MountInfo(mountinfo_file=self._write_mountinfo(
            dedent("""\
                23 28 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:14 - proc proc rw
                1341 28 7:6 / /snap/snapcraft/1 ro,nodev,relatime shared:39 - squashfs /dev/loop6 ro
                1455 28 253:0 /test-snap/prime /snap/test-snap/x1 ro,relatime shared:1 - ext4 /dev/mapper/foo rw,errors=remount-ro,data=ordered
                """)))  # noqa

        mount = mounts.for_mount_point('/proc')
        self.assertThat(mount.mount_id, Equals('23'))
        self.assertThat(mount.parent_id, Equals('28'))
        self.assertThat(mount.st_dev, Equals('0:4'))
        self.assertThat(mount.root, Equals('/'))
        self.assertThat(mount.mount_point, Equals('/proc'))
        self.assertThat(mount.mount_options,
                        Equals('rw,nosuid,nodev,noexec,relatime'))
        self.assertThat(mount.optional_fields, Equals(['shared:14']))
        self.assertThat(mount.filesystem_type, Equals('proc'))
        self.assertThat(mount.mount_source, Equals('proc'))
        self.assertThat(mount.super_options, Equals('rw'))

        mount = mounts.for_mount_point('/snap/snapcraft/1')
        self.assertThat(mount.mount_id, Equals('1341'))
        self.assertThat(mount.parent_id, Equals('28'))
        self.assertThat(mount.st_dev, Equals('7:6'))
        self.assertThat(mount.root, Equals('/'))
        self.assertThat(mount.mount_point, Equals('/snap/snapcraft/1'))
        self.assertThat(mount.mount_options, Equals('ro,nodev,relatime'))
        self.assertThat(mount.optional_fields, Equals(['shared:39']))
        self.assertThat(mount.filesystem_type, Equals('squashfs'))
        self.assertThat(mount.mount_source, Equals('/dev/loop6'))
        self.assertThat(mount.super_options, Equals('ro'))

        mount = mounts.for_mount_point('/snap/test-snap/x1')
        self.assertThat(mount.mount_id, Equals('1455'))
        self.assertThat(mount.parent_id, Equals('28'))
        self.assertThat(mount.st_dev, Equals('253:0'))
        self.assertThat(mount.root, Equals('/test-snap/prime'))
        self.assertThat(mount.mount_point, Equals('/snap/test-snap/x1'))
        self.assertThat(mount.mount_options, Equals('ro,relatime'))
        self.assertThat(mount.optional_fields, Equals(['shared:1']))
        self.assertThat(mount.filesystem_type, Equals('ext4'))
        self.assertThat(mount.mount_source, Equals('/dev/mapper/foo'))
        self.assertThat(mount.super_options,
                        Equals('rw,errors=remount-ro,data=ordered'))
    def test_mountinfo_by_root(self):
        mounts = mountinfo.MountInfo(mountinfo_file=self._write_mountinfo(
            dedent("""\
                23 28 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:14 - proc proc rw
                1341 28 7:6 / /snap/snapcraft/1 ro,nodev,relatime shared:39 - squashfs /dev/loop6 ro
                1455 28 253:0 /test-snap/prime /snap/test-snap/x1 ro,relatime shared:1 - ext4 /dev/mapper/foo rw,errors=remount-ro,data=ordered
                """)))  # noqa

        root_mounts = mounts.for_root('/')
        for mount_point in ('/proc', '/snap/snapcraft/1'):
            self.assertTrue(
                any(m for m in root_mounts if m.mount_point == mount_point),
                'Expected {!r} to be included in root mounts'.format(
                    mount_point))

        test_snap_mounts = mounts.for_root('/test-snap/prime')
        self.assertThat(test_snap_mounts, HasLength(1))
        self.expectThat(test_snap_mounts[0].mount_point,
                        Equals('/snap/test-snap/x1'))
Beispiel #7
0
 def test_mountinfo_missing_mount_point(self):
     mounts = mountinfo.MountInfo(mountinfo_file=self._write_mountinfo(""))
     raised = self.assertRaises(
         errors.MountPointNotFoundError, mounts.for_mount_point, "test-root"
     )
     self.assertThat(raised.mount_point, Equals("test-root"))
Beispiel #8
0
 def test_mountinfo_missing_root(self):
     mounts = mountinfo.MountInfo(mountinfo_file=self._write_mountinfo(""))
     raised = self.assertRaises(
         errors.RootNotMountedError, mounts.for_root, "test-root"
     )
     self.assertThat(raised.root, Equals("test-root"))