def submit(self): """ Run a build to create the image for the repository. Progress of the build can be monitored by listening for items in the Queue passed to the constructor as `q`. """ def break_callback(): return self.stop_event.is_set() env = os.environ.copy() if self.git_credentials: env['GIT_CREDENTIAL_ENV'] = self.git_credentials cmd = self.get_cmd() app_log.info("Starting build: %s", " ".join(cmd)) try: self.progress(ProgressEvent.Kind.BUILD_STATUS_CHANGE, ProgressEvent.BuildStatus.RUNNING) for line in _execute_cmd(cmd, capture=True, break_callback=break_callback, env=env): self._handle_log(line) self.progress(ProgressEvent.Kind.BUILD_STATUS_CHANGE, ProgressEvent.BuildStatus.COMPLETED) except subprocess.CalledProcessError: self.progress(ProgressEvent.Kind.BUILD_STATUS_CHANGE, ProgressEvent.BuildStatus.FAILED) except Exception: app_log.exception("Error in watch stream for %s", self.name) raise
def run(args): crew_client = Client( host=args.rmq_address, port=args.rmq_port, virtualhost=args.rmq_vhost, credentials=PlainCredentials(username=args.rmq_user, password=args.rmq_password) ) app = Application( args=args, handlers=HANDLERS, xsrf_cookies=False, cookie_secret=args.cookie_secret, debug=args.debug, reload=args.debug, gzip=args.gzip, crew=crew_client, timeout=args.timeout ) http_server = HTTPServer(app, xheaders=True) http_server.listen(args.port, address=args.address) log.info('Server started {host}:{port}'.format(host=args.address, port=args.port)) try: tornado.ioloop.IOLoop.instance().start() except Exception as e: log.exception(e) log.fatal("Server aborted by error: %r", e) return 0
def get(self): async_client = AsyncHTTPClient() auth_code = self.get_argument("code", None) if auth_code: # 第一步 获取access_token auth_token_url = self.__build_auth_token_url(auth_code) token_response = yield async_client.fetch(auth_token_url) access_token, refresh_token = self.__parse_token(token_response) # 第二不 得到用户身份信息 auth_me_url = self.__build_auth_me_url(access_token) open_response = yield async_client.fetch(auth_me_url) openid = self.__parse_me(open_response) # 第三布 获取用户基本信息 auth_user_url = self.__build_auth_user_url(access_token, openid) user_info = yield async_client.fetch(auth_user_url) user = self.__parse_user(user_info, access_token, refresh_token, openid) # 确认用户是否已经登录过 try: user = User.objects(type='qq', uid=openid)[0] except Exception as ex: app_log.exception(ex) finally: user.save() self.set_secure_cookie('userid', str(user.id)) self.set_secure_cookie('type', 'qq') self.redirect("/") else: # 登录失败,跳转到登录页面 self.redirect("/sigin")
def open(self): """ 1, 检查当前客户端时候已经打开浏览器窗口,是,发送错误提示信息 """ email = self.get_secure_cookie('email') nickname = self.get_secure_cookie('nickname') if ClientManager.is_client_connected(email): app_log.exception("client[{0}] already connected!".format(email)) self.write_message({ 'type': 'system.error', 'message': '检测到当前用户已经打开一个窗口,当前窗口自动失效' }) else: clients = ClientManager.get_clients() # 保存客户端信息 ClientManager.add_client(str(id(self)), nickname=nickname, email=email, handler=self) data = { 'type': 'add', 'clients': [] } for key in clients.keys(): client = clients[key] data['clients'].append({ "type": "add", "id": client.identity, "nickname": client.nickname, "avatar": client.avatar, "email": client.email }) self.send_to_all(json.dumps(data))
def get_job(self): """ Gets the Job in queue which name is same as `self.QUEUE_KEY`. Returns ------- job : dict or None New job data which is popped from the queue. `None` is returned when timeout. """ # Without `timeout`, this never stop on `KeyboardInterrupt` job_data = self._redis_client.blpop(self.QUEUE_KEY, self.QUEUE_POP_TIMEOUT) if job_data is None: return None try: job = json_decode(job_data[1]) errors = self.validate_job(job) if len(errors) > 0: raise ValueError( 'Validation failed: {}{}'.format(os.linesep, os.linesep.join(errors)) ) return job except ValueError: app_log.exception('Invalid job_data is received: %s', job_data) return None
def post(self): oldpath = self.get_argument("oldpath", None) newpath = self.get_argument("newpath", None) # curpath = self.get_argument("curpath", None) if not oldpath or not newpath: return self.write(json.dumps({"msg": u"文件或目录不存在", "code": 1})) toppath = self.settings.get("top_path") real_oldname = os.path.join(toppath, oldpath) real_newname = os.path.join(toppath, newpath) if not os.path.exists(real_oldname): return self.write(json.dumps({"msg": u"当前文件或目录不存在", "code": 1})) basename = os.path.basename(oldpath) move_path = os.path.join(real_newname, basename) if os.path.isdir(real_oldname) and os.path.exists(move_path): weblog.error("{}".format(move_path)) return self.write(json.dumps({"msg": u"新目录已存在", "code": 1})) pass if not os.path.isdir(real_newname) and os.path.isfile(real_oldname): return self.write( json.dumps({ "msg": u"新目录不存在".format(newpath), "code": 1 })) try: weblog.info("move {} to {} ".format(real_oldname, real_newname)) move(real_oldname, real_newname) return self.write(json.dumps({"msg": "ok", "code": 0})) except Exception as e: weblog.exception(e) return self.write(json.dumps({"msg": u"移动失败", "code": 1}))
def post(self): curpath = self.get_argument("curpath", None) filename = self.get_argument("filename", None) # super subor if curpath is None: return self.write(json.dumps({"error_code": 1, "msg": u"当前路径为空"})) else: real_file = os.path.join(self.settings.get("top_path"), curpath, filename) if curpath is not None and curpath.startswith("public/File"): weblog.info("{} can not delete".format(curpath)) return self.write( json.dumps({ "error_code": 1, "msg": u"该目录下的文件不能删除" })) if not os.path.exists(real_file): msg = u"{}不存在".format(real_file) return self.write(json.dumps({"error_code": 1, "msg": msg})) try: # cmd = "rm -rf {}".format(real_file) cmd = "mv {} /home/trash".format(real_file) weblog.info("{}".format(cmd)) os.system(cmd) return self.write(json.dumps({"error_code": 0, "msg": "文件已删除"})) except Exception as e: weblog.exception("{}".format(e)) return self.write(json.dumps({"error_code": 1, "msg": u"删除失败"}))
def emit(self, evtname, evtsrc, *data): callbacks = self.evtpool[evtname] for callback in callbacks: try: callback(evtsrc, *data) except: app_log.exception("call callback error")
def task_register(self, task_name, callback, interval=1, call_at=(), endtime=None): """ 任务注册 :param task_name: 任务名 :param callback: 任务执行方法 :param interval: 间隔时间(单位:分钟) :param call_at: 每日周期性定时调用时间,如:(8:00,14:00,18:00) :param endtime: 结束日期,格式:2015-01-01 12:12:12 :return: """ print("task register: %s" % task_name) if callable(callback): try: call = functools.partial(self._run, task_name, callback, call_at, endtime) self._task_pool.update({ task_name: DiligentPeriodicCallback(call, 1000 * 60 * float(interval)) }) except Exception, ex: app_log.exception(ex)
def on_message(self, message): app_log.debug(message) #从 websocket 收到订阅的信息。格式: {"action":"subs","stamp":"x","data":["TA703","TA705"]} self.timestamp = time.time() #any response will be regarded as a heartbeat try: content = json.loads(message) op = content['action'] if op == 'sub': self.messager.subscribe(content['data']) elif op == 'subs': # topic 可以是 1F 5F 30F 等 # topic 定义在 "data":[ "aaa","bbb","ccc"] 中 for topic in content['data']: self.messager.subscribe(topic) elif op == 'unsub': self.messager.unsubscribe(content['data']) elif op == 'unsubs': for topic in content['data']: self.messager.unsubscribe(topic) elif op == 'clear': self.messager = None self.messager = Messager(self.send) elif op == 'pong': pass elif op == 'strategy': pass except Exception as e: app_log.exception(e)
def start(): # 登记xtornado路由 def local_func(exec_func, route_path, handler_class): @xtornado.route_sync_func(route_path, handler_class) def deco_func(*args, **kwargs): return exec_func(*args, **kwargs) for route_info in route_entries.values(): if route_info['class_name'] == '<module>': exec_func = route_info['exec_func'] else: # 给method做修饰的时候,method所属的class还没处于可用状态,延迟到这里才生成对象 cls = getattr(sys.modules[route_info['exec_func'].__module__], route_info['class_name']) exec_func = getattr(cls(), route_info['exec_func'].__name__) # 录入到xtornado local_func(exec_func, route_info['route_path'], route_info['handler_class']) # todo: 远程注册服务,定时心跳通知 # 开始服务 get_application().settings['log_function'] = log_function xtornado.start() # 调用停止服务需要执行的插件 for plg in stop_plugins: try: plg[0](*plg[1], **plg[2]) except Exception as ex: app_log.exception('something wrong when stopping: {0}'.format( plg[0]))
def delete(self): curpath = self.get_argument("curpath", None) filelist = self.get_arguments("filelist[]", False) # super subor if curpath is not None and curpath.startswith( "public/File") and self.get_current_user() != "Tornado": weblog.info("{} can not delete".format(curpath)) return self.write( json.dumps({ "error_code": 1, "msg": u"该目录下的文件不能删除" })) # print(self.request.arguments) # print(self.get_query_arguments("filelist")) for i in range(len(filelist)): file = filelist[i] real_file = os.path.join(self.settings.get("top_path"), file) filelist[i] = real_file if not os.path.exists(real_file): msg = u"{}不存在".format(file) return self.write(json.dumps({"error_code": 1, "msg": msg})) file_str = " ".join(filelist) try: # cmd = "rm -rf {}".format(file_str) cmd = "mv {} /home/trash".format(file_str) weblog.info("{}".format(cmd)) os.system(cmd) return self.write(json.dumps({"error_code": 0, "msg": "文件已删除"})) except Exception as e: weblog.exception("{}".format(e)) return self.write(json.dumps({"error_code": 1, "msg": u"删除失败"}))
def load_rbacfile(): from config import RBAC_FILE try: rbac_dict = yaml.load(file(RBAC_FILE)) return rbac_dict["rights"] except IOError as ioex: app_log.exception(ioex.message)
def _call_whatever(self, callback, *args, **kwargs): try: return callback(*args, **kwargs) except (ServerDown, WriteError, ConnectionError): EVENTBUS.emit_system_notify("cacheserver.down", "") app_log.exception("call %s, args %s" % (callback.__name__, str(args)))
async def wrapper(*args, **kwargs): try: res = await f(*args, **kwargs) except Exception as e: app_log.exception(f"Error checking {f.__name__}") res = False return res
def set(self, key, val, expire=None): if expire is None: expire = _DEFAULT_CONFIG[r'expire'] result = None key = _DEFAULT_CONFIG[r'key_prefix'] + key try: client = yield self._acquire_client() b_val = self.pickle_dumps_zip(val) yield client.set(key, b_val, expire=expire) result = True self._release_client(client) except Exception as e: app_log.exception(r'cache set: {}'.format(e)) return result
def connect(self): if self.connecting: return log.info('PikaClient: Trying to connect to RabbitMQ on {1}:{2}{3}, Object: {0}'.format( repr(self), self._cp.host, self._cp.port, self._cp.virtual_host) ) self.connecting = True try: self.connection = pika.adapters.tornado_connection.TornadoConnection( self._cp, on_open_callback=self._on_connected ) self.connection.add_on_close_callback(self._on_close) except Exception as e: self.connecting = False log.exception( 'PikaClient: connection failed because: ' '"{0}", trying again in 5 seconds'.format(str(e)) ) self._on_close(None)
def _set_done(self): self._done = True for cb in self._callbacks: try: cb(self) except Exception: app_log.exception('Exception in callback %r for %r', cb, self) self._callbacks = None
async def fetch_pin(phone_number): try: pin_code = await pin.fetch_or_generate_pin(phone_number=phone_number) except pyodbc.InterfaceError: app_log.exception("Connection error in pin.fetch_or_generate_pin") raise web.HTTPError( 503, "Internal temporary server error - please try again") return pin_code
def wrapper(): try: _callable(*args, **kw_args) except Exception as e: app_log.exception(r'{}'.format(e)) if not self._stop: loop = IOLoop.current() loop.call_later(self.interval, wrapper)
def _on_channel_open(self): for func in list(self._on_open_listeners): try: func(self) except Exception as e: log.exception(e) self.IOLOOP.add_callback(self._bethink)
def _set_done(self): self._done = True for cb in self._callbacks: try: cb(self) except Exception: app_log.exception("Exception in callback %r for %r", cb, self) self._callbacks = None
def on_message(self, unused_channel, basic_deliver, properties, body): """Invoked by pika when a message is delivered from RabbitMQ. The channel is passed for your convenience. The basic_deliver object that is passed in carries the exchange, routing key, delivery tag and a redelivered flag for the message. The properties passed in is an instance of BasicProperties with the message properties and the body is the message that was sent. :param pika.channel.Channel unused_channel: The channel object :param pika.Spec.Basic.Deliver basic_deliver: basic_deliver method :param pika.Spec.BasicProperties properties: properties :param str|unicode body: The message body """ # app_log.info('Received message # %s from %s: %s', basic_deliver.delivery_tag, properties.app_id, body[:10]) app_log.info('收到消息 # %s from %s: %s', basic_deliver.delivery_tag, properties.app_id, body[:20]) # lock = redis_lock.Lock(redis_client=r, name=DATA_SOURCE_NAME, id=datetime_2_string(local_now_dt()).encode(), # expire=EXPIRE_SECONDS_OF_REDIS_LOCK, auto_renewal=True) # if lock.acquire(timeout=TIMEOUT_SECONDS_OF_REDIS_LOCK): # app_log.info("got lock") try: # SendData(body) _data = json.loads(body) """ from configurer.handlers.data_source.schema_data_response "data_source_id": Use(native_str), "status": And(Use(native_str), lambda x: x in ( DATA_RESPONSE_STATUS_START, DATA_RESPONSE_STATUS_ACCEPTED, DATA_RESPONSE_STATUS_REJECTED, DATA_RESPONSE_STATUS_RESTART)), "total_slice": And(Use(int), lambda x: x >= 0), "current_slice": And(Use(int), lambda x: x >= 0), "syncing_date": Use(string_2_date), Optional("fetch_bunch_size"): And(Use(int), lambda x: x > 0), "msg": Use(native_str), Optional(object): object """ # Job functions # CommonSync(**_data) CloudResponse(_data) except Exception as e: app_log.exception(e) # release the lock # try: # app_log.error('releasing lock') # lock.release() # except Exception as e: # app_log.error(e) # # app_log.info("lock released") # else: # app_log.error("another job is already running at {}".format(lock.get_owner_id())) self.acknowledge_message(basic_deliver.delivery_tag)
def receive_event(observer): since = datetime.now(timezone.utc).timestamp() while True: try: yield docker_client.events(since=since, on_event=observer.on_next) except HTTPError as e: app_log.exception( 'unexpected http error occurred. reconnect...') yield gen.sleep(reconnect_wait)
def _handle_message_flow(self, future): # some other errors that I do not know yet that can # lead to memory leaks due to file descriptor will no be closed try: future.result() except Exception as e: app_log.exception(e) finally: self.STOP_FLAG = True self.close()
def hardware_io_loop(HardwareIoClass, session_factory): with HardwareIoClass(session_factory) as hw: delay = hw.delay while True: try: nxt = tornado.gen.sleep(delay.total_seconds()) yield hw.execute() # Run while the clock is ticking. yield nxt # Wait for the timer to run out. except Exception as e: app_log.exception(e)
def send_to_all(cls, data): """ 向所有链接到当前服务器的客户端发送信息 @param data: """ clients = cls.get_clients() for key in clients.keys(): try: clients[key].handler.write_message(json.dumps(data)) except Exception as ex: app_log.exception(ex)
def clear_history(days): clear_date = DatetimeManage.get_days_ago(days) try: db_session.query(TblBrowsingHistory).filter( TblBrowsingHistory.browsing_date <= clear_date).delete() db_session.commit() db_session.close() weblog.info("db data history clear...") except Exception as e: print(e) weblog.exception("data history error. {}".format(e))
def _on_close(self, connection, *args): log.info('PikaClient: Try to reconnect') if self.connected: for func in list(self._on_close_listeners): try: func(self) except Exception as e: log.exception(e) self.connecting = False self.connected = False self.IOLOOP.add_callback(self.connect)
def containers(self): url = "%s/containers/json?all=1&status=running" % self.url req = HTTPRequest(url=url, method='GET') try: resp = yield Storage.http.fetch(request=req) containers = [( [i for i in x['Names'] if i.count('/') == 1][0][1:], x['Image'], x['Id'], ) for x in loads(resp.body) if 'Up' in x['Status']] raise Return(containers) except HTTPError as e: log.exception(e) raise Return([])
def run(): try: result = func() except tornado.gen.Return as e: future.set_result(e.value) except Exception as e: log.exception(e) future.set_exception(e) else: if isinstance(result, tornado.gen.Future): result = yield result future.set_result(result)
def watch_queue(self): """ Starts watching the queue and run the job in queue. """ while self._is_running: job = yield self.get_job() if job is None: continue try: yield self.run_job(job) except Exception: self.stop() app_log.exception('Unexpected exception occurred.')
def clear_old_data(): pass data_clear_date = DatetimeManage.get_days_ago(365) try: pass db_session.query(TblJijin).filter( TblJijin.jdate <= data_clear_date).delete() db_session.query(TblSum).filter( TblSum.jdate <= data_clear_date).delete() db_session.commit() db_session.close() except Exception as e: print(e) weblog.exception("data TblJijin/TblSum error. {}".format(e))
def _on_close(self, connection, *args): log.info('PikaClient: Try to reconnect') self.io_loop = tornado.ioloop.IOLoop.current() if self.connected: for func in list(self._on_close_listeners): try: func(self) except Exception as e: log.exception(e) self.connecting = False self.connected = False self.io_loop.add_callback(self.connect)
def expire(self, key, expire): key = _DEFAULT_CONFIG[r'key_prefix'] + key try: client = yield self._acquire_client() yield client.expire(key, expire) self._release_client(client) except Exception as e: app_log.exception(r'cache expire: {}'.format(e))
def on_close(self): email = self.get_secure_cookie('email') _id = str(id(self)) if ClientManager.is_effective_connect(_id): ClientManager.remove_client(email) try: data = { "type": "out", "id": _id } self.send_to_all(json.dumps(data)) except Exception as ex: app_log.exception(ex) else: app_log.info("非有效连接,关闭页面不影响其他已经打开的页面")
def pull_everything(): r = requests.get( "https://raw.githubusercontent.com/minrk/simula-summer-school/2022/repos.txt" ) r.raise_for_status() for line in r.text.splitlines(): line = line.strip() if line.startswith("#"): continue if not line: continue repo_url = line try: pull_repo(repo_url) except Exception: app_log.exception("Failed to pull repo %s", repo_url)
def update_from_subparsers(subparsers, msg): for field in list(msg.keys()): try: parsers = subparsers.get(field) if parsers: data = msg[field] for matcher, parser in parsers: if matcher.match(data): u = parser.match(data) if u: msg.update(u.groupdict()) except Exception as e: log.exception(e) return msg
def publish(self, channel, content): try: if isinstance(content, str): content = bytes(content, r'utf-8') client = yield self._acquire_client() yield client.publish(channel, content) self._release_client(client) except Exception as e: app_log.exception(r'cache publish: {}'.format(e))
def get(self, id): book = Book.objects(bid=id)[0] params = { 'book': book, "groups": self.get_groups(), "page_heading": book.title, "like": "-empty" } try: user = self.get_curent_user_model() params['user'] = user if user in book.likes: params['like'] = "" except Exception as ex: app_log.exception(ex) self.render("book/book.html", **params)
def on_message(self, message): log.debug(u'Client %s send message: "%s"', self.id, message) # deserialize message data = self._data_load(message) serial = data.get('serial', -1) msg_type = data.get('type', 'call') assert serial >= 0 log.debug("Acquiring lock for %s serial %s", self, serial) with (yield self.locks[serial].acquire()): try: if msg_type == 'call': args, kwargs = self._prepare_args(data.get('arguments', None)) callback = data.get('call', None) if callback is None: raise ValueError('Require argument "call" does\'t exist.') callee = self.resolver(callback) calee_is_route = hasattr(callee, '__self__') and isinstance(callee.__self__, WebSocketRoute) args = args if calee_is_route else [self, ].extend(args) result = yield self._executor(partial(callee, *args, **kwargs)) self._send(data=result, serial=serial, type='callback') elif msg_type == 'callback': cb = self.store.get(serial) cb.set_result(data.get('data', None)) elif msg_type == 'error': self._reject(data.get('serial', -1), data.get('data', None)) log.error('Client return error: \n\t{0}'.format(data.get('data', None))) except Exception as e: log.exception(e) self._send(data=self._format_error(e), serial=serial, type='error') finally: def clean_lock(): log.debug("Release and delete lock for %s serial %s", self, serial) if serial in self.locks: self.locks.pop(serial) self.ioloop.call_later(self._CLIENT_TIMEOUT, clean_lock)
def work(self, item): """ @param item: redis 消息对象 """ print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>" data = item['data'] if data == 1L: return app_log.info(data) try: data = json.loads(data) if data.get('to_email') and (data.get('to_email') != 'groups'): ClientManager.send_to(data.get('from_email'), data.get('to_email'), data) else: ClientManager.send_to_all(data) except Exception as ex: app_log.exception(ex)
def send_to(cls, from_email, to_email, data): """ 向特定用户发送消息 @param source_email: 发送者邮箱 @param to_email: 接受者邮箱地址 @param data: """ from_client = cls.get_client_by_email(from_email) to_client = cls.get_client_by_email(to_email) try: # 当自己给自己发送消息时 if from_email == to_email: to_client.handler.write_message(json.dumps(data)) else: to_client.handler.write_message(json.dumps(data)) from_client.handler.write_message(json.dumps(data)) except Exception as ex: app_log.exception()
def on_message(self, message): log.debug(Lazy(lambda: u'Client {0} send message: "{1}"'.format(self.id, message))) # deserialize message data = self._data_load(message) serial = data.get('serial', -1) type = data.get('type', 'call') assert serial >= 0 try: if type == 'call': with self.lock(serial): args, kwargs = self._prepare_args(data.get('arguments', None)) callback = data.get('call', None) if callback is None: raise ValueError('Require argument "call" does\'t exist.') callee = self.resolver(callback) calee_is_route = hasattr(callee, '__self__') and isinstance(callee.__self__, WebSocketRoute) args = args if calee_is_route else [self, ].extend(args) try: result = yield self._executor(partial(callee, *args, **kwargs)) self._send(data=result, serial=serial, type='callback') except Exception as e: log.exception(e) self._send(data=repr(e), serial=serial, type='error') elif type == 'callback': serial = data.get('serial', -1) assert serial >= 0 with self.lock(serial): cb = self.store.get(serial) cb.set_result(data.get('data', None)) elif type == 'error': self._reject(data.get('serial', -1), data.get('data', None)) log.error('Client return error: \n\t{0}'.format(data.get('data', None))) except Exception as e: self._send(data=repr(e), serial=serial, type='error')
def get_exporter(format, **kwargs): """get an exporter, raising appropriate errors""" # if this fails, will raise 500 try: from nbconvert.exporters.export import exporter_map except ImportError as e: raise web.HTTPError(500, "Could not import nbconvert: %s" % e) try: Exporter = exporter_map[format] except KeyError: # should this be 400? raise web.HTTPError(404, u"No exporter for format: %s" % format) try: return Exporter(**kwargs) except Exception as e: app_log.exception("Could not construct Exporter: %s", Exporter) raise web.HTTPError(500, "Could not construct Exporter: %s" % e)
def start(args, cfg): application = Application(cfg, args.debug) if args.debug: args.level = logging.DEBUG # setup logging level if specify if args.level is not None: logging.root.setLevel(args.level) # listen to port port = cfg['server']['port'] try: application.listen(port) app_log.info('listening port %s', port) except OSError: app_log.error('unable to listen port %s', port) return ioloop = tornado.ioloop.IOLoop.instance() # prevent block for IO allowed ctrl-c to pass # http://stackoverflow.com/a/9578595 def set_ping(timeout): ioloop.add_timeout(timeout, lambda: set_ping(timeout)) set_ping(timedelta(seconds=0.5)) # start main loop try: ioloop.start() except KeyboardInterrupt: app_log.info('Keyboard interrupt') except SystemExit: pass except Exception: app_log.exception('Error') raise ioloop.stop() app_log.info('Closed') return True
def flush(self): while True: try: body = [] for q in list(self.QUEUES): data = yield q.fetch() for line in data: opts, data = line body.extend([opts, '\n', data, '\n']) body = b(''.join(body)) if not body: continue url = "%s/_bulk" % Storage.ELASTICSEARCH req = HTTPRequest(method='POST', body=body, url=url) yield Storage.http.fetch(request=req) except Exception as e: log.exception(e) finally: yield sleep(1)
def post(self): email = self.get_argument('email').decode() password = self.get_argument('password').decode() try: user = User.objects(email=email, password=password).first() if not user: self.redirect('/sigin') except Exception as ex: app_log.error(ex) self.redirect('/sigin') else: self.set_secure_cookie('userid', str(user.id)) self.set_secure_cookie('admin', "True") try: next_url = self.get_argument('next') if next_url: self.redirect(next_url) return self.redirect('/') except Exception as ex: app_log.exception(ex) self.redirect('/')
def on_message(self, message): app_log.debug(message) self.timestamp = time.time() #any response will be regarded as a heartbeat try: content = json.loads(message) op = content['action'] if op == 'sub': self.messager.subscribe(content['data'], content['stamp']) elif op == 'subs': for topic in content['data']: self.messager.subscribe(topic, content['stamp']) elif op == 'unsub': self.messager.unsubscribe(content['data']) elif op == 'unsubs': for topic in content['data']: self.messager.unsubscribe(topic) elif op == 'clear': self.messager = None self.messager = Messager(self.send) elif op == 'pong': pass except Exception as e: app_log.exception(e)
def worker(): # setup logging, on start it have to do here since all fd will close by daemonocle setup_logging(cfg) application = Application(cfg, args.debug) if args.debug: args.level = logging.DEBUG # setup logging level if specify if args.level is not None: logging.root.setLevel(args.level) # listen to port port = cfg['server']['port'] try: application.listen(port) app_log.info('listening port %s', port) except OSError: app_log.error('unable to listen port %s', port) return # start main loop ioloop = tornado.ioloop.IOLoop.instance() try: ioloop.start() except KeyboardInterrupt: app_log.info('Keyboard interrupt') except SystemExit: pass except Exception: app_log.exception('Error') raise ioloop.stop() app_log.info('Closed')
def cull_idle(url, api_token, inactive_limit, cull_users=False, max_age=0, concurrency=10): """Shutdown idle single-user servers If cull_users, inactive *users* will be deleted as well. """ auth_header = { 'Authorization': 'token %s' % api_token, } req = HTTPRequest( url=url + '/users', headers=auth_header, ) now = datetime.now(timezone.utc) client = AsyncHTTPClient() if concurrency: semaphore = Semaphore(concurrency) @coroutine def fetch(req): """client.fetch wrapped in a semaphore to limit concurrency""" yield semaphore.acquire() try: return (yield client.fetch(req)) finally: yield semaphore.release() else: fetch = client.fetch resp = yield fetch(req) users = json.loads(resp.body.decode('utf8', 'replace')) futures = [] @coroutine def handle_server(user, server_name, server): """Handle (maybe) culling a single server Returns True if server is now stopped (user removable), False otherwise. """ log_name = user['name'] if server_name: log_name = '%s/%s' % (user['name'], server_name) if server.get('pending'): app_log.warning( "Not culling server %s with pending %s", log_name, server['pending']) return False # jupyterhub < 0.9 defined 'server.url' once the server was ready # as an *implicit* signal that the server was ready. # 0.9 adds a dedicated, explicit 'ready' field. # By current (0.9) definitions, servers that have no pending # events and are not ready shouldn't be in the model, # but let's check just to be safe. if not server.get('ready', bool(server['url'])): app_log.warning( "Not culling not-ready not-pending server %s: %s", log_name, server) return False if server.get('started'): age = now - parse_date(server['started']) else: # started may be undefined on jupyterhub < 0.9 age = None # check last activity # last_activity can be None in 0.9 if server['last_activity']: inactive = now - parse_date(server['last_activity']) else: # no activity yet, use start date # last_activity may be None with jupyterhub 0.9, # which introduces the 'started' field which is never None # for running servers inactive = age should_cull = (inactive is not None and inactive.total_seconds() >= inactive_limit) if should_cull: app_log.info( "Culling server %s (inactive for %s)", log_name, format_td(inactive)) if max_age and not should_cull: # only check started if max_age is specified # so that we can still be compatible with jupyterhub 0.8 # which doesn't define the 'started' field if age is not None and age.total_seconds() >= max_age: app_log.info( "Culling server %s (age: %s, inactive for %s)", log_name, format_td(age), format_td(inactive)) should_cull = True if not should_cull: app_log.debug( "Not culling server %s (age: %s, inactive for %s)", log_name, format_td(age), format_td(inactive)) return False if server_name: # culling a named server delete_url = url + "/users/%s/servers/%s" % ( quote(user['name']), quote(server['name']) ) else: delete_url = url + '/users/%s/server' % quote(user['name']) req = HTTPRequest( url=delete_url, method='DELETE', headers=auth_header, ) resp = yield fetch(req) if resp.code == 202: app_log.warning( "Server %s is slow to stop", log_name, ) # return False to prevent culling user with pending shutdowns return False return True @coroutine def handle_user(user): """Handle one user. Create a list of their servers, and async exec them. Wait for that to be done, and if all servers are stopped, possibly cull the user. """ # shutdown servers first. # Hub doesn't allow deleting users with running servers. # jupyterhub 0.9 always provides a 'servers' model. # 0.8 only does this when named servers are enabled. if 'servers' in user: servers = user['servers'] else: # jupyterhub < 0.9 without named servers enabled. # create servers dict with one entry for the default server # from the user model. # only if the server is running. servers = {} if user['server']: servers[''] = { 'last_activity': user['last_activity'], 'pending': user['pending'], 'url': user['server'], } server_futures = [ handle_server(user, server_name, server) for server_name, server in servers.items() ] results = yield multi(server_futures) if not cull_users: return # some servers are still running, cannot cull users still_alive = len(results) - sum(results) if still_alive: app_log.debug( "Not culling user %s with %i servers still alive", user['name'], still_alive) return False should_cull = False if user.get('created'): age = now - parse_date(user['created']) else: # created may be undefined on jupyterhub < 0.9 age = None # check last activity # last_activity can be None in 0.9 if user['last_activity']: inactive = now - parse_date(user['last_activity']) else: # no activity yet, use start date # last_activity may be None with jupyterhub 0.9, # which introduces the 'created' field which is never None inactive = age should_cull = (inactive is not None and inactive.total_seconds() >= inactive_limit) if should_cull: app_log.info( "Culling user %s (inactive for %s)", user['name'], inactive) if max_age and not should_cull: # only check created if max_age is specified # so that we can still be compatible with jupyterhub 0.8 # which doesn't define the 'started' field if age is not None and age.total_seconds() >= max_age: app_log.info( "Culling user %s (age: %s, inactive for %s)", user['name'], format_td(age), format_td(inactive)) should_cull = True if not should_cull: app_log.debug( "Not culling user %s (created: %s, last active: %s)", user['name'], format_td(age), format_td(inactive)) return False req = HTTPRequest( url=url + '/users/%s' % user['name'], method='DELETE', headers=auth_header, ) yield fetch(req) return True for user in users: futures.append((user['name'], handle_user(user))) for (name, f) in futures: try: result = yield f except Exception: app_log.exception("Error processing %s", name) else: if result: app_log.debug("Finished culling %s", name)
def _doMethod(self): try: # print('request.uri', self.request.uri) # print('request.path', self.request.path) # print('request.query', self.request.query) # print('request.remote_ip', self.request.remote_ip) # print('request.protocol', self.request.protocol) # print('request.host', self.request.host) # print('request.files', self.request.files) # print('xcookies', self.cookies) # print('iterate cookies') # for k in self.cookies: # # print(type(self.request.cookies[k])) # print('\trequest.cookie[{0}]= {1}'.format(k, self.get_cookie(k))) # print('request.arguments', self.request.arguments) # for k in self.request.arguments: # print('\trequest.arguments[{0}] = {1}'.format(k, self.get_argument(k))) # print('request.headers', self.request.headers) # for k in self.request.headers: # print('\trequest.headers[{0}]= {1}'.format(k, self.request.headers[k])) # deal request argument # do the filter handler.user_filter.before(self) self.__cookieArgs = None self.__headerArgs = None self.__args = None self.__requestArgs = None # deal request arguemnt def getRequestArg(param): if not self.__requestArgs: self.__requestArgs = { 'requestUri': self.request.uri, 'requestPath': self.request.path, 'requestRemoteIp': self.request.remote_ip, 'reqeustProtocol': self.request.protocol, 'requestHost': self.request.host, 'requestFiles': self.request.files, 'requestMethod': self.request.method.lower() } app_log.debug('deal request args: %s', self.__requestArgs) return None if param not in self.__requestArgs else self.__requestArgs[param] # deal cookie arguemnt def getCookieArg(param): if not self.__cookieArgs: self.__cookieArgs = {} for k in self.cookies: key = 'cookie' + k.lower().title().replace('-', '').replace('_', '') self.__cookieArgs[key] = self.get_cookie(k) app_log.debug('deal cookie args: %s', self.__cookieArgs) return None if param not in self.__cookieArgs else self.__cookieArgs[param] # deal header argument def getHeaderArg(param): if not self.__headerArgs: self.__headerArgs = {} for k in self.request.headers: key = 'header' + k.lower().title().replace('-', '').replace('_', '') self.__headerArgs[key] = self.request.headers[k] app_log.debug('deal header args: %s', self.__headerArgs) return None if param not in self.__headerArgs else self.__headerArgs[param] # deal args def getArgs(): if not self.__args: self.__args = {} for k in self.request.arguments: self.__args[k] = self.get_argument(k) if 'Content-Type' in self.request.headers: contentType = self.request.headers['Content-Type'] if (contentType.find('application/json') != -1 and self.request.method.lower() == 'post'): bodyData = json.loads(self.request.body.decode('utf-8')) for k, v in bodyData.items(): self.__args[k] = v elif (contentType.find('application/x-www-form-urlencoded') != -1 and self.request.method.lower() == 'post'): for k in self.request.body_arguments: self.__args[k] = self.get_body_argument(k) app_log.debug('deal __args: %s', self.__args) return self.__args def getArg(param): args = getArgs() return None if param not in args else args[param] def getSettingArg(param): param = param.replace('__', '') return None if param not in self.settings else self.settings[param] # deal path to service mapping path = self.request.path # /[email protected] or /user/[email protected] paths = path.split('/') packages = paths[:-1] moduleAndMethod = paths[-1].split('@') module = moduleAndMethod[0] method = moduleAndMethod[1] fullModule = [p for p in packages if p] fullModule.append(module) fullModule = 'service.' + '.'.join(fullModule) + '_service' module = importlib.import_module(fullModule) methodName = method.replace('.do', '') method = getattr(module, methodName) methodParams = inspect.getargspec(method)[0] # define method args methodArgs = {} if methodParams: for param in methodParams: if param.startswith('header'): methodArgs[param] = getHeaderArg(param) elif param.startswith('request'): methodArgs[param] = getRequestArg(param) elif param.startswith('cookie'): methodArgs[param] = getCookieArg(param) elif param.startswith('__'): methodArgs[param] = getSettingArg(param) elif param == '_session': methodArgs['_session'] = self.getSession() elif param == '_handler': methodArgs['_handler'] = self elif param == '_args': methodArgs['_args'] = getArgs() elif param == '_current_user': methodArgs[param] = self.current_user else: methodArgs[param] = getArg(param) # execute method if (inspect.isgeneratorfunction(method)): method = gen.coroutine(method) data = yield method(**methodArgs) else: data = method(**methodArgs) self.writeData(**data) # do the after filter handler.user_filter.after(self) except Exception as e: app_log.exception(e) self.writeData({'status': -100, 'errorMsg': str(e)})
async def get(self, provider_prefix, spec): """Get a built image for a given GitHub user, repo, and ref.""" # We gonna send out event streams! self.set_header('content-type', 'text/event-stream') self.set_header('cache-control', 'no-cache') # EventSource cannot handle HTTP errors, # so we have to send error messages on the eventsource if provider_prefix not in self.settings['repo_providers']: await self.fail("No provider found for prefix %s" % provider_prefix) return key = '%s:%s' % (provider_prefix, spec) try: provider = self.get_provider(provider_prefix, spec=spec) except Exception as e: app_log.exception("Failed to get provider for %s", key) await self.fail(str(e)) return repo = self.repo = provider.get_repo_url() try: ref = await provider.get_resolved_ref() except Exception as e: await self.fail("Error resolving ref for %s: %s" % (key, e)) return if ref is None: await self.fail("Could not resolve ref for %s. Double check your URL." % key) return build_name = self._generate_build_name(provider.get_build_slug(), ref).replace('_', '-') # FIXME: EnforceMax of 255 before image and 128 for tag image_name = self.image_name = '{prefix}{build_slug}:{ref}'.format( prefix=self.settings['docker_image_prefix'], build_slug=provider.get_build_slug(), ref=ref ).replace('_', '-').lower() if self.settings['use_registry']: image_manifest = await self.registry.get_image_manifest(*image_name.split('/', 1)[1].split(':', 1)) image_found = bool(image_manifest) else: # Check if the image exists locally! # Assume we're running in single-node mode! docker_client = docker.from_env(version='auto') try: docker_client.images.get(image_name) except docker.errors.ImageNotFound: # image doesn't exist, so do a build! image_found = False else: image_found = True if image_found: await self.emit({ 'phase': 'built', 'imageName': image_name, 'message': 'Found built image, launching...\n' }) await self.launch() return api = client.CoreV1Api() q = Queue() if self.settings['use_registry']: push_secret = self.settings['docker_push_secret'] else: push_secret = None build = Build( q=q, api=api, name=build_name, namespace=self.settings["build_namespace"], git_url=repo, ref=ref, image_name=image_name, push_secret=push_secret, builder_image=self.settings['builder_image_spec'], ) with BUILDS_INPROGRESS.track_inprogress(): build_starttime = time.perf_counter() pool = self.settings['build_pool'] pool.submit(build.submit) log_future = None # initial waiting event await self.emit({ 'phase': 'waiting', 'message': 'Waiting for build to start...\n', }) done = False failed = False while not done: progress = await q.get() # FIXME: If pod goes into an unrecoverable stage, such as ImagePullBackoff or # whatever, we should fail properly. if progress['kind'] == 'pod.phasechange': if progress['payload'] == 'Pending': # nothing to do, just waiting continue elif progress['payload'] == 'Deleted': event = { 'phase': 'built', 'message': 'Built image, launching...\n', 'imageName': image_name, } done = True elif progress['payload'] == 'Running': # start capturing build logs once the pod is running if log_future is None: log_future = pool.submit(build.stream_logs) continue elif progress['payload'] == 'Succeeded': # Do nothing, is ok! continue else: # FIXME: message? debug? event = {'phase': progress['payload']} elif progress['kind'] == 'log': # We expect logs to be already JSON structured anyway event = progress['payload'] payload = json.loads(event) if payload.get('phase', None) == 'failure': failed = True BUILD_TIME.labels(status='failure').observe(time.perf_counter() - build_starttime) await self.emit(event) if not failed: BUILD_TIME.labels(status='success').observe(time.perf_counter() - build_starttime) with LAUNCHES_INPROGRESS.track_inprogress(): await self.launch()