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)
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()
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()
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()
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))
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)
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()
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()
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()
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())
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
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()
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()