def updates_check(self) -> Dict[str, List[Tuple[str, str]]]:
        """
		Returns the list of packages to be updated/installed
		by a dist-upgrade.
		"""
        install = []
        update = []
        remove = []

        apt = Cache(memonly=True)
        apt.update()
        apt.open()
        apt.clear()
        apt.upgrade(dist_upgrade=True)
        for pkg in apt.get_changes():
            if pkg.marked_install:
                install.append((pkg.name, pkg.candidate.version))
            if pkg.marked_upgrade:
                update.append((pkg.name, pkg.candidate.version))
            if pkg.marked_delete:
                remove.append((pkg.name, pkg.installed.version))

        return dict(
            update=sorted(update),
            install=sorted(install),
            remove=sorted(remove),
        )
示例#2
0
class RPCAPTCache(InChRootObject):

    # pylint: disable=too-many-public-methods
    def __init__(self,
                 rfs,
                 arch,
                 notifier=None,
                 norecommend=False,
                 noauth=True):

        # pylint: disable=too-many-arguments
        InChRootObject.__init__(self, rfs)

        self.notifier = notifier
        config.set("APT::Architecture", arch)
        if norecommend:
            config.set("APT::Install-Recommends", "0")
        else:
            config.set("APT::Install-Recommends", "1")

        if noauth:
            config.set("APT::Get::AllowUnauthenticated", "1")
        else:
            config.set("APT::Get::AllowUnauthenticated", "0")

        self.cache = Cache(progress=ElbeOpProgress())
        self.cache.open(progress=ElbeOpProgress())

    def dbg_dump(self, filename):
        ts = time.localtime()
        filename = filename + ('_%02d%02d%02d' %
                               (ts.tm_hour, ts.tm_min, ts.tm_sec))
        with open(filename, 'w') as dbg:
            for p in self.cache:
                dbg.write(
                    '%s %s %d %d %d %d %d %d %d %d %d %d %d %d\n' %
                    (p.name, p.candidate.version, p.marked_keep,
                     p.marked_delete, p.marked_upgrade, p.marked_downgrade,
                     p.marked_install, p.marked_reinstall, p.is_auto_installed,
                     p.is_installed, p.is_auto_removable, p.is_now_broken,
                     p.is_inst_broken, p.is_upgradable))

    def get_sections(self):
        ret = list(set([p.section for p in self.cache]))
        ret.sort()
        return ret

    def get_pkglist(self, section):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache]
        else:
            ret = [APTPackage(p) for p in self.cache if p.section == section]

        return ret

    def mark_install(self, pkgname, version, from_user=True, nodeps=False):
        print('Mark for install "%s"' % pkgname)
        p = self.cache[pkgname]
        if version:
            p.candidate = p.versions[version]
        p.mark_install(auto_fix=not nodeps,
                       auto_inst=not nodeps,
                       from_user=from_user)

    def mark_install_devpkgs(self, ignore_pkgs, ignore_dev_pkgs):
        ignore_pkgs.discard('libc6')  # we don't want to ignore libc
        ignore_pkgs.discard('libstdc++5')
        ignore_pkgs.discard('libstdc++6')
        # list all debian src packages of all installed packages that don't
        # come from debootstrap
        src_list = [
            p.candidate.source_name for p in self.cache
            if (p.is_installed and p.name not in ignore_pkgs)
        ]
        version_dict = {
            p.name: p.candidate.version
            for p in self.cache
            if (p.is_installed and p.name not in ignore_pkgs)
        }
        # go through all packages, remember package if its source package
        # matches one of the installed packages and the binary package is a
        # '-dev' package
        dev_list = [
            s for s in self.cache if (s.candidate.source_name in src_list and (
                s.name.endswith('-dev')))
        ]
        for p in dev_list:
            if p.name not in ignore_dev_pkgs:
                name_no_suffix = p.name[:-len('-dev')]
                if name_no_suffix in version_dict:
                    version = version_dict[name_no_suffix]
                    candidate = p.versions.get(version)
                    if candidate:
                        p.candidate = candidate
                p.mark_install()
        # ensure that the symlinks package will be installed (it's needed for
        # fixing links inside the sysroot
        self.cache['symlinks'].mark_install()

        for p in ignore_dev_pkgs:
            self.cache[p].mark_delete()

        dbgsym_list = [
            s.name + '-dbgsym' for s in self.cache
            if (s.is_installed or s.marked_install)
        ]

        for p in dbgsym_list:
            if p in self.cache:
                pkg = self.cache[p]
                name_no_suffix = pkg.name[:-len('-dbgsym')]
                if name_no_suffix in version_dict:
                    version = version_dict[name_no_suffix]
                    candidate = pkg.versions.get(version)
                    if candidate:
                        pkg.candidate = candidate
                pkg.mark_install()

    def cleanup(self, exclude_pkgs):
        for p in self.cache:
            if p.is_installed and not \
               p.is_auto_installed or \
               p.is_auto_removable:
                remove = True
                for x in exclude_pkgs:
                    if x == p.name:
                        remove = False
                if remove:
                    p.mark_delete(auto_fix=True, purge=True)

    def mark_upgrade(self, pkgname, version):
        p = self.cache[pkgname]
        if version:
            p.candidate = p.versions[version]
        p.mark_upgrade()

    def mark_delete(self, pkgname):
        p = self.cache[pkgname]
        p.mark_delete(purge=True)

    def mark_keep(self, pkgname, version):
        p = self.cache[pkgname]
        p.mark_keep()

    def update(self):
        self.cache.update(fetch_progress=ElbeAcquireProgress())
        self.cache.open(progress=ElbeOpProgress())

    def commit(self):
        os.environ["DEBIAN_FRONTEND"] = "noninteractive"
        os.environ["DEBONF_NONINTERACTIVE_SEEN"] = "true"
        print("Commiting changes ...")
        self.cache.commit(ElbeAcquireProgress(),
                          ElbeInstallProgress(fileno=sys.stdout.fileno()))
        self.cache.open(progress=ElbeOpProgress())

    def clear(self):
        self.cache.clear()

    def get_dependencies(self, pkgname):
        deps = getalldeps(self.cache, pkgname)
        return [APTPackage(p, cache=self.cache) for p in deps]

    def get_installed_pkgs(self, section='all'):
        if section == 'all':
            pl = [APTPackage(p) for p in self.cache if p.is_installed]
        else:
            pl = [
                APTPackage(p) for p in self.cache
                if (p.section == section and p.is_installed)
            ]
        return pl

    def get_fileindex(self):
        index = {}

        for p in self.cache:
            if p.is_installed:
                for f in p.installed_files:
                    index[f] = p.name

        return index

    def get_marked_install(self, section='all'):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache if p.marked_install]
        else:
            ret = [
                APTPackage(p) for p in self.cache
                if (p.section == section and p.marked_install)
            ]
        return ret

    def get_upgradeable(self, section='all'):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache if p.is_upgradable]
        else:
            ret = [
                APTPackage(p) for p in self.cache
                if (p.section == section and p.is_upgradable)
            ]
        return ret

    def upgrade(self, dist_upgrade=False):
        self.cache.upgrade(dist_upgrade)

    def get_changes(self):
        changes = self.cache.get_changes()
        return [APTPackage(p) for p in changes]

    def has_pkg(self, pkgname):
        return pkgname in self.cache

    def is_installed(self, pkgname):
        if pkgname not in self.cache:
            return False
        return self.cache[pkgname].is_installed

    def get_pkg(self, pkgname):
        return APTPackage(self.cache[pkgname])

    def get_pkgs(self, pkgname):
        return [
            APTPackage(self.cache[p]) for p in sorted(self.cache.keys())
            if pkgname in p.lower()
        ]

    def compare_versions(self, ver1, ver2):
        return version_compare(ver1, ver2)

    def download_binary(self, pkgname, path, version=None):
        p = self.cache[pkgname]
        if version is None:
            pkgver = p.installed
        else:
            pkgver = p.versions[version]
        rel_filename = fetch_binary(pkgver, path, ElbeAcquireProgress())
        return self.rfs.fname(rel_filename)

    def download_source(self, pkgname, path, version=None):
        p = self.cache[pkgname]
        if version is None:
            pkgver = p.installed
        else:
            pkgver = p.versions[version]

        rel_filename = pkgver.fetch_source(path,
                                           ElbeAcquireProgress(),
                                           unpack=False)
        return self.rfs.fname(rel_filename)
示例#3
0
class RPCAPTCache(InChRootObject):

    # pylint: disable=too-many-public-methods
    def __init__(self,
                 rfs,
                 arch,
                 notifier=None,
                 norecommend=False,
                 noauth=True):

        # pylint: disable=too-many-arguments
        InChRootObject.__init__(self, rfs)

        self.notifier = notifier
        config.set("APT::Architecture", arch)
        if norecommend:
            config.set("APT::Install-Recommends", "0")
        else:
            config.set("APT::Install-Recommends", "1")

        if noauth:
            config.set("APT::Get::AllowUnauthenticated", "1")
        else:
            config.set("APT::Get::AllowUnauthenticated", "0")

        self.cache = Cache(progress=ElbeOpProgress())
        self.cache.open(progress=ElbeOpProgress())

    def dbg_dump(self, filename):
        ts = time.localtime()
        filename = filename + ('_%02d%02d%02d' %
                               (ts.tm_hour, ts.tm_min, ts.tm_sec))
        with open(filename, 'w') as dbg:
            for p in self.cache:
                dbg.write(
                    '%s %s %d %d %d %d %d %d %d %d %d %d %d %d\n' %
                    (p.name, p.candidate.version, p.marked_keep,
                     p.marked_delete, p.marked_upgrade, p.marked_downgrade,
                     p.marked_install, p.marked_reinstall, p.is_auto_installed,
                     p.is_installed, p.is_auto_removable, p.is_now_broken,
                     p.is_inst_broken, p.is_upgradable))

    def get_sections(self):
        ret = list({p.section for p in self.cache})
        ret.sort()
        return ret

    def get_pkglist(self, section):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache]
        else:
            ret = [APTPackage(p) for p in self.cache if p.section == section]

        return ret

    def mark_install(self, pkgname, version, from_user=True, nodeps=False):
        print('Mark for install "%s"' % pkgname)
        p = self.cache[pkgname]
        if version:
            p.candidate = p.versions[version]
        p.mark_install(auto_fix=not nodeps,
                       auto_inst=not nodeps,
                       from_user=from_user)

    def mark_install_devpkgs(self, ignore_pkgs, ignore_dev_pkgs):
        ignore_pkgs.discard('libc6')  # we don't want to ignore libc
        ignore_pkgs.discard('libstdc++5')
        ignore_pkgs.discard('libstdc++6')
        # list all debian src packages of all installed packages that don't
        # come from debootstrap
        src_list = [
            p.candidate.source_name for p in self.cache
            if (p.is_installed and p.name not in ignore_pkgs)
        ]
        version_dict = {
            p.name: p.candidate.version
            for p in self.cache
            if (p.is_installed and p.name not in ignore_pkgs)
        }
        # go through all packages, remember package if its source package
        # matches one of the installed packages and the binary package is a
        # '-dev' package
        dev_list = [
            s for s in self.cache if (s.candidate.source_name in src_list and (
                s.name.endswith('-dev')))
        ]
        for p in dev_list:
            if p.name not in ignore_dev_pkgs:
                name_no_suffix = p.name[:-len('-dev')]
                if name_no_suffix in version_dict:
                    version = version_dict[name_no_suffix]
                    candidate = p.versions.get(version)
                    if candidate:
                        p.candidate = candidate
                p.mark_install()
        # ensure that the symlinks package will be installed (it's needed for
        # fixing links inside the sysroot
        self.cache['symlinks'].mark_install()

        for p in ignore_dev_pkgs:
            self.cache[p].mark_delete()

        dbgsym_list = [
            s.name + '-dbgsym' for s in self.cache
            if (s.is_installed or s.marked_install)
        ]

        for p in dbgsym_list:
            if p in self.cache:
                pkg = self.cache[p]
                name_no_suffix = pkg.name[:-len('-dbgsym')]
                if name_no_suffix in version_dict:
                    version = version_dict[name_no_suffix]
                    candidate = pkg.versions.get(version)
                    if candidate:
                        pkg.candidate = candidate
                pkg.mark_install()

    def cleanup(self, exclude_pkgs):
        for p in self.cache:
            if p.is_installed and not \
               p.is_auto_installed or \
               p.is_auto_removable:
                remove = True
                for x in exclude_pkgs:
                    if x == p.name:
                        remove = False
                if remove:
                    p.mark_delete(auto_fix=True, purge=True)

    def mark_upgrade(self, pkgname, version):
        p = self.cache[pkgname]
        if version:
            p.candidate = p.versions[version]
        p.mark_upgrade()

    def mark_delete(self, pkgname):
        p = self.cache[pkgname]
        p.mark_delete(purge=True)

    def mark_keep(self, pkgname, _version):
        p = self.cache[pkgname]
        p.mark_keep()

    def update(self):
        self.cache.update(fetch_progress=ElbeAcquireProgress())
        self.cache.open(progress=ElbeOpProgress())

    def commit(self):
        os.environ["DEBIAN_FRONTEND"] = "noninteractive"
        os.environ["DEBONF_NONINTERACTIVE_SEEN"] = "true"
        print("Commiting changes ...")
        self.cache.commit(ElbeAcquireProgress(),
                          ElbeInstallProgress(fileno=sys.stdout.fileno()))
        self.cache.open(progress=ElbeOpProgress())

    def clear(self):
        self.cache.clear()

    def get_dependencies(self, pkgname):
        deps = getalldeps(self.cache, pkgname)
        return [APTPackage(p, cache=self.cache) for p in deps]

    def get_installed_pkgs(self, section='all'):
        if section == 'all':
            pl = [APTPackage(p) for p in self.cache if p.is_installed]
        else:
            pl = [
                APTPackage(p) for p in self.cache
                if (p.section == section and p.is_installed)
            ]
        return pl

    def get_fileindex(self):
        index = {}

        for p in self.cache:
            if p.is_installed:
                for f in p.installed_files:
                    index[f] = p.name

        return index

    def get_marked_install(self, section='all'):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache if p.marked_install]
        else:
            ret = [
                APTPackage(p) for p in self.cache
                if (p.section == section and p.marked_install)
            ]
        return ret

    def get_upgradeable(self, section='all'):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache if p.is_upgradable]
        else:
            ret = [
                APTPackage(p) for p in self.cache
                if (p.section == section and p.is_upgradable)
            ]
        return ret

    def upgrade(self, dist_upgrade=False):
        self.cache.upgrade(dist_upgrade)

    def get_changes(self):
        changes = self.cache.get_changes()
        return [APTPackage(p) for p in changes]

    def has_pkg(self, pkgname):
        return pkgname in self.cache

    def is_installed(self, pkgname):
        if pkgname not in self.cache:
            return False
        return self.cache[pkgname].is_installed

    def get_pkg(self, pkgname):
        return APTPackage(self.cache[pkgname])

    def get_pkgs(self, pkgname):
        return [
            APTPackage(self.cache[p]) for p in sorted(self.cache.keys())
            if pkgname in p.lower()
        ]

    def get_corresponding_source_packages(self, pkg_lst=None):

        if pkg_lst is None:
            pkg_lst = {p.name for p in self.cache if p.is_installed}

        src_set = set()

        with TagFile('/var/lib/dpkg/status') as tagfile:
            for section in tagfile:

                pkg = section['Package']

                if pkg not in pkg_lst:
                    continue

                tmp = self.cache[pkg].installed or self.cache[pkg].candidate

                src_set.add((tmp.source_name, tmp.source_version))

                if "Built-Using" not in section:
                    continue

                built_using_lst = section["Built-Using"].split(', ')
                for built_using in built_using_lst:
                    name, version = built_using.split(' ', 1)
                    version = version.strip('(= )')
                    src_set.add((name, version))

        return list(src_set)

    @staticmethod
    def compare_versions(self, ver1, ver2):
        return version_compare(ver1, ver2)

    def download_binary(self, pkgname, path, version=None):
        p = self.cache[pkgname]
        if version is None:
            pkgver = p.installed
        else:
            pkgver = p.versions[version]
        rel_filename = fetch_binary(pkgver, path, ElbeAcquireProgress())
        return self.rfs.fname(rel_filename)

    def download_source(self, src_name, src_version, dest_dir):

        allow_untrusted = config.find_b("APT::Get::AllowUnauthenticated",
                                        False)

        rec = SourceRecords()
        acq = Acquire(ElbeAcquireProgress())

        # poorman's iterator
        while True:
            next_p = rec.lookup(src_name)
            # End of the list?
            if not next_p:
                raise ("No source found for %s_%s" % (src_name, src_version))
            if src_version == rec.version:
                break

        # We don't allow untrusted package and the package is not
        # marks as trusted
        if not (allow_untrusted or rec.index.is_trusted):
            raise FetchError(
                "Can't fetch source %s_%s; Source %r is not trusted" %
                (src_name, src_version, rec.index.describe))

        # Copy from src to dst all files of the source package
        dsc = None
        files = []
        for _file in rec.files:
            src = os.path.basename(_file.path)
            dst = os.path.join(dest_dir, src)

            if 'dsc' == _file.type:
                dsc = dst

            if not (allow_untrusted or _file.hashes.usable):
                raise FetchError(
                    "Can't fetch file %s. No trusted hash found." % dst)

            # acq is accumlating the AcquireFile, the files list only
            # exists to prevent Python from GC the object .. I guess.
            # Anyway, if we don't keep the list, We will get an empty
            # directory
            files.append(
                AcquireFile(acq,
                            rec.index.archive_uri(_file.path),
                            _file.hashes,
                            _file.size,
                            src,
                            destfile=dst))
        acq.run()

        if dsc is None:
            raise ValueError("No source found for %s_%s" %
                             (src_name, src_version))

        for item in acq.items:
            if item.STAT_DONE != item.status:
                raise FetchError("Can't fetch item %s: %s" %
                                 (item.destfile, item.error_text))

        return self.rfs.fname(os.path.abspath(dsc))
示例#4
0
class RPCAPTCache(InChRootObject):
    def __init__(self,
                 rfs,
                 log,
                 arch,
                 notifier=None,
                 norecommend=False,
                 noauth=True):
        sys.stdout = open(log, 'a', buffering=0)
        sys.stderr = open(log, 'a', buffering=0)
        self.logfile = open(log, 'a', buffering=0)

        InChRootObject.__init__(self, rfs)

        self.notifier = notifier
        config.set("APT::Architecture", arch)
        if norecommend:
            config.set("APT::Install-Recommends", "1")
        else:
            config.set("APT::Install-Recommends", "0")

        if noauth:
            config.set("APT::Get::AllowUnauthenticated", "1")
        else:
            config.set("APT::Get::AllowUnauthenticated", "0")

        self.cache = Cache(progress=ElbeOpProgress())
        self.cache.open(progress=ElbeOpProgress())

    def dbg_dump(self, filename):
        ts = time.localtime()
        filename = filename + ('_%02d%02d%02d' %
                               (ts.tm_hour, ts.tm_min, ts.tm_sec))
        with open(filename, 'w') as dbg:
            for p in self.cache:
                dbg.write(
                    '%s %s %d %d %d %d %d %d %d %d %d %d %d %d\n' %
                    (p.name, p.candidate.version, p.marked_keep,
                     p.marked_delete, p.marked_upgrade, p.marked_downgrade,
                     p.marked_install, p.marked_reinstall, p.is_auto_installed,
                     p.is_installed, p.is_auto_removable, p.is_now_broken,
                     p.is_inst_broken, p.is_upgradable))

    def get_sections(self):
        ret = list(set([p.section for p in self.cache]))
        ret.sort()
        return ret

    def get_pkglist(self, section):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache]
        else:
            ret = [APTPackage(p) for p in self.cache if p.section == section]

        return ret

    def mark_install(self, pkgname, version, from_user=True, nodeps=False):
        p = self.cache[pkgname]
        if version:
            p.candidate = p.versions[version]
        p.mark_install(auto_fix=not nodeps,
                       auto_inst=not nodeps,
                       from_user=from_user)

    def mark_install_devpkgs(self, ignore_pkgs, ignore_dev_pkgs):
        ignore_pkgs.remove('libc6')  # we don't want to ignore libc
        # we don't want to ignore libstdc++
        try:
            ignore_pkgs.remove('libstdc++5')
        except:
            pass
        try:
            ignore_pkgs.remove('libstdc++6')
        except:
            pass
        # list all debian src packages of all installed packages that don't
        # come from debootstrap
        src_list = [
            p.candidate.source_name for p in self.cache
            if p.is_installed and p.name not in ignore_pkgs
        ]
        # go through all packages, remember package if its source package
        # matches one of the installed packages and the binary package is a
        # '-dev' package
        dev_list = [
            s for s in self.cache
            if (s.candidate.source_name in src_list and s.name.endswith('-dev')
                )
        ]
        for p in dev_list:
            if p.name not in ignore_dev_pkgs:
                p.mark_install()
        # ensure that the symlinks package will be installed (it's needed for
        # fixing links inside the sysroot
        self.cache['symlinks'].mark_install()

        for p in ignore_dev_pkgs:
            self.cache[p].mark_delete()

    def cleanup(self, exclude_pkgs):
        for p in self.cache:
            if (p.is_installed
                    and not p.is_auto_installed) or p.is_auto_removable:
                remove = True
                for x in exclude_pkgs:
                    if x == p.name:
                        remove = False
                if remove:
                    p.mark_delete(auto_fix=True, purge=True)

    def mark_upgrade(self, pkgname, version):
        p = self.cache[pkgname]
        if version:
            p.candidate = p.versions[version]
        p.mark_upgrade()

    def mark_delete(self, pkgname, version):
        p = self.cache[pkgname]
        p.mark_delete(purge=True)

    def mark_keep(self, pkgname, version):
        p = self.cache[pkgname]
        p.mark_keep()

    def update(self):
        self.cache.update(fetch_progress=ElbeAcquireProgress())
        self.cache.open(progress=ElbeOpProgress())

    def commit(self):
        os.environ["DEBIAN_FRONTEND"] = "noninteractive"
        os.environ["DEBONF_NONINTERACTIVE_SEEN"] = "true"
        self.cache.commit(ElbeAcquireProgress(),
                          ElbeInstallProgress(fileno=self.logfile.fileno()))
        self.cache.open(progress=ElbeOpProgress())

    def clear(self):
        self.cache.clear()

    def get_dependencies(self, pkgname):
        deps = getalldeps(self.cache, pkgname)
        return [APTPackage(p, cache=self.cache) for p in deps]

    def get_installed_pkgs(self, section='all'):
        # avoid DeprecationWarning: MD5Hash is deprecated, use Hashes instead
        # triggerd by python-apt
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", category=DeprecationWarning)
            if section == 'all':
                pl = [APTPackage(p) for p in self.cache if p.is_installed]
            else:
                pl = [
                    APTPackage(p) for p in self.cache
                    if (p.section == section and p.is_installed)
                ]
            return pl

    def get_fileindex(self):
        index = {}

        for p in self.cache:
            if p.is_installed:
                for f in p.installed_files:
                    index[f] = p.name

        return index

    def get_marked_install(self, section='all'):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache if p.marked_install]
        else:
            ret = [
                APTPackage(p) for p in self.cache
                if (p.section == section and p.marked_install)
            ]
        return ret

    def get_upgradeable(self, section='all'):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache if p.is_upgradable]
        else:
            ret = [
                APTPackage(p) for p in self.cache
                if (p.section == section and p.is_upgradable)
            ]
        return ret

    def upgrade(self, dist_upgrade=False):
        self.cache.upgrade(dist_upgrade)

    def get_changes(self):
        changes = self.cache.get_changes()
        return [APTPackage(p) for p in changes]

    def has_pkg(self, pkgname):
        return pkgname in self.cache

    def is_installed(self, pkgname):
        if not pkgname in self.cache:
            return False
        return self.cache[pkgname].is_installed

    def get_pkg(self, pkgname):
        return APTPackage(self.cache[pkgname])

    def get_pkgs(self, pkgname):
        return [
            APTPackage(self.cache[p]) for p in sorted(self.cache.keys())
            if pkgname in p.lower()
        ]

    def compare_versions(self, ver1, ver2):
        return version_compare(ver1, ver2)

    def download_binary(self, pkgname, path, version=None):
        p = self.cache[pkgname]
        if version is None:
            pkgver = p.installed
        else:
            pkgver = p.versions[version]

        rel_filename = pkgver.fetch_binary(path, ElbeAcquireProgress())
        return self.rfs.fname(rel_filename)

    def download_source(self, pkgname, path, version=None):
        p = self.cache[pkgname]
        if version is None:
            pkgver = p.installed
        else:
            pkgver = p.versions[version]

        rel_filename = pkgver.fetch_source(path,
                                           ElbeAcquireProgress(),
                                           unpack=False)
        return self.rfs.fname(rel_filename)
示例#5
0
class RPCAPTCache(InChRootObject):
    # pylint: disable=too-many-public-methods
    def __init__(
            self,
            rfs,
            log,
            arch,
            notifier=None,
            norecommend=False,
            noauth=True):

        # pylint: disable=too-many-arguments

        sys.stdout = open(log, 'a', buffering=0)
        sys.stderr = open(log, 'a', buffering=0)
        self.logfile = open(log, 'a', buffering=0)

        InChRootObject.__init__(self, rfs)

        self.notifier = notifier
        config.set("APT::Architecture", arch)
        if norecommend:
            config.set("APT::Install-Recommends", "0")
        else:
            config.set("APT::Install-Recommends", "1")

        if noauth:
            config.set("APT::Get::AllowUnauthenticated", "1")
        else:
            config.set("APT::Get::AllowUnauthenticated", "0")

        self.cache = Cache(progress=ElbeOpProgress())
        self.cache.open(progress=ElbeOpProgress())

    def dbg_dump(self, filename):
        ts = time.localtime()
        filename = filename + (
            '_%02d%02d%02d' % (ts.tm_hour, ts.tm_min, ts.tm_sec))
        with open(filename, 'w') as dbg:
            for p in self.cache:
                dbg.write(
                    '%s %s %d %d %d %d %d %d %d %d %d %d %d %d\n' %
                    (p.name,
                     p.candidate.version,
                     p.marked_keep,
                     p.marked_delete,
                     p.marked_upgrade,
                     p.marked_downgrade,
                     p.marked_install,
                     p.marked_reinstall,
                     p.is_auto_installed,
                     p.is_installed,
                     p.is_auto_removable,
                     p.is_now_broken,
                     p.is_inst_broken,
                     p.is_upgradable))

    def get_sections(self):
        ret = list(set([p.section for p in self.cache]))
        ret.sort()
        return ret

    def get_pkglist(self, section):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache]
        else:
            ret = [APTPackage(p) for p in self.cache if p.section == section]

        return ret

    def mark_install(self, pkgname, version, from_user=True, nodeps=False):
        p = self.cache[pkgname]
        if version:
            p.candidate = p.versions[version]
        p.mark_install(auto_fix=not nodeps,
                       auto_inst=not nodeps,
                       from_user=from_user)

    def mark_install_devpkgs(self, ignore_pkgs, ignore_dev_pkgs):
        ignore_pkgs.discard('libc6')  # we don't want to ignore libc
        ignore_pkgs.discard('libstdc++5')
        ignore_pkgs.discard('libstdc++6')
        # list all debian src packages of all installed packages that don't
        # come from debootstrap
        src_list = [
            p.candidate.source_name for p in self.cache if (
                p.is_installed and p.name not in ignore_pkgs)]
        # go through all packages, remember package if its source package
        # matches one of the installed packages and the binary package is a
        # '-dev' package
        dev_list = [
            s for s in self.cache if (
                s.candidate.source_name in src_list and (
                    s.name.endswith('-dev')))]
        for p in dev_list:
            if p.name not in ignore_dev_pkgs:
                p.mark_install()
        # ensure that the symlinks package will be installed (it's needed for
        # fixing links inside the sysroot
        self.cache['symlinks'].mark_install()

        for p in ignore_dev_pkgs:
            self.cache[p].mark_delete()

    def cleanup(self, exclude_pkgs):
        for p in self.cache:
            if p.is_installed and not \
               p.is_auto_installed or \
               p.is_auto_removable:
                remove = True
                for x in exclude_pkgs:
                    if x == p.name:
                        remove = False
                if remove:
                    p.mark_delete(auto_fix=True, purge=True)

    def mark_upgrade(self, pkgname, version):
        p = self.cache[pkgname]
        if version:
            p.candidate = p.versions[version]
        p.mark_upgrade()

    def mark_delete(self, pkgname):
        p = self.cache[pkgname]
        p.mark_delete(purge=True)

    def mark_keep(self, pkgname, version):
        p = self.cache[pkgname]
        p.mark_keep()

    def update(self):
        self.cache.update(fetch_progress=ElbeAcquireProgress())
        self.cache.open(progress=ElbeOpProgress())

    def commit(self):
        os.environ["DEBIAN_FRONTEND"] = "noninteractive"
        os.environ["DEBONF_NONINTERACTIVE_SEEN"] = "true"
        self.cache.commit(ElbeAcquireProgress(),
                          ElbeInstallProgress(fileno=self.logfile.fileno()))
        self.cache.open(progress=ElbeOpProgress())

    def clear(self):
        self.cache.clear()

    def get_dependencies(self, pkgname):
        deps = getalldeps(self.cache, pkgname)
        return [APTPackage(p, cache=self.cache) for p in deps]

    def get_installed_pkgs(self, section='all'):
        # avoid DeprecationWarning: MD5Hash is deprecated, use Hashes instead
        # triggerd by python-apt
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", category=DeprecationWarning)
            if section == 'all':
                pl = [APTPackage(p) for p in self.cache if p.is_installed]
            else:
                pl = [APTPackage(p) for p in self.cache if (
                    p.section == section and p.is_installed)]
            return pl

    def get_fileindex(self):
        index = {}

        for p in self.cache:
            if p.is_installed:
                for f in p.installed_files:
                    index[f] = p.name

        return index

    def get_marked_install(self, section='all'):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache if p.marked_install]
        else:
            ret = [APTPackage(p) for p in self.cache if (p.section == section
                                                         and p.marked_install)]
        return ret

    def get_upgradeable(self, section='all'):
        if section == 'all':
            ret = [APTPackage(p) for p in self.cache if p.is_upgradable]
        else:
            ret = [APTPackage(p) for p in self.cache if (p.section == section
                                                         and p.is_upgradable)]
        return ret

    def upgrade(self, dist_upgrade=False):
        self.cache.upgrade(dist_upgrade)

    def get_changes(self):
        changes = self.cache.get_changes()
        return [APTPackage(p) for p in changes]

    def has_pkg(self, pkgname):
        return pkgname in self.cache

    def is_installed(self, pkgname):
        if pkgname not in self.cache:
            return False
        return self.cache[pkgname].is_installed

    def get_pkg(self, pkgname):
        return APTPackage(self.cache[pkgname])

    def get_pkgs(self, pkgname):
        return [
            APTPackage(
                self.cache[p]) for p in sorted(
                self.cache.keys()) if pkgname in p.lower()]

    def compare_versions(self, ver1, ver2):
        return version_compare(ver1, ver2)

    def download_binary(self, pkgname, path, version=None):
        p = self.cache[pkgname]
        if version is None:
            pkgver = p.installed
        else:
            pkgver = p.versions[version]
        # avoid DeprecationWarning:
        # "MD5Hash is deprecated, use Hashes instead"
        # triggerd by python-apt
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore",
                                    category=DeprecationWarning)
            rel_filename = pkgver.fetch_binary(path,
                                               ElbeAcquireProgress())
            return self.rfs.fname(rel_filename)

    def download_source(self, pkgname, path, version=None):
        p = self.cache[pkgname]
        if version is None:
            pkgver = p.installed
        else:
            pkgver = p.versions[version]

        # avoid DeprecationWarning:
        # "MD5Hash is deprecated, use Hashes instead"
        # triggerd by python-apt
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore",
                                    category=DeprecationWarning)
            rel_filename = pkgver.fetch_source(path,
                                               ElbeAcquireProgress(),
                                               unpack=False)
            return self.rfs.fname(rel_filename)
示例#6
0
class QPackagesModel(QtCore.QAbstractTableModel):
    """
        Model used to handle the packages listed in a .ini file
    """
    def __init__(self, inifile):
        """
            :param inifile:
                Path to the packages.ini ini file
        """
        QtCore.QAbstractTableModel.__init__(self, None)
        self.packages = []
        self.to_install = []
        self.inifile = inifile
        self.cache = Cache()

        self._populate()

    def _populate(self):
        """
            Load the inifile with the package names and description
        """
        pkg_dict = DictIni(self.inifile)
        for section, packages in pkg_dict.items():
            for pkg_name, pkg_description in packages.iteritems():
                if self.cache.has_key(pkg_name):
                    pkg = self.cache[pkg_name]
                    if pkg.is_installed:
                        status = 2
                    else:
                        status = 0
                else:
                    pkg = None
                    status = 1
                    print("This package  : '%s:%s' isn't available in your \
configured repositories" % (pkg_name, pkg_description))
                self.packages.append(
                        {'name':pkg_name,
                         'description':pkg_description,
                         'package':pkg,
                         'status':status,
                         'section':section})

        self.packages = sorted(self.packages, key=lambda a:a['status'])
        self.reset()

    def _get_pkg(self, index):
        """
            Returns a pkg object for a given index
        """
        return self.packages[index.row()]['package']

    def _init_cache(self):
        """
            Initialize our cache for apt
        """
        self.cache = Cache()

    def rowCount(self, index=None):
        """
            Required function
            Returns the number of rows
        """
        return len(self.packages)

    def columnCount(self, index=None):
        """
            Required function
            Returns the number of columns
        """
        return len(TABLE_HEADER)

    def data(self, index, role):
        """
            Required function
            Returns the model's datas
        """
        if not index.isValid() or not (0 <= index.row() < self.rowCount()):
            return QtCore.QVariant()

        column = index.column()
        package = self.packages[index.row()]

        if role == QtCore.Qt.DisplayRole:
            return self.render_cell(package, column)
        elif role == QtCore.Qt.CheckStateRole:
            return self._cell_check_status(package['package'], column)
        elif role == QtCore.Qt.BackgroundColorRole:
            return self._cell_color(package['status'])


    @staticmethod
    def render_cell(package, column):
        """
            Return the column's cell content for the given package
        """
        if column == 0:
            return package['name']
        elif column == 1:
            return package['description'].decode('utf-8')
        elif column == 2:
            if not package['package']:
                return "Not Available"

    def _cell_check_status(self, pkg, column):
        """
            Returns the row's Qchecked status
        """
        if column == 2:
            if pkg and (pkg.installed or pkg.marked_install):
                return QtCore.QVariant(QtCore.Qt.Checked)
            else:
                return QtCore.QVariant(QtCore.Qt.Unchecked)

    @staticmethod
    def _cell_color(status):
        """
            Returns the cell color
        """
        if status == 2:
            return QtGui.QColor(255, 0, 0, 127)
        elif status == 1:
            return QtGui.QColor(255, 255, 0, 127)
        elif status == 0:
            return QtGui.QColor(255, 255, 255, 127)
        else:
            return QtGui.QColor(255, 127, 0, 200)

    def setData(self, index, value, role):
        """
            Changes datas informations
        """
        if role == QtCore.Qt.CheckStateRole and index.column() == 2:
            pkg = self._get_pkg(index)
            if not pkg.installed:
                if value == QtCore.QVariant(QtCore.Qt.Checked):
                    pkg.mark_install()
                    self.packages[index.row()]['status'] = -1
                    self.to_install.append(True)
                    self.emit(QtCore.SIGNAL("dataChanged(int)"),
                              len(self.to_install))
                else:
                    pkg.mark_delete()
                    self.packages[index.row()]['status'] = 0
                    self.to_install.pop()
                    self.emit(QtCore.SIGNAL("dataChanged(int)"),
                            len(self.to_install))
                ans = True
        else:
            ans = QtCore.QAbstractTableModel.setData(self, modelIndex, variant, role)
        return ans

    def flags(self, index):
        """
            Add a flag to indicate whether a field is editable/checkable ...
        """
        if not index.isValid():
            return QtCore.Qt.ItemIsEnabled

        pkg = self._get_pkg(index)
        ans = QtCore.QAbstractTableModel.flags(self, index)
        if pkg and not pkg.installed:
            if index.column() == 2:
                ans |= QtCore.Qt.ItemIsUserCheckable
                ans |= QtCore.Qt.ItemIsEditable
                ans |= QtCore.Qt.ItemIsSelectable
        else:
            ans &= ~QtCore.Qt.ItemIsEnabled
        return ans

    def headerData(self, section, orientation, role):
        """
            Native optionnal function
            Returns the table's header infos
            :orientation:
                QtCore.Qt:Orientation
            :role:
                QtCore.Qt:Role
        """
        # Alignement
        if role == QtCore.Qt.TextAlignmentRole:
            if orientation == QtCore.Qt.Horizontal:
                return QtCore.QVariant(int(QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter))
            return QtCore.QVariant(int(QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter))

        # Headers
        if role != QtCore.Qt.DisplayRole:
            return QtCore.QVariant()
        if orientation == QtCore.Qt.Horizontal:
            ret_val = TABLE_HEADER[section]
            return QtCore.QVariant(ret_val)
        else:
            return QtCore.QVariant(int(section + 1))

    #Cache update and file
    def update(self):
        """
            Update our apt cache and our packages list
        """
        acquire = QAcquireProgress()
        self._init_cache()

        print("Connecting slots")
        for sign in (QtCore.SIGNAL('statusChanged'), QtCore.SIGNAL('statusStarted()'),
                                            QtCore.SIGNAL('statusFinished()'),):
            self.connect(acquire, sign, self._reemit(sign))
        self.connect(acquire, QtCore.SIGNAL('statusFinished()'), self._update_datas)
        self.cache.update(acquire)

    def _update_datas(self):
        """
            Refresh the table's datas when a update has been called
        """
        self.cache = Cache()
        self.packages = []
        self.to_install = []
        self._populate()

    def install(self):
        """
            Install a list of packages
            @packages : a list of packages' names
        """
        acquire = QAcquireProgress()
        #FIXME : Il y a encore deux trois trucs qui vont pas
        install = QInstallProgress()
        print("Connecting slots")
        for sign in (QtCore.SIGNAL('statusChanged'), QtCore.SIGNAL('statusStarted()'),
                                            QtCore.SIGNAL('statusFinished()'),):
            self.connect(acquire, sign, self._reemit(sign))
            self.connect(install, sign, self._reemit(sign))
        self.connect(install, QtCore.SIGNAL('statusFinished()'),
                     self._update_datas)
        self.cache.commit(acquire, install)

    def _reemit(self, signal):
        """
            Returns a _reemit func for the given signal
        """
        em = self.emit
        def emitter(*args, **kw):
            em(signal, *args, **kw)
        return emitter
示例#7
0
class ZfsRequires (object):
    """
    Class manages installing additional packages

    TODO:
    - yum package handling
    - dnf package handling
    """

    packages_required = ["zfsutils-linux", "debootstrap", "gdisk", "zfs-initramfs"]
  
    def __init__(self):
        if not self.packages_required:
            return False
        self.os = (self.detect_os()).strip()
        if self.os == 'debian':
            self._package_cache = Cache()

    # [ EXECUTOR ]
    def load_runner(self, cmd):
        """
        Executes given command and returns errors if any
        :cmd: [list]
        :ret: [list]
        """
        cmd = ' '.join(cmd)
        cmd_out = Popen(cmd, shell=True, bufsize=1, stdout=PIPE, stderr=PIPE)

        ret = []
        for pipe in cmd_out.communicate():
            ret.append(pipe.decode('utf-8'))
        return ret


    def detect_os(self):
        """
        Detects OS family for correct package installation
        :returns: str
        """
        return self.load_runner(['cat /etc/os-release', '| grep ID_LIKE', '| awk -F \'=\' \'{print $2}\''])[0]

    def apt_update(self):
        """
        Updates apt package cahe
        :msg: Success or False if not needed
        """

        print(" [ Checking that requied packages are present ]")
        msg = []
        for this_package in self.packages_required:

            if not self._package_cache[this_package].is_installed:
                self._package_cache.update()
                msg.append('Package cache updated')
                msg.append(self.apt_install())
                break
            else:
                msg.append('Package '+this_package+' present')

        return msg

    def apt_install(self):
        """
        Installs packages from packages_required
        """
        res = []
        for this_package in self.packages_required:

            if not self._package_cache[this_package].is_installed:
                self._package_cache[this_package].mark_install()
                res.append(' '.join(['Package', this_package, 'marked for install.\n']))

        self._package_cache.commit()
        return ''.join(res)