13
13
import tempfile
14
14
import textwrap
15
15
import time
16
- from typing import Any , Callable , Dict , List , Optional , Tuple , Union
16
+ from typing import Dict , List , Optional , Tuple , Union
17
17
18
18
import colorama
19
19
from rich import console as rich_console
34
34
35
35
Dag = dag_lib .Dag
36
36
OptimizeTarget = optimizer .OptimizeTarget
37
+ Path = str
37
38
Resources = resources_lib .Resources
38
39
Task = task_lib .Task
39
40
40
- Path = str
41
- PostSetupFn = Callable [[str ], Any ]
42
- SKY_DIRSIZE_WARN_THRESHOLD = 100
43
41
SKY_REMOTE_APP_DIR = backend_utils .SKY_REMOTE_APP_DIR
44
42
SKY_REMOTE_WORKDIR = backend_utils .SKY_REMOTE_WORKDIR
45
43
SKY_LOGS_DIRECTORY = job_lib .SKY_LOGS_DIRECTORY
49
47
logger = sky_logging .init_logger (__name__ )
50
48
console = rich_console .Console ()
51
49
50
+ _PATH_SIZE_MEGABYTES_WARN_THRESHOLD = 256
51
+
52
52
53
53
def _check_cluster_name_is_valid (cluster_name : str ) -> None :
54
54
"""Errors out on invalid cluster names not supported by cloud providers.
@@ -104,7 +104,7 @@ def _remove_cluster_from_ssh_config(cluster_ip: str,
104
104
105
105
106
106
def _path_size_megabytes (path : str ) -> int :
107
- # Returns the size of files occupied in path in megabytes
107
+ """ Returns the size of 'path' (directory or file) in megabytes."""
108
108
return int (
109
109
subprocess .check_output (['du' , '-sh' , '-m' ,
110
110
path ]).split ()[0 ].decode ('utf-8' ))
@@ -1128,22 +1128,24 @@ def sync_workdir(self, handle: ResourceHandle, workdir: Path) -> None:
1128
1128
ip_list = self ._get_node_ips (handle .cluster_yaml , handle .launched_nodes )
1129
1129
full_workdir = os .path .abspath (os .path .expanduser (workdir ))
1130
1130
1131
- # Raise warning if directory is too large
1132
- if not os .path .exists (full_workdir ):
1133
- logger .error (f'{ fore .RED } Workdir { workdir } does not exist.'
1134
- f'{ style .RESET_ALL } ' )
1135
- sys .exit (1 )
1136
- dir_size = _path_size_megabytes (full_workdir )
1137
- if dir_size >= SKY_DIRSIZE_WARN_THRESHOLD :
1138
- logger .warning (f'{ fore .YELLOW } The size of workdir { workdir } '
1139
- f'is { dir_size } MB. Try to keep workdir small, as '
1140
- f'large sizes will slowdown rsync.{ style .RESET_ALL } ' )
1131
+ # These asserts have been validated at Task construction time.
1132
+ assert os .path .exists (full_workdir ), f'{ full_workdir } does not exist'
1141
1133
if os .path .islink (full_workdir ):
1142
1134
logger .warning (
1143
- f'{ fore .YELLOW } Workdir { workdir } is a symlink. '
1135
+ f'{ fore .YELLOW } Workdir { workdir !r } is a symlink. '
1144
1136
f'Symlink contents are not uploaded.{ style .RESET_ALL } ' )
1145
1137
else :
1146
- workdir = f'{ workdir } /'
1138
+ assert os .path .isdir (
1139
+ full_workdir ), f'{ full_workdir } should be a directory.'
1140
+ workdir = os .path .join (workdir , '' ) # Adds trailing / if needed.
1141
+
1142
+ # Raise warning if directory is too large
1143
+ dir_size = _path_size_megabytes (full_workdir )
1144
+ if dir_size >= _PATH_SIZE_MEGABYTES_WARN_THRESHOLD :
1145
+ logger .warning (
1146
+ f'{ fore .YELLOW } The size of workdir { workdir !r} '
1147
+ f'is { dir_size } MB. Try to keep workdir small, as '
1148
+ f'large sizes will slow down rsync.{ style .RESET_ALL } ' )
1147
1149
1148
1150
def _sync_workdir_node (ip ):
1149
1151
self ._rsync_up (handle ,
@@ -1157,8 +1159,11 @@ def _sync_workdir_node(ip):
1157
1159
1158
1160
num_nodes = handle .launched_nodes
1159
1161
plural = 's' if num_nodes > 1 else ''
1160
- logger .info (f'{ fore .CYAN } Syncing (on { num_nodes } node{ plural } ): '
1161
- f'{ style .BRIGHT } workdir ({ workdir } ){ style .RESET_ALL } .' )
1162
+ logger .info (
1163
+ f'{ fore .CYAN } Syncing workdir (to { num_nodes } node{ plural } ): '
1164
+ f'{ style .BRIGHT } { workdir } { style .RESET_ALL } '
1165
+ f' -> '
1166
+ f'{ style .BRIGHT } { SKY_REMOTE_WORKDIR } { style .RESET_ALL } ' )
1162
1167
with console .status ('[bold cyan]Syncing[/]' ):
1163
1168
backend_utils .run_in_parallel (_sync_workdir_node , ip_list )
1164
1169
@@ -1192,9 +1197,13 @@ def sync_to_all_nodes(src: str,
1192
1197
dst : str ,
1193
1198
command : Optional [str ] = None ,
1194
1199
run_rsync : Optional [bool ] = False ):
1195
- full_src = os .path .abspath (os .path .expanduser (src ))
1196
- if not os .path .islink (full_src ) and not os .path .isfile (full_src ):
1197
- src = f'{ src } /'
1200
+ if run_rsync :
1201
+ # Do this for local src paths, not for cloud store URIs
1202
+ # (otherwise we have '<abs path to cwd>/gs://.../object/').
1203
+ full_src = os .path .abspath (os .path .expanduser (src ))
1204
+ if not os .path .islink (full_src ) and not os .path .isfile (
1205
+ full_src ):
1206
+ src = os .path .join (src , '' ) # Adds trailing / if needed.
1198
1207
1199
1208
def _sync_node (ip ):
1200
1209
if command is not None :
@@ -1225,28 +1234,27 @@ def _sync_node(ip):
1225
1234
1226
1235
num_nodes = handle .launched_nodes
1227
1236
plural = 's' if num_nodes > 1 else ''
1228
- logger .info (f'{ fore .CYAN } Syncing (on { num_nodes } node{ plural } ): '
1229
- f'{ style .BRIGHT } { src } -> { dst } { style .RESET_ALL } ' )
1237
+ logger .info (f'{ fore .CYAN } Syncing (to { num_nodes } node{ plural } ): '
1238
+ f'{ style .BRIGHT } { src } { style .RESET_ALL } -> '
1239
+ f'{ style .BRIGHT } { dst } { style .RESET_ALL } ' )
1230
1240
with console .status ('[bold cyan]Syncing[/]' ):
1231
1241
backend_utils .run_in_parallel (_sync_node , ip_list )
1232
1242
1233
1243
# Check the files and warn
1234
1244
for dst , src in mounts .items ():
1235
1245
if not task_lib .is_cloud_store_url (src ):
1236
1246
full_src = os .path .abspath (os .path .expanduser (src ))
1237
- if not os .path .exists (full_src ):
1238
- logger .error (f'{ fore .RED } Directory "{ src } " does not exist.'
1239
- f'{ style .RESET_ALL } ' )
1240
- sys .exit (1 )
1247
+ # Checked during Task.set_file_mounts().
1248
+ assert os .path .exists (full_src ), f'{ full_src } does not exist.'
1241
1249
src_size = _path_size_megabytes (full_src )
1242
- if src_size >= SKY_DIRSIZE_WARN_THRESHOLD :
1250
+ if src_size >= _PATH_SIZE_MEGABYTES_WARN_THRESHOLD :
1243
1251
logger .warning (
1244
- f'{ fore .YELLOW } The size of file mount src { src } '
1252
+ f'{ fore .YELLOW } The size of file mount src { src !r } '
1245
1253
f'is { src_size } MB. Try to keep src small, as '
1246
1254
f'large sizes will slow down rsync.{ style .RESET_ALL } ' )
1247
1255
if os .path .islink (full_src ):
1248
1256
logger .warning (
1249
- f'{ fore .YELLOW } Source path { src } is a symlink. '
1257
+ f'{ fore .YELLOW } Source path { src !r } is a symlink. '
1250
1258
f'Symlink contents are not uploaded.{ style .RESET_ALL } ' )
1251
1259
1252
1260
for dst , src in mounts .items ():
0 commit comments