async def test_gateway_env_options(init_gateway, jp_serverapp):
    assert jp_serverapp.gateway_config.gateway_enabled is True
    assert jp_serverapp.gateway_config.url == mock_gateway_url
    assert jp_serverapp.gateway_config.http_user == mock_http_user
    assert jp_serverapp.gateway_config.connect_timeout == jp_serverapp.gateway_config.request_timeout
    assert jp_serverapp.gateway_config.connect_timeout == 44.4

    GatewayClient.instance().init_static_args()
    assert GatewayClient.instance().KERNEL_LAUNCH_TIMEOUT == int(jp_serverapp.gateway_config.request_timeout)
Exemple #2
0
def init_gateway(monkeypatch):
    """Initializes the server for use as a gateway client."""
    # Clear the singleton first since previous tests may not have used a gateway.
    GatewayClient.clear_instance()
    monkeypatch.setenv("JUPYTER_GATEWAY_URL", mock_gateway_url)
    monkeypatch.setenv("JUPYTER_GATEWAY_HTTP_USER", mock_http_user)
    monkeypatch.setenv("JUPYTER_GATEWAY_REQUEST_TIMEOUT", "44.4")
    monkeypatch.setenv("JUPYTER_GATEWAY_CONNECT_TIMEOUT", "44.4")
    yield
    GatewayClient.clear_instance()
Exemple #3
0
    async def start_kernel(self, **kwargs):
        """Starts a kernel via HTTP in an asynchronous manner.

        Parameters
        ----------
        `**kwargs` : optional
             keyword arguments that are passed down to build the kernel_cmd
             and launching the kernel (e.g. Popen kwargs).
        """
        kernel_id = kwargs.get('kernel_id')

        if kernel_id is None:
            kernel_name = kwargs.get('kernel_name', 'python3')
            kernel_url = self._get_kernel_endpoint_url()
            self.log.debug("Request new kernel at: %s" % kernel_url)

            # Let KERNEL_USERNAME take precedent over http_user config option.
            if os.environ.get('KERNEL_USERNAME'
                              ) is None and GatewayClient.instance().http_user:
                os.environ['KERNEL_USERNAME'] = GatewayClient.instance(
                ).http_user

            kernel_env = {
                k: v
                for (k, v) in dict(os.environ).items()
                if k.startswith('KERNEL_')
                or k in GatewayClient.instance().env_whitelist.split(",")
            }

            # Add any env entries in this request
            kernel_env.update(kwargs.get('env'))

            # Convey the full path to where this notebook file is located.
            if kwargs.get('cwd') is not None and kernel_env.get(
                    'KERNEL_WORKING_DIR') is None:
                kernel_env['KERNEL_WORKING_DIR'] = kwargs['cwd']

            json_body = json_encode({'name': kernel_name, 'env': kernel_env})

            response = await gateway_request(kernel_url,
                                             method='POST',
                                             body=json_body)
            self.kernel = json_decode(response.body)
            self.kernel_id = self.kernel['id']
            self.log.info(
                "HTTPKernelManager started kernel: {}, args: {}".format(
                    self.kernel_id, kwargs))
        else:
            self.kernel = await self.get_kernel(kernel_id)
            self.kernel_id = self.kernel['id']
            self.log.info("HTTPKernelManager using existing kernel: {}".format(
                self.kernel_id))
Exemple #4
0
async def test_gateway_cli_options(jp_configurable_serverapp):
    argv = [
        '--gateway-url=' + mock_gateway_url,
        '--GatewayClient.http_user='******'--GatewayClient.connect_timeout=44.4',
        '--GatewayClient.request_timeout=44.4'
    ]

    GatewayClient.clear_instance()
    app = jp_configurable_serverapp(argv=argv)

    assert app.gateway_config.gateway_enabled is True
    assert app.gateway_config.url == mock_gateway_url
    assert app.gateway_config.http_user == mock_http_user
    assert app.gateway_config.connect_timeout == app.gateway_config.request_timeout
    assert app.gateway_config.connect_timeout == 44.4
    GatewayClient.clear_instance()
Exemple #5
0
async def test_gateway_request_timeout_pad_option(
    jp_configurable_serverapp,
    monkeypatch,
    request_timeout,
    kernel_launch_timeout,
    expected_request_timeout,
    expected_kernel_launch_timeout,
):
    argv = [
        f"--GatewayClient.request_timeout={request_timeout}",
        "--GatewayClient.launch_timeout_pad=5",
    ]

    GatewayClient.clear_instance()
    app = jp_configurable_serverapp(argv=argv)

    monkeypatch.setattr(GatewayClient, "KERNEL_LAUNCH_TIMEOUT",
                        kernel_launch_timeout)
    GatewayClient.instance().init_static_args()

    assert app.gateway_config.request_timeout == expected_request_timeout
    assert GatewayClient.instance(
    ).KERNEL_LAUNCH_TIMEOUT == expected_kernel_launch_timeout

    GatewayClient.clear_instance()
Exemple #6
0
    async def start_channels(self,
                             shell=True,
                             iopub=True,
                             stdin=True,
                             hb=True,
                             control=True):
        """Starts the channels for this kernel.

        For this class, we establish a websocket connection to the destination
        and setup the channel-based queues on which applicable messages will
        be posted.
        """

        ws_url = url_path_join(GatewayClient.instance().ws_url,
                               GatewayClient.instance().kernels_endpoint,
                               url_escape(self.kernel_id), 'channels')
        # Gather cert info in case where ssl is desired...
        ssl_options = dict()
        ssl_options['ca_certs'] = GatewayClient.instance().ca_certs
        ssl_options['certfile'] = GatewayClient.instance().client_cert
        ssl_options['keyfile'] = GatewayClient.instance().client_key

        self.channel_socket = websocket.create_connection(
            ws_url,
            timeout=GatewayClient.instance().KERNEL_LAUNCH_TIMEOUT,
            enable_multithread=True,
            sslopt=ssl_options)
        self.response_router = Thread(target=self._route_responses)
        self.response_router.start()

        await ensure_async(super().start_channels(shell=shell,
                                                  iopub=iopub,
                                                  stdin=stdin,
                                                  hb=hb,
                                                  control=control))
Exemple #7
0
    def process(self, operation: Operation):
        filepath = self.get_valid_filepath(operation.filename)

        file_dir = os.path.dirname(filepath)
        file_name = os.path.basename(filepath)

        self.log.debug(f'Processing notebook: {filepath}')

        # We'll always use the ElyraEngine.  This engine is essentially the default Papermill engine
        # but allows for environment variables to be passed to the kernel process (via 'kernel_env').
        # If the current notebook server is running with Enterprise Gateway configured, we will also
        # point the 'kernel_manager_class' to our HTTPKernelManager so that notebooks run as they
        # would outside of Elyra.  Current working directory (cwd) is specified both for where papermill
        # runs the notebook (cwd) and where the directory of the kernel process (kernel_cwd).  The latter
        # of which is important when EG is configured.
        additional_kwargs = dict()
        additional_kwargs['engine_name'] = "ElyraEngine"
        additional_kwargs[
            'cwd'] = file_dir  # For local operations, papermill runs from this dir
        additional_kwargs['kernel_cwd'] = file_dir
        envs = os.environ.copy(
        )  # Make sure this process's env is "available" in the kernel subprocess
        envs.update(operation.env_vars_as_dict())
        additional_kwargs['kernel_env'] = envs
        if GatewayClient.instance().gateway_enabled:
            additional_kwargs[
                'kernel_manager_class'] = 'elyra.pipeline.http_kernel_manager.HTTPKernelManager'

        t0 = time.time()
        try:
            papermill.execute_notebook(filepath, filepath, **additional_kwargs)
        except papermill.PapermillExecutionError as pmee:
            self.log.error(
                f'Error executing {file_name} in cell {pmee.exec_count}: ' +
                f'{str(pmee.ename)} {str(pmee.evalue)}')
            raise RuntimeError(
                f'({file_name}) in cell {pmee.exec_count}: ' +
                f'{str(pmee.ename)} {str(pmee.evalue)}') from pmee
        except Exception as ex:
            self.log.error(f'Error executing {file_name}: {str(ex)}')
            raise RuntimeError(f'({file_name})') from ex

        t1 = time.time()
        duration = (t1 - t0)
        self.log.debug(f'Execution of {file_name} took {duration:.3f} secs.')
Exemple #8
0
    def process(self, operation: GenericOperation, elyra_run_name: str):
        filepath = self.get_valid_filepath(operation.filename)

        file_dir = os.path.dirname(filepath)
        file_name = os.path.basename(filepath)

        self.log.debug(f"Processing notebook: {filepath}")

        # We'll always use the ElyraEngine.  This engine is essentially the default Papermill engine
        # but allows for environment variables to be passed to the kernel process (via 'kernel_env').
        # If the current notebook server is running with Enterprise Gateway configured, we will also
        # point the 'kernel_manager_class' to GatewayKernelManager so that notebooks run as they
        # would outside of Elyra.  Current working directory (cwd) is specified both for where papermill
        # runs the notebook (cwd) and where the directory of the kernel process (kernel_cwd).  The latter
        # of which is important when EG is configured.
        additional_kwargs = dict()
        additional_kwargs["engine_name"] = "ElyraEngine"
        additional_kwargs[
            "cwd"] = file_dir  # For local operations, papermill runs from this dir
        additional_kwargs["kernel_cwd"] = file_dir
        additional_kwargs["kernel_env"] = OperationProcessor._collect_envs(
            operation, elyra_run_name)
        if GatewayClient.instance().gateway_enabled:
            additional_kwargs[
                "kernel_manager_class"] = "jupyter_server.gateway.managers.GatewayKernelManager"

        t0 = time.time()
        try:
            papermill.execute_notebook(filepath, filepath, **additional_kwargs)
        except papermill.PapermillExecutionError as pmee:
            self.log.error(
                f"Error executing {file_name} in cell {pmee.exec_count}: " +
                f"{str(pmee.ename)} {str(pmee.evalue)}")
            raise RuntimeError(
                f"({file_name}) in cell {pmee.exec_count}: " +
                f"{str(pmee.ename)} {str(pmee.evalue)}") from pmee
        except Exception as ex:
            self.log_and_raise(file_name, ex)

        t1 = time.time()
        duration = t1 - t0
        self.log.debug(f"Execution of {file_name} took {duration:.3f} secs.")
async def test_gateway_cli_options(jp_configurable_serverapp):
    argv = [
        '--gateway-url=' + mock_gateway_url,
        '--GatewayClient.http_user='******'--GatewayClient.connect_timeout=44.4',
        '--GatewayClient.request_timeout=96.0'
    ]

    GatewayClient.clear_instance()
    app = jp_configurable_serverapp(argv=argv)

    assert app.gateway_config.gateway_enabled is True
    assert app.gateway_config.url == mock_gateway_url
    assert app.gateway_config.http_user == mock_http_user
    assert app.gateway_config.connect_timeout == 44.4
    assert app.gateway_config.request_timeout == 96.0
    GatewayClient.instance().init_static_args()
    assert GatewayClient.instance().KERNEL_LAUNCH_TIMEOUT == 96  # Ensure KLT gets set from request-timeout
    GatewayClient.clear_instance()
Exemple #10
0
async def test_gateway_cli_options(jp_configurable_serverapp):
    argv = [
        "--gateway-url=" + mock_gateway_url,
        "--GatewayClient.http_user="******"--GatewayClient.connect_timeout=44.4",
        "--GatewayClient.request_timeout=96.0",
        "--GatewayClient.launch_timeout_pad=5.1",
    ]

    GatewayClient.clear_instance()
    app = jp_configurable_serverapp(argv=argv)

    assert app.gateway_config.gateway_enabled is True
    assert app.gateway_config.url == mock_gateway_url
    assert app.gateway_config.http_user == mock_http_user
    assert app.gateway_config.connect_timeout == 44.4
    assert app.gateway_config.request_timeout == 96.0
    assert app.gateway_config.launch_timeout_pad == 5.1
    GatewayClient.instance().init_static_args()
    assert (GatewayClient.instance().KERNEL_LAUNCH_TIMEOUT == 90
            )  # Ensure KLT gets set from request-timeout - launch_timeout_pad
    GatewayClient.clear_instance()
Exemple #11
0
 def teardown_class(cls):
     GatewayClient.clear_instance()
     super(TestGateway, cls).teardown_class()
Exemple #12
0
 def setup_class(cls):
     GatewayClient.clear_instance()
     super(TestGateway, cls).setup_class()
Exemple #13
0
 def __init__(self, **kwargs):
     super().__init__(**kwargs)
     self.base_endpoint = url_path_join(
         GatewayClient.instance().url,
         GatewayClient.instance().kernels_endpoint)
     self.kernel = None