diff --git a/doc/source/installation.rst b/doc/source/installation.rst index 007b848d1..c58975f68 100644 --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -46,14 +46,14 @@ master branch). To install these wheels, run the following command: Installing Ray with Anaconda ---------------------------- -If you use `Anaconda`_ and want to use Ray in a defined environment, e.g, ``ray``, use these commands: +If you use `Anaconda`_ and want to use Ray in a defined environment, e.g, ``ray``, use these commands: .. code-block:: bash conda create --name ray conda activate ray conda install --name ray pip - pip install ray + pip install ray Use ``pip list`` to confirm that ``ray`` is installed. @@ -135,25 +135,35 @@ steps are included in the installation instructions above. .. _`Node.js`: https://nodejs.org/ -The dashboard also requires: - -- Python 3 -- aiohttp -- psutil - -The latter two can be installed via pip: +The dashboard requires a few additional Python packages, which can be installed +via pip. .. code-block:: bash - pip install aiohttp psutil - -The dashboard is enabled by setting -``include_webui=True`` during initialization, i.e. + pip install ray[dashboard] -.. code-block:: python +If you are using Anaconda and have trouble installing ``psutil`` or +``setproctitle``, the try - import ray - ray.init(include_webui=True) +.. code-block:: bash + + conda install psutil setproctitle + +The command ``ray.init()`` or ``ray start --head`` will print out the address of +the dashboard. For example, + +.. code-block:: + + >>> import ray + >>> ray.init() + ====================================================================== + View the dashboard at http://127.0.0.1:8265. + Note: If Ray is running on a remote node, you will need to set up an + SSH tunnel with local port forwarding in order to access the dashboard + in your browser, e.g. by running 'ssh -L 8265:127.0.0.1:8265 + @'. Alternatively, you can set webui_host="0.0.0.0" in + the call to ray.init() to allow direct access from external machines. + ====================================================================== Docker Source Images diff --git a/python/ray/autoscaler/aws/development-example.yaml b/python/ray/autoscaler/aws/development-example.yaml index f3243bf69..3ebc3ee30 100644 --- a/python/ray/autoscaler/aws/development-example.yaml +++ b/python/ray/autoscaler/aws/development-example.yaml @@ -111,7 +111,7 @@ worker_setup_commands: [] # Command to start ray on the head node. You don't need to change this. head_start_ray_commands: - ray stop - - ulimit -n 65536; ray start --head --include-webui --num-redis-shards=10 --redis-port=6379 --autoscaling-config=~/ray_bootstrap_config.yaml + - ulimit -n 65536; ray start --head --num-redis-shards=10 --redis-port=6379 --autoscaling-config=~/ray_bootstrap_config.yaml # Command to start ray on worker nodes. You don't need to change this. worker_start_ray_commands: diff --git a/python/ray/node.py b/python/ray/node.py index 53984c53f..0c17ef8f1 100644 --- a/python/ray/node.py +++ b/python/ray/node.py @@ -86,7 +86,6 @@ class Node(object): ray_params.update_if_absent( include_log_monitor=True, resources={}, - include_webui=False, temp_dir="/tmp/ray", worker_path=os.path.join( os.path.dirname(os.path.abspath(__file__)), @@ -142,7 +141,7 @@ class Node(object): self._ray_params.raylet_socket_name, default_prefix="raylet") if head: - ray_params.update_if_absent(num_redis_shards=1, include_webui=True) + ray_params.update_if_absent(num_redis_shards=1) self._webui_url = None else: self._webui_url = ( @@ -478,10 +477,17 @@ class Node(object): process_info ] - def start_dashboard(self): - """Start the dashboard.""" + def start_dashboard(self, require_webui): + """Start the dashboard. + + Args: + require_webui (bool): If true, this will raise an exception if we + fail to start the webui. Otherwise it will print a warning if + we fail to start the webui. + """ stdout_file, stderr_file = self.new_log_files("dashboard", True) self._webui_url, process_info = ray.services.start_dashboard( + require_webui, self._ray_params.webui_host, self.redis_address, self._temp_dir, @@ -594,8 +600,11 @@ class Node(object): self.start_monitor() self.start_raylet_monitor() # The dashboard is Python3.x only. - if PY3 and self._ray_params.include_webui: - self.start_dashboard() + if PY3: + if self._ray_params.include_webui: + self.start_dashboard(require_webui=True) + elif self._ray_params.include_webui is None: + self.start_dashboard(require_webui=False) def start_ray_processes(self): """Start all of the processes on the node.""" diff --git a/python/ray/parameter.py b/python/ray/parameter.py index 4c710dd9c..f5e6125d5 100644 --- a/python/ray/parameter.py +++ b/python/ray/parameter.py @@ -59,7 +59,9 @@ class RayParams(object): huge_pages: Boolean flag indicating whether to start the Object Store with hugetlbfs support. Requires plasma_directory. include_webui: Boolean flag indicating whether to start the web - UI, which displays the status of the Ray cluster. + UI, which displays the status of the Ray cluster. If this value is + None, then the UI will be started if the relevant dependencies are + present. webui_host: The host to bind the web UI server to. Can either be 127.0.0.1 (localhost) or 0.0.0.0 (available from all interfaces). By default, this is set to 127.0.0.1 to prevent access from diff --git a/python/ray/scripts/scripts.py b/python/ray/scripts/scripts.py index e2417cdc8..250ef8a64 100644 --- a/python/ray/scripts/scripts.py +++ b/python/ray/scripts/scripts.py @@ -160,8 +160,8 @@ def cli(logging_level, logging_format): help="provide this argument for the head node") @click.option( "--include-webui", - is_flag=True, - default=False, + default=None, + type=bool, help="provide this argument if the UI should be started") @click.option( "--webui-host", diff --git a/python/ray/services.py b/python/ray/services.py index 4202abf01..ebd0a2ed8 100644 --- a/python/ray/services.py +++ b/python/ray/services.py @@ -1018,7 +1018,8 @@ def start_reporter(redis_address, return process_info -def start_dashboard(host, +def start_dashboard(require_webui, + host, redis_address, temp_dir, stdout_file=None, @@ -1027,6 +1028,9 @@ def start_dashboard(host, """Start a dashboard process. Args: + require_webui (bool): If true, this will raise an exception if we fail + to start the webui. Otherwise it will print a warning if we fail + to start the webui. host (str): The host to bind the dashboard web server to. redis_address (str): The address of the Redis instance. temp_dir (str): The temporary directory used for log files and @@ -1066,37 +1070,48 @@ def start_dashboard(host, if sys.version_info <= (3, 0): return None, None + + webui_dependencies_present = True try: import aiohttp # noqa: F401 import psutil # noqa: F401 import setproctitle # noqa: F401 import grpc # noqa: F401 except ImportError: - raise ImportError( + webui_dependencies_present = False + warning_message = ( "Failed to start the dashboard. The dashboard requires Python 3 " "as well as 'pip install aiohttp psutil setproctitle grpcio'.") + if require_webui: + raise ImportError(warning_message) + else: + logger.warning(warning_message) - process_info = start_ray_process( - command, - ray_constants.PROCESS_TYPE_DASHBOARD, - stdout_file=stdout_file, - stderr_file=stderr_file) - dashboard_url = "http://{}:{}".format( - host if host == "127.0.0.1" else get_node_ip_address(), port) - print("\n" + "=" * 70) - print("View the dashboard at {}.".format(dashboard_url)) - if host == "127.0.0.1": - note = ( - "Note: If Ray is running on a remote node, you will need to set " - "up an SSH tunnel with local port forwarding in order to access " - "the dashboard in your browser, e.g. by running " - "'ssh -L {}:{}:{} @'. Alternatively, you can set " - "webui_host=\"0.0.0.0\" in the call to ray.init() to allow direct " - "access from external machines.") - note = note.format(port, host, port) - print("\n".join(textwrap.wrap(note, width=70))) - print("=" * 70 + "\n") - return dashboard_url, process_info + if webui_dependencies_present: + process_info = start_ray_process( + command, + ray_constants.PROCESS_TYPE_DASHBOARD, + stdout_file=stdout_file, + stderr_file=stderr_file) + + dashboard_url = "http://{}:{}".format( + host if host == "127.0.0.1" else get_node_ip_address(), port) + print("\n" + "=" * 70) + print("View the dashboard at {}.".format(dashboard_url)) + if host == "127.0.0.1": + note = ( + "Note: If Ray is running on a remote node, you will need to " + "set up an SSH tunnel with local port forwarding in order to " + "access the dashboard in your browser, e.g. by running " + "'ssh -L {}:{}:{} @'. Alternatively, you can " + "set webui_host=\"0.0.0.0\" in the call to ray.init() to " + "allow direct access from external machines.") + note = note.format(port, host, port) + print("\n".join(textwrap.wrap(note, width=70))) + print("=" * 70 + "\n") + return dashboard_url, process_info + else: + return None, None def start_raylet(redis_address, diff --git a/python/ray/tests/test_metrics.py b/python/ray/tests/test_metrics.py index 7496ed749..5954de6f9 100644 --- a/python/ray/tests/test_metrics.py +++ b/python/ray/tests/test_metrics.py @@ -13,7 +13,8 @@ from ray.core.generated import node_manager_pb2_grpc from ray.test_utils import RayTestTimeoutException -def test_worker_stats(ray_start_regular): +def test_worker_stats(shutdown_only): + ray.init(num_cpus=1, include_webui=False) raylet = ray.nodes()[0] num_cpus = raylet["Resources"]["CPU"] raylet_address = "{}:{}".format(raylet["NodeManagerAddress"], diff --git a/python/ray/worker.py b/python/ray/worker.py index 01ee8f16b..64b773efb 100644 --- a/python/ray/worker.py +++ b/python/ray/worker.py @@ -547,7 +547,7 @@ def init(address=None, redis_password=ray_constants.REDIS_DEFAULT_PASSWORD, plasma_directory=None, huge_pages=False, - include_webui=False, + include_webui=None, webui_host="127.0.0.1", job_id=None, configure_logging=True, @@ -627,7 +627,9 @@ def init(address=None, huge_pages: Boolean flag indicating whether to start the Object Store with hugetlbfs support. Requires plasma_directory. include_webui: Boolean flag indicating whether to start the web - UI, which displays the status of the Ray cluster. + UI, which displays the status of the Ray cluster. If this argument + is None, then the UI will be started if the relevant dependencies + are present. webui_host: The host to bind the web UI server to. Can either be 127.0.0.1 (localhost) or 0.0.0.0 (available from all interfaces). By default, this is set to 127.0.0.1 to prevent access from