Beispiel #1
0
 async def async_request(self, command, args=None, timeout=None):
     """Send asynchronous request via SSH.
     """
     timeout = timeout if timeout is not None else self.timeout
     try:
         async with ascyncto(timeout):
             cmd, ssh_cmd, login_sh, cylc_path, msg = self.prepare_command(
                 command, args, timeout)
             proc = _remote_cylc_cmd(cmd,
                                     host=self.host,
                                     stdin_str=msg,
                                     ssh_cmd=ssh_cmd,
                                     remote_cylc_path=cylc_path,
                                     ssh_login_shell=login_sh,
                                     capture_process=True)
             while True:
                 if proc.poll() is not None:
                     break
                 await asyncio.sleep(self.SLEEP_INTERVAL)
             out, err = (f.decode() for f in proc.communicate())
             return_code = proc.wait()
             if return_code:
                 raise ClientError(err, f"return-code={return_code}")
             return json.loads(out)
     except asyncio.TimeoutError:
         raise ClientTimeout(f"Command exceeded the timeout {timeout}. "
                             f"This could be due to network problems. "
                             "Check the workflow log.")
Beispiel #2
0
    async def async_request(self,
                            command,
                            args=None,
                            timeout=None,
                            req_meta=None):
        """Send an asynchronous request using asyncio.

        Has the same arguments and return values as ``serial_request``.

        """
        timeout = (float(timeout) * 1000 if timeout else None) or self.timeout
        if not args:
            args = {}

        # Note: we are using CurveZMQ to secure the messages (see
        # self.curve_auth, self.socket.curve_...key etc.). We have set up
        # public-key cryptography on the ZMQ messaging and sockets, so
        # there is no need to encrypt messages ourselves before sending.

        # send message
        msg = {'command': command, 'args': args}
        msg.update(self.header)
        # add the request metadata
        if req_meta:
            msg['meta'].update(req_meta)
        LOG.debug('zmq:send %s', msg)
        message = encode_(msg)
        self.socket.send_string(message)

        # receive response
        if self.poller.poll(timeout):
            res = await self.socket.recv()
        else:
            if callable(self.timeout_handler):
                self.timeout_handler()
            raise ClientTimeout(
                'Timeout waiting for server response.'
                ' This could be due to network or server issues.'
                ' Check the workflow log.')

        if msg['command'] in PB_METHOD_MAP:
            response = {'data': res}
        else:
            response = decode_(res.decode())
        LOG.debug('zmq:recv %s', response)

        try:
            return response['data']
        except KeyError:
            error = response['error']
            raise ClientError(error['message'], error.get('traceback'))
Beispiel #3
0
    async def async_request(self, command, args=None, timeout=None):
        """Send an asynchronous request using asyncio.

        Has the same arguments and return values as ``serial_request``.

        """
        if timeout:
            timeout = float(timeout)
        timeout = (timeout * 1000 if timeout else None) or self.timeout
        if not args:
            args = {}

        # get secret for this request
        # assumes secret won't change during the request
        try:
            secret = self.secret()
        except cylc.flow.suite_srv_files_mgr.SuiteServiceFileError:
            raise ClientError('could not read suite passphrase')

        # send message
        msg = {'command': command, 'args': args}
        msg.update(self.header)
        LOG.debug('zmq:send %s' % msg)
        message = encrypt(msg, secret)
        self.socket.send_string(message)

        # receive response
        if self.poller.poll(timeout):
            res = await self.socket.recv()
        else:
            if self.timeout_handler:
                self.timeout_handler()
            raise ClientTimeout('Timeout waiting for server response.')

        if msg['command'] in PB_METHOD_MAP:
            response = {'data': res}
        else:
            try:
                response = decrypt(res.decode(), secret)
            except jose.exceptions.JWTError:
                raise ClientError(
                    'Could not decrypt response. Has the passphrase changed?')
        LOG.debug('zmq:recv %s' % response)

        try:
            return response['data']
        except KeyError:
            error = response['error']
            raise ClientError(error['message'], error.get('traceback'))