skypilot-nightly 1.0.0.dev2024053101__py3-none-any.whl → 1.0.0.dev2025022801__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/__init__.py +64 -32
- sky/adaptors/aws.py +23 -6
- sky/adaptors/azure.py +432 -15
- sky/adaptors/cloudflare.py +5 -5
- sky/adaptors/common.py +19 -9
- sky/adaptors/do.py +20 -0
- sky/adaptors/gcp.py +3 -2
- sky/adaptors/kubernetes.py +122 -88
- sky/adaptors/nebius.py +100 -0
- sky/adaptors/oci.py +39 -1
- sky/adaptors/vast.py +29 -0
- sky/admin_policy.py +101 -0
- sky/authentication.py +117 -98
- sky/backends/backend.py +52 -20
- sky/backends/backend_utils.py +669 -557
- sky/backends/cloud_vm_ray_backend.py +1099 -808
- sky/backends/local_docker_backend.py +14 -8
- sky/backends/wheel_utils.py +38 -20
- sky/benchmark/benchmark_utils.py +22 -23
- sky/check.py +76 -27
- sky/cli.py +1586 -1139
- sky/client/__init__.py +1 -0
- sky/client/cli.py +5683 -0
- sky/client/common.py +345 -0
- sky/client/sdk.py +1765 -0
- sky/cloud_stores.py +283 -19
- sky/clouds/__init__.py +7 -2
- sky/clouds/aws.py +303 -112
- sky/clouds/azure.py +185 -179
- sky/clouds/cloud.py +115 -37
- sky/clouds/cudo.py +29 -22
- sky/clouds/do.py +313 -0
- sky/clouds/fluidstack.py +44 -54
- sky/clouds/gcp.py +206 -65
- sky/clouds/ibm.py +26 -21
- sky/clouds/kubernetes.py +345 -91
- sky/clouds/lambda_cloud.py +40 -29
- sky/clouds/nebius.py +297 -0
- sky/clouds/oci.py +129 -90
- sky/clouds/paperspace.py +22 -18
- sky/clouds/runpod.py +53 -34
- sky/clouds/scp.py +28 -24
- sky/clouds/service_catalog/__init__.py +19 -13
- sky/clouds/service_catalog/aws_catalog.py +29 -12
- sky/clouds/service_catalog/azure_catalog.py +33 -6
- sky/clouds/service_catalog/common.py +95 -75
- sky/clouds/service_catalog/constants.py +3 -3
- sky/clouds/service_catalog/cudo_catalog.py +13 -3
- sky/clouds/service_catalog/data_fetchers/fetch_aws.py +36 -21
- sky/clouds/service_catalog/data_fetchers/fetch_azure.py +31 -4
- sky/clouds/service_catalog/data_fetchers/fetch_cudo.py +8 -117
- sky/clouds/service_catalog/data_fetchers/fetch_fluidstack.py +197 -44
- sky/clouds/service_catalog/data_fetchers/fetch_gcp.py +224 -36
- sky/clouds/service_catalog/data_fetchers/fetch_lambda_cloud.py +44 -24
- sky/clouds/service_catalog/data_fetchers/fetch_vast.py +147 -0
- sky/clouds/service_catalog/data_fetchers/fetch_vsphere.py +1 -1
- sky/clouds/service_catalog/do_catalog.py +111 -0
- sky/clouds/service_catalog/fluidstack_catalog.py +2 -2
- sky/clouds/service_catalog/gcp_catalog.py +16 -2
- sky/clouds/service_catalog/ibm_catalog.py +2 -2
- sky/clouds/service_catalog/kubernetes_catalog.py +192 -70
- sky/clouds/service_catalog/lambda_catalog.py +8 -3
- sky/clouds/service_catalog/nebius_catalog.py +116 -0
- sky/clouds/service_catalog/oci_catalog.py +31 -4
- sky/clouds/service_catalog/paperspace_catalog.py +2 -2
- sky/clouds/service_catalog/runpod_catalog.py +2 -2
- sky/clouds/service_catalog/scp_catalog.py +2 -2
- sky/clouds/service_catalog/vast_catalog.py +104 -0
- sky/clouds/service_catalog/vsphere_catalog.py +2 -2
- sky/clouds/utils/aws_utils.py +65 -0
- sky/clouds/utils/azure_utils.py +91 -0
- sky/clouds/utils/gcp_utils.py +5 -9
- sky/clouds/utils/oci_utils.py +47 -5
- sky/clouds/utils/scp_utils.py +4 -3
- sky/clouds/vast.py +280 -0
- sky/clouds/vsphere.py +22 -18
- sky/core.py +361 -107
- sky/dag.py +41 -28
- sky/data/data_transfer.py +37 -0
- sky/data/data_utils.py +211 -32
- sky/data/mounting_utils.py +182 -30
- sky/data/storage.py +2118 -270
- sky/data/storage_utils.py +126 -5
- sky/exceptions.py +179 -8
- sky/execution.py +158 -85
- sky/global_user_state.py +150 -34
- sky/jobs/__init__.py +12 -10
- sky/jobs/client/__init__.py +0 -0
- sky/jobs/client/sdk.py +302 -0
- sky/jobs/constants.py +49 -11
- sky/jobs/controller.py +161 -99
- sky/jobs/dashboard/dashboard.py +171 -25
- sky/jobs/dashboard/templates/index.html +572 -60
- sky/jobs/recovery_strategy.py +157 -156
- sky/jobs/scheduler.py +307 -0
- sky/jobs/server/__init__.py +1 -0
- sky/jobs/server/core.py +598 -0
- sky/jobs/server/dashboard_utils.py +69 -0
- sky/jobs/server/server.py +190 -0
- sky/jobs/state.py +627 -122
- sky/jobs/utils.py +615 -206
- sky/models.py +27 -0
- sky/optimizer.py +142 -83
- sky/provision/__init__.py +20 -5
- sky/provision/aws/config.py +124 -42
- sky/provision/aws/instance.py +130 -53
- sky/provision/azure/__init__.py +7 -0
- sky/{skylet/providers → provision}/azure/azure-config-template.json +19 -7
- sky/provision/azure/config.py +220 -0
- sky/provision/azure/instance.py +1012 -37
- sky/provision/common.py +31 -3
- sky/provision/constants.py +25 -0
- sky/provision/cudo/__init__.py +2 -1
- sky/provision/cudo/cudo_utils.py +112 -0
- sky/provision/cudo/cudo_wrapper.py +37 -16
- sky/provision/cudo/instance.py +28 -12
- sky/provision/do/__init__.py +11 -0
- sky/provision/do/config.py +14 -0
- sky/provision/do/constants.py +10 -0
- sky/provision/do/instance.py +287 -0
- sky/provision/do/utils.py +301 -0
- sky/provision/docker_utils.py +82 -46
- sky/provision/fluidstack/fluidstack_utils.py +57 -125
- sky/provision/fluidstack/instance.py +15 -43
- sky/provision/gcp/config.py +19 -9
- sky/provision/gcp/constants.py +7 -1
- sky/provision/gcp/instance.py +55 -34
- sky/provision/gcp/instance_utils.py +339 -80
- sky/provision/gcp/mig_utils.py +210 -0
- sky/provision/instance_setup.py +172 -133
- sky/provision/kubernetes/__init__.py +1 -0
- sky/provision/kubernetes/config.py +104 -90
- sky/provision/kubernetes/constants.py +8 -0
- sky/provision/kubernetes/instance.py +680 -325
- sky/provision/kubernetes/manifests/smarter-device-manager-daemonset.yaml +3 -0
- sky/provision/kubernetes/network.py +54 -20
- sky/provision/kubernetes/network_utils.py +70 -21
- sky/provision/kubernetes/utils.py +1370 -251
- sky/provision/lambda_cloud/__init__.py +11 -0
- sky/provision/lambda_cloud/config.py +10 -0
- sky/provision/lambda_cloud/instance.py +265 -0
- sky/{clouds/utils → provision/lambda_cloud}/lambda_utils.py +24 -23
- sky/provision/logging.py +1 -1
- sky/provision/nebius/__init__.py +11 -0
- sky/provision/nebius/config.py +11 -0
- sky/provision/nebius/instance.py +285 -0
- sky/provision/nebius/utils.py +318 -0
- sky/provision/oci/__init__.py +15 -0
- sky/provision/oci/config.py +51 -0
- sky/provision/oci/instance.py +436 -0
- sky/provision/oci/query_utils.py +681 -0
- sky/provision/paperspace/constants.py +6 -0
- sky/provision/paperspace/instance.py +4 -3
- sky/provision/paperspace/utils.py +2 -0
- sky/provision/provisioner.py +207 -130
- sky/provision/runpod/__init__.py +1 -0
- sky/provision/runpod/api/__init__.py +3 -0
- sky/provision/runpod/api/commands.py +119 -0
- sky/provision/runpod/api/pods.py +142 -0
- sky/provision/runpod/instance.py +64 -8
- sky/provision/runpod/utils.py +239 -23
- sky/provision/vast/__init__.py +10 -0
- sky/provision/vast/config.py +11 -0
- sky/provision/vast/instance.py +247 -0
- sky/provision/vast/utils.py +162 -0
- sky/provision/vsphere/common/vim_utils.py +1 -1
- sky/provision/vsphere/instance.py +8 -18
- sky/provision/vsphere/vsphere_utils.py +1 -1
- sky/resources.py +247 -102
- sky/serve/__init__.py +9 -9
- sky/serve/autoscalers.py +361 -299
- sky/serve/client/__init__.py +0 -0
- sky/serve/client/sdk.py +366 -0
- sky/serve/constants.py +12 -3
- sky/serve/controller.py +106 -36
- sky/serve/load_balancer.py +63 -12
- sky/serve/load_balancing_policies.py +84 -2
- sky/serve/replica_managers.py +42 -34
- sky/serve/serve_state.py +62 -32
- sky/serve/serve_utils.py +271 -160
- sky/serve/server/__init__.py +0 -0
- sky/serve/{core.py → server/core.py} +271 -90
- sky/serve/server/server.py +112 -0
- sky/serve/service.py +52 -16
- sky/serve/service_spec.py +95 -32
- sky/server/__init__.py +1 -0
- sky/server/common.py +430 -0
- sky/server/constants.py +21 -0
- sky/server/html/log.html +174 -0
- sky/server/requests/__init__.py +0 -0
- sky/server/requests/executor.py +472 -0
- sky/server/requests/payloads.py +487 -0
- sky/server/requests/queues/__init__.py +0 -0
- sky/server/requests/queues/mp_queue.py +76 -0
- sky/server/requests/requests.py +567 -0
- sky/server/requests/serializers/__init__.py +0 -0
- sky/server/requests/serializers/decoders.py +192 -0
- sky/server/requests/serializers/encoders.py +166 -0
- sky/server/server.py +1106 -0
- sky/server/stream_utils.py +141 -0
- sky/setup_files/MANIFEST.in +2 -5
- sky/setup_files/dependencies.py +159 -0
- sky/setup_files/setup.py +14 -125
- sky/sky_logging.py +59 -14
- sky/skylet/autostop_lib.py +2 -2
- sky/skylet/constants.py +183 -50
- sky/skylet/events.py +22 -10
- sky/skylet/job_lib.py +403 -258
- sky/skylet/log_lib.py +111 -71
- sky/skylet/log_lib.pyi +6 -0
- sky/skylet/providers/command_runner.py +6 -8
- sky/skylet/providers/ibm/node_provider.py +2 -2
- sky/skylet/providers/scp/config.py +11 -3
- sky/skylet/providers/scp/node_provider.py +8 -8
- sky/skylet/skylet.py +3 -1
- sky/skylet/subprocess_daemon.py +69 -17
- sky/skypilot_config.py +119 -57
- sky/task.py +205 -64
- sky/templates/aws-ray.yml.j2 +37 -7
- sky/templates/azure-ray.yml.j2 +27 -82
- sky/templates/cudo-ray.yml.j2 +7 -3
- sky/templates/do-ray.yml.j2 +98 -0
- sky/templates/fluidstack-ray.yml.j2 +7 -4
- sky/templates/gcp-ray.yml.j2 +26 -6
- sky/templates/ibm-ray.yml.j2 +3 -2
- sky/templates/jobs-controller.yaml.j2 +46 -11
- sky/templates/kubernetes-ingress.yml.j2 +7 -0
- sky/templates/kubernetes-loadbalancer.yml.j2 +7 -0
- sky/templates/{kubernetes-port-forward-proxy-command.sh.j2 → kubernetes-port-forward-proxy-command.sh} +51 -7
- sky/templates/kubernetes-ray.yml.j2 +292 -25
- sky/templates/lambda-ray.yml.j2 +30 -40
- sky/templates/nebius-ray.yml.j2 +79 -0
- sky/templates/oci-ray.yml.j2 +18 -57
- sky/templates/paperspace-ray.yml.j2 +10 -6
- sky/templates/runpod-ray.yml.j2 +26 -4
- sky/templates/scp-ray.yml.j2 +3 -2
- sky/templates/sky-serve-controller.yaml.j2 +12 -1
- sky/templates/skypilot-server-kubernetes-proxy.sh +36 -0
- sky/templates/vast-ray.yml.j2 +70 -0
- sky/templates/vsphere-ray.yml.j2 +8 -3
- sky/templates/websocket_proxy.py +64 -0
- sky/usage/constants.py +10 -1
- sky/usage/usage_lib.py +130 -37
- sky/utils/accelerator_registry.py +35 -51
- sky/utils/admin_policy_utils.py +147 -0
- sky/utils/annotations.py +51 -0
- sky/utils/cli_utils/status_utils.py +81 -23
- sky/utils/cluster_utils.py +356 -0
- sky/utils/command_runner.py +452 -89
- sky/utils/command_runner.pyi +77 -3
- sky/utils/common.py +54 -0
- sky/utils/common_utils.py +319 -108
- sky/utils/config_utils.py +204 -0
- sky/utils/control_master_utils.py +48 -0
- sky/utils/controller_utils.py +548 -266
- sky/utils/dag_utils.py +93 -32
- sky/utils/db_utils.py +18 -4
- sky/utils/env_options.py +29 -7
- sky/utils/kubernetes/create_cluster.sh +8 -60
- sky/utils/kubernetes/deploy_remote_cluster.sh +243 -0
- sky/utils/kubernetes/exec_kubeconfig_converter.py +73 -0
- sky/utils/kubernetes/generate_kubeconfig.sh +336 -0
- sky/utils/kubernetes/gpu_labeler.py +4 -4
- sky/utils/kubernetes/k8s_gpu_labeler_job.yaml +4 -3
- sky/utils/kubernetes/kubernetes_deploy_utils.py +228 -0
- sky/utils/kubernetes/rsync_helper.sh +24 -0
- sky/utils/kubernetes/ssh_jump_lifecycle_manager.py +1 -1
- sky/utils/log_utils.py +240 -33
- sky/utils/message_utils.py +81 -0
- sky/utils/registry.py +127 -0
- sky/utils/resources_utils.py +94 -22
- sky/utils/rich_utils.py +247 -18
- sky/utils/schemas.py +284 -64
- sky/{status_lib.py → utils/status_lib.py} +12 -7
- sky/utils/subprocess_utils.py +212 -46
- sky/utils/timeline.py +12 -7
- sky/utils/ux_utils.py +168 -15
- skypilot_nightly-1.0.0.dev2025022801.dist-info/METADATA +363 -0
- skypilot_nightly-1.0.0.dev2025022801.dist-info/RECORD +352 -0
- {skypilot_nightly-1.0.0.dev2024053101.dist-info → skypilot_nightly-1.0.0.dev2025022801.dist-info}/WHEEL +1 -1
- sky/clouds/cloud_registry.py +0 -31
- sky/jobs/core.py +0 -330
- sky/skylet/providers/azure/__init__.py +0 -2
- sky/skylet/providers/azure/azure-vm-template.json +0 -301
- sky/skylet/providers/azure/config.py +0 -170
- sky/skylet/providers/azure/node_provider.py +0 -466
- sky/skylet/providers/lambda_cloud/__init__.py +0 -2
- sky/skylet/providers/lambda_cloud/node_provider.py +0 -320
- sky/skylet/providers/oci/__init__.py +0 -2
- sky/skylet/providers/oci/node_provider.py +0 -488
- sky/skylet/providers/oci/query_helper.py +0 -383
- sky/skylet/providers/oci/utils.py +0 -21
- sky/utils/cluster_yaml_utils.py +0 -24
- sky/utils/kubernetes/generate_static_kubeconfig.sh +0 -137
- skypilot_nightly-1.0.0.dev2024053101.dist-info/METADATA +0 -315
- skypilot_nightly-1.0.0.dev2024053101.dist-info/RECORD +0 -275
- {skypilot_nightly-1.0.0.dev2024053101.dist-info → skypilot_nightly-1.0.0.dev2025022801.dist-info}/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev2024053101.dist-info → skypilot_nightly-1.0.0.dev2025022801.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev2024053101.dist-info → skypilot_nightly-1.0.0.dev2025022801.dist-info}/top_level.txt +0 -0
sky/data/mounting_utils.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
"""Helper functions for object store mounting in Sky Storage"""
|
2
2
|
import random
|
3
|
+
import shlex
|
3
4
|
import textwrap
|
4
5
|
from typing import Optional
|
5
6
|
|
@@ -13,6 +14,12 @@ _TYPE_CACHE_TTL = '5s'
|
|
13
14
|
_RENAME_DIR_LIMIT = 10000
|
14
15
|
# https://github.com/GoogleCloudPlatform/gcsfuse/releases
|
15
16
|
GCSFUSE_VERSION = '2.2.0'
|
17
|
+
# https://github.com/Azure/azure-storage-fuse/releases
|
18
|
+
BLOBFUSE2_VERSION = '2.2.0'
|
19
|
+
_BLOBFUSE_CACHE_ROOT_DIR = '~/.sky/blobfuse2_cache'
|
20
|
+
_BLOBFUSE_CACHE_DIR = ('~/.sky/blobfuse2_cache/'
|
21
|
+
'{storage_account_name}_{container_name}')
|
22
|
+
RCLONE_VERSION = 'v1.68.2'
|
16
23
|
|
17
24
|
|
18
25
|
def get_s3_mount_install_cmd() -> str:
|
@@ -24,12 +31,19 @@ def get_s3_mount_install_cmd() -> str:
|
|
24
31
|
return install_cmd
|
25
32
|
|
26
33
|
|
27
|
-
|
34
|
+
# pylint: disable=invalid-name
|
35
|
+
def get_s3_mount_cmd(bucket_name: str,
|
36
|
+
mount_path: str,
|
37
|
+
_bucket_sub_path: Optional[str] = None) -> str:
|
28
38
|
"""Returns a command to mount an S3 bucket using goofys."""
|
39
|
+
if _bucket_sub_path is None:
|
40
|
+
_bucket_sub_path = ''
|
41
|
+
else:
|
42
|
+
_bucket_sub_path = f':{_bucket_sub_path}'
|
29
43
|
mount_cmd = ('goofys -o allow_other '
|
30
44
|
f'--stat-cache-ttl {_STAT_CACHE_TTL} '
|
31
45
|
f'--type-cache-ttl {_TYPE_CACHE_TTL} '
|
32
|
-
f'{bucket_name} {mount_path}')
|
46
|
+
f'{bucket_name}{_bucket_sub_path} {mount_path}')
|
33
47
|
return mount_cmd
|
34
48
|
|
35
49
|
|
@@ -43,28 +57,110 @@ def get_gcs_mount_install_cmd() -> str:
|
|
43
57
|
return install_cmd
|
44
58
|
|
45
59
|
|
46
|
-
|
60
|
+
# pylint: disable=invalid-name
|
61
|
+
def get_gcs_mount_cmd(bucket_name: str,
|
62
|
+
mount_path: str,
|
63
|
+
_bucket_sub_path: Optional[str] = None) -> str:
|
47
64
|
"""Returns a command to mount a GCS bucket using gcsfuse."""
|
65
|
+
bucket_sub_path_arg = f'--only-dir {_bucket_sub_path} '\
|
66
|
+
if _bucket_sub_path else ''
|
48
67
|
mount_cmd = ('gcsfuse -o allow_other '
|
49
68
|
'--implicit-dirs '
|
50
69
|
f'--stat-cache-capacity {_STAT_CACHE_CAPACITY} '
|
51
70
|
f'--stat-cache-ttl {_STAT_CACHE_TTL} '
|
52
71
|
f'--type-cache-ttl {_TYPE_CACHE_TTL} '
|
53
72
|
f'--rename-dir-limit {_RENAME_DIR_LIMIT} '
|
73
|
+
f'{bucket_sub_path_arg}'
|
54
74
|
f'{bucket_name} {mount_path}')
|
55
75
|
return mount_cmd
|
56
76
|
|
57
77
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
78
|
+
def get_az_mount_install_cmd() -> str:
|
79
|
+
"""Returns a command to install AZ Container mount utility blobfuse2."""
|
80
|
+
install_cmd = ('sudo apt-get update; '
|
81
|
+
'sudo apt-get install -y '
|
82
|
+
'-o Dpkg::Options::="--force-confdef" '
|
83
|
+
'fuse3 libfuse3-dev && '
|
84
|
+
'wget -nc https://github.com/Azure/azure-storage-fuse'
|
85
|
+
f'/releases/download/blobfuse2-{BLOBFUSE2_VERSION}'
|
86
|
+
f'/blobfuse2-{BLOBFUSE2_VERSION}-Debian-11.0.x86_64.deb '
|
87
|
+
'-O /tmp/blobfuse2.deb && '
|
88
|
+
'sudo dpkg --install /tmp/blobfuse2.deb && '
|
89
|
+
f'mkdir -p {_BLOBFUSE_CACHE_ROOT_DIR};')
|
90
|
+
|
91
|
+
return install_cmd
|
92
|
+
|
93
|
+
|
94
|
+
# pylint: disable=invalid-name
|
95
|
+
def get_az_mount_cmd(container_name: str,
|
96
|
+
storage_account_name: str,
|
97
|
+
mount_path: str,
|
98
|
+
storage_account_key: Optional[str] = None,
|
99
|
+
_bucket_sub_path: Optional[str] = None) -> str:
|
100
|
+
"""Returns a command to mount an AZ Container using blobfuse2.
|
101
|
+
|
102
|
+
Args:
|
103
|
+
container_name: Name of the mounting container.
|
104
|
+
storage_account_name: Name of the storage account the given container
|
105
|
+
belongs to.
|
106
|
+
mount_path: Path where the container will be mounting.
|
107
|
+
storage_account_key: Access key for the given storage account.
|
108
|
+
_bucket_sub_path: Sub path of the mounting container.
|
109
|
+
|
110
|
+
Returns:
|
111
|
+
str: Command used to mount AZ container with blobfuse2.
|
112
|
+
"""
|
113
|
+
# Storage_account_key is set to None when mounting public container, and
|
114
|
+
# mounting public containers are not officially supported by blobfuse2 yet.
|
115
|
+
# Setting an empty SAS token value is a suggested workaround.
|
116
|
+
# https://github.com/Azure/azure-storage-fuse/issues/1338
|
117
|
+
if storage_account_key is None:
|
118
|
+
key_env_var = f'AZURE_STORAGE_SAS_TOKEN={shlex.quote(" ")}'
|
119
|
+
else:
|
120
|
+
key_env_var = ('AZURE_STORAGE_ACCESS_KEY='
|
121
|
+
f'{shlex.quote(storage_account_key)}')
|
122
|
+
|
123
|
+
cache_path = _BLOBFUSE_CACHE_DIR.format(
|
124
|
+
storage_account_name=storage_account_name,
|
125
|
+
container_name=container_name)
|
126
|
+
# The line below ensures the cache directory is new before mounting to
|
127
|
+
# avoid "config error in file_cache [temp directory not empty]" error, which
|
128
|
+
# can occur after stopping and starting the same cluster on Azure.
|
129
|
+
# This helps ensure a clean state for blobfuse2 operations.
|
130
|
+
remote_boot_time_cmd = 'date +%s -d "$(uptime -s)"'
|
131
|
+
if _bucket_sub_path is None:
|
132
|
+
bucket_sub_path_arg = ''
|
133
|
+
else:
|
134
|
+
bucket_sub_path_arg = f'--subdirectory={_bucket_sub_path}/ '
|
135
|
+
# TODO(zpoint): clear old cache that has been created in the previous boot.
|
136
|
+
mount_cmd = (f'AZURE_STORAGE_ACCOUNT={storage_account_name} '
|
137
|
+
f'{key_env_var} '
|
138
|
+
f'blobfuse2 {mount_path} --allow-other --no-symlinks '
|
139
|
+
'-o umask=022 -o default_permissions '
|
140
|
+
f'--tmp-path {cache_path}_$({remote_boot_time_cmd}) '
|
141
|
+
f'{bucket_sub_path_arg}'
|
142
|
+
f'--container-name {container_name}')
|
143
|
+
return mount_cmd
|
144
|
+
|
145
|
+
|
146
|
+
# pylint: disable=invalid-name
|
147
|
+
def get_r2_mount_cmd(r2_credentials_path: str,
|
148
|
+
r2_profile_name: str,
|
149
|
+
endpoint_url: str,
|
150
|
+
bucket_name: str,
|
151
|
+
mount_path: str,
|
152
|
+
_bucket_sub_path: Optional[str] = None) -> str:
|
61
153
|
"""Returns a command to install R2 mount utility goofys."""
|
154
|
+
if _bucket_sub_path is None:
|
155
|
+
_bucket_sub_path = ''
|
156
|
+
else:
|
157
|
+
_bucket_sub_path = f':{_bucket_sub_path}'
|
62
158
|
mount_cmd = (f'AWS_SHARED_CREDENTIALS_FILE={r2_credentials_path} '
|
63
159
|
f'AWS_PROFILE={r2_profile_name} goofys -o allow_other '
|
64
160
|
f'--stat-cache-ttl {_STAT_CACHE_TTL} '
|
65
161
|
f'--type-cache-ttl {_TYPE_CACHE_TTL} '
|
66
162
|
f'--endpoint {endpoint_url} '
|
67
|
-
f'{bucket_name} {mount_path}')
|
163
|
+
f'{bucket_name}{_bucket_sub_path} {mount_path}')
|
68
164
|
return mount_cmd
|
69
165
|
|
70
166
|
|
@@ -76,9 +172,12 @@ def get_cos_mount_install_cmd() -> str:
|
|
76
172
|
return install_cmd
|
77
173
|
|
78
174
|
|
79
|
-
def get_cos_mount_cmd(rclone_config_data: str,
|
80
|
-
|
81
|
-
|
175
|
+
def get_cos_mount_cmd(rclone_config_data: str,
|
176
|
+
rclone_config_path: str,
|
177
|
+
bucket_rclone_profile: str,
|
178
|
+
bucket_name: str,
|
179
|
+
mount_path: str,
|
180
|
+
_bucket_sub_path: Optional[str] = None) -> str:
|
82
181
|
"""Returns a command to mount an IBM COS bucket using rclone."""
|
83
182
|
# creates a fusermount soft link on older (<22) Ubuntu systems for
|
84
183
|
# rclone's mount utility.
|
@@ -90,14 +189,80 @@ def get_cos_mount_cmd(rclone_config_data: str, rclone_config_path: str,
|
|
90
189
|
'mkdir -p ~/.config/rclone/ && '
|
91
190
|
f'echo "{rclone_config_data}" >> '
|
92
191
|
f'{rclone_config_path}')
|
192
|
+
if _bucket_sub_path is None:
|
193
|
+
sub_path_arg = f'{bucket_name}/{_bucket_sub_path}'
|
194
|
+
else:
|
195
|
+
sub_path_arg = f'/{bucket_name}'
|
93
196
|
# --daemon will keep the mounting process running in the background.
|
94
197
|
mount_cmd = (f'{configure_rclone_profile} && '
|
95
198
|
'rclone mount '
|
96
|
-
f'{bucket_rclone_profile}:{
|
199
|
+
f'{bucket_rclone_profile}:{sub_path_arg} {mount_path} '
|
97
200
|
'--daemon')
|
98
201
|
return mount_cmd
|
99
202
|
|
100
203
|
|
204
|
+
def get_rclone_install_cmd() -> str:
|
205
|
+
""" RClone installation for both apt-get and rpm.
|
206
|
+
This would be common command.
|
207
|
+
"""
|
208
|
+
# pylint: disable=line-too-long
|
209
|
+
install_cmd = (
|
210
|
+
f'(which dpkg > /dev/null 2>&1 && (which rclone > /dev/null || (cd ~ > /dev/null'
|
211
|
+
f' && curl -O https://downloads.rclone.org/{RCLONE_VERSION}/rclone-{RCLONE_VERSION}-linux-amd64.deb'
|
212
|
+
f' && sudo dpkg -i rclone-{RCLONE_VERSION}-linux-amd64.deb'
|
213
|
+
f' && rm -f rclone-{RCLONE_VERSION}-linux-amd64.deb)))'
|
214
|
+
f' || (which rclone > /dev/null || (cd ~ > /dev/null'
|
215
|
+
f' && curl -O https://downloads.rclone.org/{RCLONE_VERSION}/rclone-{RCLONE_VERSION}-linux-amd64.rpm'
|
216
|
+
f' && sudo yum --nogpgcheck install rclone-{RCLONE_VERSION}-linux-amd64.rpm -y'
|
217
|
+
f' && rm -f rclone-{RCLONE_VERSION}-linux-amd64.rpm))')
|
218
|
+
return install_cmd
|
219
|
+
|
220
|
+
|
221
|
+
def get_oci_mount_cmd(mount_path: str, store_name: str, region: str,
|
222
|
+
namespace: str, compartment: str, config_file: str,
|
223
|
+
config_profile: str) -> str:
|
224
|
+
""" OCI specific RClone mount command for oci object storage. """
|
225
|
+
# pylint: disable=line-too-long
|
226
|
+
mount_cmd = (
|
227
|
+
f'sudo chown -R `whoami` {mount_path}'
|
228
|
+
f' && rclone config create oos_{store_name} oracleobjectstorage'
|
229
|
+
f' provider user_principal_auth namespace {namespace}'
|
230
|
+
f' compartment {compartment} region {region}'
|
231
|
+
f' oci-config-file {config_file}'
|
232
|
+
f' oci-config-profile {config_profile}'
|
233
|
+
f' && sed -i "s/oci-config-file/config_file/g;'
|
234
|
+
f' s/oci-config-profile/config_profile/g" ~/.config/rclone/rclone.conf'
|
235
|
+
f' && ([ ! -f /bin/fusermount3 ] && sudo ln -s /bin/fusermount /bin/fusermount3 || true)'
|
236
|
+
f' && (grep -q {mount_path} /proc/mounts || rclone mount oos_{store_name}:{store_name} {mount_path} --daemon --allow-non-empty)'
|
237
|
+
)
|
238
|
+
return mount_cmd
|
239
|
+
|
240
|
+
|
241
|
+
def get_rclone_version_check_cmd() -> str:
|
242
|
+
""" RClone version check. This would be common command. """
|
243
|
+
return f'rclone --version | grep -q {RCLONE_VERSION}'
|
244
|
+
|
245
|
+
|
246
|
+
def _get_mount_binary(mount_cmd: str) -> str:
|
247
|
+
"""Returns mounting binary in string given as the mount command.
|
248
|
+
|
249
|
+
Args:
|
250
|
+
mount_cmd: Command used to mount a cloud storage.
|
251
|
+
|
252
|
+
Returns:
|
253
|
+
str: Name of the binary used to mount a cloud storage.
|
254
|
+
"""
|
255
|
+
if 'goofys' in mount_cmd:
|
256
|
+
return 'goofys'
|
257
|
+
elif 'gcsfuse' in mount_cmd:
|
258
|
+
return 'gcsfuse'
|
259
|
+
elif 'blobfuse2' in mount_cmd:
|
260
|
+
return 'blobfuse2'
|
261
|
+
else:
|
262
|
+
assert 'rclone' in mount_cmd
|
263
|
+
return 'rclone'
|
264
|
+
|
265
|
+
|
101
266
|
def get_mounting_script(
|
102
267
|
mount_path: str,
|
103
268
|
mount_cmd: str,
|
@@ -121,8 +286,7 @@ def get_mounting_script(
|
|
121
286
|
Returns:
|
122
287
|
str: Mounting script as a str.
|
123
288
|
"""
|
124
|
-
|
125
|
-
mount_binary = mount_cmd.split()[0]
|
289
|
+
mount_binary = _get_mount_binary(mount_cmd)
|
126
290
|
installed_check = f'[ -x "$(command -v {mount_binary})" ]'
|
127
291
|
if version_check_cmd is not None:
|
128
292
|
installed_check += f' && {version_check_cmd}'
|
@@ -130,7 +294,7 @@ def get_mounting_script(
|
|
130
294
|
script = textwrap.dedent(f"""
|
131
295
|
#!/usr/bin/env bash
|
132
296
|
set -e
|
133
|
-
|
297
|
+
|
134
298
|
{command_runner.ALIAS_SUDO_TO_EMPTY_FOR_ROOT_CMD}
|
135
299
|
|
136
300
|
MOUNT_PATH={mount_path}
|
@@ -197,23 +361,11 @@ def get_mounting_command(
|
|
197
361
|
script = get_mounting_script(mount_path, mount_cmd, install_cmd,
|
198
362
|
version_check_cmd)
|
199
363
|
|
200
|
-
# TODO(romilb): Get direct bash script to work like so:
|
201
|
-
# command = f'bash <<-\EOL' \
|
202
|
-
# f'{script}' \
|
203
|
-
# 'EOL'
|
204
|
-
|
205
|
-
# TODO(romilb): This heredoc should have EOF after script, but it
|
206
|
-
# fails with sky's ssh pipeline. Instead, we don't use EOF and use )
|
207
|
-
# as the end of heredoc. This raises a warning (here-document delimited
|
208
|
-
# by end-of-file) that can be safely ignored.
|
209
|
-
|
210
364
|
# While these commands are run sequentially for each storage object,
|
211
365
|
# we add random int to be on the safer side and avoid collisions.
|
212
366
|
script_path = f'~/.sky/mount_{random.randint(0, 1000000)}.sh'
|
213
|
-
|
214
|
-
|
215
|
-
f'{
|
216
|
-
f'
|
217
|
-
f' && bash {script_path}'
|
218
|
-
f' && rm {script_path}')
|
367
|
+
command = (f'echo {shlex.quote(script)} > {script_path} && '
|
368
|
+
f'chmod +x {script_path} && '
|
369
|
+
f'bash {script_path} && '
|
370
|
+
f'rm {script_path}')
|
219
371
|
return command
|