Esempio n. 1
0
 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)
Esempio n. 2
0
 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)
Esempio n. 3
0
 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)
Esempio n. 4
0
    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)
Esempio n. 5
0
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
Esempio n. 6
0
    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)
Esempio n. 7
0
    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)
Esempio n. 8
0
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
Esempio n. 9
0
    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
Esempio n. 10
0
    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
Esempio n. 11
0
    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
Esempio n. 12
0
    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
Esempio n. 13
0
    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
Esempio n. 14
0
    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
Esempio n. 15
0
    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)
Esempio n. 16
0
    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)
Esempio n. 17
0
    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)
Esempio n. 18
0
    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)
Esempio n. 19
0
 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')
Esempio n. 20
0
 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)
Esempio n. 21
0
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()
Esempio n. 22
0
    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')
Esempio n. 23
0
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()