def docmd(self, cmd, args=""): """Send a command, and return its response code.""" yield self.putcmd(cmd, args) reply = yield self.getreply() raise Return(reply)
def terminate(self, stream, report=True): yield self._close(report=report) raise Return('OK')
def compute(self, stream=None, function=None, key=None, args=(), kwargs={}, task=None, who_has=None, report=True): """ Execute function """ self.active.add(key) # Ready function for computation msg = yield self._ready_task(function=function, key=key, args=args, kwargs=kwargs, task=task, who_has=who_has) if msg['status'] != 'OK': try: self.active.remove(key) except KeyError: pass raise Return(msg) else: function = msg['function'] args = msg['args'] kwargs = msg['kwargs'] # Log and compute in separate thread result = yield self.executor_submit(key, apply_function, function, args, kwargs, self.execution_state, key) result['key'] = key result.update(msg['diagnostics']) if result['status'] == 'OK': self.data[key] = result.pop('result') if report: response = yield self.scheduler.add_keys(address=(self.ip, self.port), keys=[key]) if not response == 'OK': logger.warn('Could not report results to scheduler: %s', str(response)) else: logger.warn( " Compute Failed\n" "Function: %s\n" "args: %s\n" "kwargs: %s\n", str(funcname(function))[:1000], convert_args_to_str(args, max_len=1000), convert_kwargs_to_str(kwargs, max_len=1000), exc_info=True) logger.debug("Send compute response to scheduler: %s, %s", key, get_msg_safe_str(msg)) try: self.active.remove(key) except KeyError: pass raise Return(result)
def check_channel_permission(self, namespace, channel): if namespace in self.channels and channel in self.channels[namespace]: return raise Return((None, 'channel permission denied'))
def on_message(self, message): yield self.client.message_received(message) raise Return((True, None))
def do_upload(): with transport_queue.request_transport(authinfo) as request: transport = yield cancellable.with_interrupt(request) raise Return( execmanager.upload_calculation(node, transport, calc_info, script_filename))
def get_one_sms(self): res = yield self.get( "SELECT account, password, url, content FROM sys_sms_config WHERE flag='1' LIMIT 1" ) raise Return(res)
def sendmail(self, from_addr, to_addrs, msg, mail_options=[], rcpt_options=[]): """This command performs an entire mail transaction. The arguments are: - from_addr : The address sending this mail. - to_addrs : A list of addresses to send this mail to. A bare string will be treated as a list with 1 address. - msg : The message to send. - mail_options : List of ESMTP options (such as 8bitmime) for the mail command. - rcpt_options : List of ESMTP options (such as DSN commands) for all the rcpt commands. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. If the server does ESMTP, message size and each of the specified options will be passed to it. If EHLO fails, HELO will be tried and ESMTP options suppressed. This method will return normally if the mail is accepted for at least one recipient. It returns a dictionary, with one entry for each recipient that was refused. Each entry contains a tuple of the SMTP error code and the accompanying error message sent by the server. This method may raise the following exceptions: SMTPHeloError The server didn't reply properly to the helo greeting. SMTPRecipientsRefused The server rejected ALL recipients (no mail was sent). SMTPSenderRefused The server didn't accept the from_addr. SMTPDataError The server replied with an unexpected error code (other than a refusal of a recipient). Note: the connection will be open even after an exception is raised. Example: >>> import smtplib >>> s=smtplib.SMTP("localhost") >>> tolist=["*****@*****.**","*****@*****.**","*****@*****.**","*****@*****.**"] >>> msg = '''\\ ... From: [email protected] ... Subject: testin'... ... ... This is a test ''' >>> s.sendmail("*****@*****.**",tolist,msg) { "*****@*****.**" : ( 550 ,"User unknown" ) } >>> s.quit() In the above example, the message was accepted for delivery to three of the four addresses, and one was rejected, with the error code 550. If all addresses are accepted, then the method will return an empty dictionary. """ yield self.ehlo_or_helo_if_needed() esmtp_opts = [] if self.does_esmtp: # Hmmm? what's this? -ddm # self.esmtp_features['7bit']="" if self.has_extn('size'): esmtp_opts.append("size=%d" % len(msg)) for option in mail_options: esmtp_opts.append(option) (code, resp) = yield self.mail(from_addr, esmtp_opts) if code != 250: yield self.rset() raise SMTPSenderRefused(code, resp, from_addr) senderrs = {} if isinstance(to_addrs, basestring): to_addrs = [to_addrs] for each in to_addrs: (code, resp) = yield self.rcpt(each, rcpt_options) if (code != 250) and (code != 251): senderrs[each] = (code, resp) if len(senderrs) == len(to_addrs): # the server refused all our recipients yield self.rset() raise SMTPRecipientsRefused(senderrs) (code, resp) = yield self.data(msg) if code != 250: yield self.rset() raise SMTPDataError(code, resp) # if we got here then somebody got our mail raise Return(senderrs)
def get_all(self): result = yield self.query( 'SELECT _id, name FROM sys_user_rank_type_config') raise Return(result)
def expn(self, address): """SMTP 'expn' command -- expands a mailing list.""" yield self.putcmd("expn", _addr_only(address)) reply = self.getreply() raise Return(reply)
def login(self, user, password): """Log in on an SMTP server that requires authentication. The arguments are: - user: The user name to authenticate with. - password: The password for the authentication. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. This method will return normally if the authentication was successful. This method may raise the following exceptions: SMTPHeloError The server didn't reply properly to the helo greeting. SMTPAuthenticationError The server didn't accept the username/ password combination. SMTPException No suitable authentication method was found. """ def encode_cram_md5(challenge, user, password): challenge = base64.decodestring(challenge) response = user + " " + hmac.HMAC(password, challenge).hexdigest() return encode_base64(response, eol="") def encode_plain(user, password): return encode_base64("\0%s\0%s" % (user, password), eol="") AUTH_PLAIN = "PLAIN" AUTH_CRAM_MD5 = "CRAM-MD5" AUTH_LOGIN = "******" yield self.ehlo_or_helo_if_needed() if not self.has_extn("auth"): raise SMTPException("SMTP AUTH extension not supported by server.") # Authentication methods the server supports: authlist = self.esmtp_features["auth"].split() # List of authentication methods we support: from preferred to # less preferred methods. Except for the purpose of testing the weaker # ones, we prefer stronger methods like CRAM-MD5: preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN] # Determine the authentication method we'll use authmethod = None for method in preferred_auths: if method in authlist: authmethod = method break if authmethod == AUTH_CRAM_MD5: (code, resp) = yield self.docmd("AUTH", AUTH_CRAM_MD5) if code == 503: # 503 == 'Error: already authenticated' raise Return((code, resp)) (code, resp) = yield self.docmd(encode_cram_md5(resp, user, password)) elif authmethod == AUTH_PLAIN: (code, resp) = yield self.docmd( "AUTH", AUTH_PLAIN + " " + encode_plain(user, password)) elif authmethod == AUTH_LOGIN: (code, resp) = yield self.docmd( "AUTH", "%s %s" % (AUTH_LOGIN, encode_base64(user, eol=""))) if code != 334: raise SMTPAuthenticationError(code, resp) (code, resp) = yield self.docmd(encode_base64(password, eol="")) elif authmethod is None: raise SMTPException("No suitable authentication method found.") if code not in (235, 503): # 235 == 'Authentication successful' # 503 == 'Error: already authenticated' raise SMTPAuthenticationError(code, resp) raise Return((code, resp))
def verify(self, address): """SMTP 'verify' command -- checks for address validity.""" yield self.putcmd("vrfy", _addr_only(address)) raise Return(self.getreply())
def noop(self): """SMTP 'noop' command -- doesn't do anything :>""" raise Return(self.docmd("noop"))
def rset(self): """SMTP 'rset' command -- resets session.""" (code, msg) = yield self.docmd(b"rset") raise Return((code, msg))
def do_kill(): with transport_queue.request_transport(authinfo) as request: transport = yield cancellable.with_interrupt(request) raise Return(execmanager.kill_calculation(node, transport))
def _fetch(self, path, method, body=None, args=None, schema=None): ''' Helper for HTTP requests. If `body` is a string, it is sent as is. If `body is not None`, it is JSON-encoded and sent. If `schema is not None`, it is used to validate any response body for JSON decoding. If `schema` is not provided, the response body is ignored. ''' # build the complete URL path = self._base_url + path # encode object body using JSON if body and not isinstance(body, basestring): # see tornado.escape.json_encode() body = json_encode(body) # encode the query parameters if args: if not isinstance(args, basestring): args = dict([(k, json_encode(v)) for (k, v) in args.iteritems()]) path = url_concat(path, args) # perform the request response = yield self._client.fetch( path, method=method, body=body, headers={'Accept': 'application/json'}) logger.debug('{} {} -> {}'.format(method, path, response.code)) # map common HTTP errors to exceptions if response.code == 404: raise KeyError(path) elif response.code not in [ httplib.OK, httplib.CREATED, httplib.NO_CONTENT ]: logger.error('unexpected HTTP response: {} {}\ \n\nResponse:\n{}'.format(response.code, response.reason, response.body)) raise RuntimeError('{} {}'.format(response.code, response.reason)) # decode the response using JSON if a schema is provided if schema: if response.code == httplib.NO_CONTENT: raise RuntimeError( 'server indicated no content when expecting response body') try: # see tornado.escape.json_decode() obj = json_decode(response.body) jsonschema.validate(obj, schema) except (ValueError, jsonschema.ValidationError) as exc: logger.error('malformed response: {}\ \n\nResponse:\n{}'.format(exc, response.body)) raise RuntimeError('malformed response') else: raise Return(obj)
def execute(self): node = self.process.node transport_queue = self.process.runner.transport if isinstance(self.data, tuple): command = self.data[0] args = self.data[1:] else: command = self.data process_status = 'Waiting for transport task: {}'.format(command) try: if command == UPLOAD_COMMAND: node.set_process_status(process_status) calc_info, script_filename = yield self._launch_task( task_upload_job, node, transport_queue, *args) raise Return(self.submit(calc_info, script_filename)) elif command == SUBMIT_COMMAND: node.set_process_status(process_status) yield self._launch_task(task_submit_job, node, transport_queue, *args) raise Return(self.update()) elif self.data == UPDATE_COMMAND: job_done = False while not job_done: scheduler_state = node.get_scheduler_state() scheduler_state_string = scheduler_state.name if scheduler_state else 'UNKNOWN' process_status = 'Monitoring scheduler: job state {}'.format( scheduler_state_string) node.set_process_status(process_status) job_done = yield self._launch_task( task_update_job, node, self.process.runner.job_manager) raise Return(self.retrieve()) elif self.data == RETRIEVE_COMMAND: node.set_process_status(process_status) # Create a temporary folder that has to be deleted by JobProcess.retrieved after successful parsing temp_folder = tempfile.mkdtemp() yield self._launch_task(task_retrieve_job, node, transport_queue, temp_folder) raise Return(self.parse(temp_folder)) else: raise RuntimeError('Unknown waiting command') except TransportTaskException as exception: raise plumpy.PauseInterruption( 'Pausing after failed transport task: {}'.format(exception)) except plumpy.KillInterruption: exc_info = sys.exc_info() yield self._launch_task(task_kill_job, node, transport_queue) self._killing.set_result(True) six.reraise(*exc_info) except Return: node.set_process_status(None) raise except (plumpy.Interruption, plumpy.CancelledError): node.set_process_status( 'Transport task {} was interrupted'.format(command)) raise finally: # If we were trying to kill but we didn't deal with it, make sure it's set here if self._killing and not self._killing.done(): self._killing.set_result(False)
def logical_operator(self, last_res, callback, node): raise Return(last_res or (yield callback(node)))
def __(self, sql, *args, **kwargs): res = yield self.__do_sql(method, sql, *args, **kwargs) raise Return(res)
def do_list_instance(): sql = "SELECT * FROM manor.manor_app_instance" rs = yield DBUtil().query(sql) raise Return(rs)
def sleep(seconds): """ Non-blocking sleep. """ yield Task(IOLoop.instance().add_timeout, time.time() + seconds) raise Return((True, None))
def gather_from_workers(who_has, rpc, close=True, serializers=None, who=None): """ Gather data directly from peers Parameters ---------- who_has: dict Dict mapping keys to sets of workers that may have that key rpc: callable Returns dict mapping key to value See Also -------- gather _gather """ from .worker import get_data_from_worker bad_addresses = set() missing_workers = set() original_who_has = who_has who_has = {k: set(v) for k, v in who_has.items()} results = dict() all_bad_keys = set() while len(results) + len(all_bad_keys) < len(who_has): d = defaultdict(list) rev = dict() bad_keys = set() for key, addresses in who_has.items(): if key in results: continue try: addr = random.choice(list(addresses - bad_addresses)) d[addr].append(key) rev[key] = addr except IndexError: bad_keys.add(key) if bad_keys: all_bad_keys |= bad_keys rpcs = {addr: rpc(addr) for addr in d} try: coroutines = { address: get_data_from_worker(rpc, keys, address, who=who, serializers=serializers, max_connections=False) for address, keys in d.items() } response = {} for worker, c in coroutines.items(): try: r = yield c except EnvironmentError: missing_workers.add(worker) else: response.update(r['data']) finally: for r in rpcs.values(): r.close_rpc() bad_addresses |= {v for k, v in rev.items() if k not in response} results.update(response) bad_keys = {k: list(original_who_has[k]) for k in all_bad_keys} raise Return((results, bad_keys, list(missing_workers)))
def close(self): yield self.clean() logger.debug('client destroyed (uid: %s)' % self.uid) raise Return((True, None))
def execute(self, *args, **kwargs): raise Return(execute(self.schema, *args, **kwargs))
def on_close(self): if hasattr(self, 'client'): yield self.client.close() del self.client raise Return((True, None))
def task_update_job(node, job_manager, cancellable): """ Transport task that will attempt to update the scheduler status of the job calculation The task will first request a transport from the queue. Once the transport is yielded, the relevant execmanager function is called, wrapped in the exponential_backoff_retry coroutine, which, in case of a caught exception, will retry after an interval that increases exponentially with the number of retries, for a maximum number of retries. If all retries fail, the task will raise a TransportTaskException :param node: the node that represents the job calculation :type node: :class:`aiida.orm.nodes.process.calculation.calcjob.CalcJobNode` :param job_manager: The job manager :type job_manager: :class:`aiida.engine.processes.calcjobs.manager.JobManager` :param cancellable: A cancel flag :type cancellable: :class:`aiida.engine.utils.InterruptableFuture` :raises: Return containing True if the tasks was successfully completed, False otherwise """ if node.get_state() == CalcJobState.RETRIEVING: logger.warning( 'CalcJob<{}> already marked as RETRIEVING, skipping task_update_job' .format(node.pk)) raise Return(True) initial_interval = TRANSPORT_TASK_RETRY_INITIAL_INTERVAL max_attempts = TRANSPORT_TASK_MAXIMUM_ATTEMTPS authinfo = node.computer.get_authinfo(node.user) job_id = node.get_job_id() @coroutine def do_update(): # Get the update request with job_manager.request_job_info_update(authinfo, job_id) as update_request: job_info = yield cancellable.with_interrupt(update_request) if job_info is None: # If the job is computed or not found assume it's done node.set_scheduler_state(JobState.DONE) job_done = True else: node.set_last_job_info(job_info) node.set_scheduler_state(job_info.job_state) job_done = job_info.job_state == JobState.DONE raise Return(job_done) try: logger.info('scheduled request to update CalcJob<{}>'.format(node.pk)) job_done = yield exponential_backoff_retry( do_update, initial_interval, max_attempts, logger=node.logger, ignore_exceptions=plumpy.Interruption) except plumpy.Interruption: raise except Exception: logger.warning('updating CalcJob<{}> failed'.format(node.pk)) raise TransportTaskException( 'update_calculation failed {} times consecutively'.format( max_attempts)) else: logger.info('updating CalcJob<{}> successful'.format(node.pk)) if job_done: node.set_state(CalcJobState.RETRIEVING) raise Return(job_done)
def _ready_task(self, function=None, key=None, args=(), kwargs={}, task=None, who_has=None): who_has = who_has or {} diagnostics = {} start = time() data = {k: self.data[k] for k in who_has if k in self.data} stop = time() if stop - start > 0.005: diagnostics['disk_load_start'] = start diagnostics['disk_load_stop'] = stop who_has = { k: set(map(coerce_to_address, v)) for k, v in who_has.items() if k not in self.data } if who_has: try: logger.info("gather %d keys from peers", len(who_has)) diagnostics['transfer_start'] = time() other = yield gather_from_workers(who_has) diagnostics['transfer_stop'] = time() self.data.update(other) yield self.scheduler.add_keys(address=self.address, keys=list(other)) data.update(other) except KeyError as e: logger.warn("Could not find data for %s", key) raise Return({ 'status': 'missing-data', 'keys': e.args, 'key': key }) try: start = default_timer() function, args, kwargs = self.deserialize(function, args, kwargs, task) diagnostics['deserialization'] = default_timer() - start except Exception as e: logger.warn("Could not deserialize task", exc_info=True) emsg = error_message(e) emsg['key'] = key raise Return(emsg) # Fill args with data args2 = pack_data(args, data) kwargs2 = pack_data(kwargs, data) raise Return({ 'status': 'OK', 'function': function, 'args': args2, 'kwargs': kwargs2, 'diagnostics': diagnostics, 'key': key })
def do_retrieve(): with transport_queue.request_transport(authinfo) as request: transport = yield cancellable.with_interrupt(request) raise Return( execmanager.retrieve_calculation(node, transport, retrieved_temporary_folder))
def snmp_count( address, oid, port=161, community="public", version=SNMP_v2c, timeout=10, bulk=False, filter=None, max_repetitions=BULK_MAX_REPETITIONS, tos=None, ioloop=None, udp_socket=None, ): """ Perform SNMP get request and returns Future to be used inside @tornado.gen.coroutine """ def true(x, y): return true logger.debug("[%s] SNMP COUNT %s", address, oid) if not filter: filter = true poid = oid + "." result = 0 if udp_socket: sock = udp_socket prev_timeout = sock.get_timeout() else: sock = UDPSocket(ioloop=ioloop, tos=tos) sock.settimeout(timeout) while True: # Get PDU if bulk: pdu = getbulk_pdu(community, oid, max_repetitions=max_repetitions, version=version) else: pdu = getnext_pdu(community, oid, version=version) # Send request and wait for response try: yield sock.sendto(pdu, (address, port)) data, addr = yield sock.recvfrom(4096) except socket.timeout: raise SNMPError(code=TIMED_OUT, oid=oid) except socket.gaierror as e: logger.debug("[%s] Cannot resolve address: %s", address, e) raise SNMPError(code=UNREACHABLE, oid=oid) except socket.error as e: logger.debug("[%s] Socket error: %s", address, e) raise SNMPError(code=UNREACHABLE, oid=oid) finally: if udp_socket: sock.settimeout(prev_timeout) else: sock.close() # Parse response try: resp = parse_get_response(data) except ValueError: raise SNMPError(code=BER_ERROR, oid=oid) if resp.error_status == NO_SUCH_NAME: # NULL result break elif resp.error_status != NO_ERROR: # Error raise SNMPError(code=resp.error_status, oid=oid) else: # Success value for oid, v in resp.varbinds: if oid.startswith(poid): # Next value if filter(oid, v): result += 1 else: logger.debug("[%s] COUNT result: %s", address, result) sock.close() raise Return(result)
def _speaker_list(self): speakers = yield self._handle_request('sonos.speakers', {}, lambda r: r['speakers'], lambda r: []) raise Return(speakers)