Exemplo n.º 1
0
class PoolInstaller(Installer):
    def __init__(self, chroot_path, pool_path, arch, environ={}):
        super(PoolInstaller, self).__init__(chroot_path, environ)

        from pyproject.pool.pool import Pool
        self.pool = Pool(pool_path)
        self.arch = arch

    @staticmethod
    def _get_package_index(packagedir):
        def filesize(path):
            return str(os.stat(path).st_size)

        def md5sum(path):
            return str(hashlib.md5(open(path, 'rb').read()).hexdigest())

        def sha256sum(path):
            return str(hashlib.sha256(open(path, 'rb').read()).hexdigest())

        index = []
        for package in os.listdir(packagedir):
            path = os.path.join(packagedir, package)
            # dl_path would best be calculated; but we don't have access to chroot_path here...
            dl_path = os.path.join('var/cache/apt/archives', package)
            if path.endswith('.deb'):
                control = debinfo.get_control_fields(path)
                for field in control.keys():
                    index.append(field + ": " + control[field])

                index.append("Filename: " + dl_path)
                index.append("Size: " + filesize(path))
                index.append("MD5sum: " + md5sum(path))
                index.append("SHA256: " + sha256sum(path))
                index.append("")

        return index

    def install(self, packages, ignore_errors=[]):
        """install packages into chroot via pool"""

        print "getting packages..."
        packagedir = join(self.chroot.path, "var/cache/apt/archives")
        self.pool.get(packagedir, packages, strict=True)

        print "generating package index..."
        sources_list = RevertibleFile(
            join(self.chroot.path, "etc/apt/sources.list"))
        print >> sources_list, "deb file:/// local debs"
        sources_list.close()

        index_file = "_dists_local_debs_binary-%s_Packages" % self.arch
        index_path = join(self.chroot.path, "var/lib/apt/lists", index_file)
        index = self._get_package_index(packagedir)
        file(index_path, "w").write("\n".join(index))
        self.chroot.system("apt-cache gencaches")

        print "installing packages..."
        self._install(packages, ignore_errors, ['--allow-unauthenticated'])
Exemplo n.º 2
0
class PoolInstaller(Installer):
    def __init__(self, chroot_path, pool_path, arch, environ={}):
        super(PoolInstaller, self).__init__(chroot_path, environ)

        from pyproject.pool.pool import Pool
        self.pool = Pool(pool_path)
        self.arch = arch

    @staticmethod
    def _get_package_index(packagedir):
        def filesize(path):
            return str(os.stat(path).st_size)

        def md5sum(path):
            return str(hashlib.md5(open(path, 'rb').read()).hexdigest())

        index = []
        for package in os.listdir(packagedir):
            path = os.path.join(packagedir, package)
            if path.endswith('.deb'):
                control = debinfo.get_control_fields(path)
                for field in control.keys():
                    index.append(field + ": " + control[field])

                index.append("Filename: " + path)
                index.append("Size: " + filesize(path))
                index.append("MD5sum: " + md5sum(path))
                index.append("")

        return index

    def install(self, packages, ignore_errors=[]):
        """install packages into chroot via pool"""

        print "getting packages..."
        packagedir = join(self.chroot.path, "var/cache/apt/archives")
        self.pool.get(packagedir, packages, strict=True)

        print "generating package index..."
        sources_list = RevertibleFile(join(self.chroot.path, "etc/apt/sources.list"))
        print >> sources_list, "deb file:/// local debs"
        sources_list.close()

        index_file = "_dists_local_debs_binary-%s_Packages" % self.arch
        index_path = join(self.chroot.path, "var/lib/apt/lists", index_file)
        index = self._get_package_index(packagedir)
        file(index_path, "w").write("\n".join(index))
        self.chroot.system("apt-cache gencaches")

        print "installing packages..."
        self._install(packages, ignore_errors, ['--allow-unauthenticated'])
Exemplo n.º 3
0
def get_packages_info(packages, pool_path):
    info = {}

    from pyproject.pool.pool import Pool
    pool = Pool(pool_path)

    tmpdir = TempDir()
    pool.get(tmpdir.path, packages, strict=True)

    for package in os.listdir(tmpdir.path):
        path = os.path.join(tmpdir.path, package)
        if path.endswith('.deb'):
            control = debinfo.get_control_fields(path)
            info[control['Package']] = control['Description']

    return info
Exemplo n.º 4
0
    def __init__(self, iterable=(), pool_path=None):
        set.__init__(self, iterable)

        if pool_path:
            from pyproject.pool.pool import Pool
            self.pool = Pool(pool_path)
        else:
            self.pool = None

        self.packageorigins = PackageOrigins()
Exemplo n.º 5
0
    def __init__(self, chroot_path, pool_path, arch, environ={}):
        super(PoolInstaller, self).__init__(chroot_path, environ)

        from pyproject.pool.pool import Pool
        self.pool = Pool(pool_path)
        self.arch = arch
Exemplo n.º 6
0
class Plan(set):
    @staticmethod
    def _parse_plan_file(path, cpp_opts=[]):
        """process plan through cpp, then parse it and add packages to plan """
        processed_plan = cpp.cpp(path, cpp_opts)
        packages = set()
        for expr in processed_plan.splitlines():
            expr = re.sub(r'#.*', '', expr)
            expr = expr.strip()
            if not expr:
                continue

            if expr.startswith("!"):
                package = expr[1:]

                if package in packages:
                    packages.remove(package)

            else:
                package = expr
                packages.add(package)

        return packages

    @classmethod
    def init_from_file(cls, plan_file_path, cpp_opts=[], pool_path=None):
        return cls(cls._parse_plan_file(plan_file_path, cpp_opts), pool_path)

    def __new__(cls, iterable=(), pool_path=None):
        return set.__new__(cls, iterable)

    def __init__(self, iterable=(), pool_path=None):
        set.__init__(self, iterable)

        if pool_path:
            from pyproject.pool.pool import Pool
            self.pool = Pool(pool_path)
        else:
            self.pool = None

        self.packageorigins = PackageOrigins()

    def _get_new_deps(self, pkg_control, old_deps, depend_fields):
        def parse_depends(val):
            if val is None or val.strip() == "":
                return []

            return re.split("\s*,\s*", val.strip())

        new_deps = set()

        raw_depends = []
        for field_name in depend_fields:
            raw_depends += parse_depends(pkg_control.get(field_name))

        for raw_depend in raw_depends:
            if "|" not in raw_depend:
                new_deps.add(Dependency(raw_depend))
                continue

            alternatives = [ Dependency(alt) for alt in raw_depend.split("|") ]

            # continue if any of the alternatives are already in resolved or unresolved sets
            if set(alternatives) & old_deps:
                continue

            # add the first alternative that exists in the pool to set of new dependencies
            for alternative in alternatives:
                if self.pool.exists(alternative.name):
                    new_deps.add(alternative)
                    break

        for dep in new_deps:
            self.packageorigins.add(dep.name, pkg_control.get('Package'))

        return new_deps

    @staticmethod
    def _get_provided(pkg_control):
        raw_provided = pkg_control.get('Provides')
        if raw_provided is None or raw_provided.strip() == "":
            return set()

        return set(re.split("\s*,\s*", raw_provided.strip()))

    def dctrls(self):
        """return plan dependencies control file info"""
        toquery = set([ Dependency(pkg) for pkg in self ])
        packages = PackageGetter(toquery, self.pool)

        dctrls = {}
        for dep in toquery:
            package_path = packages[dep]
            if package_path is None:
                raise Error('could not find package', dep.name)
            dctrls[dep] = debinfo.get_control_fields(package_path)
            dctrls[dep]['Filename'] = basename(package_path)

        return dctrls

    def resolve(self):
        """resolve plan dependencies recursively -> return spec"""
        spec = Spec()

        if not self.pool:
            return list(self)

        resolved = set()
        missing = set()
        provided = set()

        def reformat2dep(pkg):
            if '=' not in pkg:
                return pkg

            name, version = pkg.split("=", 1)
            return "%s (= %s)" % (name, version)

        unresolved = set([ Dependency(reformat2dep(pkg)) for pkg in self ])
        while unresolved:
            # get newest package versions of unresolved dependencies from the pool
            # and pray they don't conflict with our dependency restrictions
            packages = PackageGetter(unresolved, self.pool)
            new_deps = set()
            for dep in unresolved:
                package_path = packages[dep]
                if not package_path:
                    continue

                pkg_control = debinfo.get_control_fields(package_path)

                version = pkg_control['Version']
                if not dep.is_version_ok(version):
                    raise Error("dependency '%s' incompatible with newest pool version (%s)" % (dep, version))
                spec.add(dep.name, version)
                resolved.add(dep)

                new_deps |= self._get_new_deps(pkg_control, resolved | unresolved | new_deps, dep.fields)
                provided |= self._get_provided(pkg_control)

            unresolved = new_deps - resolved
            missing = (missing | packages.missing) - provided

        if missing:
            def get_origins(dep):
                # trace the package origins
                origins = []
                while dep:
                    try:
                        dep = self.packageorigins[dep][0]
                        origins.append(dep)
                    except KeyError:
                        dep = None

                return origins

            brokendeps = []
            for dep in missing:
                brokendeps.append("%s (%s)" % (dep, " -> ".join(get_origins(dep))))

            raise Error("broken dependencies: " + "\n".join(brokendeps))

        return spec
Exemplo n.º 7
0
    def __init__(self, chroot_path, pool_path, arch, environ={}):
        super(PoolInstaller, self).__init__(chroot_path, environ)

        from pyproject.pool.pool import Pool
        self.pool = Pool(pool_path)
        self.arch = arch