def disagree(about): """do not bother to translate this, it should normally not happen""" self.game.close() msg = 'The data bases for game %s have different %s' % ( self.game.seed, about) logWarning(msg) raise pb.Error(msg)
def _process_cmd_device_monitor(self, options): if not options["port"]: for item in util.get_serialports(): if "VID:PID" in item["hwid"]: options["port"] = item["port"] break # terminate opened monitors if options["port"]: for ac in list(self._acs.values()): if (isinstance(ac, SerialPortAsyncCmd) and ac.options["port"] == options["port"]): self.log.info( "Terminate previously opened monitor at {port}", port=options["port"], ) ac.ac_close() del self._acs[ac.id] if not options["port"]: raise pb.Error("Please specify serial port using `--port` option") self.log.info("Starting serial monitor at {port}", port=options["port"]) return self._defer_async_cmd(SerialPortAsyncCmd(options), pass_agent_name=False)
def cb_async_result(self, result): if self._acs_total == 0: self._acs_total = len(result) for (success, value) in result: if not success: raise pb.Error(value) self.acread_data(*value)
def readyForGameStart(self, tableid, gameid, wantedGame, playerNames, shouldSave=True): """playerNames are in wind order ESWN""" def answered(result): """callback, called after the client player said yes or no""" self.beginQuestion = None if self.connection and result: # still connected and yes, we are Client.readyForGameStart(self, tableid, gameid, wantedGame, playerNames, shouldSave) return Message.OK else: return Message.NoGameStart def cancelled(dummy): """the user does not want to start now. Back to table list""" if Debug.table: logDebug('%s: Readyforgamestart returns Message.NoGameStart for table %s' % ( self.name, self._tableById(tableid))) self.table = None self.beginQuestion = None if self.tableList: self.__updateTableList() self.tableList.show() return Message.NoGameStart if sum(not x[1].startswith('Robot ') for x in playerNames) == 1: # we play against 3 robots and we already told the server to start: no need to ask again return Client.readyForGameStart(self, tableid, gameid, wantedGame, playerNames, shouldSave) assert not self.table assert self.tables self.table = self._tableById(tableid) if not self.table: raise pb.Error('client.readyForGameStart: tableid %d unknown' % tableid) msg = m18n("The game on table <numid>%1</numid> can begin. Are you ready to play now?", tableid) self.beginQuestion = QuestionYesNo(msg, modal=False, caption=self.name).addCallback( answered).addErrback(cancelled) return self.beginQuestion
def newfunc(*arg, **kwargs): ret = None try: ret = func(*arg, **kwargs) except Exception, value: (type, value, tb) = sys.exc_info() raise pb.Error(str(type) + ':' + str(value))
def perspective_getService(self, name, monitor=None, listener=None, options=None): """Return a reference to a ZenHub service. It also associates the service with a collector so that changes can be pushed back out to collectors. :param str name: The name of the service, e.g. "EventService" :param str monitor: The name of a collector, e.g. "localhost" :param listener: A remote reference to the client :type listener: twisted.spread.pb.RemoteReference :return: A reference to a service :rtype: .service.WorkerInterceptor """ try: service = self.__services.getService(name, monitor) except RemoteBadMonitor: if self.__log.isEnabledFor(logging.DEBUG): self.__log.error("Monitor unknown monitor=%s", monitor) # This is a valid remote exception, so let it go through # to the collector daemon to handle raise except UnknownServiceError: self.__log.error("Service not found service=%s", name) raise except Exception as ex: self.__log.exception("Failed to load service service=%s", name) raise pb.Error(str(ex)) else: if service is not None and listener: service.addListener(listener, options) return service
def remote_acclose(self, ac_id): self.log.debug("Async Close: {id}", id=ac_id) if ac_id not in self._acs: raise pb.Error("Invalid Async Identifier") return_code = self._acs[ac_id].ac_close() del self._acs[ac_id] return return_code
def clientConnectionMade(self, broker): if self.sslContextFactory and not self.sslContextFactory.certificate_verified: self.remote_client.log.error( "A remote cloud could not prove that its security certificate is " "from {host}. This may cause a misconfiguration or an attacker " "intercepting your connection.", host=self.sslContextFactory.host, ) return self.remote_client.disconnect() pb.PBClientFactory.clientConnectionMade(self, broker) protocol.ReconnectingClientFactory.resetDelay(self) self.remote_client.log.info("Successfully connected") self.remote_client.log.info("Authenticating") auth_token = None try: auth_token = AccountClient().fetch_authentication_token() except Exception as e: # pylint:disable=broad-except d = defer.Deferred() d.addErrback(self.clientAuthorizationFailed) d.errback(pb.Error(e)) return d d = self.login( credentials.UsernamePassword( auth_token.encode(), get_host_id().encode(), ), client=self.remote_client, ) d.addCallback(self.remote_client.cb_client_authorization_made) d.addErrback(self.clientAuthorizationFailed) return d
def perspective_reportingForWork(self, worker, workerId, worklistId): """Allow a worker to register for work. :param worker: Reference to zenhubworker :type worker: twisted.spread.pb.RemoteReference :param int workerId: The worker's identifier :param str worklistId: The worker will work jobs from this worklist :rtype: None """ worker.busy = False worker.workerId = workerId worker.sessionId = uuid4() pool = self.__pools.get(worklistId) if pool is None: self.__log.error( "Worker asked to work unknown worklist " "worker=%s worklist=%s", workerId, worklistId, ) raise pb.Error("No such worklist: %s" % worklistId) worker.queue_name = worklistId try: pool.add(worker) except Exception as ex: self.__log.exception("Failed to add worker worker=%s", workerId) raise pb.Error( "Internal ZenHub error: %s: %s" % (ex.__class__, ex), ) self.__log.info( "Worker ready to work worker=%s session=%s worklist=%s", workerId, worker.sessionId.hex, worklistId, ) def removeWorker(worker): pool = self.__pools.get(worker.queue_name) pool.remove(worker) self.__log.info( "Worker disconnected worker=%s session=%s", worker.workerId, worker.sessionId.hex, ) worker.notifyOnDisconnect(removeWorker)
def remoteMessageReceived(self, broker, message, args, kw): """Defer execution of the message to an executor.""" begin = time.time() success = False try: args = broker.unserialize(args) kw = broker.unserialize(kw) call = ServiceCall( monitor=self.__monitor, service=self.__name, method=message, args=args, kwargs=kw, ) executor = self.__get_executor(call) self.__log.debug( "Begin processing remote message " "message=%s service=%s monitor=%s", message, self.__name, self.__monitor, ) state = yield executor.submit(call) response = broker.serialize(state, self.perspective) success = True defer.returnValue(response) except _PropagatingErrors as ex: raise except Exception as ex: self.__log.exception( "Failed to process remote message " "message=%s service=%s monitor=%s error=(%s) %s", message, self.__name, self.__monitor, ex.__class__.__name__, ex, ) raise pb.Error( "Internal ZenHub error: (%s) %s" % (ex.__class__.__name__, ex), ) finally: end = time.time() elapsed = end - begin self.callTime += elapsed self.__log.debug( "Completed processing remote message " "message=%s service=%s monitor=%s status=%s duration=%0.2f", message, self.__name, self.__monitor, "OK" if success else "ERROR", elapsed, )
def __init__(self, options=None, on_end_callback=None): self.options = options or {} self.on_end_callback = on_end_callback self._buffer = b"" self._return_code = None self._d = None self._paused = False try: self.start() except Exception as e: raise pb.Error(str(e))
def cb_async_result(self, result): if len(result) != 1: raise pb.Error("Invalid response from Remote Cloud") success, value = result[0] if not success: raise pb.Error(value) reconnected = self._agent_id is not None self._agent_id, self._ac_id = value if reconnected: self.acread_data(force=True) self.acwrite_data("", force=True) return # start bridge port = reactor.listenTCP(0, self._bridge_factory) address = port.getHost() self.log.debug("Serial Bridge is started on {address!r}", address=address) if "sock" in self.cmd_options: with open(os.path.join(self.cmd_options["sock"], "sock"), "w") as fp: fp.write("socket://localhost:%d" % address.port)
def _handle_error(self, task, exception): if task.attempt >= self.task_max_retries: # No more attempts, handle the error as a failure. self.log.warn( "Retries exhausted service=%s method=%s id=%s", task.call.service, task.call.method, task.call.id.hex, ) ex = pb.Error( ("Internal ZenHub error: ({0.__class__.__name__}) {0}".format( exception)).strip()) self._handle_failure(task, ex) else: # Still have attempts, handle the error as a retry. self._handle_retry(task, exception)
def remote_getService(self, name, monitor): """Return a reference to the named service. @param name {str} Name of the service to load @param monitor {str} Name of the collection monitor """ try: return self.__manager.getService(name, monitor) except RemoteBadMonitor: # Catch and rethrow this Exception derived exception. raise except UnknownServiceError: self.log.error("Service '%s' not found", name) raise except Exception as ex: self.log.exception("Failed to get service '%s'", name) raise pb.Error(str(ex))
def cb_psync_init_result(self, result): self._acs_total = len(result) for (success, value) in result: if not success: raise pb.Error(value) agent_id, ac_id = value try: d = self.agentpool.callRemote( "acwrite", agent_id, ac_id, dict(stage=PROJECT_SYNC_STAGE.DBINDEX.value), ) d.addCallback(self.cb_psync_dbindex_result, agent_id, ac_id) d.addErrback(self.cb_global_error) except (AttributeError, pb.DeadReferenceError): self.disconnect(exit_code=1)
def execute(self, worker, task): """Execute the task using the worker. :param worker: The worker to execute the task :type worker: WorkerRef :param task: The task to be executed by the worker :type task: ServiceCallTask """ try: # Notify listeners of a task execution attempt. self._handle_start(task, worker.workerId) # Run the task result = yield worker.run(task.call) # Task succeeded, process the result self._handle_success(task, result) except _RemoteErrors as ex: # These kinds of errors originate from the service and # are propagated directly back to the submitter. self._handle_failure(task, ex) except _InternalErrors as ex: # These are un-retryable errors that occur while attempting # to execute the call, so are logged and a summary error is # returned to the submitter. self.log.error( "(%s) %s service=%s method=%s id=%s worker=%s", type(ex), ex, task.call.service, task.call.method, task.call.id, worker.workerId, ) error = pb.Error( ("Internal ZenHub error: ({0.__class__.__name__}) {0}".format( ex)).strip()) self._handle_failure(task, error) except pb.PBConnectionLost as ex: # Lost connection to the worker; not a failure. # The attempt count is _not_ incremented. self.log.warn( "Worker no longer accepting work worker=%s error=%s", worker.workerId, ex, ) self._handle_retry(task, ex) except Exception as ex: self._handle_error(task, ex) self.log.exception("Unexpected failure worklist=%s", self.name) finally: # if the task is retryable, push the task # to the front of its queue. if task.retryable: self.worklist.pushfront(task.priority, task) self.log.debug( "Task queued for retry service=%s method=%s id=%s", task.call.service, task.call.method, task.call.id.hex, ) # Make the worker available for work again self.workers.layoff(worker)
def remote_error(self): raise pb.Error('error!!!')
def remote_acwrite(self, ac_id, data): self.log.debug("Async Write: {id}", id=ac_id) if ac_id not in self._acs: raise pb.Error("Invalid Async Identifier") return self._acs[ac_id].ac_write(data)
def remote_acread(self, ac_id): self.log.debug("Async Read: {id}", id=ac_id) if ac_id not in self._acs: raise pb.Error("Invalid Async Identifier") return self._acs[ac_id].ac_read()
def _process_cmd_run_or_test( # pylint: disable=too-many-locals,too-many-branches self, command, options): assert options and "project_id" in options project_dir = join(self.working_dir, "projects", options["project_id"]) origin_pio_ini = join(project_dir, "platformio.ini") back_pio_ini = join(project_dir, "platformio.ini.bak") # remove insecure project options try: conf = ProjectConfig(origin_pio_ini) if isfile(back_pio_ini): os.remove(back_pio_ini) os.rename(origin_pio_ini, back_pio_ini) # cleanup if conf.has_section("platformio"): for opt in conf.options("platformio"): if opt.endswith("_dir"): conf.remove_option("platformio", opt) else: conf.add_section("platformio") conf.set("platformio", "build_dir", ".pio/build") conf.save(origin_pio_ini) # restore A/M times os.utime(origin_pio_ini, (getatime(back_pio_ini), getmtime(back_pio_ini))) except NotPlatformIOProjectError as e: raise pb.Error(str(e)) cmd_args = ["platformio", "--force", command, "-d", project_dir] for env in options.get("environment", []): cmd_args.extend(["-e", env]) for target in options.get("target", []): cmd_args.extend(["-t", target]) for ignore in options.get("ignore", []): cmd_args.extend(["-i", ignore]) if options.get("upload_port", False): cmd_args.extend(["--upload-port", options.get("upload_port")]) if options.get("test_port", False): cmd_args.extend(["--test-port", options.get("test_port")]) if options.get("disable_auto_clean", False): cmd_args.append("--disable-auto-clean") if options.get("without_building", False): cmd_args.append("--without-building") if options.get("without_uploading", False): cmd_args.append("--without-uploading") if options.get("silent", False): cmd_args.append("-s") if options.get("verbose", False): cmd_args.append("-v") paused_acs = [] for ac in self._acs.values(): if not isinstance(ac, SerialPortAsyncCmd): continue self.log.info("Pause active monitor at {port}", port=ac.options["port"]) ac.pause() paused_acs.append(ac) def _cb_on_end(): if isfile(back_pio_ini): if isfile(origin_pio_ini): os.remove(origin_pio_ini) os.rename(back_pio_ini, origin_pio_ini) for ac in paused_acs: ac.unpause() self.log.info("Unpause active monitor at {port}", port=ac.options["port"]) return self._defer_async_cmd( ProcessAsyncCmd( { "executable": proc.where_is_program("platformio"), "args": cmd_args }, on_end_callback=_cb_on_end, ))
def view_get_mailing(self, client, collector, mailing_id): """ Returns the mailing content as a dictionary: - id: mailing_id (Mandatory) - header: email headers(string) - body: email body (string) - tracking_url: base url for all tracking links - delete: True if the mailing should be deleted on slave. """ self.log.debug("get_mailing(%s)", mailing_id) from models import Mailing self.cloud_client = CloudClient.grab( self.cloud_client.id) # reload object if not self.cloud_client.enabled: self.log.warn("get_mailing() refused for disabled client [%s]", self.cloud_client.serial) raise pb.Error("Not allowed!") try: mailing = Mailing.find_one({ '_id': mailing_id, 'status': { '$in': (MAILING_STATUS.FILLING_RECIPIENTS, MAILING_STATUS.READY, MAILING_STATUS.RUNNING) } }) if mailing: header = str(mailing.header).replace('\r\n', '\n') body = mailing.body.replace('\r\n', '\n') feedback_loop = mailing.feedback_loop or settings_vars.get( settings_vars.FEEDBACK_LOOP_SETTINGS) dkim = mailing.dkim if not dkim: self.log.debug( "No DKIM for mailing [%d]. Looking configuration for domain '%s'...", mailing_id, mailing.domain_name) sender_domain = SenderDomain.find_one( {'domain_name': mailing.domain_name}) if sender_domain: self.log.debug( "Found DKIM configuration for domain '%s'", mailing.domain_name) dkim = sender_domain.dkim util.StringPager( collector, pickle.dumps({ 'id': mailing_id, 'header': header, 'body': body, 'read_tracking': mailing.read_tracking, 'click_tracking': mailing.click_tracking, 'tracking_url': mailing.tracking_url, 'backup_customized_emails': mailing.backup_customized_emails, 'testing': mailing.testing, 'dkim': dkim, 'feedback_loop': feedback_loop, 'domain_name': mailing.domain_name, 'return_path_domain': settings_vars.get(settings_vars.RETURN_PATH_DOMAIN), 'type': mailing.type, 'url_encoding': mailing.url_encoding, 'delete': False, })) else: self.log.error("Mailing [%d] doesn't exist anymore.", mailing_id) util.StringPager( collector, pickle.dumps({ 'id': mailing_id, 'delete': True })) except Exception: self.log.exception("Can't get mailing [%d]", mailing_id) util.StringPager(collector, pickle.dumps({ 'id': mailing_id, 'delete': True }))
def submit(self, call): return defer.fail(pb.Error("ZenHub not ready."))