Example #1
0
    def _createDeps(
        self, productName, versionName, flavor=None, tag=None, recursive=False, exact=False, mapping=server.Mapping()
    ):
        """return a list of product dependencies for a given project.  This 
        function returns a proto-dependency list providing only as much 
        generic information as is possible without knowing the details of 
        how the data is organized on the server.  Thus, the dependency list
        will not include 
        """
        if flavor is None:
            flavor = self.flavor
        if tag is None:
            tag = self.tag
        productList = Manifest(productName, versionName, self.Eups, self.verbose - 1, log=self.log)

        # add a record for the top product
        productList.addDependency(productName, versionName, flavor, None, None, None, False)

        dependencies = None
        tablefile = None
        if self.noeups:
            if recursive and self.verbose > 0:
                print >>self.log, "Warning dependencies are not guaranteed", "to be recursive when using noeups option"

            def getTableFile(product, version, flavor):
                tablefile = self.findTableFile(product, version, flavor)
                # use the server as source of package information
                if not tablefile and self.distServer:
                    try:
                        tablefile = self.distServer.getTableFile(product, version, self.flavor)
                    except RemoteFileNotFound, e:
                        pass
                return tablefile

            tablefile = getTableFile(productName, versionName, self.flavor)
            if not tablefile:
                buildProduct, buildVersion = mapping.apply(productName, versionName, self.flavor)
                if buildProduct == productName and buildVersion != versionName:
                    tablefile = getTableFile(productName, buildVersion, self.flavor)

            if not tablefile and self.verbose > 0:
                print >>self.log, "Failed to find %s's table file; trying eups" % productName
Example #2
0
    def _createDeps(self, productName, versionName, flavor=None, tag=None, 
                    recursive=False, exact=False, mapping=server.Mapping()):
        """return a list of product dependencies for a given project.  This 
        function returns a proto-dependency list providing only as much 
        generic information as is possible without knowing the details of 
        how the data is organized on the server.  Thus, the dependency list
        will not include 
        """
        if flavor is None:  flavor = self.flavor
        if tag is None:  tag = self.tag
        productList = Manifest(productName, versionName, self.Eups, self.verbose-1,
                               log=self.log)

        # add a record for the top product
        productList.addDependency(productName, versionName, flavor, None, None, None, False)

        dependencies = None
        tablefile = None
        if self.noeups:
            if recursive and self.verbose > 0:
                print >> self.log, "Warning dependencies are not guaranteed", \
                    "to be recursive when using noeups option"

            def getTableFile(product, version, flavor):
                tablefile = self.findTableFile(product, version, flavor)
                # use the server as source of package information
                if not tablefile and self.distServer:
                    try:
                        tablefile = self.distServer.getTableFile(product, version, self.flavor)
                    except RemoteFileNotFound, e:
                        pass
                return tablefile

            tablefile = getTableFile(productName, versionName, self.flavor)
            if not tablefile:
                buildProduct, buildVersion = mapping.apply(productName, versionName, self.flavor)
                if buildProduct == productName and buildVersion != versionName:
                    tablefile = getTableFile(productName, buildVersion, self.flavor)

            if not tablefile and self.verbose > 0:
                print >> self.log, "Failed to find %s's table file; trying eups" % productName
Example #3
0
    def getManifest(self, product, version, flavor, noaction=False):
        if noaction:
            return Manifest()

        if version is None:
            raise RuntimeError("Unspecified version for %s" % product)

        tablefile = self.getTableFile(product, version, flavor)
        table = Table(tablefile)
        deps = table.dependencies(self.Eups, recursive=True)
        deps.reverse()

        manifest = Manifest(product, version)
        for p, optional, depth in deps:
            if not optional or self.Eups.findProduct(p.name, p.version):
                manifest.addDependency(p.name, p.version, p.flavor, None, None, None, optional)

        distId = "build:%s-%s.build" % (product, version)
        tableName = "%s.table" % product
        manifest.addDependency(product, version, flavor, tableName, os.path.join(product, version), distId, False)

        return manifest
Example #4
0
    def getManifest(self, product, version, flavor, noaction=False):
        if noaction:
            return Manifest()

        if version is None:
            raise RuntimeError("Unspecified version for %s" % product)

        tablefile = self.getTableFile(product, version, flavor)
        table = Table(tablefile)
        deps = table.dependencies(self.Eups, recursive=True)
        deps.reverse()

        manifest = Manifest(product, version)
        for p, optional, depth in deps:
            if not optional or self.Eups.findProduct(p.name, p.version):
                manifest.addDependency(p.name, p.version, p.flavor, None, None,
                                       None, optional)

        distId = "build:%s-%s.build" % (product, version)
        tableName = "%s.table" % product
        manifest.addDependency(product, version, flavor, tableName,
                               os.path.join(product, version), distId, False)

        return manifest
Example #5
0
    def install(self, product, version=None, updateTags=True, alsoTag=None,
                depends=DEPS_ALL, noclean=False, noeups=False, options=None,
                manifest=None, searchDep=None):
        """
        Install a product and all its dependencies.
        @param product     the name of the product to install
        @param version     the desired version of the product.  This can either 
                            be a version string or an instance of Tag.  If 
                            not provided (or None) the most preferred version 
                            will be installed.  
        @param updateTags  when True (default), server-assigned tags will 
                            be updated for this product and all its dependcies
                            to match those recommended on the server (even if
                            a product is already installed); if False, tags 
                            will not be changed.
        @param alsoTag     A list of tags to assign to all installed products
                            (in addition to server tags).  This can either be
                            a space-delimited list, a list of string names,
                            a Tag instance, or a list of Tag instances.
        @param depends     If DEPS_ALL, product and dependencies will be installed
                              DEPS_NONE, dependencies will not be installed
                              DEPS_ONLY, only dependencies will be installed,
                              usefull for developement purpose (before a 
                              setup -r .)
        @param noclean     If False (default), the build directory will get
                            cleaned up after a successful install.  A True
                            value prevents this.
        @param noeups      if False (default), needed products that are already
                            installed will be skipped over.  If True, an 
                            attempt is made to install them anyway.  This 
                            allows a product to be installed in the target
                            install stack even if it is available in another
                            stack managed by EUPS.  Note, however, that if a
                            needed product is already installed into the target
                            stack, the installation may fail.  Use with caution.
        @param options     a dictionary of named options that are used to fine-
                            tune the behavior of this Distrib class.  See 
                            discussion above for a description of the options
                            supported by this implementation; sub-classes may
                            support different ones.
        @param manifest    use this manifest (a local file) as the manifest for 
                            the requested product instead of downloading manifest
                            from the server.
        @param searchDep   if False, install will be prevented from recursively
                            looking for dependencies of dependencies listed in
                            manifests.  In this case, it is assumed that a 
                            manifest contains all necessary dependencies.  If 
                            True, the distribution identifiers in the manifest
                            file are ignored and the dependencies will always
                            be recursively searched for.  If None,
                            the choice to recurse is left up to the server 
                            where the manifest comes from (which usually 
                            defaults to False).
        """
        if alsoTag is not None:
            if isinstance(alsoTag, str):
                alsoTag = [self.eups.tags.getTag(t) for t in alsoTag.split()]
            elif isinstance(alsoTag, Tag):
                alsoTag = [alsoTag]

        pkg = self.findPackage(product, version)
        if not pkg:
            raise ProductNotFound(product, version,
                    msg="Product %s %s not found in any package repository" % 
                        (product, version))

        (product, version, flavor, pkgroot) = pkg
        productRoot = self.getInstallRoot()
        if productRoot is None:
            raise EupsException("Unable to find writable place to install in EUPS_PATH")

        if manifest is not None:
            if not manifest or os.path.exists(manifest):
                raise EupsException("%s: user-provided manifest not found" %
                                    manifest)
            man = Manifest.fromFile(manifest, self.eups, 
                                    verbosity=self.eups.verbose-1)
        else:
            man = self.repos[pkgroot].getManifest(product, version, flavor)

        man.remapEntries()              # allow user to rewrite entries in the manifest
        if product not in [p.product for p in man.getProducts()]:
            raise EupsException("You asked to install %s %s but it is not in the manifest\nCheck manifest.remap (see \"eups startup\") and/or increase the verbosity" % (product, version))

        self._msgs = {}
        self._recursiveInstall(0, man, product, version, flavor, pkgroot, 
                               productRoot, updateTags, alsoTag, options, 
                               depends, noclean, noeups)
Example #6
0
    def writeManifest(self, serverDir, productDeps, product, version,
                      flavor=None, force=False):
        """write out a manifest file for a given product with the given
        dependencies.  See getManifestPath() for an explanation of where
        manifests are deployed.  

        @param serverDir      a local directory representing the root of the 
                                  package distribution tree
        @param productDeps    the list of product dependencies.  Each item in
                                  the list is a Dependency instance
        @param product        the name of the product to create the package 
                                distribution for
        @param version        the name of the product version
        @param flavor         the flavor of the target platform; this may 
                                be ignored by the implentation
        """

        self.initServerTree(serverDir)

        out = self.getManifestPath(serverDir, product, version, self.flavor)
        mandir = os.path.dirname(out)
        if not os.path.exists(mandir):
	        os.makedirs(mandir)

        man = Manifest(product, version, self.Eups, 
                       verbosity=self.verbose-1, log=self.log)
        for dep in productDeps:
            man.addDepInst(dep)

        def getTableFile(product, version): 
            fulltablename = dep.tablefile
            tabledir = os.path.join(serverDir, "tables")
            dep.tablefile = "%s-%s.table" % (dep.product, dep.version)
            tablefile_for_distrib = os.path.join(tabledir, dep.tablefile)
            return fulltablename, tablefile_for_distrib
        
        def copyTableFile(fulltablename, tablefile_for_distrib):
            if os.access(tablefile_for_distrib, os.R_OK) and not force:
                if self.Eups.verbose > 1:
                    print >> sys.stderr, "Not recreating", tablefile_for_distrib
                return True
            if not os.path.exists(fulltablename):
                return False
                print >> sys.stderr, "Tablefile %s doesn't exist; omitting" % (fulltablename)
            if self.Eups.verbose > 1:
                print >> sys.stderr, "Copying %s to %s" % (fulltablename, tablefile_for_distrib)

            # We need to update the versions in the table file after mapping.
            # We'll use this process to copy the file instead of "server.copyfile()"
            inTable = open(fulltablename)
            outTable = open(tablefile_for_distrib, "w")
            productList = dict([(p.product, p.version) for p in productDeps])

            eups.table.expandTableFile(self.Eups, outTable, inTable, productList,
                                       toplevelName=product, recurse=False)
            return True

        #
        # Go through that manifest copying table files into the distribution tree
        #
        for dep in productDeps:
            if not dep.tablefile:
                dep.tablefile = "none"
            if dep.tablefile == "none":
                continue

            fulltablename, tablefile_for_distrib = getTableFile(product, version)
            if not copyTableFile(fulltablename, tablefile_for_distrib):
                # Try the repository version
                haveTable = False
                repoVersion = hooks.config.Eups.repoVersioner(product, version)
                if repoVersion != version:
                    fulltablename, tablefile_for_distrib = getTableFile(product, repoVersion)
                    if copyTableFile(fulltablename, tablefile_for_distrib):
                        haveTable = True
                if not haveTable:
                    print >> sys.stderr, "Tablefile %s doesn't exist; omitting" % (fulltablename)

        #
        # Finally write the manifest file itself
        #
        man.write(out, flavor=flavor, noOptional=False)
        self.setGroupPerms(out)
Example #7
0
    def create(
        self,
        distribTypeName,
        product,
        version,
        tag=None,
        nodepend=False,
        options=None,
        manifest=None,
        packageId=None,
        repositories=None,
    ):
        """create and all necessary files for making a particular package
        available and deploy them into a local server directory.  This creates
        not only the requested product but also all of its dependencies unless
        nodepends is True.  Unless Eups.force is True, it will not recreate the 
        a package that is already deployed under the serverRoot directory.
        If repositories is provided, then a dependency package is not deployed
        if it is available from any of the repositories given.  

        @param distribTypeName  the name of the distribution type to create.  
                              The recognized names are those registered to the 
                              DistribFactory passed to this Distribution's
                              constructor.  Names recognized by default include
                              "builder", "pacman", and "tarball".
        @param product      the name of the product to create
        @param version      the version of the product to create
        @param tag          if not None, update (or create) the tagged release
                              list for this tag name.  Only the information 
                              for the given product will be added/updated.  
                              (Default: True)
        @param nodepend     if True, only the requested product package will be 
                              created.  The product dependencies will be skipped.
                              (Default: False)
        @param manifest     an existing manifest filename; if provided, this 
                              will be used as the list of dependencies to assume
                              for this product, rather than generating the 
                              list from the EUPS database.  The deployed manifest
                              will be a modified version in that the distIDs for
                              undeployed packages will be updated and, if 
                              necessary, an entry will be added for the top
                              product (specified by the inputs to this function).
                              Note that this implementation will (unless 
                              nodepend is True) consult the remote server to 
                              determine if the package is available with the 
                              given distID.
        @param packageId     name:version for distribution; default 
                              product:version (either field may be omitted)
        @param repositories  if provided and nodepend=False, then dependency
                              products will not be deployed if they are 
                              already deployed in any of the repositories 
                              given.  
        """
        if not self.isWritable():
            raise RuntimeError("Unable to create packages for this repository (Choose a local repository)")

        opts = self._mergeOptions(options)

        rebuildMapping = options.get("rebuildMapping", Mapping())
        rebuildInverse = rebuildMapping.inverse()
        rebuildProduct, rebuildVersion = rebuildMapping.apply(product, version)

        try:
            distrib = self.distFactory.createDistribByName(
                distribTypeName, options=opts, flavor=self.flavor, verbosity=self.verbose
            )
        except KeyError:
            distrib = None
        if distrib is None:
            raise RuntimeError(
                '%s: Distrib name not recognized (known types are "%s")'
                % (distribTypeName, '", "'.join(self.distFactory.lookup.keys()))
            )

        # load manifest data
        if manifest is None:
            # create it from what we (eups) know about it
            man = distrib.createDependencies(
                rebuildProduct, rebuildVersion, self.flavor, exact=opts["exact"], mapping=rebuildInverse
            )
        else:
            # load it from the given file
            man = Manifest.fromFile(manifest, self.eups, self.eups.verbose - 1)

        man.remapEntries(mode="create", mapping=rebuildMapping)
        distrib.updateDependencies(man.getProducts(), flavor=self.flavor, mapping=rebuildInverse)

        # we will always overwrite the top package
        created = {}
        id = distrib.createPackage(self.pkgroot, rebuildProduct, rebuildVersion, self.flavor, overwrite=True)
        created["%s-%s" % (rebuildProduct, rebuildVersion)] = man.getDependency(
            rebuildProduct, version=rebuildVersion, flavor=self.flavor
        )

        if not nodepend:
            self._recursiveCreate(distrib, man, created, True, repositories, mapping=rebuildMapping)

        # update the manifest record for the requested product
        dp = man.getDependency(rebuildProduct, rebuildVersion)
        if dp is None:
            # this product is not found in the manifest; this might happen if
            # this function was passed a manifest file to use.  Just in case,
            # check the auto-generated manifest for a record and add it to
            # the given one
            tdp = distrib.createDependencies(rebuildProduct, rebuildVersion, self.flavor, mapping=rebuildInverse)
            tdp = tdp.getDependency(rebuildProduct, rebuildVersion)
            if tdp is not None:
                man.getProducts().append(tdp)
        else:
            dp.distId = id

        # deploy the manifest file
        if packageId:
            vals = packageId.split(":")
            if len(vals) != 2:
                raise RuntimeError, ('Expected package Id of form name:version, saw "%s"' % packageId)
            if vals[0] == "":
                vals[0] = product
            if vals[1] == "":
                vals[1] = version

            packageName, packageVersion = vals
        else:
            packageName = product
            packageVersion = version

        # A final mapping to ensure everything's what's intended
        man.remapEntries(mode="create", mapping=rebuildMapping)
        distrib.updateDependencies(man.getProducts(), flavor=self.flavor, mapping=rebuildInverse)
        packageName, packageVersion = rebuildMapping.apply(packageName, packageVersion, self.flavor)

        distrib.writeManifest(
            self.pkgroot, man.getProducts(), packageName, packageVersion, flavor=self.flavor, force=self.eups.force
        )
Example #8
0
    def writeManifest(self, serverDir, productDeps, product, version,
                      flavor=None, force=False):
        """write out a manifest file for a given product with the given
        dependencies.  See getManifestPath() for an explanation of where
        manifests are deployed.  

        @param serverDir      a local directory representing the root of the 
                                  package distribution tree
        @param productDeps    the list of product dependencies.  Each item in
                                  the list is a Dependency instance
        @param product        the name of the product to create the package 
                                distribution for
        @param version        the name of the product version
        @param flavor         the flavor of the target platform; this may 
                                be ignored by the implentation
        """

        self.initServerTree(serverDir)

        out = self.getManifestPath(serverDir, product, version, self.flavor)
        mandir = os.path.dirname(out)
        if not os.path.exists(mandir):
	        os.makedirs(mandir)

        man = Manifest(product, version, self.Eups, 
                       verbosity=self.verbose-1, log=self.log)
        for dep in productDeps:
            man.addDepInst(dep)

        def getTableFile(product, version): 
            fulltablename = dep.tablefile
            tabledir = os.path.join(serverDir, "tables")
            dep.tablefile = "%s-%s.table" % (dep.product, dep.version)
            tablefile_for_distrib = os.path.join(tabledir, dep.tablefile)
            return fulltablename, tablefile_for_distrib
        
        def copyTableFile(fulltablename, tablefile_for_distrib):
            if os.access(tablefile_for_distrib, os.R_OK) and not force:
                if self.Eups.verbose > 1:
                    print >> sys.stderr, "Not recreating", tablefile_for_distrib
                return True
            if not os.path.exists(fulltablename):
                return False
                print >> sys.stderr, "Tablefile %s doesn't exist; omitting" % (fulltablename)
            if self.Eups.verbose > 1:
                print >> sys.stderr, "Copying %s to %s" % (fulltablename, tablefile_for_distrib)

            # We need to update the versions in the table file after mapping.
            # We'll use this process to copy the file instead of "server.copyfile()"
            inTable = open(fulltablename)
            outTable = open(tablefile_for_distrib, "w")
            productList = dict([(p.product, p.version) for p in productDeps])

            eups.table.expandTableFile(self.Eups, outTable, inTable, productList,
                                       toplevelName=product, recurse=False, force=force)
            return True

        #
        # Go through that manifest copying table files into the distribution tree
        #
        for dep in productDeps:
            if not dep.tablefile:
                dep.tablefile = "none"
            if dep.tablefile == "none":
                continue

            fulltablename, tablefile_for_distrib = getTableFile(product, version)
            if not copyTableFile(fulltablename, tablefile_for_distrib):
                # Try the repository version
                haveTable = False
                repoVersion = hooks.config.Eups.repoVersioner(product, version)
                if repoVersion != version:
                    fulltablename, tablefile_for_distrib = getTableFile(product, repoVersion)
                    if copyTableFile(fulltablename, tablefile_for_distrib):
                        haveTable = True
                if not haveTable:
                    print >> sys.stderr, "Tablefile %s doesn't exist; omitting" % (fulltablename)

        #
        # Finally write the manifest file itself
        #
        man.write(out, flavor=flavor, noOptional=False)
        self.setGroupPerms(out)
Example #9
0
    def create(self, distribTypeName, product, version, tag=None, 
               nodepend=False, options=None, manifest=None, packageId=None,
               repositories=None):
        """create and all necessary files for making a particular package
        available and deploy them into a local server directory.  This creates
        not only the requested product but also all of its dependencies unless
        nodepends is True.  Unless Eups.force is True, it will not recreate the 
        a package that is already deployed under the serverRoot directory.
        If repositories is provided, then a dependency package is not deployed
        if it is available from any of the repositories given.  

        @param distribTypeName  the name of the distribution type to create.  
                              The recognized names are those registered to the 
                              DistribFactory passed to this Distribution's
                              constructor.  Names recognized by default include
                              "builder", "pacman", and "tarball".
        @param product      the name of the product to create
        @param version      the version of the product to create
        @param tag          if not None, update (or create) the tagged release
                              list for this tag name.  Only the information 
                              for the given product will be added/updated.  
                              (Default: True)
        @param nodepend     if True, only the requested product package will be 
                              created.  The product dependencies will be skipped.
                              (Default: False)
        @param manifest     an existing manifest filename; if provided, this 
                              will be used as the list of dependencies to assume
                              for this product, rather than generating the 
                              list from the EUPS database.  The deployed manifest
                              will be a modified version in that the distIDs for
                              undeployed packages will be updated and, if 
                              necessary, an entry will be added for the top
                              product (specified by the inputs to this function).
                              Note that this implementation will (unless 
                              nodepend is True) consult the remote server to 
                              determine if the package is available with the 
                              given distID.
        @param packageId     name:version for distribution; default 
                              product:version (either field may be omitted)
        @param repositories  if provided and nodepend=False, then dependency
                              products will not be deployed if they are 
                              already deployed in any of the repositories 
                              given.  
        """
        if not self.isWritable():
            raise RuntimeError("Unable to create packages for this repository (Choose a local repository)")
        
        opts = self._mergeOptions(options)

        rebuildMapping = options.get("rebuildMapping", Mapping())
        rebuildInverse = rebuildMapping.inverse()
        rebuildProduct, rebuildVersion = rebuildMapping.apply(product, version)

        try:
            distrib = self.distFactory.createDistribByName(distribTypeName, options=opts, 
                                                           flavor=self.flavor, verbosity=self.verbose)
        except KeyError:
            distrib = None
        if distrib is None:
            raise RuntimeError("%s: Distrib name not recognized (known types are \"%s\")" %
                               (distribTypeName, '", "'.join(self.distFactory.lookup.keys())))

        # load manifest data
        if manifest is None:
            # create it from what we (eups) know about it
            man = distrib.createDependencies(rebuildProduct, rebuildVersion, self.flavor, exact=opts["exact"], 
                                             mapping=rebuildInverse)
        else:
            # load it from the given file
            man = Manifest.fromFile(manifest, self.eups, self.eups.verbose-1)

        man.remapEntries(mode="create", mapping=rebuildMapping)
        distrib.updateDependencies(man.getProducts(), flavor=self.flavor, mapping=rebuildInverse)

        # we will always overwrite the top package
        created = {}
        id = distrib.createPackage(self.pkgroot, rebuildProduct, rebuildVersion, self.flavor, overwrite=True)
        created["%s-%s" % (rebuildProduct, rebuildVersion)] = man.getDependency(rebuildProduct,
                                                                                version=rebuildVersion,
                                                                                flavor=self.flavor)

        if not nodepend:
            self._recursiveCreate(distrib, man, created, True, repositories, mapping=rebuildMapping)

        # update the manifest record for the requested product
        dp = man.getDependency(rebuildProduct, rebuildVersion)
        if dp is None:
            # this product is not found in the manifest; this might happen if 
            # this function was passed a manifest file to use.  Just in case,
            # check the auto-generated manifest for a record and add it to
            # the given one
            tdp = distrib.createDependencies(rebuildProduct, rebuildVersion, self.flavor,
                                             mapping=rebuildInverse)
            tdp = tdp.getDependency(rebuildProduct, rebuildVersion)
            if tdp is not None:
               man.getProducts().append(tdp) 
        else:
            dp.distId = id

        # deploy the manifest file
        if packageId:
            vals = packageId.split(":")
            if len(vals) != 2:
                raise RuntimeError, ("Expected package Id of form name:version, saw \"%s\"" % packageId)
            if vals[0] == "":
                vals[0] = product
            if vals[1] == "":
                vals[1] = version
                
            packageName, packageVersion = vals
        else:
            packageName = product
            packageVersion = version

        # A final mapping to ensure everything's what's intended
        man.remapEntries(mode="create", mapping=rebuildMapping)
        distrib.updateDependencies(man.getProducts(), flavor=self.flavor, mapping=rebuildInverse)
        packageName, packageVersion = rebuildMapping.apply(packageName, packageVersion, self.flavor)

        distrib.writeManifest(self.pkgroot, man.getProducts(), packageName, packageVersion,
                              flavor=self.flavor, force=self.eups.force)