Skip to content

Commit 62ac17a

Browse files
authored
Add yum check for rclone installation (#7740)
* Add yum check for rclone installation * smoke test for dpkg and yum for aws mount_cached mode * Add yum check for rclone installation * smoke test for dpkg and yum for aws mount_cached mode * install fuse3 if not exist before rclone mount
1 parent 1bf4f90 commit 62ac17a

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

sky/data/mounting_utils.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@
1717
_RENAME_DIR_LIMIT = 10000
1818
# https://github.com/GoogleCloudPlatform/gcsfuse/releases
1919
GCSFUSE_VERSION = '2.2.0'
20+
21+
# Some machines do not have fuse/fuse3 installed by default
22+
# hence rclone will fail on these machines
23+
FUSE3_INSTALL_CMD = ('(command -v fusermount3 > /dev/null 2>&1 || '
24+
'((which apt-get > /dev/null 2>&1 && '
25+
'sudo apt-get update && sudo apt-get install -y fuse3) || '
26+
'(which yum > /dev/null 2>&1 && '
27+
'sudo yum install -y fuse3) || '
28+
'true)) || true')
29+
2030
# Creates a fusermount3 soft link on older (<22) Ubuntu systems to utilize
2131
# Rclone's mounting utility.
2232
FUSERMOUNT3_SOFT_LINK_CMD = ('[ ! -f /bin/fusermount3 ] && '
@@ -54,10 +64,10 @@ def get_rclone_install_cmd() -> str:
5464
f' && curl -O https://downloads.rclone.org/{RCLONE_VERSION}/rclone-{RCLONE_VERSION}-linux-${{ARCH_SUFFIX}}.deb'
5565
f' && sudo dpkg -i rclone-{RCLONE_VERSION}-linux-${{ARCH_SUFFIX}}.deb'
5666
f' && rm -f rclone-{RCLONE_VERSION}-linux-${{ARCH_SUFFIX}}.deb)))'
57-
f' || (which rclone > /dev/null || (cd ~ > /dev/null'
67+
f' || (which yum > /dev/null 2>&1 && (which rclone > /dev/null || (cd ~ > /dev/null'
5868
f' && curl -O https://downloads.rclone.org/{RCLONE_VERSION}/rclone-{RCLONE_VERSION}-linux-${{ARCH_SUFFIX}}.rpm'
5969
f' && sudo yum --nogpgcheck install rclone-{RCLONE_VERSION}-linux-${{ARCH_SUFFIX}}.rpm -y'
60-
f' && rm -f rclone-{RCLONE_VERSION}-linux-${{ARCH_SUFFIX}}.rpm))')
70+
f' && rm -f rclone-{RCLONE_VERSION}-linux-${{ARCH_SUFFIX}}.rpm)))')
6171
return install_cmd
6272

6373

@@ -94,6 +104,7 @@ def get_s3_mount_cmd(bucket_name: str,
94104
# Use rclone for ARM64 architectures since goofys doesn't support them
95105
arch_check = 'ARCH=$(uname -m) && '
96106
rclone_mount = (
107+
f'{FUSE3_INSTALL_CMD} && '
97108
f'{FUSERMOUNT3_SOFT_LINK_CMD} && '
98109
f'rclone mount :s3:{bucket_name}{_bucket_sub_path} {mount_path} '
99110
# Have to add --s3-env-auth=true to allow rclone to access private
@@ -128,6 +139,7 @@ def get_nebius_mount_cmd(nebius_profile_name: str,
128139
# Use rclone for ARM64 architectures since goofys doesn't support them
129140
arch_check = 'ARCH=$(uname -m) && '
130141
rclone_mount = (
142+
f'{FUSE3_INSTALL_CMD} && '
131143
f'{FUSERMOUNT3_SOFT_LINK_CMD} && '
132144
f'AWS_PROFILE={nebius_profile_name} '
133145
f'rclone mount :s3:{bucket_name}{_bucket_sub_path} {mount_path} '
@@ -163,6 +175,7 @@ def get_coreweave_mount_cmd(cw_credentials_path: str,
163175
# Use rclone for ARM64 architectures since goofys doesn't support them
164176
arch_check = 'ARCH=$(uname -m) && '
165177
rclone_mount = (
178+
f'{FUSE3_INSTALL_CMD} && '
166179
f'{FUSERMOUNT3_SOFT_LINK_CMD} && '
167180
f'AWS_SHARED_CREDENTIALS_FILE={cw_credentials_path} '
168181
f'AWS_PROFILE={coreweave_profile_name} '
@@ -391,6 +404,7 @@ def get_r2_mount_cmd(r2_credentials_path: str,
391404
# Use rclone for ARM64 architectures since goofys doesn't support them
392405
arch_check = 'ARCH=$(uname -m) && '
393406
rclone_mount = (
407+
f'{FUSE3_INSTALL_CMD} && '
394408
f'{FUSERMOUNT3_SOFT_LINK_CMD} && '
395409
f'AWS_SHARED_CREDENTIALS_FILE={r2_credentials_path} '
396410
f'AWS_PROFILE={r2_profile_name} '
@@ -420,7 +434,8 @@ def get_cos_mount_cmd(rclone_config: str,
420434
_bucket_sub_path: Optional[str] = None) -> str:
421435
"""Returns a command to mount an IBM COS bucket using rclone."""
422436
# stores bucket profile in rclone config file at the cluster's nodes.
423-
configure_rclone_profile = (f'{FUSERMOUNT3_SOFT_LINK_CMD}; '
437+
configure_rclone_profile = (f'{FUSE3_INSTALL_CMD} && '
438+
f'{FUSERMOUNT3_SOFT_LINK_CMD}; '
424439
f'mkdir -p {constants.RCLONE_CONFIG_DIR} && '
425440
f'echo "{rclone_config}" >> '
426441
f'{constants.RCLONE_CONFIG_PATH}')
@@ -440,7 +455,8 @@ def get_mount_cached_cmd(rclone_config: str, rclone_profile_name: str,
440455
bucket_name: str, mount_path: str) -> str:
441456
"""Returns a command to mount a bucket using rclone with vfs cache."""
442457
# stores bucket profile in rclone config file at the remote nodes.
443-
configure_rclone_profile = (f'{FUSERMOUNT3_SOFT_LINK_CMD}; '
458+
configure_rclone_profile = (f'{FUSE3_INSTALL_CMD} && '
459+
f'{FUSERMOUNT3_SOFT_LINK_CMD}; '
444460
f'mkdir -p {constants.RCLONE_CONFIG_DIR} && '
445461
f'echo {shlex.quote(rclone_config)} >> '
446462
f'{constants.RCLONE_CONFIG_PATH}')

tests/smoke_tests/test_mount_and_storage.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,38 @@ def test_aws_storage_mounts_arm64():
310310
smoke_tests_utils.run_one_test(test)
311311

312312

313+
@pytest.mark.aws
314+
@pytest.mark.parametrize(
315+
'ami',
316+
[
317+
'ami-0f5fcdfbd140e4ab7', # dpkg
318+
'ami-0a5a5b7e2278263e5' # yum
319+
])
320+
def test_aws_storage_mounts_cached(ami: str):
321+
name = smoke_tests_utils.get_cluster_name()
322+
cloud = 'aws'
323+
storage_name = f'sky-test-{int(time.time())}'
324+
with tempfile.NamedTemporaryFile(suffix='.yaml', mode='w') as f1:
325+
with tempfile.NamedTemporaryFile(suffix='.yaml', mode='w') as f2:
326+
test_commands, clean_command = _storage_mount_cached_test_command_generator(
327+
f1, f2, name, storage_name, cloud)
328+
329+
for i, cmd in enumerate(test_commands):
330+
if cmd.startswith('sky launch') and '--infra aws' in cmd:
331+
test_commands[i] = cmd.replace(
332+
'--infra aws',
333+
f'--infra aws/us-east-2 --image-id {ami}')
334+
break
335+
336+
test = smoke_tests_utils.Test(
337+
'aws_storage_mount_cached',
338+
test_commands,
339+
clean_command,
340+
timeout=20 * 60, # 20 mins
341+
)
342+
smoke_tests_utils.run_one_test(test)
343+
344+
313345
@pytest.mark.aws
314346
def test_aws_storage_mounts_with_stop():
315347
name = smoke_tests_utils.get_cluster_name()

0 commit comments

Comments
 (0)