예제 #1
0
 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)
예제 #2
0
 def terminate(self, stream, report=True):
     yield self._close(report=report)
     raise Return('OK')
예제 #3
0
    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)
예제 #4
0
 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'))
예제 #5
0
 def on_message(self, message):
     yield self.client.message_received(message)
     raise Return((True, None))
예제 #6
0
 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))
예제 #7
0
 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)
예제 #8
0
    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)
예제 #9
0
 def get_all(self):
     result = yield self.query(
         'SELECT _id, name FROM sys_user_rank_type_config')
     raise Return(result)
예제 #10
0
 def expn(self, address):
     """SMTP 'expn' command -- expands a mailing list."""
     yield self.putcmd("expn", _addr_only(address))
     reply = self.getreply()
     raise Return(reply)
예제 #11
0
    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))
예제 #12
0
 def verify(self, address):
     """SMTP 'verify' command -- checks for address validity."""
     yield self.putcmd("vrfy", _addr_only(address))
     raise Return(self.getreply())
예제 #13
0
 def noop(self):
     """SMTP 'noop' command -- doesn't do anything :>"""
     raise Return(self.docmd("noop"))
예제 #14
0
 def rset(self):
     """SMTP 'rset' command -- resets session."""
     (code, msg) = yield self.docmd(b"rset")
     raise Return((code, msg))
예제 #15
0
 def do_kill():
     with transport_queue.request_transport(authinfo) as request:
         transport = yield cancellable.with_interrupt(request)
         raise Return(execmanager.kill_calculation(node, transport))
예제 #16
0
    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)
예제 #17
0
    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)
예제 #18
0
 def logical_operator(self, last_res, callback, node):
     raise Return(last_res or (yield callback(node)))
예제 #19
0
 def __(self, sql, *args, **kwargs):
     res = yield self.__do_sql(method, sql, *args, **kwargs)
     raise Return(res)
예제 #20
0
def do_list_instance():
    sql = "SELECT * FROM manor.manor_app_instance"
    rs = yield DBUtil().query(sql)
    raise Return(rs)
예제 #21
0
def sleep(seconds):
    """
    Non-blocking sleep.
    """
    yield Task(IOLoop.instance().add_timeout, time.time() + seconds)
    raise Return((True, None))
예제 #22
0
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)))
예제 #23
0
 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))
예제 #25
0
 def on_close(self):
     if hasattr(self, 'client'):
         yield self.client.close()
         del self.client
     raise Return((True, None))
예제 #26
0
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)
예제 #27
0
    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
        })
예제 #28
0
 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))
예제 #29
0
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)
예제 #30
0
 def _speaker_list(self):
     speakers = yield self._handle_request('sonos.speakers', {},
                                           lambda r: r['speakers'],
                                           lambda r: [])
     raise Return(speakers)