示例#1
0
    def runCommand(self,
                   cfg,
                   argSet,
                   args,
                   profile=False,
                   callback=None,
                   repos=None):
        args = args[1:]
        level = log.getVerbosity()
        message = argSet.pop("message", None)
        test = argSet.pop("test", False)
        logfile = argSet.pop("log-file", None)

        if argSet or len(args) != 1: return self.usage()

        if message and logfile:
            raise errors.ConaryError("options --message and --log-file are "
                                     "mutually exclusive")
        if logfile:
            # Read the checkin message from the file
            if logfile == '-':
                message = sys.stdin.read()
            else:
                try:
                    message = open(logfile).read()
                except IOError, e:
                    raise errors.ConaryError("While opening %s: %s" %
                                             (e.filename, e.strerror))
            # Get rid of trailing white spaces, they're probably not
            # intended to be there anyway
            message = message.rstrip()
示例#2
0
def loadEntitlementFromString(xmlContent, *args, **kw):
    # handle old callers
    source = kw.get('source', '<override>')
    serverName = kw.get('serverName', None)
    if len(args):
        if len(args) == 1:
            source = args[0]
        elif len(args) == 2:
            serverName = args[0]
            source = args[1]
        else:
            raise TypeError(
                'loadEntitlementFromString() takes exactly 1 argument (%d given)'
                % len(args))

    if serverName:
        import warnings
        warnings.warn(
            "The serverName argument to loadEntitlementFromString "
            "has been deprecated", DeprecationWarning)

    returnTimeout = kw.pop('returnTimeout', False)

    p = EntitlementParser()

    # wrap this in an <entitlement> top level tag (making it optional
    # [but recommended!] in the entitlement itself)
    #
    # XXX This synthetic wrapping should probably be made obsolete; everyone
    # should use emitEntitlement, which does the right thing.
    try:
        if '<entitlement>' not in xmlContent:
            p.parse("<entitlement>" + xmlContent + "</entitlement>")
        else:
            p.parse(xmlContent)

        try:
            entClass = p.get('class', None)
            entKey = p['key']
        except KeyError:
            raise errors.ConaryError("Entitlement incomplete.  Entitlements"
                                     " must include 'server', 'class', and"
                                     " 'key' values")
    except Exception, err:
        raise errors.ConaryError("Malformed entitlement at %s:"
                                 " %s" % (source, err))
示例#3
0
def createSearchSourceStackFromStrings(searchSource,
                                       searchPath,
                                       flavor,
                                       db=None,
                                       fallBackToRepos=True):
    """
    Create a search source stack from a list of search path elements. See
    L{createSearchPathFromStrings} for the elements allowed.
    """
    try:
        strings = searchPath
        searchPath = createSearchPathFromStrings(searchPath)
        return createSearchSourceStack(searchSource,
                                       searchPath,
                                       flavor,
                                       db,
                                       fallBackToRepos=fallBackToRepos)
    except baseerrors.ConaryError, err:
        raise baseerrors.ConaryError('Could not create search path "%s": %s' %
                                     (' '.join(strings), err))
示例#4
0
def doModelUpdate(cfg, sysmodel, modelFile, otherArgs, **kwargs):
    kwargs['systemModel'] = sysmodel
    kwargs['systemModelFile'] = modelFile
    kwargs['loadTroveCache'] = True
    kwargs.setdefault('updateByDefault', True) # erase is not default case
    kwargs.setdefault('model', False)
    kwargs.setdefault('keepExisting', True) # prefer "install" to "update"
    restartInfo = kwargs.get('restartInfo', None)
    patchArgs = kwargs.pop('patchSpec', None)
    fromChangesets = []
    applyList = []

    callback = kwargs.get('callback', None)
    if not callback:
        callback = callbacks.UpdateCallback(trustThreshold=cfg.trustThreshold)
        kwargs['callback'] = callback
    else:
        callback.setTrustThreshold(cfg.trustThreshold)

    if restartInfo is None:
        addArgs = [x[1:] for x in otherArgs if x.startswith('+')]
        rmArgs = [x[1:] for x in otherArgs if x.startswith('-')]
        defArgs = [x for x in otherArgs
                    if not (x.startswith('+') or x.startswith('-'))]

        # find any default arguments that represent changesets to
        # install/update
        for defArg in list(defArgs):
            if kwargs['updateByDefault'] and os.path.isfile(defArg):
                try:
                    cs = changeset.ChangeSetFromFile(defArg)
                    fromChangesets.append((cs, defArg))
                    defArgs.remove(defArg)
                except filecontainer.BadContainer:
                    # not a changeset, must be a trove name
                    pass

        if kwargs['updateByDefault']:
            addArgs += defArgs
        else:
            rmArgs += defArgs

        if rmArgs:
            sysmodel.appendOpByName('erase', text=rmArgs)

        updateName = { False: 'update',
                       True: 'install' }[kwargs['keepExisting']]

        branchArgs = {}
        for index, spec in enumerate(addArgs):
            try:
                troveSpec = trovetup.TroveSpec(spec)
                version = versions.Label(troveSpec.version)
                branchArgs[troveSpec] = index
            except:
                # Any exception is a parse failure in one of the
                # two steps, and so we do not convert that argument
                pass
       
        if branchArgs:
            client = conaryclient.ConaryClient(cfg)
            repos = client.getRepos()
            foundTroves = repos.findTroves(cfg.installLabelPath,
                                           branchArgs.keys(),
                                           defaultFlavor = cfg.flavor)
            for troveSpec in foundTroves:
                index = branchArgs[troveSpec]
                foundTrove = foundTroves[troveSpec][0]
                addArgs[index] = addArgs[index].replace(
                    troveSpec.version,
                    '%s/%s' %(foundTrove[1].trailingLabel(),
                              foundTrove[1].trailingRevision()))

        disallowedChangesets = []
        for cs, argName in fromChangesets:
            for troveTuple in cs.getPrimaryTroveList():
                # group and redirect changesets will break the model the
                # next time it is run, so prevent them from getting in
                # the model in the first place
                if troveTuple[1].isOnLocalHost():
                    if troveTuple[0].startswith('group-'):
                        disallowedChangesets.append((argName, 'group',
                            trovetup.TroveTuple(*troveTuple).asString()))
                        continue
                    trvCs = cs.getNewTroveVersion(*troveTuple)
                    if trvCs.getType() == trove.TROVE_TYPE_REDIRECT:
                        disallowedChangesets.append((argName, 'redirect',
                            trovetup.TroveTuple(*troveTuple).asString()))
                        continue

                addArgs.append(
                    trovetup.TroveTuple(*troveTuple).asString())

        if disallowedChangesets:
            raise errors.ConaryError(
                'group and redirect changesets on a local label'
                ' cannot be installed:\n    ' + '\n    '.join(
                    '%s contains local %s: %s' % x
                    for x in disallowedChangesets))

        if addArgs:
            sysmodel.appendOpByName(updateName, text=addArgs)

        if patchArgs:
            sysmodel.appendOpByName('patch', text=patchArgs)


        kwargs['fromChangesets'] = [x[0] for x in fromChangesets]

        if kwargs.pop('model'):
            sysmodel.write(sys.stdout)
            sys.stdout.flush()
            return None

        keepExisting = kwargs.get('keepExisting')
        updateByDefault = kwargs.get('updateByDefault', True)
        applyList = cmdline.parseChangeList([], keepExisting,
                                            updateByDefault,
                                            allowChangeSets=True)

    else:
        # In the restart case, applyList == [] which says "sync to model"
        pass
        
    _updateTroves(cfg, applyList, **kwargs)
    # Clean up after ourselves
    if restartInfo:
        util.rmtree(restartInfo, ignore_errors=True)
示例#5
0
def loadEntitlementFromProgram(fullPath, serverName):
    """ Executes the given file to generate an entitlement.
        The executable must print to stdout a full valid entitlement xml
        blob.
    """
    readFd, writeFd = os.pipe()
    stdErrRead, stdErrWrite = os.pipe()
    childPid = os.fork()
    if not childPid:
        nullFd = os.open("/dev/null", os.O_RDONLY)
        try:
            try:
                os.close(readFd)
                # switch stdin to /dev/null
                os.dup2(nullFd, 0)
                os.close(nullFd)

                # both error and stderr are redirected  - the entitlement
                # should be on stdout, and error info should be
                # on stderr.
                os.dup2(writeFd, 1)
                os.dup2(stdErrWrite, 2)
                os.close(writeFd)
                os.close(stdErrWrite)
                util.massCloseFileDescriptors(3, 252)
                os.execl(fullPath, fullPath, serverName)
            except Exception:
                traceback.print_exc(sys.stderr)
        finally:
            os._exit(1)
    os.close(writeFd)
    os.close(stdErrWrite)

    # read in from pipes.  When they're closed,
    # the child process should have exited.
    output = []
    errorOutput = []
    buf = os.read(readFd, 1024)
    errBuf = os.read(stdErrRead, 1024)

    while buf or errBuf:
        if buf:
            output.append(buf)
            buf = os.read(readFd, 1024)
        if errBuf:
            errorOutput.append(errBuf)
            errBuf = os.read(stdErrRead, 1024)

    pid, status = os.waitpid(childPid, 0)
    os.close(readFd)
    os.close(stdErrRead)

    errMsg = ''
    if os.WIFEXITED(status) and os.WEXITSTATUS(status):
        errMsg = ('Entitlement generator at "%s"'
                  ' died with exit status %d' %
                  (fullPath, os.WEXITSTATUS(status)))
    elif os.WIFSIGNALED(status):
        errMsg = ('Entitlement generator at "%s"'
                  ' died with signal %d' % (fullPath, os.WTERMSIG(status)))
    else:
        errMsg = ''

    if errMsg:
        if errorOutput:
            errMsg += ' - stderr output follows:\n%s' % ''.join(errorOutput)
        else:
            errMsg += ' - no output on stderr'
        raise errors.ConaryError(errMsg)

    # looks like we generated an entitlement - they're still the possibility
    # that the entitlement is broken.
    xmlContent = ''.join(output)
    return loadEntitlementFromString(xmlContent, fullPath)