def run(self): """Perform the merge.""" from lp.services.scripts import log person_name = self.person.name log.debug('about to deactivate ~%s', person_name) self.person.deactivate(validate=False, pre_deactivate=False) log.debug('done deactivating ~%s', person_name)
def sendEmailToMaintainer(self, template_name, subject, from_address): """See `IProductNotificationJob`.""" email_template = get_email_template( "%s.txt" % template_name, app='registry') for address in self.recipients.getEmails(): body, headers = self.getBodyAndHeaders( email_template, address, self.reply_to) simple_sendmail(from_address, address, subject, body, headers) log.debug("%s has sent email to the maintainer of %s.", self.log_name, self.product.name)
def do_package(self, distro_name, archive_root): """Grab shared library info from .deb.""" fullpath = os.path.join(archive_root, self.filename) if not os.path.exists(fullpath): raise PoolFileNotFound('%s not found' % fullpath) call("dpkg -e %s" % fullpath) shlibfile = os.path.join("DEBIAN", "shlibs") if os.path.exists(shlibfile): self.shlibs = open(shlibfile).read().strip() log.debug("Grabbing shared library info from %s" % shlibfile)
def call(cmd): """Run a command, raising a RuntimeError if the command failed""" log.debug("Running %s" % cmd) p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, preexec_fn=subprocess_setup) out, err = p.communicate() for line in out.splitlines(): log.debug("> %s" % line) if p.returncode != 0: raise ExecutionError("Error %d running %s" % (p.returncode, cmd)) return p.returncode
def run(self): """Perform the merge.""" from_person_name = self.from_person.name to_person_name = self.to_person.name from lp.services.scripts import log if self.metadata.get('delete', False): log.debug( "%s is about to delete ~%s", self.log_name, from_person_name) merge_people( from_person=self.from_person, to_person=getUtility(ILaunchpadCelebrities).registry_experts, reviewer=self.reviewer, delete=True) log.debug( "%s has deleted ~%s", self.log_name, from_person_name) else: log.debug( "%s is about to merge ~%s into ~%s", self.log_name, from_person_name, to_person_name) merge_people( from_person=self.from_person, to_person=self.to_person, reviewer=self.reviewer) log.debug( "%s has merged ~%s into ~%s", self.log_name, from_person_name, to_person_name)
def preimport_sourcecheck(self, sourcepackagedata): """ Check if this SourcePackageRelease already exists. This can happen, for instance, if a source package didn't change over releases, or if Gina runs multiple times over the same release """ sourcepackagerelease = self.sphandler.checkSource( sourcepackagedata.package, sourcepackagedata.version, self.distroseries) if not sourcepackagerelease: log.debug('SPR not found in preimport: %r %r' % (sourcepackagedata.package, sourcepackagedata.version)) return None self.publish_sourcepackage(sourcepackagerelease, sourcepackagedata) return sourcepackagerelease
def findUnlistedSourcePackage(self, sp_name, sp_version, sp_component, sp_section, distroseries): """Try to find a sourcepackagerelease in the archive for the provided binarypackage data. The binarypackage data refers to a source package which we cannot find either in the database or in the input data. This commonly happens when the source package is no longer part of the distribution but a binary built from it is and thus the source is not in Sources.gz but is on the disk. This may also happen if the package has not built yet. If we fail to find it we return None and the binary importer will handle this in the same way as if the package simply wasn't in the database. I.E. the binary import will fail but the process as a whole will continue okay. """ assert not self.checkSource(sp_name, sp_version, distroseries) log.debug("Looking for source package %r (%r) in %r" % (sp_name, sp_version, sp_component)) sp_data = self._getSourcePackageDataFromDSC(sp_name, sp_version, sp_component, sp_section) if not sp_data: return None # Process the package sp_data.process_package(self.distro_name, self.archive_root) sp_data.ensure_complete() spr = self.createSourcePackageRelease(sp_data, distroseries) # Publish it because otherwise we'll have problems later. # Essentially this routine is only ever called when a binary # is encountered for which the source was not found. # Now that we have found and imported the source, we need # to be sure to publish it because the binary import code # assumes that the sources have been imported properly before # the binary import is started. Thusly since this source is # being imported "late" in the process, we publish it immediately # to make sure it doesn't get lost. SourcePackagePublisher(distroseries, self.pocket, self.component_override).publish(spr, sp_data) return spr
def preimport_binarycheck(self, archtag, binarypackagedata): """ Check if this BinaryPackageRelease already exists. This can happen, for instance, if a binary package didn't change over releases, or if Gina runs multiple times over the same release """ distroarchinfo = self.archinfo[archtag] binarypackagerelease = self.bphandler.checkBin(binarypackagedata, distroarchinfo) if not binarypackagerelease: log.debug('BPR not found in preimport: %r %r %r' % (binarypackagedata.package, binarypackagedata.version, binarypackagedata.architecture)) return None self.publish_binarypackage(binarypackagerelease, binarypackagedata, archtag) return binarypackagerelease
def run(self): """See `IRunnableJob`. Send emails to all the question recipients. """ log.debug("%s will send email for question %s.", self.log_name, self.question.id) headers = self.headers recipients = self.recipients for email in recipients.getEmails(): reason, header = recipients.getReason(email) headers['X-Launchpad-Message-Rationale'] = header headers['X-Launchpad-Message-For'] = reason.subscriber.name formatted_body = self.buildBody(reason.getReason()) simple_sendmail(self.from_address, email, self.subject, formatted_body, headers) log.debug("%s has sent email for question %s.", self.log_name, self.question.id)
def run(self): """See `IRunnableJob`. Send emails to all the question recipients. """ log.debug( "%s will send email for question %s.", self.log_name, self.question.id) headers = self.headers recipients = self.recipients for email in recipients.getEmails(): rationale, header = recipients.getReason(email) headers['X-Launchpad-Message-Rationale'] = header formatted_body = self.buildBody(rationale) simple_sendmail( self.from_address, email, self.subject, formatted_body, headers) log.debug( "%s has sent email for question %s.", self.log_name, self.question.id)
def _getSourcePackageDataFromDSC(self, sp_name, sp_version, sp_component, sp_section): try: dsc_name, dsc_path, sp_component = get_dsc_path(sp_name, sp_version, sp_component, self.archive_root) except PoolFileNotFound: # Aah well, no source package in archive either. return None log.debug("Found a source package for %s (%s) in %s" % (sp_name, sp_version, sp_component)) dsc_contents = parse_tagfile(dsc_path) dsc_contents = dict([ (name.lower(), value) for (name, value) in dsc_contents.iteritems()]) # Since the dsc doesn't know, we add in the directory, package # component and section dsc_contents['directory'] = os.path.join("pool", poolify(sp_name, sp_component)) dsc_contents['package'] = sp_name dsc_contents['component'] = sp_component dsc_contents['section'] = sp_section # the dsc doesn't list itself so add it ourselves if 'files' not in dsc_contents: log.error('DSC for %s didn\'t contain a files entry: %r' % (dsc_name, dsc_contents)) return None if not dsc_contents['files'].endswith("\n"): dsc_contents['files'] += "\n" # XXX kiko 2005-10-21: Why do we hack the md5sum and size of the DSC? # Should probably calculate it properly. dsc_contents['files'] += "xxx 000 %s" % dsc_name # SourcePackageData requires capitals capitalized_dsc = {} for k, v in dsc_contents.items(): capitalized_dsc[k.capitalize()] = v return SourcePackageData(**capitalized_dsc)
def _getSourcePackageDataFromDSC(self, sp_name, sp_version, sp_component, sp_section): try: dsc_name, dsc_path, sp_component = get_dsc_path( sp_name, sp_version, sp_component, self.archive_root) except PoolFileNotFound: # Aah well, no source package in archive either. return None log.debug("Found a source package for %s (%s) in %s" % (sp_name, sp_version, sp_component)) dsc_contents = parse_tagfile(dsc_path) dsc_contents = dict([(name.lower(), value) for (name, value) in dsc_contents.iteritems()]) # Since the dsc doesn't know, we add in the directory, package # component and section dsc_contents['directory'] = os.path.join( "pool", poolify(sp_name, sp_component)) dsc_contents['package'] = sp_name dsc_contents['component'] = sp_component dsc_contents['section'] = sp_section # the dsc doesn't list itself so add it ourselves if 'files' not in dsc_contents: log.error('DSC for %s didn\'t contain a files entry: %r' % (dsc_name, dsc_contents)) return None if not dsc_contents['files'].endswith("\n"): dsc_contents['files'] += "\n" # XXX kiko 2005-10-21: Why do we hack the md5sum and size of the DSC? # Should probably calculate it properly. dsc_contents['files'] += "xxx 000 %s" % dsc_name # SourcePackageData requires capitals capitalized_dsc = {} for k, v in dsc_contents.items(): capitalized_dsc[k.capitalize()] = v return SourcePackageData(**capitalized_dsc)
def run(self): """See `IMembershipNotificationJob`.""" TeamMembershipMailer.forMembershipStatusChange( self.member, self.team, self.reviewer, self.old_status, self.new_status, self.last_change_comment).sendAll() log.debug('MembershipNotificationJob sent email')
def run(self): """Perform the merge.""" person_name = self.person.name log.debug('about to deactivate ~%s', person_name) self.person.deactivate(validate=False, pre_deactivate=False) log.debug('done deactivating ~%s', person_name)
def run_gina(options, ztm, target_section): package_root = target_section.root distro = target_section.distro pocket_distroseries = target_section.pocketrelease distroseries = target_section.distroseries components = [c.strip() for c in target_section.components.split(",")] archs = [a.strip() for a in target_section.architectures.split(",")] pocket = target_section.pocket component_override = target_section.componentoverride source_only = target_section.source_only spnames_only = target_section.sourcepackagenames_only LIBRHOST = config.librarian.upload_host LIBRPORT = config.librarian.upload_port log.info("") log.info("=== Processing %s/%s/%s ===", distro, distroseries, pocket) log.debug("Packages read from: %s", package_root) log.info("Components to import: %s", ", ".join(components)) if component_override is not None: log.info("Override components to: %s", component_override) log.info("Architectures to import: %s", ", ".join(archs)) log.debug("Launchpad database: %s", config.database.rw_main_master) log.info("SourcePackage Only: %s", source_only) log.info("SourcePackageName Only: %s", spnames_only) log.debug("Librarian: %s:%s", LIBRHOST, LIBRPORT) log.info("") if not hasattr(PackagePublishingPocket, pocket.upper()): log.error("Could not find a pocket schema for %s", pocket) sys.exit(1) pocket = getattr(PackagePublishingPocket, pocket.upper()) if component_override: valid_components = [ component.name for component in getUtility(IComponentSet) ] if component_override not in valid_components: log.error("Could not find component %s", component_override) sys.exit(1) try: arch_component_items = ArchiveComponentItems(package_root, pocket_distroseries, components, archs, source_only) except MangledArchiveError: log.exception("Failed to analyze archive for %s", pocket_distroseries) sys.exit(1) packages_map = PackagesMap(arch_component_items) importer_handler = ImporterHandler(ztm, distro, distroseries, package_root, pocket, component_override) import_sourcepackages(distro, packages_map, package_root, importer_handler) importer_handler.commit() # XXX JeroenVermeulen 2011-09-07 bug=843728: Dominate binaries as well. dominate_imported_source_packages(ztm, log, distro, distroseries, pocket, packages_map) ztm.commit() if source_only: log.info('Source only mode... done') return for archtag in archs: try: importer_handler.ensure_arch(archtag) except DataSetupError: log.exception("Database setup required for run on %s", archtag) sys.exit(1) import_binarypackages(distro, packages_map, package_root, importer_handler) importer_handler.commit()
def run(self): """See `IMembershipNotificationJob`.""" from lp.services.scripts import log from_addr = format_address( self.team.displayname, config.canonical.noreply_from_address) admin_emails = self.team.getTeamAdminsEmailAddresses() # person might be a self.team, so we can't rely on its preferredemail. self.member_email = get_contact_email_addresses(self.member) # Make sure we don't send the same notification twice to anybody. for email in self.member_email: if email in admin_emails: admin_emails.remove(email) if self.reviewer != self.member: self.reviewer_name = self.reviewer.unique_displayname else: self.reviewer_name = 'the user' if self.last_change_comment: comment = ("\n%s said:\n %s\n" % ( self.reviewer.displayname, self.last_change_comment.strip())) else: comment = "" replacements = { 'member_name': self.member.unique_displayname, 'recipient_name': self.member.displayname, 'team_name': self.team.unique_displayname, 'team_url': canonical_url(self.team), 'old_status': self.old_status.title, 'new_status': self.new_status.title, 'reviewer_name': self.reviewer_name, 'comment': comment} template_name = 'membership-statuschange' subject = ( 'Membership change: %(member)s in %(team)s' % { 'member': self.member.name, 'team': self.team.name, }) if self.new_status == TeamMembershipStatus.EXPIRED: template_name = 'membership-expired' subject = '%s expired from team' % self.member.name elif (self.new_status == TeamMembershipStatus.APPROVED and self.old_status != TeamMembershipStatus.ADMIN): if self.old_status == TeamMembershipStatus.INVITED: subject = ('Invitation to %s accepted by %s' % (self.member.name, self.reviewer.name)) template_name = 'membership-invitation-accepted' elif self.old_status == TeamMembershipStatus.PROPOSED: subject = '%s approved by %s' % ( self.member.name, self.reviewer.name) else: subject = '%s added by %s' % ( self.member.name, self.reviewer.name) elif self.new_status == TeamMembershipStatus.INVITATION_DECLINED: subject = ('Invitation to %s declined by %s' % (self.member.name, self.reviewer.name)) template_name = 'membership-invitation-declined' elif self.new_status == TeamMembershipStatus.DEACTIVATED: subject = '%s deactivated by %s' % ( self.member.name, self.reviewer.name) elif self.new_status == TeamMembershipStatus.ADMIN: subject = '%s made admin by %s' % ( self.member.name, self.reviewer.name) elif self.new_status == TeamMembershipStatus.DECLINED: subject = '%s declined by %s' % ( self.member.name, self.reviewer.name) else: # Use the default template and subject. pass # Must have someone to mail, and be a non-open team (because open # teams are unrestricted, notifications on join/ leave do not help the # admins. if (len(admin_emails) != 0 and self.team.membership_policy != TeamMembershipPolicy.OPEN): admin_template = get_email_template( "%s-bulk.txt" % template_name, app='registry') for address in admin_emails: recipient = getUtility(IPersonSet).getByEmail(address) replacements['recipient_name'] = recipient.displayname msg = MailWrapper().format( admin_template % replacements, force_wrap=True) simple_sendmail(from_addr, address, subject, msg) # The self.member can be a self.self.team without any # self.members, and in this case we won't have a single email # address to send this notification to. if self.member_email and self.reviewer != self.member: if self.member.is_team: template = '%s-bulk.txt' % template_name else: template = '%s-personal.txt' % template_name self.member_template = get_email_template( template, app='registry') for address in self.member_email: recipient = getUtility(IPersonSet).getByEmail(address) replacements['recipient_name'] = recipient.displayname msg = MailWrapper().format( self.member_template % replacements, force_wrap=True) simple_sendmail(from_addr, address, subject, msg) log.debug('MembershipNotificationJob sent email')
def run_gina(options, ztm, target_section): # Avoid circular imports. from lp.registry.interfaces.pocket import PackagePublishingPocket package_root = target_section.root distro = target_section.distro pocket_distroseries = target_section.pocketrelease distroseries = target_section.distroseries components = [c.strip() for c in target_section.components.split(",")] archs = [a.strip() for a in target_section.architectures.split(",")] pocket = target_section.pocket component_override = target_section.componentoverride source_only = target_section.source_only spnames_only = target_section.sourcepackagenames_only LIBRHOST = config.librarian.upload_host LIBRPORT = config.librarian.upload_port log.info("") log.info("=== Processing %s/%s/%s ===", distro, distroseries, pocket) log.debug("Packages read from: %s", package_root) log.info("Components to import: %s", ", ".join(components)) if component_override is not None: log.info("Override components to: %s", component_override) log.info("Architectures to import: %s", ", ".join(archs)) log.debug("Launchpad database: %s", config.database.rw_main_master) log.info("SourcePackage Only: %s", source_only) log.info("SourcePackageName Only: %s", spnames_only) log.debug("Librarian: %s:%s", LIBRHOST, LIBRPORT) log.info("") if not hasattr(PackagePublishingPocket, pocket.upper()): log.error("Could not find a pocket schema for %s", pocket) sys.exit(1) pocket = getattr(PackagePublishingPocket, pocket.upper()) if component_override: valid_components = [component.name for component in getUtility(IComponentSet)] if component_override not in valid_components: log.error("Could not find component %s", component_override) sys.exit(1) try: arch_component_items = ArchiveComponentItems(package_root, pocket_distroseries, components, archs, source_only) except MangledArchiveError: log.exception("Failed to analyze archive for %s", pocket_distroseries) sys.exit(1) packages_map = PackagesMap(arch_component_items) importer_handler = ImporterHandler(ztm, distro, distroseries, package_root, pocket, component_override) import_sourcepackages(distro, packages_map, package_root, importer_handler) importer_handler.commit() # XXX JeroenVermeulen 2011-09-07 bug=843728: Dominate binaries as well. dominate_imported_source_packages(ztm, log, distro, distroseries, pocket, packages_map) ztm.commit() if source_only: log.info("Source only mode... done") return for archtag in archs: try: importer_handler.ensure_archinfo(archtag) except DataSetupError: log.exception("Database setup required for run on %s", archtag) sys.exit(1) import_binarypackages(distro, packages_map, package_root, importer_handler) importer_handler.commit()