def IsPackageInstalled(p): out = '' if p is None: return False, out if len(p.FilePath) > 0 and '://' in p.FilePath: # its a remote - try to file get name from cache if ReadCacheInfo(p) is False: return False, out elif len(p.FilePath) > 0 and os.path.exists(p.FilePath) is True: # FilePath if apt is not None and os.path.splitext(p.FilePath)[-1] == '.deb': from apt.debfile import DebPackage pkg = DebPackage(p.FilePath) p.Name = pkg.pkgname elif rpm is not None and os.path.splitext(p.FilePath)[-1] == '.rpm': with open(p.FilePath, 'r') as F: ts = rpm.TransactionSet() ts.setVSFlags(-1) try: pkg = ts.hdrFromFdno(F.fileno()) except rpm.error, e: print(repr(e)) LG().Log('ERROR', repr(e)) pkg = None if pkg is None: return False, out p.Name = pkg.dsOfHeader().N()
def WriteCacheInfo(p): if not os.path.isdir(cache_file_dir): if MakeDirs(cache_file_dir) is not None: return False if len(p.LocalPath) < 1: return False if apt is not None and os.path.splitext(p.LocalPath)[-1] == '.deb': from apt.debfile import DebPackage try: pkg = DebPackage(p.LocalPath) except: print("Exception opening file " + p.LocalPath, file=sys.stderr) LG().Log('ERROR', "Exception opening file " + p.LocalPath) return False p.Name = pkg.pkgname elif rpm is not None and os.path.splitext(p.LocalPath)[-1] == '.rpm': with opened_w_error(p.LocalPath, 'r') as (F, error): if error: print( "Exception opening file " + p.LocalPath, file=sys.stderr) LG().Log('ERROR', "Exception opening file " + p.LocalPath) return False ts = rpm.TransactionSet() ts.setVSFlags(-1) try: pkg = ts.hdrFromFdno(F.fileno()) except rpm.error, e: print(repr(e)) LG().Log('ERROR', repr(e)) pkg = None if pkg is None: return False p.Name = pkg.dsOfHeader().N()
class DebFile(): # the deb file which user selected debfile = '' path = '' name = '' version = '' installedsize = -1 description = '' def __init__(self, path): self.debfile = DebPackage(path) self.get_deb_info() self.path = path # check if the deb file is installable def is_installable(self): return self.debfile.check() # get missing dependencies def get_missing_deps(self): return self.debfile.missing_deps # get deb file name, version, installedsize, description def get_deb_info(self): self.name = self.debfile._sections["Package"] self.version = self.debfile._sections["Version"] self.installedsize = int(self.debfile._sections["Installed-Size"]) self.description = self.debfile._sections["Description"] # install the deb file def install_deb(self): self.debfile.install(AptProcess(self.debfile.pkgname))
def WriteCacheInfo(p): if not os.path.isdir(cache_file_dir): if MakeDirs(cache_file_dir) is not None: return False if len(p.LocalPath) < 1: return False if apt is not None and os.path.splitext(p.LocalPath)[-1] == '.deb': from apt.debfile import DebPackage try: pkg = DebPackage(p.LocalPath) except: Print("Exception opening file " + p.LocalPath, file=sys.stderr) LG().Log('ERROR', "Exception opening file " + p.LocalPath) return False p.Name = pkg.pkgname elif rpm is not None and os.path.splitext(p.LocalPath)[-1] == '.rpm': F, error = opened_w_error(p.LocalPath, 'r') if error: Print("Exception opening file " + p.LocalPath, file=sys.stderr) LG().Log('ERROR', "Exception opening file " + p.LocalPath) return False ts = rpm.TransactionSet() ts.setVSFlags(-1) try: pkg = ts.hdrFromFdno(F.fileno()) except rpm.error, e: Print(repr(e)) LG().Log('ERROR', repr(e)) pkg = None F.close() if pkg is None: return False p.Name = pkg.dsOfHeader().N()
def IsPackageInstalled(p): out = '' if p is None: return False, out if len( p.FilePath ) > 0 and '://' in p.FilePath: # its a remote - try to file get name from cache if ReadCacheInfo(p) is False: return False, out elif len(p.FilePath) > 0 and os.path.exists( p.FilePath) is True: # FilePath if apt is not None and os.path.splitext(p.FilePath)[-1] == '.deb': from apt.debfile import DebPackage pkg = DebPackage(p.FilePath) p.Name = pkg.pkgname elif rpm is not None and os.path.splitext(p.FilePath)[-1] == '.rpm': F = open(p.FilePath, 'r') ts = rpm.TransactionSet() ts.setVSFlags(-1) try: pkg = ts.hdrFromFdno(F.fileno()) except rpm.error, e: F.close() Print(repr(e)) LG().Log('ERROR', repr(e)) pkg = None F.close() if pkg is None: return False, out p.Name = pkg.dsOfHeader().N()
def _test(): """Test function""" import sys import apt from apt.debfile import DebPackage win = gtk.Window() apt_progress = GtkAptProgress() win.set_title("GtkAptProgress Demo") win.add(apt_progress) apt_progress.show() win.show() cache = apt.cache.Cache(apt_progress.open) pkg = cache["xterm"] if pkg.is_installed: pkg.mark_delete() else: pkg.mark_install() apt_progress.show_terminal(True) try: cache.commit(apt_progress.acquire, apt_progress.install) except Exception as exc: print >> sys.stderr, "Exception happened:", exc if len(sys.argv) > 1: deb = DebPackage(sys.argv[1], cache) deb.install(apt_progress.dpkg_install) win.connect("destroy", gtk.main_quit) gtk.main()
def install_debfile(self, path, kwargs=None): if not os.path.isfile(path): raise WorkitemError(4, "%s is unreadable file" % path) try: debfile = DebPackage(path) except IOError: raise WorkitemError(4, "%s is unreadable file" % path) except Exception as e: raise WorkitemError(5, e) self.cache.open() pkgName = debfile._sections["Package"] debfile.check( ) #do debfile.check for the next to do debfile.missing_deps if 0 == len(debfile.missing_deps): # try: res = debfile.install() if res: raise WorkitemError(6, "package manager failed") else: kwarg = { "apt_appname": pkgName, "apt_percent": str(200), "action": str(AppActions.INSTALLDEBFILE), } self.dbus_service.software_apt_signal("apt_finish", kwarg) if pkgName == "ubuntu-kylin-software-center" and AppActions.INSTALLDEBFILE == "upgrade": pass else: self.dbus_service.set_uksc_not_working() else: raise WorkitemError(6, "dependence not be satisfied")
def install_debfile(self, path, kwargs=None): debfile = DebPackage(path) pkgName = debfile._sections["Package"] try: debfile.install(AptProcess(self.dbus_service,pkgName,AppActions.INSTALLDEBFILE)) except Exception, e: print e print "install debfile err"
def build_debian_package(package_fetcher, package_name, apt_cache, rd_obj, levels=0, get_dependencies=False): unstable_target_distros = { 'groovy': 'quantal', 'hydro': 'raring' } target_ubuntu_distro = unstable_target_distros[rd_obj._rosdistro] level_prefix = '--' * levels print("%s> Building package %s" % (level_prefix, package_name)) deb_package_name = rd_obj.debianize_package_name(package_name) deb_package_version = rd_obj.get_version(package_name, full_version=True) + target_ubuntu_distro print("%s--> Checking if installed (%s, %s).." % (level_prefix, deb_package_name, deb_package_version)), if deb_package_name in apt_cache: installed = apt_cache[deb_package_name].installed if installed is not None and installed.version == deb_package_version: print("OK") print("%s is installed already - remove the package if you want to re-install." % (package_name)) return True print("missing!") if get_dependencies: dependencies = package_build_order([package_name], distro_name=rd_obj._rosdistro) print("%s--> Checking Dependencies:" % (level_prefix)) for dep_pkg_name in dependencies: if dep_pkg_name != package_name: print("%s---- %s....." % (level_prefix, dep_pkg_name)), debian_pkg_name = rd_obj.debianize_package_name(dep_pkg_name) if debian_pkg_name in apt_cache and apt_cache[debian_pkg_name].installed is not None: print(" OK! (installed version %s)" % apt_cache[debian_pkg_name].installed.version) else: print(" Needs build, building...") build_debian_package(package_fetcher, dep_pkg_name, apt_cache, rd_obj, levels + 1) print("%s<<-- Dependencies OKAY." % (level_prefix)) print("%s>>> Build debian package %s from repo %s" % (level_prefix, deb_package_name, package_fetcher.url(package_name))) repo_path = package_fetcher.checkout_package(package_name) client = GitClient(repo_path) deb_package_tag = deb_package_name + '_' + rd_obj.get_version(package_name, full_version=True) + '_' + target_ubuntu_distro bloom_package_version = 'debian/' + deb_package_tag client.update(bloom_package_version) installed_builddeps = install_debian_build_dependencies(repo_path) if not installed_builddeps: raise RosGitBuildError("%s!!! Error building %s from %s: Can't install build-dependencies!" % (level_prefix, deb_package_name, package_fetcher.url(package_name))) (returncode, result, message) = run_shell_command('debuild clean', repo_path, shell=True, show_stdout=False) if returncode != 0: raise RosGitBuildError("%s!!! Error building %s from %s: %s \n %s" % (level_prefix, deb_package_name, package_fetcher.url(package_name), 'debuild clean', message)) (returncode, result, message) = run_shell_command('debuild binary', repo_path, shell=True, show_stdout=False) if returncode != 0: raise RosGitBuildError("%s!!! Error building %s from %s: %s \n %s" % (level_prefix, deb_package_name, package_fetcher.url(package_name), 'debuild binary', message)) deb_files = glob.glob(os.path.join(repo_path, '..', '%s*.deb' % (deb_package_name + '_' + rd_obj.get_version(package_name, full_version=True)))) if len(deb_files) > 0: # install the deb from apt.debfile import DebPackage deb_pkg = DebPackage(deb_files[0]) deb_pkg.check() packages_needed = ' '.join(deb_pkg.missing_deps) (returncode, result, message) = run_shell_command('sudo apt-get -y install %s' % packages_needed, shell=True, show_stdout=True) if returncode != 0: raise RosGitBuildError("%s!!! Error building %s: can't install dependent packages %s" % (level_prefix, deb_package_name, packages_needed)) (returncode, result, message) = run_shell_command('sudo dpkg -i %s' % deb_files[0], shell=True, show_stdout=True) if returncode != 0: raise RosGitBuildError("%s!!! Error building %s from %s: %s \n %s" % (level_prefix, deb_package_name, package_fetcher.url(package_name), 'debuild binary', message)) else: raise RosGitBuildError("%s!!! Can't find a built debian package for %s after the build!" % (level_prefix, deb_package_name))
def IsPackageInstalled(p): out = '' if p is None: return False, out if len( p.FilePath ) > 0 and '://' in p.FilePath: # its a remote - try to file get name from cache if ReadCacheInfo(p) is False: return False, out elif len(p.FilePath) > 0 and os.path.exists( p.FilePath) is True: # FilePath if apt is not None and os.path.splitext(p.FilePath)[-1] == '.deb': from apt.debfile import DebPackage pkg = DebPackage(p.FilePath) p.Name = pkg.pkgname elif rpm is not None and os.path.splitext(p.FilePath)[-1] == '.rpm': with open(p.FilePath, 'r') as F: ts = rpm.TransactionSet() ts.setVSFlags(-1) try: pkg = ts.hdrFromFdno(F.fileno()) except rpm.error as e: print(repr(e)) LG().Log('ERROR', repr(e)) pkg = None if pkg is None: return False, out p.Name = pkg.dsOfHeader().N() if len(p.Name) < 1: return False, out if p.PackageGroup is True: if p.cmds[p.PackageManager]['stat_group'] is not None: cmd = p.cmds[p.PackageManager]['stat_group'] + '"' + p.Name + '"' else: print('ERROR. PackageGroup is not valid for ' + p.PackageManager, file=sys.stdout) LG().Log( 'ERROR', 'ERROR. PackageGroup is not valid for ' + p.PackageManager) return False, out else: cmd = 'LANG=en_US.UTF8 ' + p.cmds[p.PackageManager]['stat'] + p.Name code, out = RunGetOutput(cmd, False) if p.PackageGroup is True: # implemented for YUM only. if 'Installed' in out: return True, out else: return False, out # regular packages print('check installed:' + out) LG().Log('INFO', 'check installed:' + out) if code is 0: if 'deinstall' in out or 'not-installed' in out: code = 1 if code is not int(p.ReturnCode): return False, out return True, out
def __init__(self, db, doc=None, application=None): super(AppDetailsDebFile, self).__init__(db, doc, application) if doc: raise DebFileOpenError("AppDetailsDebFile: doc must be None.") self._error = None self._deb = None # check errors before creating the DebPackage if not os.path.exists(self._app.request): self._error = _("Not found") self._error_not_found = utf8( _(u"The file \u201c%s\u201d " "does not exist.")) % utf8(self._app.request) elif not is_deb_file(self._app.request): self._error = _("Not found") self._error_not_found = utf8( _(u"The file \u201c%s\u201d " "is not a software package.")) % utf8(self._app.request) if self._error is not None: return try: with ExecutionTime("create DebPackage"): # Cache() used to be faster here than self._cache._cache # but that is no longer the case with the latest apt self._deb = DebPackage(self._app.request, self._cache._cache) except: # deb files which are corrupt self._error = _("Internal Error") self._error_not_found = utf8( _(u"The file \u201c%s\u201d " "could not be opened.")) % utf8(self._app.request) return if self.pkgname and self.pkgname != self._app.pkgname: # this happens when the deb file has a quirky file name self._app.pkgname = self.pkgname # load pkg cache self._pkg = None if (self._app.pkgname in self._cache and self._cache[self._app.pkgname].candidate): self._pkg = self._cache[self._app.pkgname] # load xapian document self._doc = None try: self._doc = self._db.get_xapian_document( self._app.appname, self._app.pkgname) except: pass # check deb and set failure state on error with ExecutionTime("AppDetailsDebFile._deb.check()"): if not self._deb.check(): self._error = self._deb._failure_string.strip()
def deb_install(): try: deb = resource_get('deb') d = DebPackage(deb) d.install() set_state('elasticsearch.installed') except CalledProcessError: status_set('error', 'Elasticsearch could not be installed with package')
def IsPackageInstalled(p): out = '' if p is None: return False, out if len(p.FilePath) > 0 and '://' in p.FilePath: # its a remote - try to file get name from cache if ReadCacheInfo(p) is False: return False, out elif len(p.FilePath) > 0 and os.path.exists(p.FilePath) is True: # FilePath if apt is not None and os.path.splitext(p.FilePath)[-1] == '.deb': from apt.debfile import DebPackage pkg = DebPackage(p.FilePath) p.Name = pkg.pkgname elif rpm is not None and os.path.splitext(p.FilePath)[-1] == '.rpm': with open(p.FilePath, 'r') as F: ts = rpm.TransactionSet() ts.setVSFlags(-1) try: pkg = ts.hdrFromFdno(F.fileno()) except rpm.error as e: print(repr(e)) LG().Log('ERROR', repr(e)) pkg = None if pkg is None: return False, out p.Name = pkg.dsOfHeader().N() if len(p.Name) < 1: return False, out if p.PackageGroup is True: if p.cmds[p.PackageManager]['stat_group'] is not None: cmd = p.cmds[p.PackageManager]['stat_group'] + '"' + p.Name + '"' else: print('ERROR. PackageGroup is not valid for ' + p.PackageManager, file=sys.stdout) LG().Log( 'ERROR', 'ERROR. PackageGroup is not valid for ' + p.PackageManager) return False, out else: cmd = 'LANG=en_US.UTF8 ' + p.cmds[p.PackageManager]['stat'] + p.Name code, out = RunGetOutput(cmd, False) if p.PackageGroup is True: # implemented for YUM only. if 'Installed' in out: return True, out else: return False, out # regular packages print('check installed:' + out) LG().Log('INFO', 'check installed:' + out) if code is 0: if 'deinstall' in out or 'not-installed' in out: code = 1 if code is not int(p.ReturnCode): return False, out return True, out
def __init__(self, db, doc=None, application=None): super(AppDetailsDebFile, self).__init__(db, doc, application) if doc: raise ValueError("doc must be None for deb files") try: # for some reason Cache() is much faster than "self._cache._cache" # on startup with ExecutionTime("create DebPackage"): self._deb = DebPackage(self._app.request, Cache()) except: self._deb = None self._pkg = None if not os.path.exists(self._app.request): self._error = _("Not found") self._error_not_found = utf8( _(u"The file \u201c%s\u201d does not exist.")) % utf8( self._app.request) else: mimetype = guess_type(self._app.request) if mimetype[0] != "application/x-debian-package": self._error = _("Not found") self._error_not_found = utf8( _(u"The file \u201c%s\u201d is not a software package." )) % utf8(self._app.request) else: # deb files which are corrupt self._error = _("Internal Error") self._error_not_found = utf8( _(u"The file \u201c%s\u201d could not be opened.") ) % utf8(self._app.request) return if self.pkgname and self.pkgname != self._app.pkgname: # this happens when the deb file has a quirky file name self._app.pkgname = self.pkgname # load pkg cache self._pkg = None if (self._app.pkgname in self._cache and self._cache[self._app.pkgname].candidate): self._pkg = self._cache[self._app.pkgname] # load xapian document self._doc = None try: self._doc = self._db.get_xapian_document( self._app.appname, self._app.pkgname) except: pass # check deb and set failure state on error with ExecutionTime("AppDetailsDebFile._deb.check()"): if not self._deb.check(): self._error = self._deb._failure_string
class DebFile(): # the deb file which user selected debfile = '' path = '' name = '' version = '' installedsize = -1 description = '' def __init__(self, path): self.debfile = DebPackage(path) self.get_deb_info() self.path = path # check if the deb file is installable @property def is_installable(self): return self.debfile.check() # get missing dependencies def get_missing_deps(self): self.debfile.check() #do check for get missing_deps return self.debfile.missing_deps # get deb file name, version, installedsize, description def get_deb_info(self): try: self.name = self.debfile._sections["Package"] except: self.name = "" try: self.version = self.debfile._sections["Version"] except: self.version = "" try: self.installedsize = int( float(self.debfile._sections["Installed-Size"])) except: try: self.installedsize = int(float(self.debfile._sections["Size"])) except: self.installedsize = 0 try: self.description = self.debfile._sections["Description"] except: self.description = "" # install the deb file def install_deb(self): self.debfile.install(AptProcess(self.debfile.pkgname))
def install_debfile(self, path, sender=None): print("####install deb file: ", path) # path = "".join([chr(character) for character in path]) # add by zhangxin for chinese .deb path 11.19 granted = self.auth_with_policykit(sender, PACKAGES_MANAGER_TOOLS) if not granted: kwarg = { "appname": path, "action": AppActions.INSTALLDEBFILE, } self.software_auth_signal("auth_cancel", kwarg) return False else: kwarg = { "appname": path, "action": AppActions.INSTALLDEBFILE, } self.software_auth_signal("auth_ensure", kwarg) #print("send auth signal") if not os.path.isfile(path): raise WorkitemError(4, "%s is unreadable file" % path) try: debfile = DebPackage(path) except IOError: raise WorkitemError(4, "%s is unreadable file" % path) except Exception as e: raise WorkitemError(5, e) #self.cache.open() pkgName = debfile._sections["Package"] debfile.check( ) #do debfile.check for the next to do debfile.missing_deps if 0 == len(debfile.missing_deps): # try: res = debfile.install() if res: kwarg = { "apt_appname": pkgName, "apt_percent": str(-200), "action": str(AppActions.INSTALLDEBFILE), } self.software_apt_signal("apt_finish", kwarg) raise WorkitemError(6, "package manager failed") else: kwarg = { "apt_appname": pkgName, "apt_percent": str(200), "action": str(AppActions.INSTALLDEBFILE), } self.software_apt_signal("apt_finish", kwarg) else: raise WorkitemError(16, "dependence not be satisfied") return True
def main(package): cache = apt.Cache() debfile = DebPackage(package, cache=cache) if debfile.check(): show_dependencies(debfile) prompt = "Do you want to continue [Y/n]? " choice = input(prompt) if "y" == choice.lower() or not choice: try: cache.commit(apt.progress.text.AcquireProgress()) except apt.cache.FetchFailedException as e: print(e) else: print("Abort.")
def WriteCacheInfo(p): if not os.path.isdir(cache_file_dir): if MakeDirs(cache_file_dir) is not None: return False if len(p.LocalPath) < 1: return False if apt is not None and os.path.splitext(p.LocalPath)[-1] == '.deb': from apt.debfile import DebPackage try: pkg = DebPackage(p.LocalPath) except: print("Exception opening file " + p.LocalPath, file=sys.stderr) LG().Log('ERROR', "Exception opening file " + p.LocalPath) return False p.Name = pkg.pkgname elif rpm is not None and os.path.splitext(p.LocalPath)[-1] == '.rpm': with opened_w_error(p.LocalPath, 'r') as (F, error): if error: print("Exception opening file " + p.LocalPath, file=sys.stderr) LG().Log('ERROR', "Exception opening file " + p.LocalPath) return False ts = rpm.TransactionSet() ts.setVSFlags(-1) try: pkg = ts.hdrFromFdno(F.fileno()) except rpm.error as e: print(repr(e)) LG().Log('ERROR', repr(e)) pkg = None if pkg is None: return False p.Name = pkg.dsOfHeader().N() if len(p.Name) < 1: return False cache_file_path = cache_file_dir + '/' + os.path.basename(p.LocalPath) with opened_w_error(cache_file_path, 'w+') as (F, error): if error: print("Exception creating cache file " + cache_file_path + " Error Code: " + str(error.errno) + " Error: " + error.strerror, file=sys.stderr) LG().Log( 'ERROR', "Exception creating cache file " + cache_file_path + " Error Code: " + str(error.errno) + " Error: " + error.strerror) return False F.write(p.Name + '\n') F.close() return True
def install_deps(self, path, kwargs=None): debfile = DebPackage(path) pkgName = debfile._sections["Package"] debfile.check() deps = debfile.missing_deps if(len(deps) > 0): self.cache.open() for pkgn in deps: pkg = self.get_pkg_by_name(pkgn) pkg.mark_install() try: self.cache.commit(FetchProcess(self.dbus_service, pkgName, AppActions.INSTALLDEPS), AptProcess(self.dbus_service, pkgName, AppActions.INSTALLDEPS)) except Exception, e: print e print "install err"
def install_deps(self, path, kwargs=None): debfile = DebPackage(path) pkgName = debfile._sections["Package"] debfile.check() deps = debfile.missing_deps if(len(deps) > 0): self.cache.open() for pkgn in deps: pkg = self.get_pkg_by_name(pkgn) pkg.mark_install() try: self.cache.commit(FetchProcess(self.dbus_service, pkgName, AppActions.INSTALLDEPS), AptProcess(self.dbus_service, pkgName, AppActions.INSTALLDEPS)) except Exception as e: print(e) print("install err")
def WriteCacheInfo(p): if not os.path.isdir(cache_file_dir): if MakeDirs(cache_file_dir) is not None: return False if len(p.LocalPath) < 1: return False if apt is not None and os.path.splitext(p.LocalPath)[-1] == '.deb': from apt.debfile import DebPackage try: pkg = DebPackage(p.LocalPath) except: print("Exception opening file " + p.LocalPath, file=sys.stderr) LG().Log('ERROR', "Exception opening file " + p.LocalPath) return False p.Name = pkg.pkgname elif rpm is not None and os.path.splitext(p.LocalPath)[-1] == '.rpm': with opened_w_error(p.LocalPath, 'r') as (F, error): if error: print("Exception opening file " + p.LocalPath, file=sys.stderr) LG().Log('ERROR', "Exception opening file " + p.LocalPath) return False ts = rpm.TransactionSet() ts.setVSFlags(-1) try: pkg = ts.hdrFromFdno(F.fileno()) except rpm.error as e: print(repr(e)) LG().Log('ERROR', repr(e)) pkg = None if pkg is None: return False p.Name = pkg.dsOfHeader().N() if len(p.Name) < 1: return False cache_file_path = cache_file_dir + '/' + os.path.basename(p.LocalPath) with opened_w_error(cache_file_path, 'w+') as (F, error): if error: print("Exception creating cache file " + cache_file_path + " Error Code: " + str(error.errno) + " Error: " + error.strerror, file=sys.stderr) LG().Log('ERROR', "Exception creating cache file " + cache_file_path + " Error Code: " + str(error.errno) + " Error: " + error.strerror) return False F.write(p.Name + '\n') F.close() return True
def installdeb(self, pkg): """ Install the Debian package. :param pkg: The path to the package to install :type pkg: str """ # Get the DebPackage object and the filename dpkg = DebPackage(filename=pkg, cache=self.cache) pkg_name = basename(pkg) # Look for package conflicts if not dpkg.check_conflicts(): self.feedback.block(dpkg.conflicts, 'CONFLICT') self.feedback.error('Cannot install package <{0}>, conflicts with:'.format(pkg_name)) return False # Get any version in cache cache_version = dpkg.compare_to_version_in_cache() action = 'Installed' # Not installed if cache_version == dpkg.VERSION_NONE: self.feedback.info('Package <{0}> not installed'.format(pkg_name)) # Upgrading if cache_version == dpkg.VERSION_OUTDATED: self.feedback.info('Package <{0}> outdated, upgrading'.format(pkg_name)) action = 'Updated' # Same version if cache_version == dpkg.VERSION_SAME: return self.feedback.info('Package <{0}> already installed'.format(pkg_name)) # Installed is newer if cache_version == dpkg.VERSION_NEWER: return self.feedback.info('Package <{0}> has newer version installed'.format(pkg_name)) # Install the package dpkg.install() self.feedback.success('{0}: {1}'.format(action, pkg_name))
def __init__(self, db, doc=None, application=None): super(AppDetailsDebFile, self).__init__(db, doc, application) if doc: raise DebFileOpenError("AppDetailsDebFile: doc must be None.") self._error = None self._deb = None # check errors before creating the DebPackage if not os.path.exists(self._app.request): self._error = _("Not found") self._error_not_found = utf8(_(u"The file \u201c%s\u201d " "does not exist.")) % utf8(self._app.request) elif not is_deb_file(self._app.request): self._error = _("Not found") self._error_not_found = utf8(_(u"The file \u201c%s\u201d " "is not a software package.")) % utf8(self._app.request) if self._error is not None: return try: with ExecutionTime("create DebPackage"): # Cache() used to be faster here than self._cache._cache # but that is no longer the case with the latest apt self._deb = DebPackage(self._app.request, self._cache._cache) except: # deb files which are corrupt self._error = _("Internal Error") self._error_not_found = utf8(_(u"The file \u201c%s\u201d " "could not be opened.")) % utf8(self._app.request) return if self.pkgname and self.pkgname != self._app.pkgname: # this happens when the deb file has a quirky file name self._app.pkgname = self.pkgname # load pkg cache self._pkg = None if (self._app.pkgname in self._cache and self._cache[self._app.pkgname].candidate): self._pkg = self._cache[self._app.pkgname] # load xapian document self._doc = None try: self._doc = self._db.get_xapian_document( self._app.appname, self._app.pkgname) except: pass # check deb and set failure state on error with ExecutionTime("AppDetailsDebFile._deb.check()"): if not self._deb.check(): self._error = self._deb._failure_string.strip()
def __init__(self, db, doc=None, application=None): super(AppDetailsDebFile, self).__init__(db, doc, application) if doc: raise ValueError("doc must be None for deb files") try: # for some reason Cache() is much faster than "self._cache._cache" # on startup with ExecutionTime("create DebPackage"): self._deb = DebPackage(self._app.request, Cache()) except: self._deb = None self._pkg = None if not os.path.exists(self._app.request): self._error = _("Not found") self._error_not_found = utf8(_(u"The file \u201c%s\u201d does not exist.")) % utf8(self._app.request) else: mimetype = guess_type(self._app.request) if mimetype[0] != "application/x-debian-package": self._error = _("Not found") self._error_not_found = utf8(_(u"The file \u201c%s\u201d is not a software package.")) % utf8(self._app.request) else: # deb files which are corrupt self._error = _("Internal Error") self._error_not_found = utf8(_(u"The file \u201c%s\u201d could not be opened.")) % utf8(self._app.request) return if self.pkgname and self.pkgname != self._app.pkgname: # this happens when the deb file has a quirky file name self._app.pkgname = self.pkgname # load pkg cache self._pkg = None if (self._app.pkgname in self._cache and self._cache[self._app.pkgname].candidate): self._pkg = self._cache[self._app.pkgname] # load xapian document self._doc = None try: self._doc = self._db.get_xapian_document( self._app.appname, self._app.pkgname) except: pass # check deb and set failure state on error with ExecutionTime("AppDetailsDebFile._deb.check()"): if not self._deb.check(): self._error = self._deb._failure_string
def UnpackAndInstall(): # Detect OS linuxDistro = platform.linux_distribution() OSType = linuxDistro[0] # check which OS if OSType == 'Ubuntu': from apt.debfile import DebPackage pkg = DebPackage(outputName) command = 'sudo dpkg -i ' + outputName #The thing that attempts to unpack: try: subprocess.check_call(command, shell=True) except subprocess.CalledProcessError: print(col.LT_RED + "Install Failed." + col.NC) """
def run(self): exec_word = None self.desktop_path = "/usr/share/applications/" + self.pkgname + ".desktop" # print("desktop_path:%s" % self.desktop_path) #判断是否存在同名的desktop文件 if os.path.exists(self.desktop_path): setting = QSettings(self.desktop_path, QSettings.IniFormat) setting.beginGroup("Desktop Entry") exec_word = str(setting.value("Exec")).split(" ")[0].split("%")[0] #不存在同名的desktop文件则进行deb包解析 else: self.debfile = DebPackage(LOCAL_DEB_FILE) for desktop in self.debfile.filelist: if desktop.endswith(".desktop"): self.desktop = desktop setting = QSettings("/" + self.desktop, QSettings.IniFormat) setting.beginGroup("Desktop Entry") exec_word = str(setting.value("Exec")).split(" ")[0].split("%")[0] self.parse_over.emit(exec_word)
def installdeb(self, pkg): """ Install the Debian package. :param pkg: The path to the package to install :type pkg: str """ # Get the DebPackage object and the filename dpkg = DebPackage(filename=pkg, cache=self.cache) pkg_name = basename(pkg) # Look for package conflicts if not dpkg.check_conflicts(): self.feedback.block(dpkg.conflicts, 'CONFLICT') self.feedback.error( 'Cannot install package <{0}>, conflicts with:'.format( pkg_name)) return False # Get any version in cache cache_version = dpkg.compare_to_version_in_cache() action = 'Installed' # Not installed if cache_version == dpkg.VERSION_NONE: self.feedback.info('Package <{0}> not installed'.format(pkg_name)) # Upgrading if cache_version == dpkg.VERSION_OUTDATED: return self.feedback.info( 'Package <{0}> has newer version installed'.format(pkg_name)) # Same version if cache_version == dpkg.VERSION_SAME: return self.feedback.info( 'Package <{0}> already installed'.format(pkg_name)) # Installed is newer if cache_version == dpkg.VERSION_NEWER: self.feedback.info( 'Package <{0}> outdated, upgrading'.format(pkg_name)) action = 'Updated' # Install the package dpkg.install() self.feedback.success('{0}: {1}'.format(action, pkg_name))
def get_builtin(): """ Get the full package name of emacs-el in unstable, download it and get names of built-in packages. Output: list of strings """ emacs_page = urllib.request.urlopen( 'https://packages.debian.org/sid/all/emacs-el/download').read().decode( ) emacs_pkgname = re.findall(r'(emacs-el_.+_all.deb)', emacs_page)[0] url = 'http://ftp.us.debian.org/debian/pool/main/e/emacs/' + emacs_pkgname print(f'Downloading {emacs_pkgname}...') with urllib.request.urlopen(url) as response, open(emacs_pkgname, 'wb') as out_file: data = response.read() out_file.write(data) emacs_package = DebPackage(emacs_pkgname) builtins = [] for pkg in emacs_package.filelist: if '.el' in pkg: builtin = pkg.split('/')[-1] builtins.append(builtin.split('.')[0]) return builtins
class AppDetailsDebFile(AppDetails): def __init__(self, db, doc=None, application=None): super(AppDetailsDebFile, self).__init__(db, doc, application) if doc: raise ValueError("doc must be None for deb files") try: with ExecutionTime("create DebPackage"): # Cache() used to be faster here than self._cache._cache # but that is no longer the case with the latest apt self._deb = DebPackage(self._app.request, self._cache._cache) except: self._deb = None self._pkg = None if not os.path.exists(self._app.request): self._error = _("Not found") self._error_not_found = utf8( _(u"The file \u201c%s\u201d " "does not exist.")) % utf8(self._app.request) else: mimetype = guess_type(self._app.request) if mimetype[0] != "application/x-debian-package": self._error = _("Not found") self._error_not_found = utf8( _(u"The file \u201c%s\u201d " "is not a software package.")) % utf8( self._app.request) else: # deb files which are corrupt self._error = _("Internal Error") self._error_not_found = utf8( _(u"The file \u201c%s\u201d " "could not be opened.")) % utf8(self._app.request) return if self.pkgname and self.pkgname != self._app.pkgname: # this happens when the deb file has a quirky file name self._app.pkgname = self.pkgname # load pkg cache self._pkg = None if (self._app.pkgname in self._cache and self._cache[self._app.pkgname].candidate): self._pkg = self._cache[self._app.pkgname] # load xapian document self._doc = None try: self._doc = self._db.get_xapian_document( self._app.appname, self._app.pkgname) except: pass # check deb and set failure state on error with ExecutionTime("AppDetailsDebFile._deb.check()"): if not self._deb.check(): self._error = self._deb._failure_string.strip() @property def description(self): if self._deb: description = self._deb._sections["Description"] s = ('\n').join(description.split('\n')[1:]).replace(" .\n", "") return utf8(s) return "" @property def maintenance_status(self): pass @property def pkgname(self): if self._deb: return self._deb._sections["Package"] @property def pkg_state(self): if self._error: if self._error_not_found: return PkgStates.NOT_FOUND else: return PkgStates.ERROR if self._deb: deb_state = self._deb.compare_to_version_in_cache() if deb_state == DebPackage.VERSION_NONE: return PkgStates.UNINSTALLED elif deb_state == DebPackage.VERSION_OUTDATED: if self._cache[self.pkgname].installed: return PkgStates.INSTALLED else: return PkgStates.UNINSTALLED elif deb_state == DebPackage.VERSION_SAME: return PkgStates.REINSTALLABLE elif deb_state == DebPackage.VERSION_NEWER: if self._cache[self.pkgname].installed: return PkgStates.UPGRADABLE else: return PkgStates.UNINSTALLED @property def summary(self): if self._deb: description = self._deb._sections["Description"] # ensure its utf8(), see #738771 return utf8(description.split('\n')[0]) @property def display_summary(self): if self._doc: name = self._db.get_appname(self._doc) if name: return self.summary else: # by spec.. return self._db.get_pkgname(self._doc) return self.summary @property def version(self): if self._deb: return self._deb._sections["Version"] @property def installed_size(self): installed_size = 0 if self._deb: try: installed_size = long(self._deb._sections["Installed-Size"]) except: pass return installed_size * 1024 @property def warning(self): # FIXME: use more concise warnings if self._deb: deb_state = self._deb.compare_to_version_in_cache( use_installed=False) if deb_state == DebPackage.VERSION_NONE: return utf8( _("Only install this file if you trust the origin.")) elif (not self._cache[self.pkgname].installed and self._cache[self.pkgname].candidate and self._cache[self.pkgname].candidate.downloadable): if deb_state == DebPackage.VERSION_OUTDATED: return utf8( _("Please install \"%s\" via your normal " "software channels. Only install this file if you " "trust the origin.")) % utf8(self.name) elif deb_state == DebPackage.VERSION_SAME: return utf8( _("Please install \"%s\" via your normal " "software channels. Only install this file if you " "trust the origin.")) % utf8(self.name) elif deb_state == DebPackage.VERSION_NEWER: return utf8( _("An older version of \"%s\" is available in " "your normal software channels. Only install this " "file if you trust the origin.")) % utf8(self.name) @property def website(self): if self._deb: website = None try: website = self._deb._sections["Homepage"] except: pass if website: return website
def install_debfile(self, path, sender=None): # print("####install deb file: ", path) # 开启密码认证机制 granted = self.auth_with_policykit(sender, PACKAGES_MANAGER_TOOLS) if not granted: kwarg = { "appname": path, "action": AppActions.INSTALLDEBFILE, } self.software_auth_signal("auth_cancel", kwarg) return False else: kwarg = { "appname": path, "action": AppActions.INSTALLDEBFILE, } self.software_auth_signal("auth_ensure", kwarg) #print("send auth signal") if not os.path.isfile(path): raise WorkitemError(4, "%s is unreadable file" % path) try: debfile = DebPackage(path) except IOError: raise WorkitemError(4, "%s is unreadable file" % path) except Exception as e: raise WorkitemError(5, e) #self.cache.open() #获取软件包名 pkgName = debfile._sections["Package"] debfile.check( ) #do debfile.check for the next to do debfile.missing_deps # print("len:%s" % len(debfile.missing_deps)) # 安装源中存在的依赖包 if len(debfile.missing_deps) != 0: for deb in debfile.missing_deps: pkg = self.get_pkg_by_name(deb) # print("lj.pkg:%s" %pkg) pkg.mark_install() try: self.cache.commit( FetchProcess(self, deb, AppActions.INSTALL_ONE), None) except apt.cache.LockFailedException: raise WorkitemError(3, "package manager is running.") #安装软件包 res = debfile.install() if res: kwarg = { "apt_appname": pkgName, "apt_percent": str(-200), "action": str(AppActions.INSTALLDEBFILE), } self.software_apt_signal("apt_finish", kwarg) raise WorkitemError(6, "package manager failed") else: kwarg = { "apt_appname": pkgName, "apt_percent": str(200), "action": str(AppActions.INSTALLDEBFILE), } self.software_apt_signal("apt_finish", kwarg) # else: # kwarg = {"apt_appname": pkgName, # "apt_percent": str(-200), # "action": str(AppActions.INSTALLDEBFILE), # } # self.software_apt_signal("apt_error", kwarg) # raise WorkitemError(16, "dependence not be satisfied") return True
from apt.debfile import DebPackage win = gtk.Window() apt_progress = GtkAptProgress() win.set_title("GtkAptProgress Demo") win.add(apt_progress) apt_progress.show() win.show() cache = apt.cache.Cache(apt_progress.open) pkg = cache["xterm"] if pkg.is_installed: pkg.mark_delete() else: pkg.mark_install() apt_progress.show_terminal(True) try: cache.commit(apt_progress.acquire, apt_progress.install) except Exception, exc: print >> sys.stderr, "Exception happened:", exc if len(sys.argv) > 1: deb = DebPackage(sys.argv[1], cache) deb.install(apt_progress.dpkg_install) win.connect("destroy", gtk.main_quit) gtk.main() if __name__ == "__main__": _test() # vim: ts=4 et sts=4
def build_debian_package(package_fetcher, package_name, apt_cache, rd_obj, levels=0, get_dependencies=False): unstable_target_distros = {'groovy': 'quantal', 'hydro': 'raring'} target_ubuntu_distro = unstable_target_distros[rd_obj._rosdistro] level_prefix = '--' * levels print("%s> Building package %s" % (level_prefix, package_name)) deb_package_name = rd_obj.debianize_package_name(package_name) deb_package_version = rd_obj.get_version( package_name, full_version=True) + target_ubuntu_distro print("%s--> Checking if installed (%s, %s).." % (level_prefix, deb_package_name, deb_package_version)), if deb_package_name in apt_cache: installed = apt_cache[deb_package_name].installed if installed is not None and installed.version == deb_package_version: print("OK") print( "%s is installed already - remove the package if you want to re-install." % (package_name)) return True print("missing!") if get_dependencies: dependencies = package_build_order([package_name], distro_name=rd_obj._rosdistro) print("%s--> Checking Dependencies:" % (level_prefix)) for dep_pkg_name in dependencies: if dep_pkg_name != package_name: print("%s---- %s....." % (level_prefix, dep_pkg_name)), debian_pkg_name = rd_obj.debianize_package_name(dep_pkg_name) if debian_pkg_name in apt_cache and apt_cache[ debian_pkg_name].installed is not None: print(" OK! (installed version %s)" % apt_cache[debian_pkg_name].installed.version) else: print(" Needs build, building...") build_debian_package(package_fetcher, dep_pkg_name, apt_cache, rd_obj, levels + 1) print("%s<<-- Dependencies OKAY." % (level_prefix)) print("%s>>> Build debian package %s from repo %s" % (level_prefix, deb_package_name, package_fetcher.url(package_name))) repo_path = package_fetcher.checkout_package(package_name) client = GitClient(repo_path) deb_package_tag = deb_package_name + '_' + rd_obj.get_version( package_name, full_version=True) + '_' + target_ubuntu_distro bloom_package_version = 'debian/' + deb_package_tag client.update(bloom_package_version) installed_builddeps = install_debian_build_dependencies(repo_path) if not installed_builddeps: raise RosGitBuildError( "%s!!! Error building %s from %s: Can't install build-dependencies!" % (level_prefix, deb_package_name, package_fetcher.url(package_name))) (returncode, result, message) = run_shell_command('debuild clean', repo_path, shell=True, show_stdout=False) if returncode != 0: raise RosGitBuildError( "%s!!! Error building %s from %s: %s \n %s" % (level_prefix, deb_package_name, package_fetcher.url(package_name), 'debuild clean', message)) (returncode, result, message) = run_shell_command('debuild binary', repo_path, shell=True, show_stdout=False) if returncode != 0: raise RosGitBuildError( "%s!!! Error building %s from %s: %s \n %s" % (level_prefix, deb_package_name, package_fetcher.url(package_name), 'debuild binary', message)) deb_files = glob.glob( os.path.join( repo_path, '..', '%s*.deb' % (deb_package_name + '_' + rd_obj.get_version(package_name, full_version=True)))) if len(deb_files) > 0: # install the deb from apt.debfile import DebPackage deb_pkg = DebPackage(deb_files[0]) deb_pkg.check() packages_needed = ' '.join(deb_pkg.missing_deps) (returncode, result, message) = run_shell_command( 'sudo apt-get -y install %s' % packages_needed, shell=True, show_stdout=True) if returncode != 0: raise RosGitBuildError( "%s!!! Error building %s: can't install dependent packages %s" % (level_prefix, deb_package_name, packages_needed)) (returncode, result, message) = run_shell_command('sudo dpkg -i %s' % deb_files[0], shell=True, show_stdout=True) if returncode != 0: raise RosGitBuildError( "%s!!! Error building %s from %s: %s \n %s" % (level_prefix, deb_package_name, package_fetcher.url(package_name), 'debuild binary', message)) else: raise RosGitBuildError( "%s!!! Can't find a built debian package for %s after the build!" % (level_prefix, deb_package_name))
def __init__(self, path): self.debfile = DebPackage(path) self.get_deb_info() self.path = path
def deb_install(): deb = resource_get('deb') d = DebPackage(deb) d.install() set_state('elasticsearch.installed')
def __init__(self, deb_file): AbstractPackageFile.__init__(self, deb_file) self.package = DebPackage(deb_file, CACHE) self.package.check()
elif(argn > 1): arg = sys.argv[1] if(arg == '-quiet'): LAUNCH_MODE = 'quiet' elif(arg == '-remove'): if(sys.argv[2]): LAUNCH_MODE = 'remove' REMOVE_SOFT = sys.argv[2] else: sys.exit(0) else: LAUNCH_MODE = 'manual' if(check_local_deb_file(arg)): LOCAL_DEB_FILE = arg try: DebPackage(str(LOCAL_DEB_FILE)) except: MessageBox = File_window() MessageBox.setText(_("Failed to open the file. The file format is not supported or the file is abnormal")) MessageBox.exec() sys.exit(0) else: sys.exit(0) ex = Example() ex.show() signal.signal(signal.SIGINT, lambda : close_filelock()) signal.signal(signal.SIGTERM, lambda : close_filelock()) signal.signal(signal.SIGINT, quit) signal.signal(signal.SIGTERM, quit) sys.exit(app.exec_())
def get_changelog(self, pkg_name:str, no_local:bool=False): self.refresh_cache() self.candidate = self.parse_package_metadata(pkg_name) # parse the package's origin if not self.candidate.downloadable: origin = "local_package" elif self.candidate.origin == "linuxmint": origin = "linuxmint" elif self.candidate.origin.startswith("LP-PPA-"): origin = "LP-PPA" elif self.apt_origins and self.candidate.origin in self.apt_origins.list(): origin = "APT" else: origin = "unsupported" # Check for changelog of installed package first has_local_changelog = False uri = None if not no_local and self.candidate.is_installed: if _DEBUG: print("Package is installed...") uri = self.get_changelog_from_filelist( self.candidate.installed_files, local=True) # Ubuntu kernel workarounds if self.candidate.origin == "Ubuntu": if self.candidate.source_name == "linux-signed": uri = uri.replace("linux-image","linux-modules") if self.candidate.source_name == "linux-meta": uri = None if uri and not os.path.isfile(uri): uri = None # Do nothing if local changelog exists if uri: has_local_changelog = True # all origins that APT supports elif origin == 'APT': uri = self.get_apt_changelog_uri( self.apt_origins.get(self.candidate.origin)) r = self.check_url(uri) if not r: self.exit_on_fail(2) # Linux Mint repo elif origin == 'linuxmint': # Mint repos don't have .debian.tar.xz files, only full packages, so # check the package cache first base_uri, _ = os.path.split(self.candidate.uri) r, uri = self.get_changelog_uri(base_uri) if not r: # fall back to last change info for the source package # Mint's naming scheme seems to be using amd64 unless source # is i386 only, we always check amd64 first base_uri = "http://packages.linuxmint.com/dev/%s_%s_%s.changes" uri = base_uri % (self.candidate.source_name, self.candidate.source_version, "amd64") r = self.check_url(uri, False) if not r: uri = base_uri % (self.candidate.source_name, self.candidate.source_version, "i386") r = self.check_url(uri, False) if not r: self.exit_on_fail(3) # Launchpad PPA elif origin == 'LP-PPA': ppa_owner, ppa_name, _ = \ self.candidate.uri.split("ppa.launchpad.net/")[1].split("/", 2) base_uri = "http://ppa.launchpad.net/%s/%s/ubuntu/pool/main/{self.source_prefix()}/%s" % (ppa_owner, ppa_name, self.candidate.source_name) r, uri = self.get_changelog_uri(base_uri) if not r: # fall back to last change info only uri = "https://launchpad.net/~%s/+archive/ubuntu/%s/+files/%s_%s_source.changes" % (ppa_owner, ppa_name, self.candidate.source_name, self.candidate.source_version) r = self.check_url(uri, False) if not r: self.exit_on_fail(4) # Not supported origin elif origin == 'unsupported': if _DEBUG: print("Unsupported Package") base_uri, _ = os.path.split(self.candidate.uri) r, uri = self.get_changelog_uri(base_uri) if not r: self.exit_on_fail(5) # Locally installed package without local changelog or remote # source, hope it's cached and contains a changelog elif origin == 'local_package': uri = self.apt_cache_path + self.candidate.filename if not os.path.isfile(uri): self.exit_on_fail(6) # Changelog downloading, extracting and processing: changelog = "" # local changelog if has_local_changelog and not no_local: if _DEBUG: print("Using local changelog:",uri) try: filename = os.path.basename(uri) # determine file type by name/extension # as per debian policy 4.4 the encoding must be UTF-8 # as per policy 12.7 the name must be changelog.Debian.gz or # changelog.gz (deprecated) if filename.lower().endswith('.gz'): changelog = gzip.open(uri,'r').read().decode('utf-8') elif filename.lower().endswith('.xz'): # just in case / future proofing changelog = lzma.open(uri,'r').read().decode('utf-8') elif filename.lower() == 'changelog': changelog = open(uri, 'r').read().encode().decode('utf-8') else: raise ValueError('Unknown changelog format') except Exception as e: _generic_exception_handler(e) self.exit_on_fail(1) # APT-format changelog, download directly # - unfortunately this is slow since the servers support no compression elif origin == "APT": if _DEBUG: print("Downloading: %s (%.2f MB)" % (uri, r.length / self.MB)) changelog = r.text r.close() # last change changelog, download directly elif uri.endswith('.changes'): if _DEBUG: print("Downloading: %s (%.2f MB)" % (uri, r.length / self.MB)) changes = r.text.split("Changes:")[1].split("Checksums")[0].split("\n") r.close() for change in changes: change = change.strip() if change: if change == ".": change = "" changelog += change + "\n" # compressed binary source, download and extract changelog else: source_is_cache = uri.startswith(self.apt_cache_path) if _DEBUG: print("Using cached package:" if source_is_cache else "Downloading: %s (%.2f MB)" % (uri, r.length / self.MB)) try: if not source_is_cache: # download stream to temporary file tmpFile = tempfile.NamedTemporaryFile(prefix="apt-changelog-") if self.interactive and r.length: # download chunks with progress indicator recv_length = 0 blocks = 60 for data in r.iter_content(chunk_size=16384): recv_length += len(data) tmpFile.write(data) recv_pct = recv_length / r.length recv_blocks = int(blocks * recv_pct) print("\r[%(progress)s%(spacer)s] %(percentage).1f%%" % { "progress": "=" * recv_blocks, "spacer": " " * (blocks - recv_blocks), "percentage": recv_pct * 100 }, end="", flush=True) # clear progress bar when done print("\r" + " " * (blocks + 10), end="\r", flush=True) else: # no content-length or non-interactive, download in one go # up to the configured max_download_size, ask only when # exceeded r.raw.decode_content = True size = 0 size_exceeded = False while True: buf = r.raw.read(16*1024) if not size_exceeded: size += len(buf) if size > self.max_download_size: if not self.user_confirm(self.max_download_size_msg_unknown): r.close() tmpFile.close() return "" else: size_exceeded = True if not buf: break tmpFile.write(buf) r.close() tmpFile.seek(0) if uri.endswith(".deb"): # process .deb file if source_is_cache: f = uri else: f = tmpFile.name # We could copy the downloaded .deb files to the apt # cache here but then we'd need to run the script elevated: # shutil.copy(f, self.apt_cache_path + os.path.basename(uri)) deb = DebPackage(f) changelog_file = self.get_changelog_from_filelist(deb.filelist) if changelog_file: changelog = deb.data_content(changelog_file) if changelog.startswith('Automatically decompressed:'): changelog = changelog[29:] else: raise ValueError('Malformed Debian package') elif uri.endswith(".diff.gz"): # Ubuntu partner repo has .diff.gz files, # we can extract a changelog from that data = gzip.open(tmpFile.name, "r").read().decode('utf-8') additions = data.split("+++") for addition in additions: lines = addition.split("\n") if "/debian/changelog" in lines[0]: for line in lines[2:]: if line.startswith("+"): changelog += "%s\n" % line[1:] else: break if not changelog: raise ValueError('No changelog in .diff.gz') else: # process .tar.xz file with tarfile.open(fileobj=tmpFile, mode="r:xz") as tar: changelog_file = self.get_changelog_from_filelist( [s.name for s in tar.getmembers() if s.type in (b"0", b"2")]) if changelog_file: changelog = tar.extractfile(changelog_file).read().decode() else: raise ValueError('No changelog in source package') except Exception as e: _generic_exception_handler(e) self.exit_on_fail(520) if 'tmpFile' in vars(): try: tmpFile.close() except Exception as e: _generic_exception_handler(e) # ALL DONE return changelog
class DebFile(AbstractPackageFile): def __init__(self, deb_file): AbstractPackageFile.__init__(self, deb_file) self.package = DebPackage(deb_file, CACHE) self.package.check() def is_source(self): try: self.package['Source'] except KeyError as exception: if self.arch == 'source': return True else: return False return True @property def requires(self): return self.package.depends @property def arch(self): return self.package['Architecture'] @property def name(self): return self.package.pkgname @property def license(self): try: return self.package['License'] except KeyError as _: pass @property def conflicts(self): return self.package.conflicts @property def version(self): return self.package['Version'] @property def summary(self): return self.description @property def upgradable(self): return super(DebFile, self).upgradable() @property def provides(self): return self.package.provides @property def platform(self): return None @property def description(self): return self.package['Description'] @property def installed(self): return self.package.compare_to_version_in_cache() \ != DebPackage.VERSION_NONE @property def release(self): try: return self.package['Distribution'] except KeyError as _: return 'unstable'
def get_changelog(self, pkg_name:str, no_local:bool=False): self.refresh_cache() self.candidate = self.parse_package_metadata(pkg_name) # parse the package's origin if not self.candidate.downloadable: origin = "local_package" elif self.candidate.origin == "linuxmint": origin = "linuxmint" elif self.candidate.origin.startswith("LP-PPA-"): origin = "LP-PPA" elif self.apt_origins and self.candidate.origin in self.apt_origins.list(): origin = "APT" else: origin = "unsupported" # Check for changelog of installed package first has_local_changelog = False uri = None if not no_local and self.candidate.is_installed: if _DEBUG: print("Package is installed...") uri = self.get_changelog_from_filelist( self.candidate.installed_files, local=True) # Ubuntu kernel workarounds if self.candidate.origin == "Ubuntu": if self.candidate.source_name == "linux-signed": uri = uri.replace("linux-image","linux-modules") if self.candidate.source_name == "linux-meta": uri = None if uri and not os.path.isfile(uri): uri = None # Do nothing if local changelog exists if uri: has_local_changelog = True # all origins that APT supports elif origin == 'APT': uri = self.get_apt_changelog_uri( self.apt_origins.get(self.candidate.origin)) r = self.check_url(uri) if not r: self.exit_on_fail(2) # Linux Mint repo elif origin == 'linuxmint': # Mint repos don't have .debian.tar.xz files, only full packages, so # check the package cache first base_uri, _ = os.path.split(self.candidate.uri) r, uri = self.get_changelog_uri(base_uri) if not r: # fall back to last change info for the source package # Mint's naming scheme seems to be using amd64 unless source # is i386 only, we always check amd64 first base_uri = "http://packages.linuxmint.com/dev/%s_%s_%s.changes" uri = base_uri % (self.candidate.source_name, self.candidate.source_version, "amd64") r = self.check_url(uri, False) if not r: uri = base_uri % (self.candidate.source_name, self.candidate.source_version, "i386") r = self.check_url(uri, False) if not r: self.exit_on_fail(3) # Launchpad PPA elif origin == 'LP-PPA': ppa_owner, ppa_name, _ = \ self.candidate.uri.split("ppa.launchpad.net/")[1].split("/", 2) base_uri = "http://ppa.launchpad.net/%(owner)s/%(name)s/ubuntu/pool/main/%(source_prefix)s/%(source_name)s" % \ { "owner": ppa_owner, "name": ppa_name, "source_prefix": self.source_prefix(), "source_name": self.candidate.source_name } r, uri = self.get_changelog_uri(base_uri) if not r: # fall back to last change info only uri = "https://launchpad.net/~%(owner)s/+archive/ubuntu/%(name)s/+files/%(source_name)s_%(source_version)s_source.changes" % \ { "owner" : ppa_owner, "name": ppa_name, "source_name": self.candidate.source_name, "source_version": self.candidate.source_version } r = self.check_url(uri, False) if not r: self.exit_on_fail(4) # Not supported origin elif origin == 'unsupported': if _DEBUG: print("Unsupported Package") base_uri, _ = os.path.split(self.candidate.uri) r, uri = self.get_changelog_uri(base_uri) if not r: self.exit_on_fail(5) # Locally installed package without local changelog or remote # source, hope it's cached and contains a changelog elif origin == 'local_package': uri = self.apt_cache_path + self.candidate.filename if not os.path.isfile(uri): self.exit_on_fail(6) # Changelog downloading, extracting and processing: changelog = "" # local changelog if has_local_changelog and not no_local: if _DEBUG: print("Using local changelog:",uri) try: filename = os.path.basename(uri) # determine file type by name/extension # as per debian policy 4.4 the encoding must be UTF-8 # as per policy 12.7 the name must be changelog.Debian.gz or # changelog.gz (deprecated) if filename.lower().endswith('.gz'): changelog = gzip.open(uri,'r').read().decode('utf-8') elif filename.lower().endswith('.xz'): # just in case / future proofing changelog = lzma.open(uri,'r').read().decode('utf-8') elif filename.lower() == 'changelog': changelog = open(uri, 'r').read().encode().decode('utf-8') else: raise ValueError('Unknown changelog format') except Exception as e: _generic_exception_handler(e) self.exit_on_fail(1) # APT-format changelog, download directly # - unfortunately this is slow since the servers support no compression elif origin == "APT": if _DEBUG: print("Downloading: %s (%.2f MB)" % (uri, r.length / self.MB)) changelog = r.text r.close() # last change changelog, download directly elif uri.endswith('.changes'): if _DEBUG: print("Downloading: %s (%.2f MB)" % (uri, r.length / self.MB)) changes = r.text.split("Changes:")[1].split("Checksums")[0].split("\n") r.close() for change in changes: change = change.strip() if change: if change == ".": change = "" changelog += change + "\n" # compressed binary source, download and extract changelog else: source_is_cache = uri.startswith(self.apt_cache_path) if _DEBUG: print("Using cached package:" if source_is_cache else "Downloading: %s (%.2f MB)" % (uri, r.length / self.MB)) try: if not source_is_cache: # download stream to temporary file tmpFile = tempfile.NamedTemporaryFile(prefix="apt-changelog-") if self.interactive and r.length: # download chunks with progress indicator recv_length = 0 blocks = 60 for data in r.iter_content(chunk_size=16384): recv_length += len(data) tmpFile.write(data) recv_pct = recv_length / r.length recv_blocks = int(blocks * recv_pct) print("\r[%(progress)s%(spacer)s] %(percentage).1f%%" % { "progress": "=" * recv_blocks, "spacer": " " * (blocks - recv_blocks), "percentage": recv_pct * 100 }, end="", flush=True) # clear progress bar when done print("\r" + " " * (blocks + 10), end="\r", flush=True) else: # no content-length or non-interactive, download in one go # up to the configured max_download_size, ask only when # exceeded r.raw.decode_content = True size = 0 size_exceeded = False while True: buf = r.raw.read(16*1024) if not size_exceeded: size += len(buf) if size > self.max_download_size: if not self.user_confirm(self.max_download_size_msg_unknown): r.close() tmpFile.close() return "" else: size_exceeded = True if not buf: break tmpFile.write(buf) r.close() tmpFile.seek(0) if uri.endswith(".deb"): # process .deb file if source_is_cache: f = uri else: f = tmpFile.name # We could copy the downloaded .deb files to the apt # cache here but then we'd need to run the script elevated: # shutil.copy(f, self.apt_cache_path + os.path.basename(uri)) deb = DebPackage(f) changelog_file = self.get_changelog_from_filelist(deb.filelist) if changelog_file: changelog = deb.data_content(changelog_file) if changelog.startswith('Automatically decompressed:'): changelog = changelog[29:] else: raise ValueError('Malformed Debian package') elif uri.endswith(".diff.gz"): # Ubuntu partner repo has .diff.gz files, # we can extract a changelog from that data = gzip.open(tmpFile.name, "r").read().decode('utf-8') additions = data.split("+++") for addition in additions: lines = addition.split("\n") if "/debian/changelog" in lines[0]: for line in lines[2:]: if line.startswith("+"): changelog += "%s\n" % line[1:] else: break if not changelog: raise ValueError('No changelog in .diff.gz') else: # process .tar.xz file with tarfile.open(fileobj=tmpFile, mode="r:xz") as tar: changelog_file = self.get_changelog_from_filelist( [s.name for s in tar.getmembers() if s.type in (b"0", b"2")]) if changelog_file: changelog = tar.extractfile(changelog_file).read().decode() else: raise ValueError('No changelog in source package') except Exception as e: _generic_exception_handler(e) self.exit_on_fail(520) if 'tmpFile' in vars(): try: tmpFile.close() except Exception as e: _generic_exception_handler(e) # ALL DONE return changelog
class AppDetailsDebFile(AppDetails): def __init__(self, db, doc=None, application=None): super(AppDetailsDebFile, self).__init__(db, doc, application) if doc: raise ValueError("doc must be None for deb files") try: with ExecutionTime("create DebPackage"): # Cache() used to be faster here than self._cache._cache # but that is no longer the case with the latest apt self._deb = DebPackage(self._app.request, self._cache._cache) except: self._deb = None self._pkg = None if not os.path.exists(self._app.request): self._error = _("Not found") self._error_not_found = utf8(_(u"The file \u201c%s\u201d " "does not exist.")) % utf8(self._app.request) else: mimetype = guess_type(self._app.request) if mimetype[0] != "application/x-debian-package": self._error = _("Not found") self._error_not_found = utf8(_(u"The file \u201c%s\u201d " "is not a software package.")) % utf8( self._app.request) else: # deb files which are corrupt self._error = _("Internal Error") self._error_not_found = utf8(_(u"The file \u201c%s\u201d " "could not be opened.")) % utf8(self._app.request) return if self.pkgname and self.pkgname != self._app.pkgname: # this happens when the deb file has a quirky file name self._app.pkgname = self.pkgname # load pkg cache self._pkg = None if (self._app.pkgname in self._cache and self._cache[self._app.pkgname].candidate): self._pkg = self._cache[self._app.pkgname] # load xapian document self._doc = None try: self._doc = self._db.get_xapian_document( self._app.appname, self._app.pkgname) except: pass # check deb and set failure state on error with ExecutionTime("AppDetailsDebFile._deb.check()"): if not self._deb.check(): self._error = self._deb._failure_string.strip() @property def description(self): if self._deb: description = self._deb._sections["Description"] s = ('\n').join(description.split('\n')[1:]).replace(" .\n", "") return utf8(s) return "" @property def maintenance_status(self): pass @property def pkgname(self): if self._deb: return self._deb._sections["Package"] @property def pkg_state(self): if self._error: if self._error_not_found: return PkgStates.NOT_FOUND else: return PkgStates.ERROR if self._deb: deb_state = self._deb.compare_to_version_in_cache() if deb_state == DebPackage.VERSION_NONE: return PkgStates.UNINSTALLED elif deb_state == DebPackage.VERSION_OUTDATED: if self._cache[self.pkgname].installed: return PkgStates.INSTALLED else: return PkgStates.UNINSTALLED elif deb_state == DebPackage.VERSION_SAME: return PkgStates.REINSTALLABLE elif deb_state == DebPackage.VERSION_NEWER: if self._cache[self.pkgname].installed: return PkgStates.UPGRADABLE else: return PkgStates.UNINSTALLED @property def summary(self): if self._deb: description = self._deb._sections["Description"] # ensure its utf8(), see #738771 return utf8(description.split('\n')[0]) @property def display_summary(self): if self._doc: name = self._db.get_appname(self._doc) if name: return self.summary else: # by spec.. return self._db.get_pkgname(self._doc) return self.summary @property def version(self): if self._deb: return self._deb._sections["Version"] @property def installed_size(self): installed_size = 0 if self._deb: try: installed_size = long(self._deb._sections["Installed-Size"]) except: pass return installed_size * 1024 @property def warning(self): # FIXME: use more concise warnings if self._deb: deb_state = self._deb.compare_to_version_in_cache( use_installed=False) if deb_state == DebPackage.VERSION_NONE: return utf8( _("Only install this file if you trust the origin.")) elif (not self._cache[self.pkgname].installed and self._cache[self.pkgname].candidate and self._cache[self.pkgname].candidate.downloadable): if deb_state == DebPackage.VERSION_OUTDATED: return utf8(_("Please install \"%s\" via your normal " "software channels. Only install this file if you " "trust the origin.")) % utf8(self.name) elif deb_state == DebPackage.VERSION_SAME: return utf8(_("Please install \"%s\" via your normal " "software channels. Only install this file if you " "trust the origin.")) % utf8(self.name) elif deb_state == DebPackage.VERSION_NEWER: return utf8(_("An older version of \"%s\" is available in " "your normal software channels. Only install this " "file if you trust the origin.")) % utf8(self.name) @property def website(self): if self._deb: website = None try: website = self._deb._sections["Homepage"] except: pass if website: return website
def get_files(stream): """Reads the information stream and returns the directories being changed. This supports versions 1, 2, and 3 of the information protocol. """ directories = set() # First detect which version of the description protocol we're getting line = stream.readline().strip() # Doing this more complicated version checking to guard against a newer # version being sent without supporting it. version_prefix = "VERSION " if line.startswith(version_prefix): version = int(line[len(version_prefix):]) else: version = 1 # Check for unsupported versions if not (1 <= version <= 3): log.error( ( "ERROR: Unsupported APT helper configuration protocol version " "({})!" ).format(version) ) sys.exit(1) log.debug("Parsing version %d of APT hook protocol.", version) if version == 1: # handle the version 1 case first, it's simple while line != "": log.debug("Hook protocol line: '%s'", line) pkg = DebPackage(filename=line) # Keep the package objects around only as long as they're needed, # otherwise you'll open too many files. directories.update(directories_for_package(pkg)) line = stream.readline().strip() else: line = stream.readline().strip() # The first block is the APT configuration space, which is terminated # with a blank line. We don't care about the info in there, so we skip # it log.debug("Skipping APT configuration lines.") while line != "": log.debug("Hook protocol line: '%s'", line) line = stream.readline().strip() line = stream.readline().strip() # Versions 2 and 3 are very similar; version 3 adds two fields for # architecture after both version fields. Fields are space-delimited in # both versions. if version == 2: # In this case, fields are: # package name, old version, change direction, new version, action. field_count = 5 elif version == 3: # In this case the fields are: # package name, old version, old version arch, old version # multi-arch type, change direction, new version, new version arch, # new version multi-arch type, action. field_count = 9 # Fields are space-delimited, in this order: package name, old version, # change direction, new version, action, and if version 3, # architecture. I recommend reading the apt.conf(5) man page for more # details. apt_cache = apt.Cache() while line != "": log.debug("Hook protocol line: '%s'", line) # I'm doing a reverse split on space to guard against possible # quoting in the package name. fields = line.rsplit(" ", maxsplit=(field_count - 1)) log.debug("Hook fields: %s", fields) # Pull out the fields we need. pkg_name, installed_version, *_, action = fields # If the package is being removed or configured, `action` is # `**REMOVE**` or `**CONFIGURE**` respectively. Otherwise it's the # path to the package file being installed. if action in {"**REMOVE**", "**CONFIGURE**"}: cached_package = apt_cache[pkg_name] if cached_package.is_installed: # Only look at packages being reconfigured after they've # been installed. If they aren't installed yet, the package # from the apt cache won't have any files to list (and the # package is probably being installed anyways in this run # anyways). directories.update(directories_for_package(cached_package)) else: deb_package = DebPackage(filename=action) directories.update(directories_for_package(deb_package)) if installed_version != "-": # If we're upgrading from an old package, make sure to look # for those files that might be removed when the old # package is removed. cached_package = apt_cache[pkg_name] directories.update(directories_for_package(cached_package)) line = stream.readline().strip() return directories