Exemple #1
0
def buildVirtualFeeds(feedPairs, feeders):
    """Build a virtual feeds dict suitable for forming part of a
    component config.

    @param feedPairs: List of virtual feeds, as name-feederName pairs. For
                      example, [('bar:baz', 'qux')] defines one
                      virtual feed 'bar:baz', which is provided by
                      the component's 'qux' feed.
    @type  feedPairs: List of (feedId, feedName) -- both strings.
    @param feeders: The feeders exported by this component, from the
                    registry.
    @type  feeders: List of str.
    """
    ret = {}
    for virtual, real in feedPairs:
        if real not in feeders:
            raise errors.ConfigError('virtual feed maps to unknown feeder: '
                                     '%s -> %s' % (virtual, real))
        try:
            common.parseFeedId(virtual)
        except:
            raise errors.ConfigError(
                'virtual feed name not a valid feedId: %s' % (virtual, ))
        ret[virtual] = real
    return ret
Exemple #2
0
    def check_properties(self, props, addMessage):
        props = self.config['properties']
        rotateType = props.get('rotate-type', 'none')

        if not rotateType in ['none', 'size', 'time']:
            msg = messages.Error(T_(
                N_("The configuration property 'rotate-type' should be set to "
                   "'size', time', or 'none', not '%s'. "
                   "Please fix the configuration."), rotateType),
                                 mid='rotate-type')
            addMessage(msg)
            raise errors.ConfigError(msg)

        if rotateType in ['size', 'time']:
            if rotateType not in props.keys():
                msg = messages.Error(T_(
                    N_("The configuration property '%s' should be set. "
                       "Please fix the configuration."), rotateType),
                                     mid='rotate-type')
                addMessage(msg)
                raise errors.ConfigError(msg)

            if props[rotateType] == 0:
                msg = messages.Error(T_(N_("Configuration error: " \
                    "'rotate-type' %s value cannot be set to 0."),
                    rotateType), mid='rotate-type')
                addMessage(msg)
                raise errors.ConfigError(msg)
Exemple #3
0
    def addIPFilter(self, filter):
        """
        Add an IP filter of the form IP/prefix-length (CIDR syntax), or just
        a single IP address
        """
        definition = filter.split('/')
        if len(definition) == 2:
            (net, prefixlen) = definition
            prefixlen = int(prefixlen)
        elif len(definition) == 1:
            net = definition[0]
            prefixlen = 32
        else:
            raise errors.ConfigError("Cannot parse filter definition %s" %
                                     filter)

        if prefixlen < 0 or prefixlen > 32:
            raise errors.ConfigError("Invalid prefix length")

        mask = ~((1 << (32 - prefixlen)) - 1)
        try:
            net = struct.unpack(">I", socket.inet_pton(socket.AF_INET, net))[0]
        except socket.error:
            raise errors.ConfigError("Failed to parse network address %s" %
                                     net)
        net = net & mask  # just in case

        self.filters.append((net, mask))
Exemple #4
0
    def check_properties(self, props, addMessage):

        if props.get('type', 'master') == 'slave':
            for k in 'socket-path', 'username', 'password':
                if not 'porter-' + k in props:
                    raise errors.ConfigError("slave mode, missing required"
                                             " property 'porter-%s'" % k)

        if 'burst-size' in props and 'burst-time' in props:
            raise errors.ConfigError('both burst-size and burst-time '
                                     'set, cannot satisfy')
Exemple #5
0
    def check_properties(self, props, addMessage):
        props = self.config['properties']
        deintMode = props.get('deinterlace-mode', 'auto')
        deintMethod = props.get('deinterlace-method', 'ffmpeg')

        if deintMode not in deinterlace.DEINTERLACE_MODE:
            msg = "'%s' is not a valid deinterlace mode." % deintMode
            raise errors.ConfigError(msg)
        if deintMethod not in deinterlace.DEINTERLACE_METHOD:
            msg = "'%s' is not a valid deinterlace method." % deintMethod
            raise errors.ConfigError(msg)
Exemple #6
0
    def _parseFlow(self, node):
        # <flow name="...">
        #   <component>
        #   ...
        # </flow>
        # "name" cannot be atmosphere or manager
        name, = self.parseAttributes(node, ('name', ))
        if name == 'atmosphere':
            raise errors.ConfigError("<flow> cannot have 'atmosphere' as name")
        if name == 'manager':
            raise errors.ConfigError("<flow> cannot have 'manager' as name")

        components = []

        def parseComponent(node):
            return self.parseComponent(node, name, True, True)

        parsers = {'component': (parseComponent, components.append)}
        self.parseFromTable(node, parsers)

        # handle master clock selection; probably should be done in the
        # manager in persistent "flow" objects rather than here in the
        # config
        masters = [x for x in components if x.config['clock-master']]
        if len(masters) > 1:
            raise errors.ConfigError(
                "Multiple clock masters in flow %s: %s" %
                (name, ', '.join([m.name for m in masters])))

        need_sync = [(x.defs.getClockPriority(), x) for x in components
                     if x.defs.getNeedsSynchronization()]
        need_sync.sort()
        need_sync = [x[1] for x in need_sync]

        if need_sync:
            if masters:
                master = masters[0]
            else:
                master = need_sync[-1]

            masterAvatarId = master.config['avatarId']
            self.info("Setting %s as clock master" % masterAvatarId)

            for c in need_sync:
                c.config['clock-master'] = masterAvatarId
        elif masters:
            self.info('master clock specified, but no synchronization '
                      'necessary -- ignoring')
            masters[0].config['clock-master'] = None

        return ConfigEntryFlow(name, components)
Exemple #7
0
 def _buildVersionTuple(self, version):
     if version is None:
         return configure.versionTuple
     elif isinstance(version, tuple):
         assert len(version) == 4
         return version
     elif isinstance(version, str):
         try:
             return common.versionStringToTuple(version)
         except:
             raise errors.ConfigError(
                 "<component> version %r not parseable" % version)
     raise errors.ConfigError("<component> version %r not parseable" %
                              version)
Exemple #8
0
    def check_properties(self, props, addMessage):
        deintMode = props.get('deinterlace-mode', 'auto')
        deintMethod = props.get('deinterlace-method', 'ffmpeg')

        if deintMode not in deinterlace.DEINTERLACE_MODE:
            msg = messages.Error(T_(N_("Configuration error: '%s' " \
                "is not a valid deinterlace mode." % deintMode)))
            addMessage(msg)
            raise errors.ConfigError(msg)

        if deintMethod not in deinterlace.DEINTERLACE_METHOD:
            msg = messages.Error(T_(N_("Configuration error: '%s' " \
                "is not a valid deinterlace method." % deintMethod)))
            self.debug("'%s' is not a valid deinterlace method", deintMethod)
            addMessage(msg)
            raise errors.ConfigError(msg)
Exemple #9
0
 def __init__(self, name, components):
     self.name = name
     self.components = {}
     for c in components:
         if c.name in self.components:
             raise errors.ConfigError(
                 'flow %s already has component named %s' % (name, c.name))
         self.components[c.name] = c
Exemple #10
0
    def check_properties(self, props, addMessage):
        props = self.config['properties']
        speed = props.get('speed', 3)

        if speed > 3:
            msg = messages.Error(T_(N_(
                "The configuration property 'speed' can only take "
                "values from 0 to 3")), mid='speed')
            addMessage(msg)
            raise errors.ConfigError(msg)
Exemple #11
0
 def check_limit(prop_name, lower_limit, upper_limit):
     val = props.get(prop_name, None)
     if val is None:
         return
     if val < lower_limit or val > upper_limit:
         msg = messages.Error(T_(N_(
             "The configuration property '%s' can only take "
             "values from %d to %d"),
             prop_name, lower_limit, upper_limit), mid='config')
         addMessage(msg)
         raise errors.ConfigError(msg)
Exemple #12
0
    def do_setup(self):
        conf = self.config

        # we need either a filename or data
        props = conf['properties']
        filename = data = None
        if 'filename' in props:
            filename = props['filename']
            self.debug('using file %s for passwords', filename)
        elif 'data' in props:
            data = props['data']
            self.debug('using in-line data for passwords')
        else:
            return defer.fail(errors.ConfigError(
                'PasswdSaltSha256 needs either a <data> or <filename> entry'))
        # FIXME: generalize to a start method, possibly linked to mood
        if filename:
            try:
                lines = open(filename).readlines()
            except IOError, e:
                return defer.fail(errors.ConfigError(str(e)))
Exemple #13
0
    def _parseParameters(self):
        root = self.doc.documentElement
        if not root.nodeName == 'planet':
            raise errors.ConfigError("unexpected root node': %s" %
                                     (root.nodeName, ))

        parsers = {
            'atmosphere': (_ignore, _ignore),
            'flow': (_ignore, _ignore),
            'manager': (lambda n: self._parseManagerWithoutRegistry(n),
                        lambda v: setattr(self, 'manager', v))
        }
        self.parseFromTable(root, parsers)
Exemple #14
0
 def _parseEater(self, node):
     # <eater name="eater-name">
     #   <feed alias="foo"?>feeding-component:feed-name</feed>*
     # </eater>
     name, = self.parseAttributes(node, ('name', ))
     feeds = []
     parsers = {'feed': (self._parseFeed, feeds.append)}
     self.parseFromTable(node, parsers)
     if len(feeds) == 0:
         # we have an eater node with no feeds
         raise errors.ConfigError(
             "Eater node %s with no <feed> nodes, is not allowed" %
             (name, ))
     return [(name, feedId, alias) for feedId, alias in feeds]
Exemple #15
0
    def do_check(self):
        props = self.config['properties']
        self.fixRenamedProperties(
            props, [('issuer', 'issuer-class'),
                    ('porter_socket_path', 'porter-socket-path'),
                    ('porter_username', 'porter-username'),
                    ('porter_password', 'porter-password'),
                    ('mount_point', 'mount-point')])

        path = props.get('path', None)
        plugs = self.plugs.get(FILEPROVIDER_SOCKET, [])
        if plugs:
            if path:
                self.warning("The component property 'path' should not be used"
                             " in conjunction with a file provider plug.")
                # For now we don't want the admin to show a warning messages
                #msg = messages.Warning(T_(N_(
                #            "The component property 'path' should not be used"
                #            " in conjunction with a file provider plug.")))
                #self.addMessage(msg)

        if props.get('type', 'master') == 'slave':
            for k in 'socket-path', 'username', 'password':
                if not 'porter-' + k in props:
                    msg = 'slave mode, missing required property porter-%s' % k
                    return defer.fail(errors.ConfigError(msg))
            if plugs or not path:
                return
            if os.path.isfile(path):
                self._singleFile = True
            elif os.path.isdir(path):
                self._singleFile = False
            else:
                msg = "the file or directory specified in 'path': %s does " \
                    "not exist or is neither a file nor directory" % path
                return defer.fail(errors.ConfigError(msg))
Exemple #16
0
    def parseBouncerAndPlugs(self):
        # <planet>
        #     <manager>?
        #     <atmosphere>*
        #     <flow>*
        # </planet>
        root = self.doc.documentElement
        if not root.nodeName == 'planet':
            raise errors.ConfigError("unexpected root node': %s" %
                                     (root.nodeName, ))

        parsers = {
            'atmosphere': (_ignore, _ignore),
            'flow': (_ignore, _ignore),
            'manager': (self._parseManagerWithRegistry, _ignore)
        }
        self.parseFromTable(root, parsers)
Exemple #17
0
    def _parse(self):
        # <admin>
        #   <plugs>
        root = self.doc.documentElement
        if not root.nodeName == 'admin':
            raise errors.ConfigError("unexpected root node': %s" %
                (root.nodeName, ))

        def parseplugs(node):
            return fluconfig.buildPlugsSet(self.parsePlugs(node),
                                 self.plugs.keys())

        def addplugs(plugs):
            for socket in plugs:
                self.plugs[socket].extend(plugs[socket])
        parsers = {'plugs': (parseplugs, addplugs)}

        self.parseFromTable(root, parsers)
        self.doc.unlink()
        self.doc = None
Exemple #18
0
    def parse(self):
        # <planet>
        #     <manager>?
        #     <atmosphere>*
        #     <flow>*
        # </planet>
        root = self.doc.documentElement
        if root.nodeName != 'planet':
            raise errors.ConfigError("unexpected root node': %s" %
                                     (root.nodeName, ))

        parsers = {
            'atmosphere':
            (self._parseAtmosphere, self.atmosphere.components.update),
            'flow': (self._parseFlow, self.flows.append),
            'manager': (_ignore, _ignore)
        }
        self.parseFromTable(root, parsers)
        self.doc.unlink()
        self.doc = None
Exemple #19
0
 def check_properties(self, props, addMessage):
     profile = props.get('profile', 'default')
     if profile not in PROFILES.keys():
         raise errors.ConfigError("The profile '%s' do not exists.")
Exemple #20
0
    def parseComponent(self, node, parent, isFeedComponent, needsWorker):
        """
        Parse a <component></component> block.

        @rtype: L{ConfigEntryComponent}
        """
        # <component name="..." type="..." label="..."? worker="..."?
        #            project="..."? version="..."?>
        #   <source>...</source>*
        #   <eater name="...">...</eater>*
        #   <property name="name">value</property>*
        #   <clock-master>...</clock-master>?
        #   <plugs>...</plugs>*
        #   <virtual-feed name="foo" real="bar"/>*
        # </component>
        # F0.10
        # source tag is deprecated

        attrs = self.parseAttributes(node, ('name', 'type'), (
            'label',
            'worker',
            'project',
            'version',
        ))
        name, componentType, label, worker, project, version = attrs
        if needsWorker and not worker:
            raise errors.ConfigError(
                'component %s does not specify the worker '
                'that it is to run on' % (name, ))
        elif worker and not needsWorker:
            raise errors.ConfigError('component %s specifies a worker to run '
                                     'on, but does not need a worker' %
                                     (name, ))

        properties = []
        plugs = []
        eaters = []
        clockmasters = []
        sources = []
        virtual_feeds = []

        def parseBool(node):
            return self.parseTextNode(node, common.strToBool)

        parsers = {
            'property': (self._parseProperty, properties.append),
            'compound-property':
            (self._parseCompoundProperty, properties.append),
            'plugs': (self.parsePlugs, plugs.extend)
        }

        if isFeedComponent:
            parsers.update({
                'eater': (self._parseEater, eaters.extend),
                'clock-master': (parseBool, clockmasters.append),
                'source': (self._parseSource, sources.append),
                'virtual-feed': (self._parseVirtualFeed, virtual_feeds.append)
            })

        self.parseFromTable(node, parsers)

        if len(clockmasters) == 0:
            isClockMaster = None
        elif len(clockmasters) == 1:
            isClockMaster = clockmasters[0]
        else:
            raise errors.ConfigError("Only one <clock-master> node allowed")

        if sources:
            msg = ('"source" tag has been deprecated in favor of "eater",'
                   ' please update your configuration file (found in'
                   ' component %r)' % name)
            warnings.warn(msg, DeprecationWarning)

        for feedId in sources:
            # map old <source> nodes to new <eater> nodes
            eaters.append((None, feedId))

        return ConfigEntryComponent(name, parent, componentType, label,
                                    properties, plugs, worker, eaters,
                                    isClockMaster, project, version,
                                    virtual_feeds)
Exemple #21
0
 def record(v):
     if getattr(ret, k):
         raise errors.ConfigError('duplicate %s: %s' %
                                  (k, getattr(ret, k)))
     setattr(ret, k, v)
Exemple #22
0
 def eparse(v):
     v = str(v)
     if v not in allowed:
         raise errors.ConfigError('unknown value %s (should be '
                                  'one of %r)' % (v, allowed))
     return v
Exemple #23
0
def buildEatersDict(eatersList, eaterDefs):
    """Build a eaters dict suitable for forming part of a component
    config.

    @param eatersList: List of eaters. For example,
                       [('default', 'othercomp:feeder', 'foo')] says
                       that our eater 'default' will be fed by the feed
                       identified by the feedId 'othercomp:feeder', and
                       that it has the alias 'foo'. Alias is optional.
    @type  eatersList: List of (eaterName, feedId, eaterAlias?)
    @param  eaterDefs: The set of allowed and required eaters
    @type   eaterDefs: List of
                       L{flumotion.common.registry.RegistryEntryEater}
    @returns: Dict of eaterName => [(feedId, eaterAlias)]
    """
    def parseEaterTuple(tup):
        def parse(eaterName, feedId, eaterAlias=None):
            if eaterAlias is None:
                eaterAlias = eaterName
            return (eaterName, feedId, eaterAlias)

        return parse(*tup)

    eaters = {}
    for eater, feedId, alias in [parseEaterTuple(t) for t in eatersList]:
        if eater is None:
            if not eaterDefs:
                raise errors.ConfigError(
                    "Feed %r cannot be connected, component has no eaters" %
                    (feedId, ))
            # cope with old <source> entries
            eater = eaterDefs[0].getName()
        if alias is None:
            alias = eater
        feeders = eaters.get(eater, [])
        if feedId in feeders:
            raise errors.ConfigError(
                "Already have a feedId %s eating from %s" % (feedId, eater))
        while alias in [a for f, a in feeders]:
            log.debug('config', "Duplicate alias %s for eater %s, "
                      "uniquifying", alias, eater)
            alias += '-bis'

        feeders.append((feedId, alias))
        eaters[eater] = feeders
    for e in eaterDefs:
        eater = e.getName()
        if e.getRequired() and not eater in eaters:
            raise errors.ConfigError("Component wants to eat on %s,"
                                     " but no feeders specified." %
                                     (e.getName(), ))
        if not e.getMultiple() and len(eaters.get(eater, [])) > 1:
            raise errors.ConfigError("Component does not support multiple "
                                     "sources feeding %s (%r)" %
                                     (eater, eaters[eater]))
    aliases = reduce(list.__add__,
                     [[x[1] for x in tups] for tups in eaters.values()], [])
    # FIXME: Python 2.3 has no sets
    # if len(aliases) != len(set(aliases):
    while aliases:
        alias = aliases.pop()
        if alias in aliases:
            raise errors.ConfigError("Duplicate alias: %s" % (alias, ))

    return eaters
Exemple #24
0
 def gotcomponent(val):
     if self.bouncer is not None:
         raise errors.ConfigError('can only have one bouncer '
                                  '(%s is superfluous)' % (val.name, ))
     # FIXME: assert that it is a bouncer !
     self.bouncer = val