def test_qemu_binary_is_executable(self, arch):
     """Check that qemu binary qemu-{arch} is executable."""
     cont = proot_distribution_dir(self.container_dir)
     proot_binary = os.path.join(cont, "bin/qemu-{}".format(arch))
     stat_result = os.stat(proot_binary)
     executable_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
     self.assertTrue(stat_result.st_mode & executable_mask != 0)
 def test_proot_binary_is_executable(self):
     """Check that that the proot binary is executable."""
     cont = proot_distribution_dir(self.container_dir)
     proot_binary = os.path.join(cont, "bin/proot")
     stat_result = os.stat(proot_binary)
     executable_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
     self.assertTrue(stat_result.st_mode & executable_mask != 0)
 def test_qemu_binary_is_executable(self, arch):
     """Check that qemu binary qemu-{arch} is executable."""
     cont = proot_distribution_dir(self.container_dir)
     proot_binary = os.path.join(cont, "bin/qemu-{}".format(arch))
     stat_result = os.stat(proot_binary)
     executable_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
     self.assertTrue(stat_result.st_mode & executable_mask != 0)
 def test_proot_binary_is_executable(self):
     """Check that that the proot binary is executable."""
     cont = proot_distribution_dir(self.container_dir)
     proot_binary = os.path.join(cont, "bin/proot")
     stat_result = os.stat(proot_binary)
     executable_mask = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
     self.assertTrue(stat_result.st_mode & executable_mask != 0)
def proot_distro_from_container(container_dir):
    """Return a ProotDistribution from a container dir."""
    path_to_proot_dir = constants.proot_distribution_dir(container_dir)
    path_to_proot_bin = os.path.join(path_to_proot_dir, "bin/proot")
    path_to_qemu_template = os.path.join(path_to_proot_dir, "bin/qemu-{arch}")

    def _get_qemu_binary(arch):
        """Get the qemu binary for architecture."""
        qemu_arch = architecture.Alias.qemu(arch)
        return path_to_qemu_template.format(arch=qemu_arch)

    def _get_proot_binary():
        """Get the proot binary."""
        return path_to_proot_bin

    return ProotDistribution(proot=_get_proot_binary, qemu=_get_qemu_binary)
def _fetch_proot_distribution(container_root, target_arch):
    """Fetch the initial proot distribution if it is not available.

    Touches /.have-proot-distribution when complete
    """
    path_to_proot_check = constants.have_proot_distribution(container_root)
    path_to_proot_dir = constants.proot_distribution_dir(container_root)

    def _download_proot(distribution_dir, arch):
        """Download arch build of proot into distribution."""
        from psqtraviscontainer.download import download_file

        with directory.Navigation(os.path.join(distribution_dir, "bin")):
            proot_url = _PROOT_URL_BASE.format(arch=arch)
            path_to_proot = download_file(proot_url, "proot")
            os.chmod(path_to_proot,
                     os.stat(path_to_proot).st_mode | stat.S_IXUSR)
            return path_to_proot

    def _extract_qemu(qemu_deb_path, qemu_temp_dir):
        """Extract qemu."""
        printer.unicode_safe(
            colored.magenta(("""-> Extracting {0}\n"""
                             """""").format(qemu_deb_path),
                            bold=True))
        debian_package.extract_deb_data(qemu_deb_path, qemu_temp_dir)

    def _remove_unused_emulators(qemu_binaries_path):
        """Remove unused emulators from qemu distribution."""
        distributions = distro.available_distributions()
        cur_arch = platform.machine()
        archs = [d["info"].kwargs["arch"] for d in distributions]
        archs = set([
            architecture.Alias.qemu(a) for a in chain(*archs)
            if a != architecture.Alias.universal(cur_arch)
        ])
        keep_binaries = ["qemu-" + a for a in archs] + ["proot"]

        for root, _, filenames in os.walk(qemu_binaries_path):
            for filename in filenames:
                if os.path.basename(filename) not in keep_binaries:
                    os.remove(os.path.join(root, filename))

    def _download_qemu(distribution_dir, arch):
        """Download arch build of qemu and extract binaries."""
        qemu_url = _QEMU_URL_BASE.format(arch=arch)

        with TemporarilyDownloadedFile(qemu_url,
                                       filename="qemu.deb") as qemu_deb:
            # Go into a separate subdirectory and extract the qemu deb
            # there, then copy out the requisite files, so that we don't
            # cause tons of pollution
            qemu_tmp = os.path.join(path_to_proot_dir, "_qemu_tmp")
            with directory.Navigation(qemu_tmp):
                qemu_binaries_path = os.path.join(qemu_tmp, "usr", "bin")
                _extract_qemu(qemu_deb.path(), qemu_tmp)
                _remove_unused_emulators(qemu_binaries_path)

                for filename in os.listdir(qemu_binaries_path):
                    shutil.copy(os.path.join(qemu_binaries_path, filename),
                                os.path.join(path_to_proot_dir, "bin"))

            shutil.rmtree(qemu_tmp)

        return os.path.join(distribution_dir, "bin", "qemu-{arch}")

    try:
        os.stat(path_to_proot_check)
        printer.unicode_safe(
            colored.green(
                """-> """
                """Using pre-existing proot """
                """distribution\n""",
                bold=True))

    except OSError:
        create_msg = """Creating distribution of proot in {}\n"""
        root_relative = os.path.relpath(container_root)
        printer.unicode_safe(
            colored.yellow(create_msg.format(root_relative), bold=True))

        # Distro check does not exist - create the ./_proot directory
        # and download files for this architecture
        with directory.Navigation(path_to_proot_dir):
            proot_arch = architecture.Alias.universal(platform.machine())
            _download_proot(path_to_proot_dir, proot_arch)

            # We may not need qemu if we're not going to emulate
            # anything.
            if (architecture.Alias.universal(platform.machine()) !=
                    architecture.Alias.universal(target_arch)
                    or os.environ.get("_FORCE_DOWNLOAD_QEMU", None)):
                qemu_arch = architecture.Alias.debian(platform.machine())
                _download_qemu(path_to_proot_dir, qemu_arch)

        with open(path_to_proot_check, "w+") as check_file:
            check_file.write("done")

        printer.unicode_safe(
            colored.green("""\N{check mark} """
                          """Successfully installed proot """
                          """distribution to """
                          """{}\n""".format(root_relative),
                          bold=True))

    return proot_distro_from_container(container_root)
 def test_has_qemu_executables(self, arch):
     """Check that we have a qemu executable qemu-{arch}."""
     cont = proot_distribution_dir(self.container_dir)
     self.assertThat(os.path.join(cont, "bin/qemu-{}".format(arch)),
                     FileExists())
 def test_has_proot_executable(self):
     """Check that we have a proot executable in our distribution."""
     cont = proot_distribution_dir(self.container_dir)
     self.assertThat(os.path.join(cont, "bin/proot"),
                     FileExists())
 def test_has_proot_dir(self):
     """Check that we have a proot directory in our distribution."""
     self.assertThat(proot_distribution_dir(self.container_dir),
                     DirExists())
 def test_has_qemu_executables(self, arch):
     """Check that we have a qemu executable qemu-{arch}."""
     cont = proot_distribution_dir(self.container_dir)
     self.assertThat(os.path.join(cont, "bin/qemu-{}".format(arch)),
                     FileExists())
 def test_has_proot_executable(self):
     """Check that we have a proot executable in our distribution."""
     cont = proot_distribution_dir(self.container_dir)
     self.assertThat(os.path.join(cont, "bin/proot"), FileExists())
 def test_has_proot_dir(self):
     """Check that we have a proot directory in our distribution."""
     self.assertThat(proot_distribution_dir(self.container_dir),
                     DirExists())