Exemple #1
0
    def createBranch(self,
                     project,
                     name,
                     platformLabel,
                     namespace=None,
                     description=''):
        project = self.getProject(project)
        if project.project_branches and \
                name in [b.name for b in project.project_branches]:
            raise errors.RbuildError("Branch named '%s' already exists" % name)
        doc = xobj.Document()
        doc.project_branch = br = xobj.XObj()
        br.project = xobj.XObj()
        # Why?
        for key in ('id', 'name', 'short_name', 'domain_name'):
            setattr(br.project, key, getattr(project, key))

        br.name = name
        br.platform_label = unicode(platformLabel)
        br.description = description
        if namespace:
            br.namespace = namespace
        try:
            br = project.project_branches.append(doc)
        except robj.errors.HTTPConflictError:
            raise errors.RbuildError("Branch named '%s' already exists" % name)
        return br.label
Exemple #2
0
    def getImages(self,
                  name,
                  project=None,
                  branch=None,
                  stage=None,
                  trailingVersion=None):
        '''
            Get an image by name. project limits search to that project.
            branch limits search to that branch. stage limits serach to that stage.
            trailingVersion limits the image to ones built with that group
            trailingVersion. If the query returns multiple images, return the most
            recently created.

            @param name: name of image
            @type name: str
            @param shortName: short name of project
            @type shortName: str
            @param stageName: name of stage, requires shortName
            @type stageName: str
            @param trailingVersion: trailing version of product group
            @type trailingVersion: str or None
            @return: image or None
            @rtype: rObj(image)
        '''
        # we only support stage filter if we also got a project and branch
        if stage and not (project and branch):
            raise errors.RbuildError(
                'Must provide project and branch if stage is provided')

        client = self.api._client
        uri = self.api._uri + '/images'

        # filter by image name
        filter_by = ';filter_by=AND(EQUAL(name,%s)' % name

        if project:
            filter_by += ',EQUAL(project.short_name,%s)' % project
            if stage:
                filter_by += ',EQUAL(project_branch.label,%s)' % branch
                filter_by += ',EQUAL(stage_name,%s)' % stage

        if trailingVersion:
            # filter by group trailing version
            filter_by += ',EQUAL(trailing_version,%s)' % trailingVersion

        uri += filter_by + ')'

        # always sort by most recently created first
        uri += ';order_by=-time_created'

        try:
            return client.do_GET(uri)
        except robj.errors.HTTPNotFoundError:
            raise errors.RbuildError("Unable to fetch images at '%s'" + uri)
Exemple #3
0
    def getImageTypeDef(self, product, version, imageType, arch):
        client = self.api._client
        uri = ('/products/%s/versions/%s/imageTypeDefinitions' %
               (product, version))
        try:
            for imageTypeDef in client.do_GET(uri):
                if (imageTypeDef.container.name == imageType
                        and imageTypeDef.architecture.name == arch):
                    return imageTypeDef
        except robj.errors.HTTPNotFoundError:
            raise errors.RbuildError(
                "Project '%s' and version '%s' not found" % (product, version))

        raise errors.RbuildError("No image type definition with name '%s'"
                                 " and architecture '%s'" % (imageType, arch))
Exemple #4
0
 def __init__(self, handle=None, baseDirectory=None):
     ProductStore.__init__(self, handle)
     productDirectory = getDefaultProductDirectory(baseDirectory)
     if productDirectory is None:
         if baseDirectory is None:
             raise errors.RbuildError('Could not find product directory')
         else:
             raise errors.RbuildError("No product directory at '%s'" %
                                      baseDirectory)
     self._baseDirectory = os.path.realpath(productDirectory)
     self._testProductDirectory(self._baseDirectory)
     stageName = getStageNameFromDirectory(os.getcwd())
     if stageName is not None:
         # Cannot load product yet, so cannot validate
         self._currentStage = stageName
     self.statusStore = None
Exemple #5
0
    def getProjectBranches(self, *args, **kwargs):
        '''
            Get a list of branches for a project
        '''
        try:
            project = kwargs.pop('project', args[0])
        except IndexError:
            raise TypeError("Required argument 'project' (pos 1) noti found")
        order_by = kwargs.pop('order_by', None)

        # name might be a label
        shortName, _, domainName = project.partition('.')
        project = self.getProject(shortName)

        # if the user gave us full repo hostname make
        # sure they gave us the right one
        if (domainName and project.domain_name != domainName):
            raise errors.RbuildError("could not find a project matching '%s'" %
                                     '.'.join((shortName, domainName)))

        if order_by:
            reverse = (order_by[0] == '-')
            if order_by[0] in ('-', '+'):
                order_by = order_by[1:]
            return sorted(
                project.project_branches,
                key=lambda b: getattr(b, order_by),
                reverse=reverse,
            )
        else:
            return project.project_branches
Exemple #6
0
    def createProject(self,
                      title,
                      shortName,
                      hostName=None,
                      domainName=None,
                      description='',
                      external=False,
                      external_params=None):
        assert ((external and external_params is not None)
                or (not external and external_params is None))

        doc = xobj.Document()
        doc.project = proj = xobj.XObj()
        proj.name = title
        proj.short_name = shortName
        proj.hostname = hostName or shortName
        proj.description = description or ''
        if domainName:
            proj.domain_name = domainName

        if external:
            proj.external = 'true'
            (proj.labels, proj.upstream_url, proj.auth_type, proj.user_name,
             proj.password, proj.entitlement) = external_params
        else:
            proj.external = 'false'
        try:
            return self.api.projects.append(doc).project_id
        except robj.errors.HTTPConflictError:
            raise errors.RbuildError("A project with conflicting "
                                     "parameters already exists")
Exemple #7
0
    def createTarget(self, ttype, ddata):
        '''
        Create a target using the descriptor data provided

        @param ttype: target type
        @type ttype: string
        @param ddata: descriptor data for target
        @type: DescriptorData
        @return: the created Target
        @rtype: robj.HTTPData
        '''
        # Construct the target xml
        target_doc = xobj.Document()
        target_doc.target = target = xobj.XObj()
        target.description = ddata.getField('description')
        target.name = ddata.getField('name')
        target.zone_name = ddata.getField('zone')
        target.target_type_name = ttype

        try:
            target = self.api.targets.append(target_doc, tag='target')
        except robj.errors.HTTPConflictError:
            raise errors.RbuildError(
                "A target with conflicting parameters already exists")
        return target
Exemple #8
0
    def configureTargetCredentials(self, target, ddata):
        '''
        Configure credentials for a target

        @param ddata: descriptor for target
        @type ddata: DescriptorData
        @param target: target to configure
        @type target: rObj(target)
        @return: the configured target
        @rtype: rObj(target)
        '''
        # make sure our target object is up to date
        target.refresh()

        doc = xobj.Document()
        doc.job = job = xobj.XObj()
        job.job_type = target.actions[1]._root.job_type
        job.descriptor = target.actions[1]._root.descriptor
        job.descriptor_data = xobj.parse(ddata.toxml()).descriptor_data

        jobObj = target.jobs.append(doc)
        while jobObj.job_state.name in ['Queued', 'Running']:
            jobObj.refresh()

        if jobObj.job_state.name == 'Failed':
            raise errors.RbuildError('Unable to set credentials')
        return target
Exemple #9
0
 def commit(self, message):
     """
     Commit a product definition change
     """
     if not self._handle.facade.conary.commit(
             self.getProductDefinitionDirectory(), message=message):
         raise errors.RbuildError('Failed to commit product definition')
Exemple #10
0
    def getBranchIdFromName(self, productName, versionName):
        #pylint: disable-msg=R0914
        # not a great candidate for refactoring
        productId = self.getProductId(productName)
        error, versionList = self.server.getProductVersionListForProduct(
            productId)
        if error:
            raise errors.RbuilderError(*versionList)

        versionNames = []
        # W0612: leave unused variables as documentation
        # W0631: versionId is guaranteed to be defined
        #pylint: disable-msg=W0612,W0631
        for (versionId2, productId2, namespace, versionName2,
             desc) in versionList:
            versionNames.append(versionName2)
            if versionName == versionName2:
                return versionId2

        errstr = '%s is not a valid version for product %s.' % \
            (versionName, productName)
        if versionNames:
            errstr += '\nValid versions are: %s' % \
                ', '.join(versionNames)
        else:
            errstr += '\nNo versions found for product %s.' % productName
        raise errors.RbuildError(errstr)
Exemple #11
0
    def startProductBuilds(self,
                           productName,
                           versionName,
                           stageName,
                           force=False):
        productId = self.getProductId(productName)
        error, versionList = self.server.getProductVersionListForProduct(
            productId)
        if error:
            raise errors.RbuilderError(*versionList)

        versionId = None
        # W0612: leave unused variables as documentation
        # W0631: versionId is guaranteed to be defined
        #pylint: disable-msg=W0612,W0631
        if versionList:
            if len(versionList[0]) == 4:
                #This is an older rBuilder
                for (versionId2, productId2, versionName2,
                     desc) in versionList:
                    if versionName == versionName2:
                        versionId = versionId2
                        break
            else:
                for (versionId2, productId2, namespace, versionName2,
                     desc) in versionList:
                    if versionName == versionName2:
                        versionId = versionId2
                        break
        if versionId is None:
            raise errors.RbuildError(
                "could not find version %r for product %r" %
                (versionName, productName))
        error, buildIds = self.server.newBuildsFromProductDefinition(
            versionId, stageName, force)

        if error:
            if buildIds[0] == 'TroveNotFoundForBuildDefinition':
                errFlavors = '\n'.join(buildIds[1][0])
                raise errors.RbuildError(
                    '%s\n\nTo submit the partial set of '
                    'builds, re-run this command with --force' % errFlavors)
            else:
                raise errors.RbuilderError(*buildIds)
        return buildIds
Exemple #12
0
    def getTarget(self, name):
        client = self.api._client
        uri = self.api._uri + '/targets'
        uri += ';filter_by=[name,EQUAL,%s]' % (name, )

        targets = client.do_GET(uri)
        if targets:
            return targets[0]
        raise errors.RbuildError("Target '%s' not found" % (name, ))
Exemple #13
0
 def update(self):
     """
     This is the only acceptable way to update a product definition
     checkout, because it invalidates the cached copy of the data.
     """
     if not self._handle.facade.conary.updateCheckout(
             self.getProductDefinitionDirectory()):
         raise errors.RbuildError('Failed to update product definition')
     ProductStore.update(self)
Exemple #14
0
 def getProductId(self, productName):
     error, productId = self.server.getProjectIdByHostname(productName)
     if error:
         if productId[0] == 'ItemNotFound':
             raise errors.RbuildError('Product %s not found' % \
                 productName)
         else:
             raise errors.RbuilderError(*productId)
     return productId
Exemple #15
0
    def watchImages(self, buildIds, timeout=0, interval=5, quiet=False):
        interval = 10
        st = time.time()
        timedOut = False
        dropped = 0
        finalStatus = {}

        activeBuilds = dict.fromkeys(buildIds)
        while activeBuilds:
            for buildId in list(activeBuilds):
                try:
                    error, buildStatus = self.server.getBuildStatus(buildId)
                except socket.timeout:
                    dropped += 1
                    if dropped >= 3:
                        raise errors.RbuildError(
                            'rBuilder connection timed out after 3 attempts')
                    self._handle.ui.info(
                        'Status request timed out, trying again')
                    time.sleep(interval)
                    continue

                if error:
                    raise errors.RbuilderError(*buildStatus)
                dropped = 0
                if activeBuilds[buildId] != buildStatus:
                    st = time.time()  # reset timeout counter if status changes
                    activeBuilds[buildId] = buildStatus
                    if not quiet:
                        self._handle.ui.write(
                            '%s: %s "%s"', buildId,
                            self.statusNames.get(buildStatus['status'],
                                                 self.statusNames[-1]),
                            buildStatus['message'])
                    if activeBuilds[buildId]['status'] > 200:
                        finalStatus[buildId] = activeBuilds.pop(buildId)
            if activeBuilds:
                time.sleep(interval)
                if timeout and time.time() - st > timeout:
                    timedOut = True
                    break

        if timedOut:
            self._handle.ui.error(
                'Timed out while waiting for build status'
                ' to change (%d seconds)', timeout)
        else:
            self._handle.ui.write('All jobs completed')
        if activeBuilds:
            self._handle.ui.warning('Unfinished builds:')
            self._printStatus(activeBuilds, '    Last status: ')
        self._handle.ui.write('Finished builds:')
        self._printStatus(finalStatus, '    ')
        if any(x['status'] != 300 for x in finalStatus.values()):
            return False
        else:
            return True
Exemple #16
0
 def getProject(self, shortName):
     # FIXME: robj allows neither URL construction nor searching/filtering,
     # so the only "kosher" way to find a project is to iterate over all of
     # them. So cheating looks attractive by comparison...
     client = self.api._client
     uri = self.api._uri + '/projects/' + shortName
     try:
         return client.do_GET(uri)
     except robj.errors.HTTPNotFoundError:
         raise errors.RbuildError("Project '%s' not found" % (shortName, ))
Exemple #17
0
 def api(self):
     if self._api is None:
         top = robj.connect(self._url)
         for ver in top.api_versions:
             if ver.name == 'v1':
                 break
         else:
             raise errors.RbuildError("No compatible REST API found on "
                                      "rBuilder '%s'" %
                                      self._url.__safe_str__())
         self._api = ver
     return self._api
Exemple #18
0
 def getGroups(self, shortName, label, **kwargs):
     client = self.api._client
     uri = ('/products/%s/repos/search?type=group&label=%s' %
            (shortName, label))
     try:
         groups = client.do_GET(uri)
         if groups:
             return groups
         return []
     except robj.errors.HTTPNotFoundError:
         raise errors.RbuildError("Project '%s' and label '%s' not found" %
                                  (shortName, label))
Exemple #19
0
 def _testProductDirectory(baseDirectory):
     """
     Test to see whether a product directory has been checked out
     @param baseDirectory: name of product directory
     @type baseDirectory: string
     @raise errors.RbuildError: If no product definition is checked out
     in an .rbuild directory under baseDirectory
     """
     productDefPath = (baseDirectory +
                       '/.rbuild/product-definition/product-definition.xml')
     if not os.path.exists(productDefPath):
         raise errors.RbuildError('No product directory at %r' %
                                  baseDirectory)
Exemple #20
0
    def getTargetTypes(self):
        '''
        Return all target types

        @return: mapping of TargetType name to TargetType
        @rtype: dict
        '''
        client = self.api._client
        uri = self.api._uri + '/target_types'
        try:
            return dict((x.name, x) for x in client.do_GET(uri))
        except robj.errors.HTTPNotFoundError:
            raise errors.RbuildError(msg='Target types url not found: %s' %
                                     uri)
Exemple #21
0
    def getImageDefDescriptor(self, imageType):
        # image_type_definition_descriptors are not in a collection, and they
        # have an xml header, which causes rObj to process them incorrectly
        # thus this mess
        client = self.api._client._client  # Ew
        uri = self.api._uri + \
            '/platforms/image_type_definition_descriptors/' + imageType

        request = client.do_GET(uri)
        request.wait()
        response = request.response
        if response.status >= 400:
            raise errors.RbuildError(response.reason)
        return response.content
Exemple #22
0
    def getWindowsBuildService(self):
        systems = self.api.inventory.infrastructure_systems

        wbsSystems = [
            x for x in systems
            if x.system_type.name == 'infrastructure-windows-build-node'
        ]

        if len(wbsSystems) == 0:
            raise errors.RbuildError(
                'Could not find any available Windows '
                'Build Service systems on your rBuilder. A Windows Build '
                'Service is required for building Windows related packages.')

        wbs = random.choice(wbsSystems)

        if len(wbs.networks) == 0:
            raise errors.RbuildError('Could not find any usable networks on '
                                     'the Windows Build Service.')

        network = wbs.networks[0]
        address = str(network.ip_address) or str(network.dns_name)
        return address
Exemple #23
0
 def getProductDefinitionSchemaVersion(self):
     # rBuilder 5.2.3 <= version < rBuilder 6.1.0
     ver = getattr(self.api, 'proddefSchemaVersion', None)
     if ver is not None:
         return str(ver)
     # version >= rBuilder 6.1.0
     version_info = getattr(self.api, 'version_info', None)
     if version_info is not None:
         ver = getattr(version_info, 'product_definition_schema_version',
                       None)
         if ver is not None:
             return str(ver)
     # proddefSchemaVersion was added in rBuilder 5.2.3, prior to that the
     # schema version was 2.0.
     raise errors.RbuildError("Unable to determine the product definition "
                              "version offered by rBuilder")
Exemple #24
0
 def _findTrove(self,
                name,
                version,
                flavor=None,
                labelPath=None,
                defaultFlavor=None,
                allowMissing=False):
     #pylint: disable-msg=R0913
     # findTrove really needs all these arguments to pass through
     """
     Gets a reference to a trove in the repository.
     @param name: package to find
     @type name: string
     @param version: version of package to find
     @type version: string or C{conary.versions.Version} B{opaque}
     @param flavor: flavor of package to find (optional)
     @type flavor: string or C{deps.Flavor} B{opaque}
     @param labelPath: label(s) to find package on
     @type labelPath: None, conary.versions.Label, or list of
     conary.versions.Label
     @param defaultFlavor: Flavor to use for those troves specifying None
     for their flavor.
     @type defaultFlavor: str or None
     @param allowMissing: if True, allow None as a return value if 
     the package was not found.
     @return: C{(name, version, flavor)} tuple.
     Note that C{version} and C{flavor} objects are B{opaque}.
     @rtype: (string, conary.versions.Version conary.deps.deps.Flavor)
     """
     repos = self._getRepositoryClient()
     flavor = self._getFlavor(flavor)
     defaultFlavor = self._getFlavor(defaultFlavor)
     try:
         results = repos.findTroves(labelPath, [(name, version, flavor)],
                                    defaultFlavor=defaultFlavor,
                                    allowMissing=allowMissing)
     except conaryerrors.LabelPathNeeded:
         errstr = "%s is not a label. Please specify a label where a " \
                  "product definition can be found, or specify a product " \
                  "short name and version." % str(version)
         raise errors.RbuildError(errstr)
     if not results:
         return None
     troveTup, = results[name, version, flavor]
     return troveTup
Exemple #25
0
    def _pollBuild(self, buildId, interval=10, max_dropped=3):
        dropped = 0
        buildStatus = None
        while buildStatus is None:
            try:
                error, buildStatus = self.server.getBuildStatus(buildId)
            except socket.timeout:
                dropped += 1
                if dropped >= max_dropped:
                    raise errors.RbuildError(
                        'rBuilder connection timed out after 3 attempts')
                self._handle.ui.info('Status request timed out, trying again')
                time.sleep(interval)
                continue

        if error:
            raise errors.RbuilderError(*buildStatus)
        return buildStatus
Exemple #26
0
 def getStageDirectory(self, stageName=None):
     """
     Get the absolute directory associated with a given stage name.
     @param stageName: stage name, or None to use the active stage.
     @type stageName: string
     @return: string of absolute directory corrosponding to C{stageName},
     if none found, then return None.
     @rtype: string or None
     """
     if stageName is None:
         stageName = self.getActiveStageName()
     if stageName is not None:
         stageDirectory = '%s/%s' % (self._baseDirectory, stageName)
         if not os.path.exists(stageDirectory):
             raise errors.RbuildError('Stage directory for %r'
                                      ' does not exist' % stageName)
         return stageDirectory
     else:
         return None
Exemple #27
0
 def updateCheckout(self, targetDir):
     """
     Update a subdirectory containing a checkout of a conary
     source package.  Similar to the C{cvc update} command.
     @param targetDir: subdirectory containing package to update
     @type targetDir: string
     @return: Status
     @rtype: bool
     """
     # Conary likes absolute paths RBLD-137
     targetDir = os.path.abspath(targetDir)
     try:
         return checkin.nologUpdateSrc(self._getRepositoryClient(),
                                       [targetDir])
     except (builderrors.UpToDate, builderrors.NotCheckedInError):
         # The end result is an up to date checkout, so ignore the exception
         return True
     except builderrors.CheckinError, e:
         # All other exceptions are deemed failures
         raise errors.RbuildError(str(e))
Exemple #28
0
 def createProject(self,
                   title,
                   shortName,
                   hostName=None,
                   domainName=None,
                   description=''):
     doc = xobj.Document()
     doc.project = proj = xobj.XObj()
     proj.name = title
     proj.short_name = shortName
     proj.hostname = hostName or shortName
     proj.description = description or ''
     if domainName:
         proj.domain_name = domainName
     proj.external = 'false'
     try:
         return self.api.projects.append(doc).project_id
     except robj.errors.HTTPConflictError:
         raise errors.RbuildError("A project with conflicting "
                                  "parameters already exists")
Exemple #29
0
    def promoteGroups(self, groupList, fromTo, infoOnly=False):
        """
        Promote the troves in C{groupList} using the promote map in
        C{fromTo}. The former should be a list of trove tuples, and the
        latter a dictionary mapping of labels (C{from: to}).

        @param groupList: List of group trove tuples to promote
        @type  groupList: [(name, version, flavor)]
        @param fromTo: Mapping of labels to execute promote on
        @type  fromTo: {from: to}
        @param infoOnly: If C{True}, return without committing anything
        @type  infoOnly: C{bool}
        """
        def getLabelOrBranch(label):
            if isinstance(label, types.StringTypes):
                if label.startswith('/'):
                    return self._getVersion(label)
                else:
                    return self._getLabel(label)
            return label

        promoteMap = dict(
            (self._getLabel(fromLabel), getLabelOrBranch(toLabel))
            for (fromLabel, toLabel) in fromTo.iteritems())

        client = self._getConaryClient()
        success, cs = client.createSiblingCloneChangeSet(promoteMap,
                                                         groupList,
                                                         cloneSources=True)

        if not success:
            raise errors.RbuildError('Promote failed.')
        else:
            packageList = [
                x.getNewNameVersionFlavor() for x in cs.iterNewTroveList()
            ]
            packageList = [(str(x[0]), str(x[1]), str(x[2]))
                           for x in packageList]
            if not infoOnly:
                self._getRepositoryClient().commitChangeSet(cs)
            return packageList
Exemple #30
0
    def _getResources(self, resource, **kwargs):
        '''
            Get a fitlered and ordered list of resoruces

            @param resource: resource collection name
            @param order_by: field and direction to order results
            @param uri: alternative uri
            @return: list of resources
            @rtype: list
        '''
        uri = kwargs.pop('uri', None)
        order_by = kwargs.pop('order_by', None)

        fullUri = self.api._uri + '/'
        if uri is not None:
            fullUri += uri.strip('/') + '/'
        fullUri += resource

        filter_by = []
        for field, param in kwargs.items():
            param = self._singleBackslashRe.sub('r\\\\', param)
            param = param.replace('"', r'\"')
            filter_by.append('EQUAL(%s,"%s")' % (field, param))

        if filter_by:
            fullUri += ';filter_by=AND(%s)' % ','.join(filter_by)

        # always sort by most recently created first
        if order_by:
            fullUri += ';order_by=%s' % order_by

        client = self.api._client
        try:
            results = client.do_GET(fullUri)
            if results:
                return results
            return []
        except robj.errors.HTTPNotFoundError:
            raise errors.RbuildError("Unable to fetch resource '%s' at '%s'" %
                                     (resource, fullUri))