skypilot-nightly 1.0.0.dev20241121__py3-none-any.whl → 1.0.0.dev20241122__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sky/skylet/constants.py CHANGED
@@ -39,6 +39,7 @@ SKY_GET_PYTHON_PATH_CMD = (f'[ -s {SKY_PYTHON_PATH_FILE} ] && '
39
39
  'which python3')
40
40
  # Python executable, e.g., /opt/conda/bin/python3
41
41
  SKY_PYTHON_CMD = f'$({SKY_GET_PYTHON_PATH_CMD})'
42
+ # Prefer SKY_UV_PIP_CMD, which is faster. TODO(cooper): remove all usages.
42
43
  SKY_PIP_CMD = f'{SKY_PYTHON_CMD} -m pip'
43
44
  # Ray executable, e.g., /opt/conda/bin/ray
44
45
  # We need to add SKY_PYTHON_CMD before ray executable because:
@@ -50,6 +51,10 @@ SKY_RAY_CMD = (f'{SKY_PYTHON_CMD} $([ -s {SKY_RAY_PATH_FILE} ] && '
50
51
  SKY_REMOTE_PYTHON_ENV_NAME = 'skypilot-runtime'
51
52
  SKY_REMOTE_PYTHON_ENV = f'~/{SKY_REMOTE_PYTHON_ENV_NAME}'
52
53
  ACTIVATE_SKY_REMOTE_PYTHON_ENV = f'source {SKY_REMOTE_PYTHON_ENV}/bin/activate'
54
+ # uv is used for venv and pip, much faster than python implementations.
55
+ SKY_UV_INSTALL_DIR = '"$HOME/.local/bin"'
56
+ SKY_UV_CMD = f'{SKY_UV_INSTALL_DIR}/uv'
57
+ SKY_UV_PIP_CMD = f'VIRTUAL_ENV={SKY_REMOTE_PYTHON_ENV} {SKY_UV_CMD} pip'
53
58
  # Deleting the SKY_REMOTE_PYTHON_ENV_NAME from the PATH to deactivate the
54
59
  # environment. `deactivate` command does not work when conda is used.
55
60
  DEACTIVATE_SKY_REMOTE_PYTHON_ENV = (
@@ -148,31 +153,29 @@ CONDA_INSTALLATION_COMMANDS = (
148
153
  'echo "Creating conda env with Python 3.10" && '
149
154
  f'conda create -y -n {SKY_REMOTE_PYTHON_ENV_NAME} python=3.10 && '
150
155
  f'conda activate {SKY_REMOTE_PYTHON_ENV_NAME};'
156
+ # Install uv for venv management and pip installation.
157
+ 'which uv >/dev/null 2>&1 || '
158
+ 'curl -LsSf https://astral.sh/uv/install.sh '
159
+ f'| UV_INSTALL_DIR={SKY_UV_INSTALL_DIR} sh;'
151
160
  # Create a separate conda environment for SkyPilot dependencies.
152
161
  f'[ -d {SKY_REMOTE_PYTHON_ENV} ] || '
153
162
  # Do NOT use --system-site-packages here, because if users upgrade any
154
163
  # packages in the base env, they interfere with skypilot dependencies.
155
164
  # Reference: https://github.com/skypilot-org/skypilot/issues/4097
156
- f'{SKY_PYTHON_CMD} -m venv {SKY_REMOTE_PYTHON_ENV};'
165
+ f'{SKY_UV_CMD} venv {SKY_REMOTE_PYTHON_ENV};'
157
166
  f'echo "$(echo {SKY_REMOTE_PYTHON_ENV})/bin/python" > {SKY_PYTHON_PATH_FILE};'
158
167
  )
159
168
 
160
169
  _sky_version = str(version.parse(sky.__version__))
161
170
  RAY_STATUS = f'RAY_ADDRESS=127.0.0.1:{SKY_REMOTE_RAY_PORT} {SKY_RAY_CMD} status'
162
- # Install ray and skypilot on the remote cluster if they are not already
163
- # installed. {var} will be replaced with the actual value in
164
- # backend_utils.write_cluster_config.
165
- RAY_SKYPILOT_INSTALLATION_COMMANDS = (
171
+ RAY_INSTALLATION_COMMANDS = (
166
172
  'mkdir -p ~/sky_workdir && mkdir -p ~/.sky/sky_app;'
167
- # Disable the pip version check to avoid the warning message, which makes
168
- # the output hard to read.
169
- 'export PIP_DISABLE_PIP_VERSION_CHECK=1;'
170
173
  # Print the PATH in provision.log to help debug PATH issues.
171
174
  'echo PATH=$PATH; '
172
175
  # Install setuptools<=69.5.1 to avoid the issue with the latest setuptools
173
176
  # causing the error:
174
177
  # ImportError: cannot import name 'packaging' from 'pkg_resources'"
175
- f'{SKY_PIP_CMD} install "setuptools<70"; '
178
+ f'{SKY_UV_PIP_CMD} install "setuptools<70"; '
176
179
  # Backward compatibility for ray upgrade (#3248): do not upgrade ray if the
177
180
  # ray cluster is already running, to avoid the ray cluster being restarted.
178
181
  #
@@ -186,10 +189,10 @@ RAY_SKYPILOT_INSTALLATION_COMMANDS = (
186
189
  # latest ray port 6380, but those existing cluster launched before #1790
187
190
  # that has ray cluster on the default port 6379 will be upgraded and
188
191
  # restarted.
189
- f'{SKY_PIP_CMD} list | grep "ray " | '
192
+ f'{SKY_UV_PIP_CMD} list | grep "ray " | '
190
193
  f'grep {SKY_REMOTE_RAY_VERSION} 2>&1 > /dev/null '
191
194
  f'|| {RAY_STATUS} || '
192
- f'{SKY_PIP_CMD} install --exists-action w -U ray[default]=={SKY_REMOTE_RAY_VERSION}; ' # pylint: disable=line-too-long
195
+ f'{SKY_UV_PIP_CMD} install -U ray[default]=={SKY_REMOTE_RAY_VERSION}; ' # pylint: disable=line-too-long
193
196
  # In some envs, e.g. pip does not have permission to write under /opt/conda
194
197
  # ray package will be installed under ~/.local/bin. If the user's PATH does
195
198
  # not include ~/.local/bin (the pip install will have the output: `WARNING:
@@ -202,24 +205,31 @@ RAY_SKYPILOT_INSTALLATION_COMMANDS = (
202
205
  # Writes ray path to file if it does not exist or the file is empty.
203
206
  f'[ -s {SKY_RAY_PATH_FILE} ] || '
204
207
  f'{{ {ACTIVATE_SKY_REMOTE_PYTHON_ENV} && '
205
- f'which ray > {SKY_RAY_PATH_FILE} || exit 1; }}; '
206
- # END ray package check and installation
207
- f'{{ {SKY_PIP_CMD} list | grep "skypilot " && '
208
+ f'which ray > {SKY_RAY_PATH_FILE} || exit 1; }}; ')
209
+
210
+ SKYPILOT_WHEEL_INSTALLATION_COMMANDS = (
211
+ f'{{ {SKY_UV_PIP_CMD} list | grep "skypilot " && '
208
212
  '[ "$(cat ~/.sky/wheels/current_sky_wheel_hash)" == "{sky_wheel_hash}" ]; } || ' # pylint: disable=line-too-long
209
- f'{{ {SKY_PIP_CMD} uninstall skypilot -y; '
210
- f'{SKY_PIP_CMD} install "$(echo ~/.sky/wheels/{{sky_wheel_hash}}/'
213
+ f'{{ {SKY_UV_PIP_CMD} uninstall skypilot; '
214
+ f'{SKY_UV_PIP_CMD} install "$(echo ~/.sky/wheels/{{sky_wheel_hash}}/'
211
215
  f'skypilot-{_sky_version}*.whl)[{{cloud}}, remote]" && '
212
216
  'echo "{sky_wheel_hash}" > ~/.sky/wheels/current_sky_wheel_hash || '
213
- 'exit 1; }; '
214
- # END SkyPilot package check and installation
217
+ 'exit 1; }; ')
215
218
 
219
+ # Install ray and skypilot on the remote cluster if they are not already
220
+ # installed. {var} will be replaced with the actual value in
221
+ # backend_utils.write_cluster_config.
222
+ RAY_SKYPILOT_INSTALLATION_COMMANDS = (
223
+ f'{RAY_INSTALLATION_COMMANDS} '
224
+ f'{SKYPILOT_WHEEL_INSTALLATION_COMMANDS} '
216
225
  # Only patch ray when the ray version is the same as the expected version.
217
226
  # The ray installation above can be skipped due to the existing ray cluster
218
227
  # for backward compatibility. In this case, we should not patch the ray
219
228
  # files.
220
- f'{SKY_PIP_CMD} list | grep "ray " | grep {SKY_REMOTE_RAY_VERSION} 2>&1 > /dev/null '
221
- f'&& {{ {SKY_PYTHON_CMD} -c "from sky.skylet.ray_patches import patch; patch()" '
222
- '|| exit 1; };')
229
+ f'{SKY_UV_PIP_CMD} list | grep "ray " | '
230
+ f'grep {SKY_REMOTE_RAY_VERSION} 2>&1 > /dev/null && '
231
+ f'{{ {SKY_PYTHON_CMD} -c '
232
+ '"from sky.skylet.ray_patches import patch; patch()" || exit 1; }; ')
223
233
 
224
234
  # The name for the environment variable that stores SkyPilot user hash, which
225
235
  # is mainly used to make sure sky commands runs on a VM launched by SkyPilot
@@ -222,7 +222,9 @@ provider:
222
222
  - protocol: TCP
223
223
  port: 22
224
224
  targetPort: 22
225
- # Service that maps to the head node of the Ray cluster.
225
+ # Service that maps to the head node of the Ray cluster, so that the
226
+ # worker nodes can find the head node using
227
+ # {{cluster_name_on_cloud}}-head.{{k8s_namespace}}.svc.cluster.local
226
228
  - apiVersion: v1
227
229
  kind: Service
228
230
  metadata:
@@ -235,18 +237,12 @@ provider:
235
237
  # names.
236
238
  name: {{cluster_name_on_cloud}}-head
237
239
  spec:
240
+ # Create a headless service so that the head node can be reached by
241
+ # the worker nodes with any port number.
242
+ clusterIP: None
238
243
  # This selector must match the head node pod's selector below.
239
244
  selector:
240
245
  component: {{cluster_name_on_cloud}}-head
241
- ports:
242
- - name: client
243
- protocol: TCP
244
- port: 10001
245
- targetPort: 10001
246
- - name: dashboard
247
- protocol: TCP
248
- port: 8265
249
- targetPort: 8265
250
246
 
251
247
  # Specify the pod type for the ray head node (as configured below).
252
248
  head_node_type: ray_head_default
@@ -280,7 +276,6 @@ available_node_types:
280
276
  # serviceAccountName: skypilot-service-account
281
277
  serviceAccountName: {{k8s_service_account_name}}
282
278
  automountServiceAccountToken: {{k8s_automount_sa_token}}
283
-
284
279
  restartPolicy: Never
285
280
 
286
281
  # Add node selector if GPU/TPUs are requested:
@@ -322,18 +317,147 @@ available_node_types:
322
317
  - name: ray-node
323
318
  imagePullPolicy: IfNotPresent
324
319
  image: {{image_id}}
320
+ env:
321
+ - name: SKYPILOT_POD_NODE_TYPE
322
+ valueFrom:
323
+ fieldRef:
324
+ fieldPath: metadata.labels['ray-node-type']
325
325
  # Do not change this command - it keeps the pod alive until it is
326
326
  # explicitly killed.
327
327
  command: ["/bin/bash", "-c", "--"]
328
328
  args:
329
329
  - |
330
330
  # Helper function to conditionally use sudo
331
+ # TODO(zhwu): consolidate the two prefix_cmd and sudo replacements
331
332
  prefix_cmd() { if [ $(id -u) -ne 0 ]; then echo "sudo"; else echo ""; fi; }
333
+ [ $(id -u) -eq 0 ] && function sudo() { "$@"; } || true;
334
+
335
+ STEPS=("apt-ssh-setup" "runtime-setup" "env-setup")
332
336
 
333
- # Run apt update in background and log to a file
337
+ # STEP 1: Run apt update, install missing packages, and set up ssh.
334
338
  (
339
+ (
335
340
  DEBIAN_FRONTEND=noninteractive $(prefix_cmd) apt-get update > /tmp/apt-update.log 2>&1 || \
336
341
  echo "Warning: apt-get update failed. Continuing anyway..." >> /tmp/apt-update.log
342
+ PACKAGES="rsync curl netcat gcc patch pciutils fuse openssh-server";
343
+
344
+ # Separate packages into two groups: packages that are installed first
345
+ # so that curl and rsync are available sooner to unblock the following
346
+ # conda installation and rsync.
347
+ set -e
348
+ INSTALL_FIRST="";
349
+ MISSING_PACKAGES="";
350
+ for pkg in $PACKAGES; do
351
+ if [ "$pkg" == "netcat" ]; then
352
+ if ! dpkg -l | grep -q "^ii \(netcat\|netcat-openbsd\|netcat-traditional\) "; then
353
+ INSTALL_FIRST="$INSTALL_FIRST netcat-openbsd";
354
+ fi
355
+ elif ! dpkg -l | grep -q "^ii $pkg "; then
356
+ if [ "$pkg" == "curl" ] || [ "$pkg" == "rsync" ]; then
357
+ INSTALL_FIRST="$INSTALL_FIRST $pkg";
358
+ else
359
+ MISSING_PACKAGES="$MISSING_PACKAGES $pkg";
360
+ fi
361
+ fi
362
+ done;
363
+ if [ ! -z "$INSTALL_FIRST" ]; then
364
+ echo "Installing core packages: $INSTALL_FIRST";
365
+ DEBIAN_FRONTEND=noninteractive $(prefix_cmd) apt-get install -y $INSTALL_FIRST;
366
+ fi;
367
+ # SSH and other packages are not necessary, so we disable set -e
368
+ set +e
369
+
370
+ if [ ! -z "$MISSING_PACKAGES" ]; then
371
+ echo "Installing missing packages: $MISSING_PACKAGES";
372
+ DEBIAN_FRONTEND=noninteractive $(prefix_cmd) apt-get install -y $MISSING_PACKAGES;
373
+ fi;
374
+ $(prefix_cmd) mkdir -p /var/run/sshd;
375
+ $(prefix_cmd) sed -i "s/PermitRootLogin prohibit-password/PermitRootLogin yes/" /etc/ssh/sshd_config;
376
+ $(prefix_cmd) sed "s@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g" -i /etc/pam.d/sshd;
377
+ cd /etc/ssh/ && $(prefix_cmd) ssh-keygen -A;
378
+ $(prefix_cmd) mkdir -p ~/.ssh;
379
+ $(prefix_cmd) chown -R $(whoami) ~/.ssh;
380
+ $(prefix_cmd) chmod 700 ~/.ssh;
381
+ $(prefix_cmd) cat /etc/secret-volume/ssh-publickey* > ~/.ssh/authorized_keys;
382
+ $(prefix_cmd) chmod 644 ~/.ssh/authorized_keys;
383
+ $(prefix_cmd) service ssh restart;
384
+ $(prefix_cmd) sed -i "s/mesg n/tty -s \&\& mesg n/" ~/.profile;
385
+ ) > /tmp/${STEPS[0]}.log 2>&1 || {
386
+ echo "Error: ${STEPS[0]} failed. Continuing anyway..." > /tmp/${STEPS[0]}.failed
387
+ cat /tmp/${STEPS[0]}.log
388
+ exit 1
389
+ }
390
+ ) &
391
+
392
+ # STEP 2: Install conda, ray and skypilot (for dependencies); start
393
+ # ray cluster.
394
+ (
395
+ (
396
+ set -e
397
+ mkdir -p ~/.sky
398
+ # Wait for `curl` package to be installed before installing conda
399
+ # and ray.
400
+ until dpkg -l | grep -q "^ii curl "; do
401
+ sleep 0.1
402
+ echo "Waiting for curl package to be installed..."
403
+ done
404
+ {{ conda_installation_commands }}
405
+ {{ ray_installation_commands }}
406
+ VIRTUAL_ENV=~/skypilot-runtime ~/.local/bin/uv pip install skypilot[kubernetes,remote]
407
+ touch /tmp/ray_skypilot_installation_complete
408
+ echo "=== Ray and skypilot installation completed ==="
409
+
410
+ # Disable set -e, as we have some commands that are ok to fail
411
+ # after the ray start.
412
+ # TODO(zhwu): this is a hack, we should fix the commands that are
413
+ # ok to fail.
414
+ if [ "$SKYPILOT_POD_NODE_TYPE" == "head" ]; then
415
+ set +e
416
+ {{ ray_head_start_command }}
417
+ else
418
+ # Start ray worker on the worker pod.
419
+ # Wait until the head pod is available with an IP address
420
+ export SKYPILOT_RAY_HEAD_IP="{{cluster_name_on_cloud}}-head.{{k8s_namespace}}.svc.cluster.local"
421
+ export SKYPILOT_RAY_PORT={{skypilot_ray_port}}
422
+ # Wait until the ray cluster is started on the head pod
423
+ until dpkg -l | grep -q "^ii \(netcat\|netcat-openbsd\|netcat-traditional\) "; do
424
+ sleep 0.1
425
+ echo "Waiting for netcat package to be installed..."
426
+ done
427
+ until nc -z -w 1 ${SKYPILOT_RAY_HEAD_IP} ${SKYPILOT_RAY_PORT}; do
428
+ sleep 0.1
429
+ done
430
+
431
+ set +e
432
+ {{ ray_worker_start_command }}
433
+ fi
434
+ ) > /tmp/${STEPS[1]}.log 2>&1 || {
435
+ echo "Error: ${STEPS[1]} failed. Continuing anyway..." > /tmp/${STEPS[1]}.failed
436
+ cat /tmp/${STEPS[1]}.log
437
+ exit 1
438
+ }
439
+ ) &
440
+
441
+
442
+ # STEP 3: Set up environment variables; this should be relatively fast.
443
+ (
444
+ (
445
+ set -e
446
+ if [ $(id -u) -eq 0 ]; then
447
+ echo 'alias sudo=""' >> ~/.bashrc; echo succeed;
448
+ else
449
+ if command -v sudo >/dev/null 2>&1; then
450
+ timeout 2 sudo -l >/dev/null 2>&1 && echo succeed || { echo 52; exit 52; };
451
+ else
452
+ { echo 52; exit 52; };
453
+ fi;
454
+ fi;
455
+ printenv | while IFS='=' read -r key value; do echo "export $key=\"$value\""; done > ~/container_env_var.sh && $(prefix_cmd) mv ~/container_env_var.sh /etc/profile.d/container_env_var.sh
456
+ ) > /tmp/${STEPS[2]}.log 2>&1 || {
457
+ echo "Error: ${STEPS[2]} failed. Continuing anyway..." > /tmp/${STEPS[2]}.failed
458
+ cat /tmp/${STEPS[2]}.log
459
+ exit 1
460
+ }
337
461
  ) &
338
462
 
339
463
  function mylsof { p=$(for pid in /proc/{0..9}*; do i=$(basename "$pid"); for file in "$pid"/fd/*; do link=$(readlink -e "$file"); if [ "$link" = "$1" ]; then echo "$i"; fi; done; done); echo "$p"; };
@@ -441,42 +565,48 @@ setup_commands:
441
565
  # Line 'sudo grep ..': set the number of threads per process to unlimited to avoid ray job submit stucking issue when the number of running ray jobs increase.
442
566
  # Line 'mkdir -p ..': disable host key check
443
567
  # Line 'python3 -c ..': patch the buggy ray files and enable `-o allow_other` option for `goofys`
568
+ # Line 'for step in ..': check if any failure indicator exists for the setup done in pod args and print the error message. This is only a best effort, as the
569
+ # commands in pod args are asynchronous and we cannot guarantee the failure indicators are created before the setup commands finish.
444
570
  - |
445
- PACKAGES="gcc patch pciutils rsync fuse curl";
446
- MISSING_PACKAGES="";
447
- for pkg in $PACKAGES; do
448
- if ! dpkg -l | grep -q "^ii $pkg "; then
449
- MISSING_PACKAGES="$MISSING_PACKAGES $pkg";
450
- fi
451
- done;
452
- if [ ! -z "$MISSING_PACKAGES" ]; then
453
- echo "Installing missing packages: $MISSING_PACKAGES";
454
- sudo DEBIAN_FRONTEND=noninteractive apt-get install -y $MISSING_PACKAGES;
455
- fi;
456
571
  mkdir -p ~/.ssh; touch ~/.ssh/config;
457
572
  {%- for initial_setup_command in initial_setup_commands %}
458
573
  {{ initial_setup_command }}
459
574
  {%- endfor %}
460
- {{ conda_installation_commands }}
461
- {{ ray_skypilot_installation_commands }}
575
+ STEPS=("apt-ssh-setup" "runtime-setup" "env-setup")
576
+ start_epoch=$(date +%s);
577
+ echo "=== Logs for asynchronous ray and skypilot installation ===";
578
+ [ -f /tmp/ray_skypilot_installation_complete ] && cat /tmp/${STEPS[1]}.log ||
579
+ { tail -f -n +1 /tmp/${STEPS[1]}.log & TAIL_PID=$!; echo "Tail PID: $TAIL_PID"; until [ -f /tmp/ray_skypilot_installation_complete ]; do sleep 0.5; done; kill $TAIL_PID || true; };
580
+ [ -f /tmp/${STEPS[1]}.failed ] && { echo "Error: ${STEPS[1]} failed. Exiting."; exit 1; } || true;
581
+ end_epoch=$(date +%s);
582
+ echo "=== Ray and skypilot dependencies installation completed in $(($end_epoch - $start_epoch)) secs ===";
583
+ start_epoch=$(date +%s);
584
+ {{ skypilot_wheel_installation_commands }}
585
+ end_epoch=$(date +%s);
586
+ echo "=== Skypilot wheel installation completed in $(($end_epoch - $start_epoch)) secs ===";
587
+ start_epoch=$(date +%s);
462
588
  sudo touch ~/.sudo_as_admin_successful;
463
589
  sudo bash -c 'rm -rf /etc/security/limits.d; echo "* soft nofile 1048576" >> /etc/security/limits.conf; echo "* hard nofile 1048576" >> /etc/security/limits.conf';
464
- sudo grep -e '^DefaultTasksMax' /etc/systemd/system.conf || (sudo bash -c 'echo "DefaultTasksMax=infinity" >> /etc/systemd/system.conf'); sudo systemctl set-property user-$(id -u $(whoami)).slice TasksMax=infinity; sudo systemctl daemon-reload;
590
+ sudo grep -e '^DefaultTasksMax' /etc/systemd/system.conf || (sudo bash -c 'echo "DefaultTasksMax=infinity" >> /etc/systemd/system.conf');
591
+ ulimit -n 1048576;
465
592
  mkdir -p ~/.ssh; (grep -Pzo -q "Host \*\n StrictHostKeyChecking no" ~/.ssh/config) || printf "Host *\n StrictHostKeyChecking no\n" >> ~/.ssh/config;
466
593
  [ -f /etc/fuse.conf ] && sudo sed -i 's/#user_allow_other/user_allow_other/g' /etc/fuse.conf || (sudo sh -c 'echo "user_allow_other" > /etc/fuse.conf'); # This is needed for `-o allow_other` option for `goofys`;
467
- {% if tpu_requested %}
468
- # The /tmp/tpu_logs directory is where TPU-related logs, such as logs from
469
- # the TPU runtime, are written. These capture runtime information about the
470
- # TPU execution, including any warnings, errors, or general activity of
471
- # the TPU driver. By default, the /tmp/tpu_logs directory is created with
472
- # 755 permissions, and the user of the provisioned pod is not necessarily
473
- # a root. Hence, we need to update the write permission so the logs can be
474
- # properly written.
475
- # TODO(Doyoung): Investigate to see why TPU workload fails to run without
476
- # execution permission, such as granting 766 to log file. Check if it's a
477
- # must and see if there's a workaround to grant minimum permission.
478
- - sudo chmod 777 /tmp/tpu_logs;
479
- {% endif %}
594
+ end_epoch=$(date +%s);
595
+ echo "=== Setup system configs and fuse completed in $(($end_epoch - $start_epoch)) secs ===";
596
+ for step in $STEPS; do [ -f "/tmp/${step}.failed" ] && { echo "Error: /tmp/${step}.failed found:"; cat /tmp/${step}.log; exit 1; } || true; done;
597
+ {% if tpu_requested %}
598
+ # The /tmp/tpu_logs directory is where TPU-related logs, such as logs from
599
+ # the TPU runtime, are written. These capture runtime information about the
600
+ # TPU execution, including any warnings, errors, or general activity of
601
+ # the TPU driver. By default, the /tmp/tpu_logs directory is created with
602
+ # 755 permissions, and the user of the provisioned pod is not necessarily
603
+ # a root. Hence, we need to update the write permission so the logs can be
604
+ # properly written.
605
+ # TODO(Doyoung): Investigate to see why TPU workload fails to run without
606
+ # execution permission, such as granting 766 to log file. Check if it's a
607
+ # must and see if there's a workaround to grant minimum permission.
608
+ sudo chmod 777 /tmp/tpu_logs;
609
+ {% endif %}
480
610
 
481
611
  # Format: `REMOTE_PATH : LOCAL_PATH`
482
612
  file_mounts: {
@@ -2,9 +2,10 @@
2
2
  from multiprocessing import pool
3
3
  import os
4
4
  import random
5
+ import resource
5
6
  import subprocess
6
7
  import time
7
- from typing import Any, Callable, Iterable, List, Optional, Tuple, Union
8
+ from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
8
9
 
9
10
  import colorama
10
11
  import psutil
@@ -18,6 +19,8 @@ from sky.utils import ux_utils
18
19
 
19
20
  logger = sky_logging.init_logger(__name__)
20
21
 
22
+ _fd_limit_warning_shown = False
23
+
21
24
 
22
25
  @timeline.event
23
26
  def run(cmd, **kwargs):
@@ -43,12 +46,54 @@ def run_no_outputs(cmd, **kwargs):
43
46
  **kwargs)
44
47
 
45
48
 
46
- def get_parallel_threads() -> int:
47
- """Returns the number of idle CPUs."""
49
+ def _get_thread_multiplier(cloud_str: Optional[str] = None) -> int:
50
+ # If using Kubernetes, we use 4x the number of cores.
51
+ if cloud_str and cloud_str.lower() == 'kubernetes':
52
+ return 4
53
+ return 1
54
+
55
+
56
+ def get_max_workers_for_file_mounts(common_file_mounts: Dict[str, str],
57
+ cloud_str: Optional[str] = None) -> int:
58
+ global _fd_limit_warning_shown
59
+ fd_limit, _ = resource.getrlimit(resource.RLIMIT_NOFILE)
60
+
61
+ # Raise warning for low fd_limit (only once)
62
+ if fd_limit < 1024 and not _fd_limit_warning_shown:
63
+ logger.warning(
64
+ f'Open file descriptor limit ({fd_limit}) is low. File sync to '
65
+ 'remote clusters may be slow. Consider increasing the limit using '
66
+ '`ulimit -n <number>` or modifying system limits.')
67
+ _fd_limit_warning_shown = True
68
+
69
+ fd_per_rsync = 5
70
+ for src in common_file_mounts.values():
71
+ if os.path.isdir(src):
72
+ # Assume that each file/folder under src takes 5 file descriptors
73
+ # on average.
74
+ fd_per_rsync = max(fd_per_rsync, len(os.listdir(src)) * 5)
75
+
76
+ # Reserve some file descriptors for the system and other processes
77
+ fd_reserve = 100
78
+
79
+ max_workers = (fd_limit - fd_reserve) // fd_per_rsync
80
+ # At least 1 worker, and avoid too many workers overloading the system.
81
+ num_threads = get_parallel_threads(cloud_str)
82
+ max_workers = min(max(max_workers, 1), num_threads)
83
+ logger.debug(f'Using {max_workers} workers for file mounts.')
84
+ return max_workers
85
+
86
+
87
+ def get_parallel_threads(cloud_str: Optional[str] = None) -> int:
88
+ """Returns the number of threads to use for parallel execution.
89
+
90
+ Args:
91
+ cloud_str: The cloud
92
+ """
48
93
  cpu_count = os.cpu_count()
49
94
  if cpu_count is None:
50
95
  cpu_count = 1
51
- return max(4, cpu_count - 1)
96
+ return max(4, cpu_count - 1) * _get_thread_multiplier(cloud_str)
52
97
 
53
98
 
54
99
  def run_in_parallel(func: Callable,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: skypilot-nightly
3
- Version: 1.0.0.dev20241121
3
+ Version: 1.0.0.dev20241122
4
4
  Summary: SkyPilot: An intercloud broker for the clouds
5
5
  Author: SkyPilot Team
6
6
  License: Apache 2.0
@@ -1,4 +1,4 @@
1
- sky/__init__.py,sha256=SCQV-Q-BPSS_Xa37LmEJ5zO8u_tBijR-C7U6m9OAVAQ,5882
1
+ sky/__init__.py,sha256=9rkn0Uy1cjIXtImEc_jmOOF1EEB5YgeBWSYeUlDzDmQ,5882
2
2
  sky/admin_policy.py,sha256=hPo02f_A32gCqhUueF0QYy1fMSSKqRwYEg_9FxScN_s,3248
3
3
  sky/authentication.py,sha256=pAdCT60OxxiXI9KXDyP2lQ9u9vMc6aMtq5Xi2h_hbdw,20984
4
4
  sky/check.py,sha256=D3Y3saIFAYVvPxuBHnVgJEO0fUVDxgjwuMBaO-D778k,9472
@@ -10,7 +10,7 @@ sky/exceptions.py,sha256=E3C2Ejcc8RUDAUQn7ar_Jr97C_AxD2rKKMmJOfLJ9d0,8965
10
10
  sky/execution.py,sha256=k6_n-kY1w93UVJZncQdNjqnil1aFIz5WGVwALNUCMqo,27458
11
11
  sky/global_user_state.py,sha256=ob3jvtG_yMPGvLlVScgeJ9pqk3FP4jhfEixw8WzFwho,29682
12
12
  sky/optimizer.py,sha256=GjvKQIBtY3NlULzau_9tfa7V2KYVJRrmNrjKVIWCPIQ,59753
13
- sky/resources.py,sha256=usmB8p7HyzyWHcevQ8HV6eIlukYJ9BC0trFOaE2kNuw,69049
13
+ sky/resources.py,sha256=260JnyzYz0uAYVH8lIfbHjSZUvHne8mfoWmjo_YgeEI,69106
14
14
  sky/sky_logging.py,sha256=oLmTmwkuucIto3LHXLJfMcyRpYSkmZAZa5XzQPA5IHk,4434
15
15
  sky/skypilot_config.py,sha256=E3g65cX3P3dT9b5N0GgFBG6yB0FXwIGpisKoozmJmWU,9094
16
16
  sky/status_lib.py,sha256=J7Jb4_Dz0v2T64ttOdyUgpokvl4S0sBJrMfH7Fvo51A,1457
@@ -30,8 +30,8 @@ sky/adaptors/runpod.py,sha256=4Nt_BfZhJAKQNA3wO8cxvvNI8x4NsDGHu_4EhRDlGYQ,225
30
30
  sky/adaptors/vsphere.py,sha256=zJP9SeObEoLrpgHW2VHvZE48EhgVf8GfAEIwBeaDMfM,2129
31
31
  sky/backends/__init__.py,sha256=UDjwbUgpTRApbPJnNfR786GadUuwgRk3vsWoVu5RB_c,536
32
32
  sky/backends/backend.py,sha256=wwfbrxPhjMPs6PSyy3tAHI8WJhl-xhgzWBsAZjmJJ6g,6249
33
- sky/backends/backend_utils.py,sha256=vese_H1lOFL40r-LPhjqqM8OlgICDgEW-YtNQ95cYs8,125608
34
- sky/backends/cloud_vm_ray_backend.py,sha256=aeb45nVxAqiku2AU66CRd9-UK4b9nqoZYSL8z2kYOnI,232706
33
+ sky/backends/backend_utils.py,sha256=_Kx8fp_inwxL8xf4I6HFWUGOZRT9edDM-2osaJaMlP0,126074
34
+ sky/backends/cloud_vm_ray_backend.py,sha256=BDpruXsj-u4wc3WYscLhIbSjjsNZ85iI7fkb-T8f2Bs,233321
35
35
  sky/backends/docker_utils.py,sha256=Hyw1YY20EyghhEbYx6O2FIMDcGkNzBzV9TM7LFynei8,8358
36
36
  sky/backends/local_docker_backend.py,sha256=0JL5m0YUgOmOL4aWEUe4tmt89dsxjk4_WXkPwgEKEis,16801
37
37
  sky/backends/wheel_utils.py,sha256=CUVOwlBtQjOMv-RSDGx2jMQ0M1D0w9ZPm0TDafJwBDI,8180
@@ -40,21 +40,21 @@ sky/benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  sky/benchmark/benchmark_state.py,sha256=X8CXmuU9KgsDRhKedhFgjeRMUFWtQsjFs1qECvPG2yg,8723
41
41
  sky/benchmark/benchmark_utils.py,sha256=eb-i6zYoo-Zkod-T9qtCu1FcYLw--Yyos1SyibUPZNE,26194
42
42
  sky/clouds/__init__.py,sha256=WuNIJEnZmBO72tU5awgaaL3rdvFRSkgaYNNeuY68dXo,1356
43
- sky/clouds/aws.py,sha256=um7-lam6BfYYgCvNAMsIY_Gty8wt8cOlCHsu3Ah3Od8,49616
44
- sky/clouds/azure.py,sha256=38eUcB1_lt5FvDWo-G_pKIIsT1c_bCU2AifEYo7KX9Y,30756
45
- sky/clouds/cloud.py,sha256=Y_9Hi2DhAbrqMLvb_NFPt--N5V6ua8BgbwV4xIc19KU,35216
43
+ sky/clouds/aws.py,sha256=mGXgTWU-XU8tQ3jkzHN80gu39REWQikHWeeOkTcb5SA,49644
44
+ sky/clouds/azure.py,sha256=KtnnNZn4ZEr7xndBHxX91v0YXSI1QWPgIefuM1zDUBA,30784
45
+ sky/clouds/cloud.py,sha256=NIODnzroLwMA3VJq3DOFt1voUoZJB8aielpDkX61iD0,35240
46
46
  sky/clouds/cloud_registry.py,sha256=oLoYFjm_SDTgdHokY7b6A5Utq80HXRQNxV0fLjDdVsQ,2361
47
- sky/clouds/cudo.py,sha256=UiY273Sln7VOYDYx93yWiWH_RLlOKZ2cm7mA31ld4A8,13094
48
- sky/clouds/fluidstack.py,sha256=ufve4wXo_VmaEkxqTw2Jnt-DORBDRnqUPU1kB_mD89s,12383
49
- sky/clouds/gcp.py,sha256=BjCehW3s0IYkRDdEEDm0vYWXQDpOV8KU98OMVRPnQNg,54676
50
- sky/clouds/ibm.py,sha256=w8bo1EIY_YWYNu0fy-OpAyr6DZviU0tpIXUsiV01rVE,21423
51
- sky/clouds/kubernetes.py,sha256=EuHD_xl5pbW2_9lPNuNdxss2X4DPbHnnD0VoiereshI,29590
52
- sky/clouds/lambda_cloud.py,sha256=ExL_uixdFrF9qSL5JYXpaOXCZ9_eOA2q444kcmBHBXQ,12644
53
- sky/clouds/oci.py,sha256=KAu32FFM3rB1Ngp8vJmVxxwNpmAmgrzTDV0FIof3MKI,26525
54
- sky/clouds/paperspace.py,sha256=4cjNua6jpuxmfidvLY4tSRX1oj_QaaHDinPMunGplyU,10868
55
- sky/clouds/runpod.py,sha256=_4myVdGIvQshkka8fn6mBXHgz5TZqhrNhAEM2_HrCT8,11487
56
- sky/clouds/scp.py,sha256=NivPvzQxA90R37QR3fgTup8ScGfxKsXAhH0xklAj5QU,15817
57
- sky/clouds/vsphere.py,sha256=ZzlcQBzv0aaRYXwZOrdKIGFK94LaOfDSV3lJBg9xyc4,12256
47
+ sky/clouds/cudo.py,sha256=mglcsoYhdWwgkVgFcoZLE0M_UCXOJkvW6nITufPd_BQ,13118
48
+ sky/clouds/fluidstack.py,sha256=u2I6jXEtTqgqRWi2EafMsKqc8VkUq1cR6CSDUvk72_U,12407
49
+ sky/clouds/gcp.py,sha256=RH3MMdgR3FWPiwm7rFrJ5oebtTcSUVoh7UfQMc_6U4A,54704
50
+ sky/clouds/ibm.py,sha256=0ArRTQx1_DpTNGByFhukzFedEDzmVjBsGiiques1bQ0,21447
51
+ sky/clouds/kubernetes.py,sha256=Kt2ymUvxE5FgoYx5V-shPHX28mCidj9uJtS1p3X0Yu4,31412
52
+ sky/clouds/lambda_cloud.py,sha256=42AmcN2X_wdBMuAw606nR_pQCBAy5QFiAo711_WRqDE,12672
53
+ sky/clouds/oci.py,sha256=OzGWoU3DiMbFujMQLXgCr94Oqb9EyP0CsM4gMYOeU9s,26553
54
+ sky/clouds/paperspace.py,sha256=0UxOcv_NaLY5hrFoAA_ZienclZUOqzf0yxXXZu4jXG0,10896
55
+ sky/clouds/runpod.py,sha256=UlHFPQY4wGGi0gLDO-vZoeJcgbQTCYXh4Pk8mKQBNUk,11515
56
+ sky/clouds/scp.py,sha256=JHyMqkAAqr9lJq79IVjj3rU1g-ZCCGLZTJEzIhYsw7c,15845
57
+ sky/clouds/vsphere.py,sha256=LzO-Mc-zDgpaDYZxNKGdEFa0eR5DHpTgKsPX60mPi10,12280
58
58
  sky/clouds/service_catalog/__init__.py,sha256=cFZ3HLdQVa42xOhK2XxuB_xPIX4X1UR89InR4y2y_78,14757
59
59
  sky/clouds/service_catalog/aws_catalog.py,sha256=j33lNC5GXWK6CiGWZORCnumGlRODmCAT2_lfWp0YtBc,13106
60
60
  sky/clouds/service_catalog/azure_catalog.py,sha256=5Q51x_WEKvQ2YSgJvZHRH3URlbwIstYuwpjaWW_wJlw,8149
@@ -107,10 +107,10 @@ sky/provision/__init__.py,sha256=rnuwL9x3qQGhX3EYW6KyZWfw_yBqGSiFBDz86T5xus4,633
107
107
  sky/provision/common.py,sha256=E8AlSUFcn0FYQq1erNmoVfMAdsF9tP2yxfyk-9PLvQU,10286
108
108
  sky/provision/constants.py,sha256=oc_XDUkcoLQ_lwDy5yMeMSWviKS0j0s1c0pjlvpNeWY,800
109
109
  sky/provision/docker_utils.py,sha256=l4AMzwXGZd8RyNq8AwOaKV9bFSofLYfSyj2NBhkXYsY,19200
110
- sky/provision/instance_setup.py,sha256=UBuVHjQ7f80un7aLY-kCLR0CCNVx-qIq1bh06nxuwJk,23050
110
+ sky/provision/instance_setup.py,sha256=8Pudbpke6ah0xufr2UwtsDnNZ64-aAYkz8M44ZA0huI,23218
111
111
  sky/provision/logging.py,sha256=yZWgejrFBhhRjAtvFu5N5bRXIMK5TuwNjp1vKQqz2pw,2103
112
112
  sky/provision/metadata_utils.py,sha256=LrxeV4wD2QPzNdXV_npj8q-pr35FatxBBjF_jSbpOT0,4013
113
- sky/provision/provisioner.py,sha256=mTvtBjS-Xz64LJcyeHx_-wdM8Gin8D49YRaV_TADaz4,25334
113
+ sky/provision/provisioner.py,sha256=REh4ajMIzFMJu4vAj81Qo9qAbJ7-3_5_IpzjBjo_MH0,29154
114
114
  sky/provision/aws/__init__.py,sha256=mxq8PeWJqUtalDozTNpbtENErRZ1ktEs8uf2aG9UUgU,731
115
115
  sky/provision/aws/config.py,sha256=dbwulPxXGIJjKJddv85PbtlXOjwLemaD65j3DISNsK0,24214
116
116
  sky/provision/aws/instance.py,sha256=eCslJ2XfJo_pkQMnKFQqhGnUIRvwKiT12oxBY5-klss,40750
@@ -137,10 +137,10 @@ sky/provision/gcp/instance_utils.py,sha256=veRBr6Oziv0KaUdC4acuWeaOremNV0gMYCCHa
137
137
  sky/provision/gcp/mig_utils.py,sha256=oFpcFZoapHMILSE4iIm8V5bxP1RhbMHRF7cciqq8qAk,7883
138
138
  sky/provision/kubernetes/__init__.py,sha256=y6yVfii81WYG3ROxv4hiIj-ydinS5-xGxLvXnARVQoI,719
139
139
  sky/provision/kubernetes/config.py,sha256=WEKcFXXhe89bLGAvoMiBvTDxdxkpTIA6ezrj2vmzldc,29072
140
- sky/provision/kubernetes/instance.py,sha256=BWgIb1bsxFeMOwN7RtE7nDI0aFPU_WtQq7iEuyq51nc,47111
140
+ sky/provision/kubernetes/instance.py,sha256=2zd_Z09amOsi0vPZjQYMJCkCWbN2YecMLL9HkmUuPrM,48414
141
141
  sky/provision/kubernetes/network.py,sha256=EpNjRQ131CXepqbdkoRKFu4szVrm0oKEpv1l8EgOkjU,12364
142
142
  sky/provision/kubernetes/network_utils.py,sha256=t1FS3K400fetH7cBuRgQJZl5_jEeMshsvsYmnMUcq8k,11399
143
- sky/provision/kubernetes/utils.py,sha256=4Gqn66jE0Nzs4UBjajfUM4E4mXWYnYzdhLz6SQG44Kg,101244
143
+ sky/provision/kubernetes/utils.py,sha256=5nzyD2d5sroM1ajB6M40IycuZX5OYiwzpb4hd4U6eS8,101291
144
144
  sky/provision/kubernetes/manifests/smarter-device-manager-configmap.yaml,sha256=AMzYzlY0JIlfBWj5eX054Rc1XDW2thUcLSOGMJVhIdA,229
145
145
  sky/provision/kubernetes/manifests/smarter-device-manager-daemonset.yaml,sha256=RtTq4F1QUmR2Uunb6zuuRaPhV7hpesz4saHjn3Ncsb4,2010
146
146
  sky/provision/lambda_cloud/__init__.py,sha256=6EEvSgtUeEiup9ivIFevHmgv0GqleroO2X0K7TRa2nE,612
@@ -194,7 +194,7 @@ sky/skylet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
194
194
  sky/skylet/attempt_skylet.py,sha256=GZ6ITjjA0m-da3IxXXfoHR6n4pjp3X3TOXUqVvSrV0k,2136
195
195
  sky/skylet/autostop_lib.py,sha256=JPDHmByuhoNYXSUHl-OnyeJUkOFWn7gDM1FrS7Kr3E8,4478
196
196
  sky/skylet/configs.py,sha256=UtnpmEL0F9hH6PSjhsps7xgjGZ6qzPOfW1p2yj9tSng,1887
197
- sky/skylet/constants.py,sha256=sQFbGSSiB4oAicMA_ctbtIo8FzaUSO1FGyQbMcuEnFA,14468
197
+ sky/skylet/constants.py,sha256=MtE7Tj3m2Fn_IMxifyxOxIT3KTM6tanszqNnU_tlop8,14872
198
198
  sky/skylet/events.py,sha256=A09E7LmmwzcGrSG0n8K7d3EZ1ZJr1mmmzoGyhnArYJA,12303
199
199
  sky/skylet/job_lib.py,sha256=Lfk3h-NLoi9mLo5-BPur43fUHVKMpa2hR5wEOCZGsB4,43846
200
200
  sky/skylet/log_lib.py,sha256=tFJXRb-DClFhUh6wQ45cSBNtBkdOZCGlVfwDnqKFRgE,20394
@@ -228,7 +228,7 @@ sky/templates/jobs-controller.yaml.j2,sha256=Gu3ogFxFYr09VEXP-6zEbrCUOFo1aYxWEjA
228
228
  sky/templates/kubernetes-ingress.yml.j2,sha256=73iDklVDWBMbItg0IexCa6_ClXPJOxw7PWz3leku4nE,1340
229
229
  sky/templates/kubernetes-loadbalancer.yml.j2,sha256=IxrNYM366N01bbkJEbZ_UPYxUP8wyVEbRNFHRsBuLsw,626
230
230
  sky/templates/kubernetes-port-forward-proxy-command.sh,sha256=HlG7CPBBedCVBlL9qv0erW_eKm6Irj0LFyaAWuJW_lc,3148
231
- sky/templates/kubernetes-ray.yml.j2,sha256=w7KNEBjj3zbd8RqWJuKwZSpQwMCdUAfUb7I7jNBn0XY,20672
231
+ sky/templates/kubernetes-ray.yml.j2,sha256=uymIxWyu7yHOL_G2XJZp0EiqHYtgbIJe4fZPXU6F1gc,28017
232
232
  sky/templates/kubernetes-ssh-jump.yml.j2,sha256=k5W5sOIMppU7dDkJMwPlqsUcb92y7L5_TVG3hkgMy8M,2747
233
233
  sky/templates/lambda-ray.yml.j2,sha256=HyvO_tX2vxwSsc4IFVSqGuIbjLMk0bevP9bcxb8ZQII,4498
234
234
  sky/templates/local-ray.yml.j2,sha256=FNHeyHF6nW9nU9QLIZceUWfvrFTTcO51KqhTnYCEFaA,1185
@@ -258,7 +258,7 @@ sky/utils/log_utils.py,sha256=oZYF45uC7GFjAqO-Je-aiX6zhtq91TP-KKaIbQNF-jY,14024
258
258
  sky/utils/resources_utils.py,sha256=Xqi7gxPYw2y5wl5okUI5zx5LEij0hJF_V3Zi8q7TXYg,7890
259
259
  sky/utils/rich_utils.py,sha256=hmnI1X5dKvRIQzB7EyNb34FT97qFNve-0QHqM5r0mVk,3066
260
260
  sky/utils/schemas.py,sha256=yz8IKUA2oWJartaranIc9MfDZmZcIybPZUGViw1Ii1Q,29475
261
- sky/utils/subprocess_utils.py,sha256=4pnt_QPvPuh3ylG5xlr18JlZeF6693h3fmG1uaD8qLo,8669
261
+ sky/utils/subprocess_utils.py,sha256=iLOda3vfkD-sIUPlfkDGZs9HnJWLlLRvHVgca9DZH8s,10410
262
262
  sky/utils/timeline.py,sha256=ebHxKJK2HX0utGArrUgSezTPkcwav3VETa_AQS34t-E,3925
263
263
  sky/utils/ux_utils.py,sha256=CqyIFGDuSE8fQasPkna_loZMwtboC9KedR09WEQ7qz0,6502
264
264
  sky/utils/validator.py,sha256=cAFERCoC7jH0DFKepcU4x9SYmdrYL1iVmW9tXA18hvo,701
@@ -275,9 +275,9 @@ sky/utils/kubernetes/k8s_gpu_labeler_job.yaml,sha256=k0TBoQ4zgf79-sVkixKSGYFHQ7Z
275
275
  sky/utils/kubernetes/k8s_gpu_labeler_setup.yaml,sha256=VLKT2KKimZu1GDg_4AIlIt488oMQvhRZWwsj9vBbPUg,3812
276
276
  sky/utils/kubernetes/rsync_helper.sh,sha256=hyYDaYSNxYaNvzUQBzC8AidB7nDeojizjkzc_CTxycY,1077
277
277
  sky/utils/kubernetes/ssh_jump_lifecycle_manager.py,sha256=RFLJ3k7MR5UN4SKHykQ0lV9SgXumoULpKYIAt1vh-HU,6560
278
- skypilot_nightly-1.0.0.dev20241121.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
279
- skypilot_nightly-1.0.0.dev20241121.dist-info/METADATA,sha256=2P9MAo9kQQSy6-t-MITf4Az4j2ucbnnlN6rE1V4aVxs,20222
280
- skypilot_nightly-1.0.0.dev20241121.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
281
- skypilot_nightly-1.0.0.dev20241121.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
282
- skypilot_nightly-1.0.0.dev20241121.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
283
- skypilot_nightly-1.0.0.dev20241121.dist-info/RECORD,,
278
+ skypilot_nightly-1.0.0.dev20241122.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
279
+ skypilot_nightly-1.0.0.dev20241122.dist-info/METADATA,sha256=zxomzD3shH_UFn3jG4yVym0RY1iIAqt0-9CYfrJauhU,20222
280
+ skypilot_nightly-1.0.0.dev20241122.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
281
+ skypilot_nightly-1.0.0.dev20241122.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
282
+ skypilot_nightly-1.0.0.dev20241122.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
283
+ skypilot_nightly-1.0.0.dev20241122.dist-info/RECORD,,