def get_errata(update_id): h = rhnSQL.prepare("""select e.id, e.advisory, e.advisory_name, e.advisory_rel from rhnerrata e where e.advisory_name = :name """) h.execute(name=update_id) ret = h.fetchone_dict() or None if not ret: return None h = rhnSQL.prepare("""select distinct c.label from rhnchannelerrata ce join rhnchannel c on c.id = ce.channel_id where ce.errata_id = :eid """) h.execute(eid=ret['id']) channels = h.fetchall_dict() or [] ret['channels'] = channels ret['packages'] = [] h = rhnSQL.prepare(""" select p.id as package_id, pn.name, pevr.epoch, pevr.version, pevr.release, pa.label as arch, p.org_id, cv.checksum, cv.checksum_type from rhnerratapackage ep join rhnpackage p on p.id = ep.package_id join rhnpackagename pn on pn.id = p.name_id join rhnpackageevr pevr on pevr.id = p.evr_id join rhnpackagearch pa on pa.id = p.package_arch_id join rhnchecksumview cv on cv.id = p.checksum_id where ep.errata_id = :eid """) h.execute(eid=ret['id']) packages = h.fetchall_dict() or [] for pkg in packages: ipackage = IncompletePackage().populate(pkg) ipackage['epoch'] = pkg.get('epoch', '') ipackage['checksums'] = { ipackage['checksum_type']: ipackage['checksum'] } ret['packages'].append(ipackage) return ret
def associate_package(self, pack): package = {} package['name'] = pack.name package['version'] = pack.version package['release'] = pack.release package['arch'] = pack.arch package['checksum'] = pack.a_pkg.checksum package['checksum_type'] = pack.a_pkg.checksum_type package['channels'] = [{'label': self.channel_label, 'id': self.channel['id']}] package['org_id'] = self.channel['org_id'] # use epoch from file header because createrepo puts epoch="0" to # primary.xml even for packages with epoch='' package['epoch'] = pack.a_pkg.header['epoch'] return IncompletePackage().populate(package)
def associate_package(self, pack): package = {} package['name'] = pack.name package['version'] = pack.version package['release'] = pack.release package['arch'] = pack.arch if pack.a_pkg: package['checksum'] = pack.a_pkg.checksum package['checksum_type'] = pack.a_pkg.checksum_type # use epoch from file header because createrepo puts epoch="0" to # primary.xml even for packages with epoch='' package['epoch'] = pack.a_pkg.header['epoch'] else: # RPM not available but package metadata are in DB, reuse these values package['checksum'] = pack.checksum package['checksum_type'] = pack.checksum_type package['epoch'] = pack.epoch package['channels'] = [{'label': self.channel_label, 'id': self.channel['id']}] package['org_id'] = self.channel['org_id'] return IncompletePackage().populate(package)
def _channelPackageSubscription(self, authobj, info): # Authorize the org id passed authobj.authzOrg(info) packageList = info.get('packages') or [] if not packageList: log_debug(1, "No packages found; done") return 0 if 'channels' not in info or not info['channels']: log_debug(1, "No channels found; done") return 0 channelList = info['channels'] authobj.authzChannels(channelList) # Have to turn the channel list into a list of Channel objects channelList = [Channel().populate({'label': x}) for x in channelList] # Since we're dealing with superusers, we allow them to change the org # id # XXX check if we don't open ourselves too much (misa 20030422) org_id = info.get('orgId') if org_id == '': org_id = None batch = Collection() package_keys = ['name', 'version', 'release', 'epoch', 'arch'] for package in packageList: for k in package_keys: if k not in package: raise Exception("Missing key %s" % k) if k == 'epoch': if package[k] is not None: if package[k] == '': package[k] = None else: package[k] = str(package[k]) else: package[k] = str(package[k]) if package['arch'] == 'src' or package['arch'] == 'nosrc': # Source package - no reason to continue continue _checksum_sql_filter = "" if 'md5sum' in package: # for old rhnpush compatibility package['checksum_type'] = 'md5' package['checksum'] = package['md5sum'] exec_args = { 'name': package['name'], 'pkg_epoch': package['epoch'], 'pkg_version': package['version'], 'pkg_rel': package['release'], 'pkg_arch': package['arch'], 'orgid': org_id } if 'checksum' in package and CFG.ENABLE_NVREA: _checksum_sql_filter = """and c.checksum = :checksum and c.checksum_type = :checksum_type""" exec_args.update({ 'checksum_type': package['checksum_type'], 'checksum': package['checksum'] }) h = rhnSQL.prepare(self._get_pkg_info_query % _checksum_sql_filter) h.execute(**exec_args) row = h.fetchone_dict() package['checksum_type'] = row['checksum_type'] package['checksum'] = row['checksum'] package['org_id'] = org_id package['channels'] = channelList batch.append(IncompletePackage().populate(package)) caller = "server.app.channelPackageSubscription" backend = SQLBackend() importer = ChannelPackageSubscription(batch, backend, caller=caller) try: importer.run() except IncompatibleArchError: e = sys.exc_info()[1] raise_with_tb(rhnFault(50, string.join(e.args), explain=0), sys.exc_info()[2]) except InvalidChannelError: e = sys.exc_info()[1] raise_with_tb(rhnFault(50, str(e), explain=0), sys.exc_info()[2]) affected_channels = importer.affected_channels log_debug(3, "Computing errata cache for systems affected by channels", affected_channels) schedule_errata_cache_update(affected_channels) rhnSQL.commit() return 0
def upload_updates(self, notices): batch = [] typemap = { 'security': 'Security Advisory', 'recommended': 'Bug Fix Advisory', 'bugfix': 'Bug Fix Advisory', 'optional': 'Product Enhancement Advisory', 'feature': 'Product Enhancement Advisory', 'enhancement': 'Product Enhancement Advisory' } channel_advisory_names = self.list_errata() for notice in notices: notice = self.fix_notice(notice) if not self.force_all_errata and notice[ 'update_id'] in channel_advisory_names: continue advisory = notice['update_id'] + '-' + notice['version'] existing_errata = self.get_errata(notice['update_id']) e = Erratum() e['errata_from'] = notice['from'] e['advisory'] = advisory e['advisory_name'] = notice['update_id'] e['advisory_rel'] = notice['version'] e['advisory_type'] = typemap.get(notice['type'], 'Product Enhancement Advisory') e['product'] = notice['release'] or 'Unknown' e['description'] = notice['description'] e['synopsis'] = notice['title'] or notice['update_id'] if (notice['type'] == 'security' and notice['severity'] and not e['synopsis'].startswith(notice['severity'] + ': ')): e['synopsis'] = notice['severity'] + ': ' + e['synopsis'] if 'summary' in notice and not notice['summary'] is None: e['topic'] = notice['summary'] else: e['topic'] = ' ' if 'solution' in notice and not notice['solution'] is None: e['solution'] = notice['solution'] else: e['solution'] = ' ' e['issue_date'] = self._to_db_date(notice['issued']) if notice['updated']: e['update_date'] = self._to_db_date(notice['updated']) else: e['update_date'] = self._to_db_date(notice['issued']) e['org_id'] = self.org_id e['notes'] = '' e['channels'] = [] e['packages'] = [] e['files'] = [] if existing_errata: e['channels'] = existing_errata['channels'] e['packages'] = existing_errata['packages'] e['channels'].append({'label': self.channel_label}) for pkg in notice['pkglist'][0]['packages']: param_dict = { 'name': pkg['name'], 'version': pkg['version'], 'release': pkg['release'], 'arch': pkg['arch'], 'channel_id': int(self.channel['id']), } if pkg['epoch'] == '0': epochStatement = "(pevr.epoch is NULL or pevr.epoch = '0')" elif pkg['epoch'] is None or pkg['epoch'] == '': epochStatement = "pevr.epoch is NULL" else: epochStatement = "pevr.epoch = :epoch" param_dict['epoch'] = pkg['epoch'] if self.org_id: param_dict['org_id'] = self.org_id orgStatement = "= :org_id" else: orgStatement = "is NULL" h = rhnSQL.prepare(""" select p.id, pevr.epoch, c.checksum, c.checksum_type from rhnPackage p join rhnPackagename pn on p.name_id = pn.id join rhnpackageevr pevr on p.evr_id = pevr.id join rhnpackagearch pa on p.package_arch_id = pa.id join rhnArchType at on pa.arch_type_id = at.id join rhnChecksumView c on p.checksum_id = c.id join rhnChannelPackage cp on p.id = cp.package_id where pn.name = :name and p.org_id %s and pevr.version = :version and pevr.release = :release and pa.label = :arch and %s and at.label = 'rpm' and cp.channel_id = :channel_id """ % (orgStatement, epochStatement)) h.execute(**param_dict) cs = h.fetchone_dict() or None if not cs: if 'epoch' in param_dict: epoch = param_dict['epoch'] + ":" else: epoch = "" log( 2, "No checksum found for %s-%s%s-%s.%s." " Skipping Package" % (param_dict['name'], epoch, param_dict['version'], param_dict['release'], param_dict['arch'])) continue newpkgs = [] for oldpkg in e['packages']: if oldpkg['package_id'] != cs['id']: newpkgs.append(oldpkg) package = IncompletePackage().populate(pkg) package['epoch'] = cs['epoch'] package['org_id'] = self.org_id package['checksums'] = {cs['checksum_type']: cs['checksum']} package['checksum_type'] = cs['checksum_type'] package['checksum'] = cs['checksum'] package['package_id'] = cs['id'] newpkgs.append(package) e['packages'] = newpkgs if len(e['packages']) == 0: # FIXME: print only with higher debug option log(2, "Advisory %s has empty package list." % e['advisory_name']) e['keywords'] = [] if notice['reboot_suggested']: kw = Keyword() kw.populate({'keyword': 'reboot_suggested'}) e['keywords'].append(kw) if notice['restart_suggested']: kw = Keyword() kw.populate({'keyword': 'restart_suggested'}) e['keywords'].append(kw) e['bugs'] = [] e['cve'] = [] if notice['references']: bzs = [ r for r in notice['references'] if r['type'] == 'bugzilla' ] if len(bzs): tmp = {} for bz in bzs: try: bz_id = int(bz['id']) # This can happen in some incorrectly generated updateinfo, let's be smart except ValueError: log( 2, "Bugzilla assigned to advisory %s has invalid id: %s, trying to get it from URL..." % (e['advisory_name'], bz['id'])) bz_id = int( re.search(r"\d+$", bz['href']).group(0)) if bz_id not in tmp: bug = Bug() bug.populate({ 'bug_id': bz_id, 'summary': bz['title'], 'href': bz['href'] }) e['bugs'].append(bug) tmp[bz_id] = None cves = [r for r in notice['references'] if r['type'] == 'cve'] if len(cves): tmp = {} for cve in cves: if cve['id'] not in tmp: e['cve'].append(cve['id']) tmp[cve['id']] = None others = [ r for r in notice['references'] if not r['type'] == 'bugzilla' and not r['type'] == 'cve' ] if len(others): tmp = len(others) refers_to = "" for other in others: if refers_to: refers_to += "\n" refers_to += other['href'] e['refers_to'] = refers_to e['locally_modified'] = None batch.append(e) if batch: log(0, "Syncing %s new errata to channel." % len(batch)) backend = SQLBackend() importer = ErrataImport(batch, backend) importer.run() self.regen = True elif notices: log(0, "No new errata to sync.")
def upload_updates(self, notices): batch = [] skipped_updates = 0 typemap = { 'security': 'Security Advisory', 'recommended': 'Bug Fix Advisory', 'bugfix': 'Bug Fix Advisory', 'optional': 'Product Enhancement Advisory', 'feature': 'Product Enhancement Advisory', 'enhancement': 'Product Enhancement Advisory' } for notice in notices: notice = self.fix_notice(notice) existing_errata = self.get_errata(notice['update_id']) e = Erratum() e['errata_from'] = notice['from'] e['advisory'] = notice['update_id'] e['advisory_name'] = notice['update_id'] e['advisory_rel'] = notice['version'] e['advisory_type'] = typemap.get(notice['type'], 'Product Enhancement Advisory') e['product'] = notice['release'] or 'Unknown' e['description'] = notice['description'] e['synopsis'] = notice['title'] or notice['update_id'] if (notice['type'] == 'security' and notice['severity'] and not e['synopsis'].startswith(notice['severity'] + ': ')): e['synopsis'] = notice['severity'] + ': ' + e['synopsis'] if 'summary' in notice and not notice['summary'] is None: e['topic'] = notice['summary'] else: e['topic'] = ' ' if 'solution' in notice and not notice['solution'] is None: e['solution'] = notice['solution'] else: e['solution'] = ' ' e['issue_date'] = self._to_db_date(notice['issued']) if notice['updated']: e['update_date'] = self._to_db_date(notice['updated']) else: e['update_date'] = self._to_db_date(notice['issued']) e['org_id'] = self.channel['org_id'] e['notes'] = '' e['channels'] = [] e['packages'] = [] e['files'] = [] if existing_errata: e['channels'] = existing_errata['channels'] e['packages'] = existing_errata['packages'] e['channels'].append({'label': self.channel_label}) for pkg in notice['pkglist'][0]['packages']: param_dict = { 'name': pkg['name'], 'version': pkg['version'], 'release': pkg['release'], 'arch': pkg['arch'], 'channel_id': int(self.channel['id']), } if pkg['epoch'] == '0': epochStatement = "(pevr.epoch is NULL or pevr.epoch = '0')" elif pkg['epoch'] is None or pkg['epoch'] == '': epochStatement = "pevr.epoch is NULL" else: epochStatement = "pevr.epoch = :epoch" param_dict['epoch'] = pkg['epoch'] if self.channel['org_id']: param_dict['org_id'] = self.channel['org_id'] orgStatement = "= :org_id" else: orgStatement = "is NULL" h = rhnSQL.prepare(""" select p.id, pevr.epoch, c.checksum, c.checksum_type from rhnPackage p join rhnPackagename pn on p.name_id = pn.id join rhnpackageevr pevr on p.evr_id = pevr.id join rhnpackagearch pa on p.package_arch_id = pa.id join rhnArchType at on pa.arch_type_id = at.id join rhnChecksumView c on p.checksum_id = c.id join rhnChannelPackage cp on p.id = cp.package_id where pn.name = :name and p.org_id %s and pevr.version = :version and pevr.release = :release and pa.label = :arch and %s and at.label = 'rpm' and cp.channel_id = :channel_id """ % (orgStatement, epochStatement)) h.execute(**param_dict) cs = h.fetchone_dict() or None if not cs: if param_dict.has_key('epoch'): epoch = param_dict['epoch'] + ":" else: epoch = "" log_debug( 1, "No checksum found for %s-%s%s-%s.%s." " Skipping Package" % (param_dict['name'], epoch, param_dict['version'], param_dict['release'], param_dict['arch'])) continue newpkgs = [] for oldpkg in e['packages']: if oldpkg['package_id'] != cs['id']: newpkgs.append(oldpkg) package = IncompletePackage().populate(pkg) package['epoch'] = cs['epoch'] package['org_id'] = self.channel['org_id'] package['checksums'] = {cs['checksum_type']: cs['checksum']} package['checksum_type'] = cs['checksum_type'] package['checksum'] = cs['checksum'] package['package_id'] = cs['id'] newpkgs.append(package) e['packages'] = newpkgs if len(e['packages']) == 0: skipped_updates = skipped_updates + 1 continue e['keywords'] = [] if notice['reboot_suggested']: kw = Keyword() kw.populate({'keyword': 'reboot_suggested'}) e['keywords'].append(kw) if notice['restart_suggested']: kw = Keyword() kw.populate({'keyword': 'restart_suggested'}) e['keywords'].append(kw) e['bugs'] = [] e['cve'] = [] if notice['references']: bzs = [ r for r in notice['references'] if r['type'] == 'bugzilla' ] if len(bzs): tmp = {} for bz in bzs: if bz['id'] not in tmp: bug = Bug() bug.populate({ 'bug_id': bz['id'], 'summary': bz['title'], 'href': bz['href'] }) e['bugs'].append(bug) tmp[bz['id']] = None cves = [r for r in notice['references'] if r['type'] == 'cve'] if len(cves): tmp = {} for cve in cves: if cve['id'] not in tmp: e['cve'].append(cve['id']) tmp[cve['id']] = None others = [ r for r in notice['references'] if not r['type'] == 'bugzilla' and not r['type'] == 'cve' ] if len(others): tmp = len(others) refers_to = "" for other in others: if refers_to: refers_to += "\n" refers_to += other['href'] e['refers_to'] = refers_to e['locally_modified'] = None batch.append(e) if skipped_updates > 0: self.print_msg("%d errata skipped because of empty package list." % skipped_updates) backend = SQLBackend() importer = ErrataImport(batch, backend) importer.run() self.regen = True