def __import_to(self, confman): prefix = "usr/lib/poni-config/" def callback(member, contents): if member.name.endswith("/") or not member.name.startswith(prefix): # not a poni-config file, skip return dest_sub = member.name[len(prefix):] dest_path = confman.system_root / dest_sub dest_dir = dest_path.dirname() if not dest_dir.exists(): dest_dir.makedirs() write = not dest_path.exists() if (not write) and dest_path.exists(): old = dest_path.bytes() write = (old != contents) logger = self.log.info if self.verbose else self.log.debug pretty_path = confman.root_dir.relpathto(dest_path) if write: file(dest_path, "wb").write(contents) logger("imported: %s", pretty_path) else: logger("unchanged: %s", pretty_path) data_tar = apt_inst.DebFile(file(self.source)).data # reads each file into memory and calls the callback, but there's no file-object based option... data_tar.go(callback)
def write_package_stanza(self, deb_path, dest): """Write a stanza for the package to a Packages file. @param deb_path: The path to the deb package. @param dest: A writable package file. """ deb_file = open(deb_path) deb = apt_inst.DebFile(deb_file) control = deb.control.extractdata("control") deb_file.close() filename = os.path.basename(deb_path) size = os.path.getsize(deb_path) contents = read_binary_file(deb_path) md5 = hashlib.md5(contents).hexdigest() sha1 = hashlib.sha1(contents).hexdigest() sha256 = hashlib.sha256(contents).hexdigest() tag_section = apt_pkg.TagSection(control) new_tags = [("Filename", filename), ("Size", str(size)), ("MD5sum", md5), ("SHA1", sha1), ("SHA256", sha256)] try: tag_section.write(dest, apt_pkg.REWRITE_PACKAGE_ORDER, [apt_pkg.TagRewrite(k, v) for k, v in new_tags]) except AttributeError: # support for python-apt < 1.9 section = apt_pkg.rewrite_section(tag_section, apt_pkg.REWRITE_PACKAGE_ORDER, new_tags) dest.write(section.encode("utf-8"))
def check(self, upload): cnf = Config() future_cutoff = time.time() + cnf.find_i('Dinstall::FutureTimeTravelGrace', 24*3600) past_cutoff = time.mktime(time.strptime(cnf.find('Dinstall::PastCutoffYear', '1975'), '%Y')) class TarTime(object): def __init__(self): self.future_files = dict() self.past_files = dict() def callback(self, member, data): if member.mtime > future_cutoff: self.future_files[member.name] = member.mtime elif member.mtime < past_cutoff: self.past_files[member.name] = member.mtime def format_reason(filename, direction, files): reason = "{0}: has {1} file(s) with a timestamp too far in the {2}:\n".format(filename, len(files), direction) for fn, ts in files.iteritems(): reason += " {0} ({1})".format(fn, time.ctime(ts)) return reason for binary in upload.changes.binaries: filename = binary.hashed_file.filename path = os.path.join(upload.directory, filename) deb = apt_inst.DebFile(path) tar = TarTime() deb.control.go(tar.callback) if tar.future_files: raise Reject(format_reason(filename, 'future', tar.future_files)) if tar.past_files: raise Reject(format_reason(filename, 'past', tar.past_files))
def open(self, filename): " open given debfile " self.filename = filename self._debfile = apt_inst.DebFile(self.filename) control = self._debfile.control.extractdata("control") self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"]
def parse(fname): """ read a deb """ control = apt_inst.DebFile(fname).control.extractdata("control") sections = apt_pkg.TagSection(control) if "Modaliases" in sections: modaliases = sections["Modaliases"] else: modaliases = '' return (sections["Architecture"], sections["Package"], modaliases)
def test_success_a_member(self): """fd should be kept around as long as a tarfile member""" before = os.listdir("/proc/self/fd") data = apt_inst.DebFile(self.GOOD_DEB).data after = os.listdir("/proc/self/fd") self.assertEqual(len(before), len(after) - 1) del data after = os.listdir("/proc/self/fd") self.assertEqual(before, after)
def _install_deb_file(self, path): """Fake the the given deb file is installed in the system.""" deb_file = open(path) deb = apt_inst.DebFile(deb_file) control = deb.control.extractdata("control") deb_file.close() lines = control.splitlines() lines.insert(1, b"Status: install ok installed") status = b"\n".join(lines) append_binary_file(self.dpkg_status, status + b"\n\n")
def main(): """Main function""" if len(sys.argv) < 2: print("need filename argumnet", file=sys.stderr) sys.exit(1) fobj = open(sys.argv[1]) try: apt_inst.DebFile(fobj).data.go(callback) finally: fobj.close()
def __init__(self, directory, hashed_file): self.hashed_file = hashed_file """file object for the .deb @type: HashedFile """ path = os.path.join(directory, hashed_file.input_filename) data = apt_inst.DebFile(path).control.extractdata("control") self.control = apt_pkg.TagSection(data) """dict to access fields in DEBIAN/control
def open(self, filename): """ open given debfile """ self._dbg(3, "open '%s'" % filename) self._need_pkgs = [] self._installed_conflicts = set() self._failure_string = "" self.filename = filename self._debfile = apt_inst.DebFile(self.filename) control = self._debfile.control.extractdata("control") self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"] self._check_was_run = False
def RunTrigger(self): logging.info('Extracting...') try: package_file = open(self._package_path) apt_inst.DebFile(package_file).data.extractall( self._package_extract_dir) package_file.close() except (IOError, SystemError) as e: error = ('Could not open and extract application package %s: %s' % (self._package_path, str(e))) logging.error(error) raise triggers.TriggerError(error)
def test_no_debian_binary(self): """opening package without debian-binary should not leak fd""" before = os.listdir("/proc/self/fd") with self._create_deb_without("debian-binary") as temp: try: apt_inst.DebFile(temp.name) except SystemError as e: self.assertIn("missing debian-binary", str(e)) else: self.fail("Did not raise an exception") after = os.listdir("/proc/self/fd") self.assertEqual(before, after)
def test_nocontrol(self): """opening package without control.tar.gz should not leak fd""" before = os.listdir("/proc/self/fd") with self._create_deb_without("control.tar.gz") as temp: try: apt_inst.DebFile(temp.name) except SystemError as e: self.assertIn("control.tar", str(e)) else: self.fail("Did not raise an exception") after = os.listdir("/proc/self/fd") self.assertEqual(before, after)
def provision(self, dst, clean_target=True, keep_deb=False): deb_file = os.path.join(self.source_dir, os.path.basename(self.source)) if clean_target: tmp_deb = tempfile.NamedTemporaryFile().name shutil.move(deb_file, tmp_deb) shutil.rmtree(dst) os.makedirs(dst) shutil.move(tmp_deb, deb_file) deb = apt_inst.DebFile(deb_file) deb.data.extractall(dst) if not keep_deb: os.remove(deb_file)
def main(): """Main function.""" if len(sys.argv) < 3: print("Usage: %s package.deb outdir\n" % (__file__), file=sys.stderr) sys.exit(1) if not os.path.exists(sys.argv[2]): print("The directory %s does not exist\n" % (sys.argv[2]), file=sys.stderr) sys.exit(1) fobj = open(sys.argv[1]) try: apt_inst.DebFile(fobj).data.extractall(sys.argv[2]) finally: fobj.close()
def verifyDebTimestamp(self): """Check specific DEB format timestamp checks.""" self.logger.debug("Verifying timestamps in %s" % (self.filename)) future_cutoff = time.time() + self.policy.future_time_grace earliest_year = time.strptime(str(self.policy.earliest_year), "%Y") past_cutoff = time.mktime(earliest_year) tar_checker = TarFileDateChecker(future_cutoff, past_cutoff) tar_checker.reset() try: deb_file = apt_inst.DebFile(self.filepath) except SystemError as error: # We get an error from the constructor if the .deb does not # contain all the expected top-level members (debian-binary, # control.tar.gz, and data.tar.*). yield UploadError(str(error)) return try: deb_file.control.go(tar_checker.callback) deb_file.data.go(tar_checker.callback) future_files = tar_checker.future_files.keys() if future_files: first_file = future_files[0] timestamp = time.ctime(tar_checker.future_files[first_file]) yield UploadError( "%s: has %s file(s) with a time stamp too " "far into the future (e.g. %s [%s])." % (self.filename, len(future_files), first_file, timestamp)) ancient_files = tar_checker.ancient_files.keys() if ancient_files: first_file = ancient_files[0] timestamp = time.ctime(tar_checker.ancient_files[first_file]) yield UploadError( "%s: has %s file(s) with a time stamp too " "far in the past (e.g. %s [%s])." % (self.filename, len(ancient_files), first_file, timestamp)) except (SystemExit, KeyboardInterrupt): raise except Exception as error: # There is a very large number of places where we # might get an exception while checking the timestamps. # Many of them come from apt_inst/apt_pkg and they are # terrible in giving sane exceptions. We thusly capture # them all and make them into rejection messages instead yield UploadError("%s: deb contents timestamp check failed: %s" % (self.filename, error))
def run(self, config_file, introspection_method=None): self._setup_parser(config_file) if introspection_method: print(introspection_method()) return self._result() if not self._needs_qemu(): return None if os.path.isfile(self._result()): logging.info(("{0} is already there. " "Delete it to re-fetch it.").format(self._result())) return self._result() qemu_package = self.config.get_qemu_package_name() print("Going to fetch qemu Debian package ({}).".format(qemu_package)) workdir = self.config.get_workdir() with tempfile.TemporaryDirectory(dir=workdir) as tempdir: chown_to_user(tempdir) qemu_repository = self.config.get_qemu_repository() if qemu_repository: key_url = self.config.get_qemu_repository_key() else: qemu_repository = self.config.get_bootstrap_repository() key_url = self.config.get_bootstrap_repository_key() d = PackageDownloader(repository=qemu_repository, repository_key=key_url, architectures=[get_debian_architecture()]) package_file = d.download(package_name=qemu_package, dest=tempdir) apt_inst.DebFile(package_file).data.extractall(tempdir) qemu_binary = os.path.join(tempdir, 'usr', 'bin', self._get_qemu_binary_name()) chown_to_user(qemu_binary) shutil.move(qemu_binary, self._result()) print_success("Fetched qemu binary {}.".format(self._result())) return self._result()
def get_package_stanza(self, deb_path): """Return a stanza for the package to be included in a Packages file. @param deb_path: The path to the deb package. """ deb_file = open(deb_path) deb = apt_inst.DebFile(deb_file) control = deb.control.extractdata("control") deb_file.close() filename = os.path.basename(deb_path) size = os.path.getsize(deb_path) contents = read_binary_file(deb_path) md5 = hashlib.md5(contents).hexdigest() sha1 = hashlib.sha1(contents).hexdigest() sha256 = hashlib.sha256(contents).hexdigest() # Use rewrite_section to ensure that the field order is correct. return apt_pkg.rewrite_section(apt_pkg.TagSection(control), apt_pkg.REWRITE_PACKAGE_ORDER, [("Filename", filename), ("Size", str(size)), ("MD5sum", md5), ("SHA1", sha1), ("SHA256", sha256)])
def provide_dell_recovery_file_chooser_picked(self, widget=None): """Called when a file is selected on the add dell-recovery page""" ok_button = self.builder_widgets.get_object('builder_add_ok') filefilter = Gtk.FileFilter() filefilter.add_pattern("*.deb") self.file_dialog.set_filter(filefilter) ret = self.run_file_dialog() if ret is not None: import apt_inst import apt_pkg control = apt_inst.DebFile(ret).control.extractdata("control") sections = apt_pkg.TagSection(control) if sections["Package"] != 'dell-recovery': self.add_dell_recovery_deb = '' else: self.add_dell_recovery_deb = ret if self.add_dell_recovery_deb: ok_button.set_sensitive(True)
def extractAndParseControl(self): """Extract and parse control information.""" try: deb_file = apt_inst.DebFile(self.filepath) control_file = deb_file.control.extractdata("control") control_lines = apt_pkg.TagSection(control_file) except (SystemExit, KeyboardInterrupt): raise except: yield UploadError( "%s: extracting control file raised %s, giving up." % (self.filename, sys.exc_type)) return for mandatory_field in self.mandatory_fields: if control_lines.find(mandatory_field) is None: yield UploadError("%s: control file lacks mandatory field %r" % (self.filename, mandatory_field)) control = {} for key in control_lines.keys(): control[key] = control_lines.find(key) self.parseControl(control)
def Callback(member, data): """ callback for debExtract """ print "'%s','%s',%u,%u,%u,%u,%u,%u,%u" \ % (member.name, member.linkname, member.mode, member.uid, member.gid, member.size, member.mtime, member.major, member.minor) if __name__ == "__main__": if len(sys.argv) < 2: print "need filename argumnet" sys.exit(1) file = sys.argv[1] print "Working on: %s" % file print "Displaying data.tar.gz:" apt_inst.DebFile(open(file)).data.go(Callback) print "Now extracting the control file:" control = apt_inst.DebFile(open(file)).control.extractdata("control") sections = apt_pkg.TagSection(control) print "Maintainer is: " print sections["Maintainer"] print print "DependsOn: " depends = sections["Depends"] print apt_pkg.parse_depends(depends) print "extracting archive" dir = "/tmp/deb"
def test_regression_bug_977000(self): """opening with a file handle should work correctly""" with open(self.GOOD_DEB) as good_deb: apt_inst.DebFile(good_deb).control.extractdata("control")
def __init__(self, fname): self.file = open(fname) self.deb = apt_inst.DebFile(self)
def deb_extract_control(fh): """extract DEBIAN/control from a binary package""" return apt_inst.DebFile(fh).control.extractdata("control")
def extract_header(self, filename): """Extract control file contents from a deb package.""" handle = open(filename) control = apt_inst.DebFile(handle).control.extractdata("control") handle.close() return sanitize_deb_header(control)
def test_success(self): """opening package successfully should not leak fd""" before = os.listdir("/proc/self/fd") apt_inst.DebFile(self.GOOD_DEB) after = os.listdir("/proc/self/fd") self.assertEqual(before, after)
def testExtractData(self): deb = apt_inst.DebFile(self.LARGE_PACKAGE_CONTENT) self.assertRaises(MemoryError, deb.data.extractdata, "large-file")
import os.path from pathlib import Path cache = apt.Cache() for pkg in cache: if not pkg.installed: continue ver = pkg.installed try: x = ver.fetch_binary("pkg") except: continue package = apt.debfile.DebPackage(x) ar = apt_inst.DebFile(x) tarfile = ar.data for file in pkg.installed_files: if not os.path.isdir(file): if file.startswith('/etc'): p = Path("." + file) p2 = Path("./temp").joinpath(pkg.name) p3 = p2.joinpath(p) if not p3.parent.exists(): p3.parent.mkdir(parents=True) try: data = tarfile.extractdata(file[1:]) with p3.open('wb') as f: f.write(data) except Exception as ex: