def _get_pkgs_install_date(self, pkg_dicts): # Convert package names to dpkg list filenames queries = [self._pkg_name_to_dpkg_list_file(p["name"]) for p in pkg_dicts] # Call stat in batches exec_gen = execute_command_batch( self._session, ['stat', '-c', '%n: %Y'], queries, cmd_err_filter('No such file or directory')) # Parse and accumulate stat results in a dict results = {} for (out, _, exc) in exec_gen: if exc: out = exc.stdout # One file not found, so continue # Parse the output and store by filename for outlines in out.splitlines(): (fname, ftime) = outlines.split(": ") results[fname] = str( pytz.utc.localize( datetime.utcfromtimestamp(float(ftime)))) # Now lookup the packages in the results for p in pkg_dicts: fname = self._pkg_name_to_dpkg_list_file(p["name"]) if fname in results: p["install_date"] = results[fname]
def _get_packagefields_for_files(self, files): # Call dpkg query in batches exec_gen = execute_command_batch( self._session, ['dpkg-query', '-S'], files, cmd_err_filter('no path found matching pattern')) # Parse and accumulate stat results in a dict file_to_package_dict = {} for (out, _, exc) in exec_gen: if exc: out = exc.stdout # One file not found, so continue # Now go through the output and assign packages to files for outline in out.splitlines(): # Parse package name (architecture) and path # TODO: Handle query of /bin/sh better outdict = self._parse_dpkgquery_line(outline) if not outdict: lgr.debug("Skipping line %s", outline) continue # Pull the found path from the dictionary found_name = outdict.pop('path') if not found_name: raise ValueError( "Record %s got no path defined... skipping" % repr(outdict) ) # Associate the file to the package name (and architecture) pkg = outdict lgr.debug("Identified file %r to belong to package %s", found_name, pkg) file_to_package_dict[found_name] = pkg return file_to_package_dict