示例#1
0
    def configure_pipeline(self, pipeline, properties):
        self.debug('configure_pipeline for disker')
        self._clock = pipeline.get_clock()
        self._symlinkToLastRecording = \
            properties.get('symlink-to-last-recording', None)
        self._symlinkToCurrentRecording = \
            properties.get('symlink-to-current-recording', None)
        self._recordAtStart = properties.get('start-recording', True)
        self._defaultFilenameTemplate = properties.get(
            'filename', '%s.%%Y%%m%%d-%%H%%M%%S' % self.getName())
        self._startFilenameTemplate = self._defaultFilenameTemplate
        icalfn = properties.get('ical-schedule')
        if self._can_schedule and icalfn:
            self.scheduleRecordings(open(icalfn, 'r'))
        elif icalfn:
            # ical schedule is set, but self._can_schedule is False

            def missingModule(moduleName):
                m = messages.Error(T_(
                    N_("An iCal file has been specified for scheduling, "
                       "but the '%s' module is not installed.\n"), moduleName),
                                   mid='error-python-%s' % moduleName)
                documentation.messageAddPythonInstall(m, moduleName)
                self.debug(m)
                self.addMessage(m)

            if not eventcalendar.HAS_ICALENDAR:
                missingModule('icalendar')
            if not eventcalendar.HAS_DATEUTIL:
                missingModule('dateutil')
            # self._can_schedule is False, so one of the above surely happened
            raise errors.ComponentSetupHandledError()

        self.writeIndex = properties.get('write-index', False)
        self.reactToMarks = properties.get('react-to-stream-markers', False)
        self.syncOnTdt = properties.get('sync-on-tdt', False)
        self.timeOverlap = properties.get('time-overlap', 0)

        sink = self.get_element('fdsink')

        if gstreamer.element_factory_has_property('multifdsink',
                                                  'resend-streamheader'):
            sink.set_property('resend-streamheader', False)
        else:
            self.debug("resend-streamheader property not available, "
                       "resending streamheader when it changes in the caps")
        sink.get_pad('sink').connect('notify::caps', self._notify_caps_cb)
        # connect to client-removed so we can detect errors in file writing
        sink.connect('client-removed', self._client_removed_cb)

        if self.writeIndex:
            sink.connect('client-added', self._client_added_cb)

        if self.reactToMarks:
            pfx = properties.get('stream-marker-filename-prefix', '%03d.')
            self._markerPrefix = pfx

        if self.reactToMarks or self.writeIndex or self.syncOnTdt:
            sink.get_pad("sink").add_data_probe(self._src_pad_probe)
示例#2
0
 def addError(self, id, format, *args, **kwargs):
     self.warning(format, *args)
     m = messages.Message(messages.ERROR,
                          T_(format, *args),
                          id=id,
                          **kwargs)
     self.addMessage(m)
     raise errors.ComponentSetupHandledError()
示例#3
0
 def check_algorithms(self, algorithms):
     if not algorithms:
         m = messages.Error(T_(
             N_("The multibouncer requires at least one bouncer "
                "algorithm plug to be present")),
                            mid='no-algorithm')
         self.addMessage(m)
         raise errors.ComponentSetupHandledError()
示例#4
0
 def checkErrorCallback(result):
     # if the mood is now sad, it means an error was encountered
     # during check, and we should return a failure here.
     # since the checks are responsible for adding a message,
     # this is a handled error.
     current = self.state.get('mood')
     if current == moods.sad.value:
         self.warning('Running checks made the component sad.')
         raise errors.ComponentSetupHandledError()
示例#5
0
    def do_setup(self):
        root = self._get_root()
        self._site = self.siteClass(resource=root)
        if self.type == 'slave':
            # Streamer is slaved to a porter.

            # We have two things we want to do in parallel:
            #  - ParseLaunchComponent.do_start()
            #  - log in to the porter, then register our mountpoint with
            #    the porter.
            # So, we return a DeferredList with a deferred for each of
            # these tasks. The second one's a bit tricky: we pass a dummy
            # deferred to our PorterClientFactory that gets fired once
            # we've done all of the tasks the first time (it's an
            # automatically-reconnecting client factory, and we only fire
            # this deferred the first time)

            self._porterDeferred = d = defer.Deferred()
            mountpoints = [self.mountPoint]
            if self.multi_files:
                self._pbclient = porterclient.HTTPPorterClientFactory(
                    self._site, [], d, prefixes=mountpoints)
            else:
                self._pbclient = porterclient.HTTPPorterClientFactory(
                    self._site, mountpoints, d)

            creds = credentials.UsernamePassword(self._porterUsername,
                                                 self._porterPassword)
            self._pbclient.startLogin(creds, self._pbclient.medium)

            self.info("Starting porter login at \"%s\"", self._porterPath)
            # This will eventually cause d to fire
            reactor.connectWith(fdserver.FDConnector,
                                self._porterPath,
                                self._pbclient,
                                10,
                                checkPID=False)
        else:
            # Streamer is standalone.
            try:
                iface = self.iface or ""
                self.info('Listening on port %d, interface=%r', self.port,
                          iface)
                self._tport = reactor.listenTCP(self.port,
                                                self._site,
                                                interface=iface)
            except error.CannotListenError:
                t = 'Port %d is not available.' % self.port
                self.warning(t)
                m = messages.Error(
                    T_(N_("Network error: TCP port %d is not available."),
                       self.port))
                self.addMessage(m)
                self.setMood(moods.sad)
                return defer.fail(errors.ComponentSetupHandledError(t))
示例#6
0
 def create_pipeline(self):
     try:
         unparsed = self.get_pipeline_string(self.config['properties'])
     except errors.MissingElementError, e:
         self.warning('Missing %s element' % e.args[0])
         m = messages.Error(
             T_(
                 N_("The worker does not have the '%s' element installed.\n"
                    "Please install the necessary plug-in and restart "
                    "the component.\n"), e.args[0]))
         self.addMessage(m)
         raise errors.ComponentSetupHandledError(e)
示例#7
0
    def setup(self, component):
        self._icsfile = self.props['file']

        try:
            handle = open(self._icsfile, 'r')
        except IOError, e:
            m = messages.Error(T_(N_(
                "Failed to open iCalendar file '%s'. "
                "Check permissions on that file."), self._icsfile),
                               mid='error-icalbouncer-file')
            component.addMessage(m)
            raise errors.ComponentSetupHandledError()
示例#8
0
class IcalBouncerAlgorithm(base.BouncerAlgorithm):

    logCategory = 'icalbouncer'
    events = []
    maxKeyCardDuration = timedelta(days=1)

    def get_namespace(self):
        return 'icalbouncer'

    def start(self, component):
        self.props = self.args['properties']
        self.iCalScheduler = None
        self.subscriptionToken = None
        self.check_properties(component)
        self.setup(component)

    def check_properties(self, component):

        def missingModule(moduleName):
            m = messages.Error(T_(N_(
                "To use the iCalendar bouncer you need to have "
                "the '%s' module installed.\n"), moduleName),
                               mid='error-python-%s' % moduleName)
            documentation.messageAddPythonInstall(m, moduleName)
            component.addMessage(m)

        if not eventcalendar.HAS_ICALENDAR:
            missingModule('icalendar')
        if not eventcalendar.HAS_DATEUTIL:
            missingModule('dateutil')

    def setup(self, component):
        self._icsfile = self.props['file']

        try:
            handle = open(self._icsfile, 'r')
        except IOError, e:
            m = messages.Error(T_(N_(
                "Failed to open iCalendar file '%s'. "
                "Check permissions on that file."), self._icsfile),
                               mid='error-icalbouncer-file')
            component.addMessage(m)
            raise errors.ComponentSetupHandledError()

        try:
            self.iCalScheduler = scheduler.ICalScheduler(handle)
        except (ValueError, IndexError, KeyError), e:
            m = messages.Error(T_(N_(
                "Error parsing ical file '%s'."), self._icsfile),
                               debug=log.getExceptionMessage(e),
                               mid="error-icalbouncer-file")
            component.addMessage(m)
            raise errors.ComponentSetupHandledError()
示例#9
0
    def start(self, component):
        self.props = self.args['properties']
        self.deny_default = self.props.get('deny-default', True)

        self.allows = netutils.RoutingTable()
        self.denies = netutils.RoutingTable()
        for p, t in (('allow', self.allows), ('deny', self.denies)):
            for s in self.props.get(p, []):
                try:
                    ip, mask = s.split('/')
                    t.addSubnet(True, ip, int(mask))
                except Exception, e:
                    m = messages.Error(
                        T_(N_("Invalid value for property %r: %s"), p, s),
                        log.getExceptionMessage(e),
                        mid='match-type')
                    component.addMessage(m)
                    raise errors.ComponentSetupHandledError()
示例#10
0
    def do_setup(self):
        # Create our combined PB-server/fd-passing channel
        self.have_properties()
        realm = PorterRealm(self)
        checker = checkers.FlexibleCredentialsChecker()
        checker.addUser(self._username, self._password)
        if not self._requirePassword:
            checker.allowPasswordless(True)

        p = portal.Portal(realm, [checker])
        serverfactory = pb.PBServerFactory(p)

        try:
            # Rather than a normal listenTCP() or listenUNIX(), we use
            # listenWith so that we can specify our particular Port, which
            # creates Transports that we know how to pass FDs over.
            try:
                os.unlink(self._socketPath)
            except OSError:
                pass

            self._socketlistener = reactor.listenWith(fdserver.FDPort,
                                                      self._socketPath,
                                                      serverfactory,
                                                      mode=self._socketMode)
            self.info("Now listening on socketPath %s", self._socketPath)
        except error.CannotListenError:
            self.warning("Failed to create socket %s" % self._socketPath)
            m = messages.Error(
                T_(N_("Network error: socket path %s is not available."),
                   self._socketPath))
            self.addMessage(m)
            self.setMood(moods.sad)
            return defer.fail(errors.ComponentSetupHandledError())

        # Create the class that deals with the specific protocol we're proxying
        # in this porter.
        try:
            proto = reflect.namedAny(self._porterProtocol)
            self.debug("Created proto %r" % proto)
        except (ImportError, AttributeError):
            self.warning("Failed to import protocol '%s', defaulting to HTTP" %
                         self._porterProtocol)
            proto = HTTPPorterProtocol

        # And of course we also want to listen for incoming requests in the
        # appropriate protocol (HTTP, RTSP, etc.)
        factory = PorterProtocolFactory(self, proto)
        try:
            reactor.listenWith(fdserver.PassableServerPort,
                               self._port,
                               factory,
                               interface=self._interface)
            self.info("Now listening on interface %r on port %d",
                      self._interface, self._port)
        except error.CannotListenError:
            self.warning("Failed to listen on interface %r on port %d",
                         self._interface, self._port)
            m = messages.Error(
                T_(N_("Network error: TCP port %d is not available."),
                   self._port))
            self.addMessage(m)
            self.setMood(moods.sad)
            return defer.fail(errors.ComponentSetupHandledError())
示例#11
0
    def do_setup(self):
        self.have_properties(self.config['properties'])

        root = self._rootResource
        if root is None:
            root = self._getDefaultRootResource()

        if root is None:
            raise errors.WrongStateError(
                "a resource or path property must be set")

        site = Site(root, self)
        self._timeoutRequestsCallLater = reactor.callLater(
            self.REQUEST_TIMEOUT, self._timeoutRequests)

        # Create statistics handler and start updating ui state
        self.stats = serverstats.ServerStatistics()
        updater = StatisticsUpdater(self.uiState, "request-statistics")
        self.stats.startUpdates(updater)
        updater = StatisticsUpdater(self.uiState, "provider-statistics")
        self._fileProviderPlug.startStatsUpdates(updater)
        self._updateUptime()

        d = defer.Deferred()
        if self.type == 'slave':
            # Streamer is slaved to a porter.
            if self._singleFile:
                self._pbclient = porterclient.HTTPPorterClientFactory(
                    site, [self.mountPoint], d)
            else:
                self._pbclient = porterclient.HTTPPorterClientFactory(
                    site, [], d, prefixes=[self.mountPoint])
            creds = credentials.UsernamePassword(self._porterUsername,
                                                 self._porterPassword)
            self._pbclient.startLogin(creds, self._pbclient.medium)
            self.info("Logging to porter on socketPath %s", self._porterPath)
            # This will eventually cause d to fire
            reactor.connectWith(fdserver.FDConnector,
                                self._porterPath,
                                self._pbclient,
                                10,
                                checkPID=False)
        else:
            # File Streamer is standalone.
            try:
                self.debug('Going to listen on port %d' % self.port)
                iface = ""
                # we could be listening on port 0, in which case we need
                # to figure out the actual port we listen on
                self._twistedPort = reactor.listenTCP(self.port,
                                                      site,
                                                      interface=iface)
                self.port = self._twistedPort.getHost().port
                self.info('Listening on interface %r on port %d', iface,
                          self.port)
            except error.CannotListenError:
                t = 'Port %d is not available.' % self.port
                self.warning(t)
                m = messages.Error(
                    T_(N_("Network error: TCP port %d is not available."),
                       self.port))
                self.addMessage(m)
                self.setMood(moods.sad)
                return defer.fail(errors.ComponentSetupHandledError(t))
            # fire callback so component gets happy
            d.callback(None)
        # we are responsible for setting component happy

        def setComponentHappy(result):
            self.httpauth.scheduleKeepAlive()
            self.setMood(moods.happy)
            return result

        d.addCallback(setComponentHappy)
        return d
示例#12
0
    def start(self, component):
        self.watchable_keycards = watched.WatchedDict(
        )  # keycard id -> Keycard
        self.contexts = {}  # keycard id -> {algorithm name -> result}
        self.algorithms = util.OrderedDict()  # name -> algorithm

        def add_entry(entry, algorithm):
            name = entry['type']
            if name in self.algorithms:
                suffix = 1
                while ('%s-%d' % (name, suffix)) in self.algorithms:
                    suffix += 1
                name = '%s-%d' % (name, suffix)

            assert name not in self.algorithms
            self.algorithms[name] = algorithm
            return name

        # get all algorithm plugs this component has, put them into
        # self.algorithms with unique names
        entries = component.config['plugs'].get(base.BOUNCER_ALGORITHM_SOCKET,
                                                [])
        algorithms = component.plugs.get(base.BOUNCER_ALGORITHM_SOCKET, [])

        if not algorithms:
            m = messages.Error(T_(
                N_("The multibouncerplug requires at least one bouncer "
                   "algorithm plug to be present")),
                               mid='no-algorithm')
            component.addMessage(m)
            raise errors.ComponentSetupHandledError()

        for entry, algorithm in zip(entries, algorithms):
            # add the algorithm to the algorithms dictionary
            name = add_entry(entry, algorithm)
            # provide the algorithm with the keycard store
            algorithm.set_keycard_store(self.watchable_keycards)
            # provide the algorithm with an expiry function crafted especially
            # for it (containing its unique name)
            expire = lambda ids: self.algorithm_expire_keycard_ids(ids, name)
            algorithm.set_expire_function(expire)

        self.debug("configured with algorithms %r", self.algorithms.keys())

        # create the algorithm combinator
        props = self.args['properties']
        self.combinator = combinator.AlgorithmCombinator(self.algorithms)

        if 'combination' in props and combinator.pyparsing is None:
            m = messages.Error(T_(
                N_("To use the 'combination' property you need to "
                   "have the 'pyparsing' module installed.\n")),
                               mid='missing-pyparsing')
            documentation.messageAddPythonInstall(m, 'pyparsing')
            component.addMessage(m)
            raise errors.ComponentSetupHandledError()

        # get the combination specification, defaulting to implicit AND
        spec = props.get('combination', ' and '.join(self.algorithms.keys()))
        self.debug("using combination %s", spec)
        try:
            self.combinator.create_combination(spec)
        except combinator.ParseException, e:
            m = messages.Error(T_(N_("Invalid algorithms combination: %s"),
                                  str(e)),
                               mid='wrong-combination')

            component.addMessage(m)
            raise errors.ComponentSetupHandledError()
示例#13
0
    def do_setup(self):
        def add_entry(entry, algorithm):
            name = entry['type']
            if name in self.algorithms:
                suffix = 1
                while ('%s-%d' % (name, suffix)) in self.algorithms:
                    suffix += 1
                name = '%s-%d' % (name, suffix)

            assert name not in self.algorithms
            self.algorithms[name] = algorithm
            return name

        # get all algorithm plugs this component has, put them into
        # self.algorithms with unique names
        entries = self.config['plugs'].get(base.BOUNCER_ALGORITHM_SOCKET, [])
        algorithms = self.plugs.get(base.BOUNCER_ALGORITHM_SOCKET, [])

        # check if there's at least one algorithm plug in a separate method, so
        # subclasses can override it
        self.check_algorithms(algorithms)

        for entry, algorithm in zip(entries, algorithms):
            # add the algorithm to the algorithms dictionary
            name = add_entry(entry, algorithm)
            # provide the algorithm with the keycard store
            algorithm.set_keycard_store(self.watchable_keycards)
            # provide the algorithm with an expiry function crafted especially
            # for it (containing its unique name)
            expire = lambda ids: self.algorithm_expire_keycard_ids(ids, name)
            algorithm.set_expire_function(expire)

        # we don't have any algorithms, stop here (see StaticMultiBouncer to
        # see why we need this)
        if not self.algorithms:
            return

        self.debug("configured with algorithms %r", self.algorithms.keys())

        # create the algorithm combinator
        props = self.config['properties']
        self.combinator = combinator.AlgorithmCombinator(self.algorithms)

        if 'combination' in props and combinator.pyparsing is None:
            m = messages.Error(T_(
                N_("To use the 'combination' property you need to "
                   "have the 'pyparsing' module installed.\n")),
                               mid='missing-pyparsing')
            documentation.messageAddPythonInstall(m, 'pyparsing')
            self.addMessage(m)
            raise errors.ComponentSetupHandledError()

        # get the combination specification, defaulting to implicit AND
        spec = props.get('combination', ' and '.join(self.algorithms.keys()))
        self.debug("using combination %s", spec)
        try:
            self.combinator.create_combination(spec)
        except combinator.ParseException, e:
            m = messages.Error(T_(N_("Invalid algorithms combination: %s"),
                                  str(e)),
                               mid='wrong-combination')
            self.addMessage(m)
            raise errors.ComponentSetupHandledError()