def produce_inhibitor(self, module): report_with_remediation( title='Upgrade process was interrupted because {0} is enabled in ' 'PAM configuration and SA user refused to disable it ' 'automatically.'.format(module), summary='Module {0} was surpassed by SSSD and therefore it was ' 'removed from RHEL-8. Keeping it in PAM configuration may ' 'lock out the system thus it is necessary to disable it ' 'before the upgrade process can continue.'.format(module), remediation='Disable {0} module and switch to SSSD to recover ' 'its functionality.'.format(module), flags=['inhibitor'])
def process(self): if has_package(InstalledRedHatSignedRPM, 'dosfstools'): report_with_remediation( title='Dosfstools incompatible changes in the next major version', summary='The automatic alignment of data clusters that was added in 3.0.8 and broken for ' 'FAT32 starting with 3.0.20 has been reinstated. If you need to create file systems ' 'for finicky devices that have broken FAT implementations use the option -a to ' 'disable alignment.\n' 'The fsck.fat now defaults to interactive repair mode which previously had to be ' 'selected with the -r option.\n', remediation='Please update your scripts to be compatible with the changes.', severity='low')
def process(self): if not rhsm.skip_rhsm(): for info in self.consume(SourceRHSMInfo): if not info.attached_skus: report_with_remediation( title='The system is not registered or subscribed.', summary= 'The system has to be registered and subscribed to be able to proceed the upgrade.', remediation= ('Register your system with the subscription-manager tool and attach it to proper SKUs' ' to be able to proceed the upgrade.'), severity='high', flags=['inhibitor'])
def process(self): url = "https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html-single/configuring_basic_system_settings/#using-python3" # noqa: E501; pylint: disable=line-too-long title = "Difference in Python versions and support in RHEL 8" severity = "high" summary = ("In RHEL 8, there is no 'python' command." " Python 3 (backward incompatible) is the primary Python version" " and Python 2 is available with limited support and limited set of packages." " Read more here: {}".format(url)) remediation = "alternatives --set python /usr/bin/python3" reporting.report_with_remediation(title=title, severity=severity, summary=summary, remediation=remediation)
def process(self): for storage_info in self.consume(StorageInfo): for blk in storage_info.lsblk: if blk.tp == 'crypt': report_with_remediation( title='LUKS encrypted partition detected', summary= 'Upgrading system with encrypted partitions is not supported', remediation= 'If the encrypted partition is not system one and the system ' 'is not depending on it, you can remove/blacklist it from ' 'the system', severity='high', flags=['inhibitor']) break
def process(self): if has_package(InstalledRedHatSignedRPM, 'powertop'): report_with_remediation( title= 'PowerTOP compatibility options removed in the next major version', summary= 'The -d (dump) option which has been kept for RHEL backward compatibility has been ' 'dropped.\n' 'The -h option which has been used for RHEL backward compatibility is no longer ' 'alias for --html, but it\'s now an alias for --help to follow the upstream.\n' 'The -u option which has been used for RHEL backward compatibility as an alias for ' '--help has been dropped.\n', remediation= 'Please remove the dropped options from your scripts.', severity='low')
def generate_report(packages): """ Generate a report if exists packages unsigned in the system """ if not len(packages): return unsigned_packages_new_line = '\n'.join(packages) unsigned_packages = ' '.join(packages) remediation = 'yum remove {}'.format(unsigned_packages) summary = 'The following packages have not been signed by Red Hat ' \ 'and may be removed in the upgrade process:\n{}'.format(unsigned_packages_new_line) reporting.report_with_remediation( title='Packages not signed by Red Hat found in the system', summary=summary, remediation=remediation, severity='high', )
def process(self): for fact in self.consume(InstalledRedHatSignedRPM): for rpm in fact.items: if rpm.name == 'irssi': report_with_remediation( title= 'Irssi incompatible changes in the next major version', summary= 'Disabled support for the insecure SSLv2 protocol.\n' 'Disabled SSLv3 due to the POODLE vulnerability.\n' 'Removing networks will now remove all attached servers and channels.\n' 'Removed --disable-ipv6 option.\n', remediation= 'Please update your scripts to be compatible with the changes.', severity='low') break
def process(self): for decision in self.consume(SelinuxPermissiveDecision): if decision.set_permissive: success, err_msg = selinux_set_permissive() if not success: # FIXME: add an "action required" flag later report_with_remediation( title='Could not set SElinux into permissive mode', summary='{}'.format(err_msg), remediation= 'Please set SElinux into permissive mode manually.', severity='high', ) self.log.critical( 'Could not set SElinux into permissive mode: %s.' % err_msg)
def process(self): for fact in self.consume(InstalledRedHatSignedRPM): for rpm in fact.items: if rpm.name == 'powertop': report_with_remediation( title= 'PowerTOP compatibility options removed in the next major version', summary= 'The -d (dump) option which has been kept for RHEL backward compatibility has been dropped.\n' 'The -h option which has been used for RHEL backward compatibility is no longer alias for --html, ' 'but it\'s now an alias for --help to follow the upstream.\n' 'The -u option which has been used for RHEL backward compatibility as an alias for --help ' 'has been dropped.\n', remediation= 'Please remove the dropped options from your scripts.', severity='low') break
def process(self): for fact in self.consume(ActiveKernelModulesFacts): for active_module in fact.kernel_modules: if active_module.filename == 'btrfs': report_with_remediation( title='Btrfs removed in the next major version', summary= 'The Btrfs file system was introduced as Technology Preview with the initial release ' 'of Red Hat Enterprise Linux 6 and Red Hat Enterprise Linux 7. As of versions 6.6 and ' '7.4 this technology has been deprecated and will be removed in next major version.', remediation= 'Please consider migrating your Btrfs mount point(s) to a different filesystem ' 'before next upgrade attempt. If no Btrfs filesystem is in use, please unload ' 'btrfs kernel module running "# rmmod btrfs".', severity='high', flags=['inhibitor']) break
def process(self): openssh_messages = self.consume(OpenSshConfig) config = next(openssh_messages, None) if list(openssh_messages): api.current_logger().warning( 'Unexpectedly received more than one OpenSshConfig message.') if not config: raise StopActorExecutionError( 'Could not check openssh configuration', details={'details': 'No OpenSshConfig facts found.'}) if not config.permit_root_login: # TODO find out whether the file was modified and will be # replaced by the update. If so, this message is bogus report_with_remediation( title='Possible problems with remote login using root account', summary='OpenSSH configuration file does not explicitly state ' 'the option PermitRootLogin in sshd_config file, ' 'which will default in RHEL8 to "prohibit-password".', remediation='If you depend on remote root logins using ' 'passwords, consider setting up a different ' 'user for remote administration or adding ' '"PermitRootLogin yes" to sshd_config.', severity='high', flags=['inhibitor']) # Check if there is at least one PermitRootLogin other than "no" # in match blocks (other than Match All). # This usually means some more complicated setup depending on the # default value being globally "yes" and being overwritten by this # match block if semantics_changes(config): report_with_remediation( title='OpenSSH configured to allow root login', summary='OpenSSH is configured to deny root logins in match ' 'blocks, but not explicitly enabled in global or ' '"Match all" context. This update changes the ' 'default to disable root logins using paswords ' 'so your server migth get inaccessible.', remediation='Consider using different user for administrative ' 'logins or make sure your configration file ' 'contains the line "PermitRootLogin yes" ' 'in global context if desired.', severity='high', flags=['inhibitor'])
def process(self): removed_ciphers = [ "blowfish-cbc", "cast128-cbc", "arcfour", "arcfour128", "arcfour256", ] removed_macs = [ "hmac-ripemd160", ] found_ciphers = [] found_macs = [] for config in self.consume(OpenSshConfig): for cipher in removed_ciphers: if config.ciphers and cipher in config.ciphers: found_ciphers.append(cipher) for mac in removed_macs: if config.macs and mac in config.macs: found_macs.append(mac) if found_ciphers: report_with_remediation( title='OpenSSH configured to use removed ciphers', summary='OpenSSH is configured to use removed ciphers {}. ' 'These ciphers were removed from OpenSSH and if ' 'present the sshd daemon will not start in RHEL 8' ''.format(','.join(found_ciphers)), remediation='Remove the following ciphers from sshd_config: ' '{}'.format(','.join(found_ciphers)), severity='high', flags=['inhibitor']) if found_macs: report_with_remediation( title='OpenSSH configured to use removed mac', summary='OpenSSH is configured to use removed mac {}. ' 'This MAC was removed from OpenSSH and if present ' 'the sshd daemon will not start in RHEL 8' ''.format(','.join(found_macs)), remediation='Remove the following MACs from sshd_config: ' '{}'.format(','.join(found_macs)), severity='high', flags=['inhibitor'])
def process(self): messages = self.consume(PamConfiguration) config = next(messages, None) if list(messages): api.current_logger().warning( 'Unexpectedly received more than one PamConfiguration message.' ) if not config: raise StopActorExecutionError( 'Could not check pam configuration', details={'details': 'No PamConfiguration facts found.'}) # This list contain tupples of removed modules and their recommended replacements removed_modules = [ ('pam_tally2', 'pam_faillock'), ] found_services = set() found_modules = set() replacements = set() for service in config.services: for module in removed_modules: removed = module[0] replacement = module[1] if removed in service.modules: found_services.add(service.service) found_modules.add(removed) replacements.add(replacement) if found_modules: report_with_remediation( title='The {} pam module(s) no longer available'.format( ', '.join(found_modules)), summary='The services {} using PAM are configured to ' 'use {} module(s), which is no longer available ' 'in Red Hat Enterprise Linux 8.'.format( ', '.join(found_services), ', '.join(found_modules)), remediation='If you depend on its functionality, it is ' 'recommended to migrate to {}. Otherwise ' 'please remove the pam module(s) from all the files ' 'under /etc/pam.d/.'.format(', '.join(replacements)), severity='high', flags=['inhibitor'])
def process(self): if has_package(InstalledRedHatSignedRPM, 'grep'): report_with_remediation( title='Grep has incompatible changes in the next major version', summary= 'If a file contains data improperly encoded for the current locale, and this is ' 'discovered before any of the file\'s contents are output, grep now treats the file ' 'as binary.\n' 'The \'grep -P\' no longer reports an error and exits when given invalid UTF-8 data. ' 'Instead, it considers the data to be non-matching.\n' 'In locales with multibyte character encodings other than UTF-8, grep -P now reports ' 'an error and exits instead of misbehaving.\n' 'When searching binary data, grep now may treat non-text bytes as line terminators. ' 'This can boost performance significantly.\n' 'The \'grep -z\' no longer automatically treats the byte \'\\200\' as binary data.\n' 'Context no longer excludes selected lines omitted because of -m. For example, ' '\'grep "^" -m1 -A1\' now outputs the first two input lines, not just the first ' 'line.\n', remediation= 'Please update your scripts to be compatible with the changes.', severity='low')
def report_skipped_repos(self, repos, pkgs): title = 'Some enabled RPM repositories are unknown to Leapp' summary_data = [] summary_data.append( 'The following repositories with Red Hat-signed packages are unknown to Leapp:' ) summary_data.extend(['- ' + r for r in repos]) summary_data.append( 'And the following packages installed from those repositories may not be upgraded:' ) summary_data.extend(['- ' + p for p in pkgs]) summary = '\n'.join(summary_data) reporting.report_with_remediation( title=title, summary=summary, remediation= 'You can file a request to add this repository to the scope of in-place upgrades by filing a support ticket', severity='low') if is_verbose(): self.log.info('\n'.join([title, summary]))
def process(self): unsupported_tables = [] unsupported_ipset_types = [] list_separator_fmt = '\n -' for facts in self.consume(FirewalldFacts): for table in facts.ebtablesTablesInUse: if not private.isEbtablesTableSupported(table): unsupported_tables.append(table) for ipset_type in facts.ipsetTypesInUse: if not private.isIpsetTypeSupportedByNftables(ipset_type): unsupported_ipset_types.append(ipset_type) if unsupported_tables: format_tuple = ( list_separator_fmt, list_separator_fmt.join(list(set(unsupported_tables))), ) report_with_remediation( title='Firewalld is using an unsupported ebtables table.', summary='ebtables in RHEL-8 does not support these tables:{}{}' .format(*format_tuple), remediation= 'Remove firewalld direct rules that use these ebtables tables:{}{}' .format(*format_tuple), severity='high', flags=['inhibitor']) if unsupported_ipset_types: format_tuple = ( list_separator_fmt, list_separator_fmt.join(list(set(unsupported_ipset_types))), ) report_with_remediation( title='Firewalld is using an unsupported ipset type.', summary= 'These ipset types are not supported by firewalld\'s nftables backend:{}{}' .format(*format_tuple), remediation='Remove ipsets of these types from firewalld:{}{}'. format(*format_tuple), severity='high', flags=['inhibitor'])
def process(self): for decision in self.consume(SelinuxRelabelDecision): if decision.set_relabel: try: with open('/.autorelabel', 'w'): pass report_generic( title='SElinux scheduled for relabelling', summary= '/.autorelabel file touched on root in order to schedule SElinux relabelling.', severity='low', ) except OSError as e: # FIXME: add an "action required" flag later report_with_remediation( title='Could not schedule SElinux for relabelling', summary='./autorelabel file could not be created: {}.'. format(e), remediation= 'Please set autorelabelling manually after the upgrade.', severity='high') self.log.critical( 'Could not schedule SElinux for relabelling: %s.' % e)
def process(self): with open('files/removed_drivers.txt', 'r') as removed: removed_drivers = [] whitelisted_modules = set() collected_drivers = set() drivers_to_report = set() # Extracting kernel drivers from the files/removed_drivers.txt. for line in removed.readlines(): token = line.strip() if token.startswith('#') or not token: # We do not want comments or empty lines. continue removed_drivers.append(token) # Consuming whitelisted kernel modules. for fact in self.consume(WhitelistedKernelModules): whitelisted_modules.update(fact.whitelisted_modules) # Collecting only non-whitelisted drivers that are part of the # files/removed_drivers.txt. for fact in self.consume(ActiveKernelModulesFacts): for active_module in fact.kernel_modules: if active_module.filename in whitelisted_modules: continue if active_module.filename in removed_drivers: collected_drivers.add(active_module.filename) # Going over the collected drivers and considering for reporting only # those drivers that are currently used by some device. udevadm_db = '' for fact in self.consume(UdevAdmInfoData): udevadm_db += fact.db for line in udevadm_db.split('\n'): if 'E: DRIVER=' in line: _, driver = line.split('=') if driver in collected_drivers: drivers_to_report.add(driver) # In the end, we are only going to report drivers that are: # - removed in the RHEL8 (are part of files/removed_drivers.txt) # - not whitelisted # - currently being used by some device if drivers_to_report: title = ( 'Detected loaded kernel drivers which have been removed ' 'in RHEL 8. Upgrade cannot proceed.') URL = ( 'https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html-single/' 'considerations_in_adopting_rhel_8/index#removed-device-drivers_hardware-enablement' ) summary = ( 'Support for the following currently loaded RHEL 7 ' 'device drivers has been removed in RHEL 8: \n - {}' '\nPlease see {} for details.'.format( '\n - '.join(drivers_to_report), URL)) remediation = ( 'Please disable detected kernel drivers in ' 'order to proceed with the upgrade process using the rmmod tool.' ) report_with_remediation(title=title, summary=summary, remediation=remediation, severity='high', flags=['inhibitor'])