def _rpm(b, manager, package, version, entry, pathname): """ Resolve dependencies on RPM-based systems. """ # If this Python package is actually part of a system # package, abandon it. p = subprocess.Popen(['rpm', '-qf', pathname], close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.communicate() if 0 == p.returncode: return # This package was installed via `easy_install`. Make # sure Python is in the blueprint so it can be used as # a package manager. if pattern_egg.search(entry): p = subprocess.Popen(['rpm', '--qf=%{VERSION}-%{RELEASE}.%{ARCH}', '-q', 'python'], close_fds=True, stdout=subprocess.PIPE) stdout, stderr = p.communicate() if 0 != p.returncode: return versions = b.packages['yum']['python'] if stdout not in versions: versions.add(stdout) if not ignore.package('python', package): b.add_package('python', package, version) # This package was installed via `pip`. Figure out how # `pip` was installed and use that as this package's # manager. elif pattern_egginfo.search(entry) and os.path.exists( os.path.join(pathname, 'installed-files.txt')): p = subprocess.Popen(['rpm', '-q', 'python-pip'], close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.communicate() if 0 != p.returncode: if not ignore.package('pip', package): b.add_package('pip', package, version) else: if not ignore.package('python-pip', package): b.add_package('python-pip', package, version)
def php(b): logging.info('searching for PEAR/PECL packages') # Precompile a pattern for parsing the output of `{pear,pecl} list`. pattern = re.compile(r'^([0-9a-zA-Z_]+)\s+([0-9][0-9a-zA-Z\.-]*)\s') # PEAR packages are managed by `php-pear` (obviously). PECL packages # are managed by `php5-dev` because they require development headers # (less obvious but still makes sense). if util.lsb_release_codename() is None: pecl_manager = 'php-devel' else: pecl_manager = 'php5-dev' for manager, progname in (('php-pear', 'pear'), (pecl_manager, 'pecl')): try: p = subprocess.Popen([progname, 'list'], close_fds=True, stdout=subprocess.PIPE) except OSError: continue for line in p.stdout: match = pattern.match(line) if match is None: continue package, version = match.group(1), match.group(2) if not ignore.package(manager, package): b.add_package(manager, package, version)
def apt(b): logging.info('searching for APT packages') # Try for the full list of packages. If this fails, don't even # bother with the rest because this is probably a Yum/RPM-based # system. try: p = subprocess.Popen(['dpkg-query', '-f=${Status}\x1E${Package}\x1E${Version}\n', '-W'], close_fds=True, stdout=subprocess.PIPE) except OSError: return for line in p.stdout: status, package, version = line.strip().split('\x1E') if 'install ok installed' != status: continue if ignore.package('apt', package): continue b.add_package('apt', package, version) # Create service resources for each service init script or config # found in this package. p = subprocess.Popen(['dpkg-query', '-L', package], close_fds=True, stdout=subprocess.PIPE) for line in p.stdout: try: manager, service = util.parse_service(line.rstrip()) if not ignore.service(manager, service): b.add_service(manager, service) b.add_service_package(manager, service, 'apt', package) except ValueError: pass
def _dpkg_query(b, manager, package, version, entry, pathname): """ Resolve dependencies on Debian-based systems. """ # If this Python package is actually part of a system # package, abandon it. p = subprocess.Popen(['dpkg-query', '-S', pathname], close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.communicate() if 0 == p.returncode: return # This package was installed via `easy_install`. Make # sure its version of Python is in the blueprint so it # can be used as a package manager. if pattern_egg.search(entry): p = subprocess.Popen(['dpkg-query', '-f=${Version}', '-W', manager], close_fds=True, stdout=subprocess.PIPE) stdout, stderr = p.communicate() if 0 != p.returncode: return versions = b.packages['apt'][manager] if stdout not in versions: versions.add(stdout) if not ignore.package(manager, package): b.add_package(manager, package, version) # This package was installed via `pip`. Figure out how # `pip` was installed and use that as this package's # manager. elif pattern_egginfo.search(entry) and os.path.exists( os.path.join(pathname, 'installed-files.txt')): p = subprocess.Popen(['dpkg-query', '-W', 'python-pip'], close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.communicate() if 0 != p.returncode: if not ignore.package('pip', package): b.add_package('pip', package, version) else: if not ignore.package('python-pip', package): b.add_package('python-pip', package, version)
def apt(b): logging.info('searching for APT packages') # Try for the full list of packages. If this fails, don't even # bother with the rest because this is probably a Yum/RPM-based # system. try: p = subprocess.Popen(['dpkg-query', '-f=${Package} ${Version}\n', '-W'], close_fds=True, stdout=subprocess.PIPE) except OSError: return for line in p.stdout: package, version = line.strip().split() if ignore.package('apt', package): continue b.packages['apt'][package].append(version)
def yum(b): logging.info('searching for Yum packages') # Try for the full list of packages. If this fails, don't even # bother with the rest because this is probably a Debian-based # system. try: p = subprocess.Popen( [ 'rpm', '--qf=%{NAME}\x1E%{GROUP}\x1E%{EPOCH}' # No , '\x1E%{VERSION}-%{RELEASE}\x1E%{ARCH}\n', '-qa' ], close_fds=True, stdout=subprocess.PIPE) except OSError: return for line in p.stdout: package, group, epoch, version, arch = line.strip().split('\x1E') if ignore.package('yum', package): continue if '(none)' != epoch: version = '{0}:{1}'.format(epoch, version) if '(none)' != arch: version = '{0}.{1}'.format(version, arch) b.add_package('yum', package, version) # Create service resources for each service init script or config # in this package. p = subprocess.Popen(['rpm', '-ql', package], close_fds=True, stdout=subprocess.PIPE) for line in p.stdout: try: manager, service = util.parse_service(line.rstrip()) if not ignore.service(manager, service): b.add_service(manager, service) b.add_service_package(manager, service, 'yum', package) except ValueError: pass
def npm(b): logging.info('searching for npm packages') # Precompile a pattern for parsing the output of `{pear,pecl} list`. pattern = re.compile(r'^\S+ (\S+)@(\S+)$') try: p = subprocess.Popen(['npm', 'ls', '-g'], close_fds=True, stdout=subprocess.PIPE) for line in p.stdout: match = pattern.match(line.rstrip()) if match is None: continue package, version = match.group(1), match.group(2) if not ignore.package('nodejs', package): b.add_package('nodejs', package, version) except OSError: pass
def gem(b): logging.info('searching for Ruby gems') # Precompile a pattern for extracting the version of Ruby that was used # to install the gem. pattern = re.compile(r'gems/([^/]+)/gems') # Look for gems in all the typical places. This is easier than looking # for `gem` commands, which may or may not be on `PATH`. for globname in ('/usr/lib/ruby/gems/*/gems', '/usr/local/lib/ruby/gems/*/gems', '/var/lib/gems/*/gems'): for dirname in glob.glob(globname): # The `ruby1.9.1` (really 1.9.2) package on Maverick begins # including RubyGems in the `ruby1.9.1` package and marks the # `rubygems1.9.1` package as virtual. So for Maverick and # newer, the manager is actually `ruby1.9.1`. match = pattern.search(dirname) if '1.9.1' == match.group(1) and util.rubygems_virtual(): manager = 'ruby{0}'.format(match.group(1)) # RPM-based distros just have one RubyGems package. elif util.lsb_release_codename() is None: manager = 'rubygems' # Debian-based distros qualify the package name with the version # of Ruby it will use. else: manager = 'rubygems{0}'.format(match.group(1)) for entry in os.listdir(dirname): try: package, version = entry.rsplit('-', 1) except ValueError: logging.warning( 'skipping questionably named gem {0}'.format(entry)) continue if not ignore.package(manager, package): b.add_package(manager, package, version)
def gem(b): logging.info('searching for Ruby gems') # Precompile a pattern for extracting the version of Ruby that was used # to install the gem. pattern = re.compile(r'gems/([^/]+)/gems') # Look for gems in all the typical places. This is easier than looking # for `gem` commands, which may or may not be on `PATH`. for globname in ('/usr/lib/ruby/gems/*/gems', '/usr/local/lib/ruby/gems/*/gems', '/var/lib/gems/*/gems'): for dirname in glob.glob(globname): # The `ruby1.9.1` (really 1.9.2) package on Maverick begins # including RubyGems in the `ruby1.9.1` package and marks the # `rubygems1.9.1` package as virtual. So for Maverick and # newer, the manager is actually `ruby1.9.1`. match = pattern.search(dirname) if '1.9.1' == match.group(1) and util.rubygems_virtual(): manager = 'ruby{0}'.format(match.group(1)) # RPM-based distros just have one RubyGems package. elif util.lsb_release_codename() is None: manager = 'rubygems' # Debian-based distros qualify the package name with the version # of Ruby it will use. else: manager = 'rubygems{0}'.format(match.group(1)) for entry in os.listdir(dirname): try: package, version = entry.rsplit('-', 1) except ValueError: logging.warning('skipping questionably named gem {0}'. format(entry)) continue if not ignore.package(manager, package): b.add_package(manager, package, version)
def yum(b): logging.info('searching for Yum packages') # Try for the full list of packages. If this fails, don't even # bother with the rest because this is probably a Debian-based # system. try: p = subprocess.Popen(['rpm', '--qf=%{NAME}\x1E%{GROUP}\x1E%{EPOCH}' # No , '\x1E%{VERSION}-%{RELEASE}.%{ARCH}\n', '-qa'], close_fds=True, stdout=subprocess.PIPE) except OSError: return for line in p.stdout: package, group, epoch, version = line.strip().split('\x1E') if ignore.package('yum', package): continue if '(none)' != epoch: version = '{0}:{1}'.format(epoch, version) b.packages['yum'][package].append(version)
def yum(b): logging.info('searching for Yum packages') # Try for the full list of packages. If this fails, don't even # bother with the rest because this is probably a Debian-based # system. try: p = subprocess.Popen(['rpm', '--qf=%{NAME}\x1E%{GROUP}\x1E%{EPOCH}' # No , '\x1E%{VERSION}-%{RELEASE}\x1E%{ARCH}\n', '-qa'], close_fds=True, stdout=subprocess.PIPE) except OSError: return for line in p.stdout: package, group, epoch, version, arch = line.strip().split('\x1E') if ignore.package('yum', package): continue if '(none)' != epoch: version = '{0}:{1}'.format(epoch, version) if '(none)' != arch: version = '{0}.{1}'.format(version, arch) b.add_package('yum', package, version) # Create service resources for each service init script or config # in this package. p = subprocess.Popen(['rpm', '-ql', package], close_fds=True, stdout=subprocess.PIPE) for line in p.stdout: try: manager, service = util.parse_service(line.rstrip()) if not ignore.service(manager, service): b.add_service(manager, service) b.add_service_package(manager, service, 'yum', package) except ValueError: pass
def apt(b): logging.info('searching for APT packages') # Try for the full list of packages. If this fails, don't even # bother with the rest because this is probably a Yum/RPM-based # system. try: p = subprocess.Popen( ['dpkg-query', '-f=${Status}\x1E${Package}\x1E${Version}\n', '-W'], close_fds=True, stdout=subprocess.PIPE) except OSError: return for line in p.stdout: status, package, version = line.strip().split('\x1E') if 'install ok installed' != status: continue if ignore.package('apt', package): continue b.add_package('apt', package, version) # Create service resources for each service init script or config # found in this package. p = subprocess.Popen(['dpkg-query', '-L', package], close_fds=True, stdout=subprocess.PIPE) for line in p.stdout: try: manager, service = util.parse_service(line.rstrip()) if not ignore.service(manager, service): b.add_service(manager, service) b.add_service_package(manager, service, 'apt', package) except ValueError: pass