Пример #1
0
    def _checkParameters(self, distroseries):
        """Sanity check the supplied script parameters."""
        # Did the user provide a suite name? (distribution defaults
        # to 'ubuntu' which is fine.)
        if distroseries == distroseries.distribution.currentseries:
            # SoyuzScript defaults to the latest series.  Since this
            # will never get obsoleted it's safe to assume that the
            # user let this option default, so complain and exit.
            raise SoyuzScriptError(
                "Please specify a valid distroseries name with -s/--suite "
                "and which is not the most recent distroseries.")

        # Is the distroseries in an obsolete state?  Bail out now if not.
        if distroseries.status != SeriesStatus.OBSOLETE:
            raise SoyuzScriptError(
                "%s is not at status OBSOLETE." % distroseries.name)
Пример #2
0
 def loadProcessors(arch_tags):
     """Load processors for specified arch tags."""
     processors = set()
     for name in arch_tags:
         try:
             processor = getUtility(IProcessorSet).getByName(name)
             processors.add(processor)
         except ProcessorNotFound:
             raise SoyuzScriptError(
                 "Invalid architecture tag: '%s'" % name)
     return processors
Пример #3
0
 def build_location(distro, suite, component, packageset_names=None):
     """Build and return package location."""
     location = build_package_location(
         distro, suite=suite, packageset_names=packageset_names)
     if component is not None:
         try:
             the_component = getUtility(IComponentSet)[component]
         except NotFoundError:
             raise SoyuzScriptError(
                 "Invalid component name: '%s'" % component)
         location.component = the_component
     return location
Пример #4
0
    def mainTask(self):
        """Main function entry point."""
        opts = self.options

        if not specified(opts.from_distribution):
            raise SoyuzScriptError(
                "error: origin distribution not specified.")

        if not specified(opts.to_distribution):
            raise SoyuzScriptError(
                "error: destination distribution not specified.")

        if not specified(opts.to_archive):
            raise SoyuzScriptError(
                "error: destination copy archive not specified.")
        if not valid_name(opts.to_archive):
            raise SoyuzScriptError(
                "Invalid destination archive name: '%s'" % opts.to_archive)
        if opts.include_binaries:
            raise SoyuzScriptError(
                "error: copying of binary packages is not supported yet.")

        if (specified(opts.from_user) and not specified(opts.from_archive)):
            opts.from_archive = 'ppa'

        if specified(opts.from_archive) and not valid_name(opts.from_archive):
            raise SoyuzScriptError(
                "Invalid origin archive name: '%s'" % opts.from_archive)

        # For the love of $DEITY, WTF doesn't this method just accept a
        # single parameter "opts" ...
        self.populateArchive(
            opts.from_archive, opts.from_distribution, opts.from_suite,
            opts.from_user, opts.component, opts.to_distribution,
            opts.to_suite, opts.to_archive, opts.to_user, opts.reason,
            opts.include_binaries, opts.arch_tags, opts.merge_copy_flag,
            opts.packageset_delta_flag, opts.packageset_tags,
            opts.nonvirtualized)
Пример #5
0
    def populateArchive(
        self, from_archive, from_distribution, from_suite, from_user,
        component, to_distribution, to_suite, to_archive, to_user, reason,
        include_binaries, arch_tags, merge_copy_flag,
        packageset_delta_flag, packageset_tags, nonvirtualized):
        """Create archive, populate it with packages and builds.

        Please note: if a component was specified for the origin then the
        same component must be used for the destination.

        :param from_archive: the (optional) origin archive name.
        :param from_distribution: the origin's distribution.
        :param from_suite: the origin's suite.
        :param from_user: the name of the origin PPA's owner.
        :param component: the origin's component.

        :param to_distribution: destination distribution.
        :param to_suite: destination suite.

        :param to_archive: destination copy archive name.
        :param to_user: destination archive owner name.
        :param reason: reason for the package copy operation.

        :param include_binaries: whether binaries should be copied as well.
        :param arch_tags: architecture tags for which to create
            builds.
        :param merge_copy_flag: whether this is a repeated population of an
            existing copy archive.
        :param packageset_delta_flag: only show packages that are fresher or
            new in the origin archive. Do not copy anything.

        :param packageset_tags: list of packagesets to limit the packages
            copied to.
        """

        def loadProcessors(arch_tags):
            """Load processors for specified arch tags."""
            processors = set()
            for name in arch_tags:
                try:
                    processor = getUtility(IProcessorSet).getByName(name)
                    processors.add(processor)
                except ProcessorNotFound:
                    raise SoyuzScriptError(
                        "Invalid architecture tag: '%s'" % name)
            return processors

        def build_location(distro, suite, component, packageset_names=None):
            """Build and return package location."""
            location = build_package_location(
                distro, suite=suite, packageset_names=packageset_names)
            if component is not None:
                try:
                    the_component = getUtility(IComponentSet)[component]
                except NotFoundError:
                    raise SoyuzScriptError(
                        "Invalid component name: '%s'" % component)
                location.component = the_component
            return location

        archive_set = getUtility(IArchiveSet)
        # Build the origin package location.
        the_origin = build_location(
            from_distribution, from_suite, component,
            packageset_names=packageset_tags)

        # Use a non-PPA(!) origin archive if specified and existent.
        if from_archive is not None and from_user is None:
            origin_archive = archive_set.getByDistroAndName(
                the_origin.distribution, from_archive)
            if origin_archive is not None:
                the_origin.archive = origin_archive
            else:
                raise SoyuzScriptError(
                    "Origin archive does not exist: '%s'" % from_archive)
        # Use a PPA if specified and existent.
        if from_user is not None:
            origin_archive = archive_set.getPPAByDistributionAndOwnerName(
                the_origin.distribution, from_user, from_archive)
            if origin_archive is not None:
                the_origin.archive = origin_archive
            else:
                raise SoyuzScriptError(
                    "No PPA for user: '******'" % from_user)

        if the_origin.archive.private:
            raise SoyuzScriptError(
                "Cannot copy from private archive (%s)"
                % the_origin.archive.reference)

        # Build the destination package location.
        the_destination = build_location(to_distribution, to_suite, component)

        # First try to access the destination copy archive.
        copy_archive = getUtility(IArchiveSet).getByDistroAndName(
            the_destination.distribution, to_archive)

        the_destination.archive = copy_archive

        if packageset_delta_flag:
            if copy_archive is None:
                raise SoyuzScriptError(
                    "error: package set delta requested for non-existing "
                    " destination archive.")
            else:
                self._packageset_delta(the_origin, the_destination)
                return

        if not specified(to_user):
            if merge_copy_flag:
                what = 'package copy requestor'
            else:
                what = 'copy archive owner'
            raise SoyuzScriptError("error: %s not specified." % what)

        registrant = getUtility(IPersonSet).getByName(to_user)
        if registrant is None:
            raise SoyuzScriptError("Invalid user name: '%s'" % to_user)

        # No copy archive with the specified name found, create one.
        if copy_archive is None:
            if not specified(reason):
                raise SoyuzScriptError(
                    "error: reason for copy archive creation not specified.")
            if merge_copy_flag:
                raise SoyuzScriptError(
                    "error: merge copy requested for non-existing archive.")
            # The architecture tags should only be specified if the
            # destination copy archive does not exist yet and needs to be
            # created.
            if not specified(arch_tags):
                raise SoyuzScriptError(
                    "error: architecture tags not specified.")

            # First load the processors for the specified arch tags
            # from the database. This will fail if an invalid arch tag
            # name was specified on the command line; that's why it should be
            # done before creating the copy archive.
            processors = loadProcessors(arch_tags)

            # The copy archive is created in disabled mode. This gives the
            # archive owner the chance to tweak the build dependencies
            # before the switch is flipped and build activity starts.
            # Also, builds for copy archives should default to using
            # virtual builders.
            virtual = not nonvirtualized
            copy_archive = getUtility(IArchiveSet).new(
                ArchivePurpose.COPY, registrant, name=to_archive,
                distribution=the_destination.distribution,
                description=reason, enabled=False,
                require_virtualized=virtual, processors=processors)
            the_destination.archive = copy_archive
        else:
            # Archive name clash! Creation requested for existing archive with
            # the same name and distribution.
            if not merge_copy_flag:
                raise SoyuzScriptError(
                    "error: archive '%s' already exists for '%s'."
                    % (to_archive, the_destination.distribution.name))
            # The user is not supposed to specify processors on the command
            # line for existing copy archives. The processors specified when
            # the archive was created will be read from the database instead.
            if specified(arch_tags):
                raise SoyuzScriptError(
                    "error: cannot specify architecture tags for *existing* "
                    "archive.")
            # Refuse to copy to a disabled copy archive.
            if not copy_archive.enabled:
                raise SoyuzScriptError(
                    "error: cannot copy to disabled archive")

        # Now instantiate the package copy request that will capture the
        # archive population parameters in the database.
        pcr = getUtility(IPackageCopyRequestSet).new(
            the_origin, the_destination, registrant,
            copy_binaries=include_binaries, reason=unicode(reason))

        # Clone the source packages. We currently do not support the copying
        # of binary packages. It's a forthcoming feature.
        pkg_cloner = getUtility(IPackageCloner)

        # Mark the package copy request as being "in progress".
        pcr.markAsInprogress()
        self.txn.commit()

        if merge_copy_flag:
            pkg_cloner.mergeCopy(the_origin, the_destination)
        else:
            pkg_cloner.clonePackages(
                the_origin, the_destination, processors=processors)

        # Mark the package copy request as completed.
        pcr.markAsCompleted()