@@ -1227,11 +1227,15 @@ def launch(
1227
1227
clusters = [handle .get_cluster_name ()])
1228
1228
# job_id will be None if no job was submitted (e.g. no entrypoint
1229
1229
# provided)
1230
+ returncode = 0
1230
1231
if not detach_run and job_id is not None :
1231
- sdk .tail_logs (handle .get_cluster_name (), job_id , follow = True )
1232
+ returncode = sdk .tail_logs (handle .get_cluster_name (),
1233
+ job_id ,
1234
+ follow = True )
1232
1235
click .secho (
1233
1236
ux_utils .command_hint_messages (ux_utils .CommandHintType .CLUSTER_JOB ,
1234
1237
job_id , handle .get_cluster_name ()))
1238
+ sys .exit (returncode )
1235
1239
1236
1240
1237
1241
@cli .command (cls = _DocumentedCodeCommand )
@@ -1377,7 +1381,8 @@ def exec(cluster: Optional[str], cluster_option: Optional[str],
1377
1381
job_id_handle = _async_call_or_wait (request_id , async_call , 'sky.exec' )
1378
1382
if not async_call and not detach_run :
1379
1383
job_id , _ = job_id_handle
1380
- sdk .tail_logs (cluster , job_id , follow = True )
1384
+ returncode = sdk .tail_logs (cluster , job_id , follow = True )
1385
+ sys .exit (returncode )
1381
1386
1382
1387
1383
1388
def _handle_jobs_queue_request (
@@ -2121,12 +2126,20 @@ def logs(
2121
2126
one job_id can be provided.
2122
2127
2123
2128
2. If ``--status`` is specified, print the status of the job and exit with
2124
- returncode 0 if the job succeeded, or 1 otherwise. At most one job_id can
2125
- be specified.
2129
+ returncode 0 if the job succeeded. At most one job_id can
2130
+ be specified. Other possible return codes:
2131
+
2132
+ - 100: job failed.
2133
+ - 101: job not finished.
2134
+ - 102: job not found.
2135
+ - 103: job was cancelled by the user.
2126
2136
2127
2137
3. If ``--sync-down`` is specified, the logs of the job will be downloaded
2128
2138
from the cluster and saved to the local machine under
2129
- ``~/sky_logs``. Mulitple job_ids can be specified.
2139
+ ``~/sky_logs``. Multiple job_ids can be specified.
2140
+
2141
+ 4. If the job fails or fetching the logs fails, the command will exit with
2142
+ a non-zero return code.
2130
2143
"""
2131
2144
if sync_down and status :
2132
2145
raise click .UsageError (
@@ -2174,17 +2187,18 @@ def logs(
2174
2187
# it will return {None: None}.
2175
2188
if job_id is None :
2176
2189
click .secho (f'No job found on cluster { cluster !r} .' , fg = 'red' )
2177
- sys .exit (1 )
2190
+ sys .exit (exceptions . JobExitCode . NOT_FOUND )
2178
2191
job_status = list (job_statuses .values ())[0 ]
2179
2192
job_status_str = job_status .value if job_status is not None else 'None'
2180
2193
click .echo (f'Job { job_id } : { job_status_str } ' )
2181
2194
if job_status == job_lib .JobStatus .SUCCEEDED :
2182
2195
return
2183
2196
else :
2197
+ returncode = exceptions .JobExitCode .from_job_status (job_status )
2184
2198
if job_status is None :
2185
2199
id_str = '' if job_id is None else f'{ job_id } '
2186
2200
click .secho (f'Job { id_str } not found' , fg = 'red' )
2187
- sys .exit (1 )
2201
+ sys .exit (returncode )
2188
2202
2189
2203
job_str = f'job { job_id } '
2190
2204
if job_id is None :
@@ -2194,7 +2208,8 @@ def logs(
2194
2208
f'{ colorama .Style .RESET_ALL } ' )
2195
2209
2196
2210
# Stream logs from the server.
2197
- sdk .tail_logs (cluster , job_id , follow , tail = tail )
2211
+ returncode = sdk .tail_logs (cluster , job_id , follow , tail = tail )
2212
+ sys .exit (returncode )
2198
2213
2199
2214
2200
2215
@cli .command ()
@@ -3893,10 +3908,11 @@ def jobs_launch(
3893
3908
'sky.jobs.launch' )
3894
3909
if not async_call and not detach_run :
3895
3910
job_id = job_id_handle [0 ]
3896
- managed_jobs .tail_logs (name = None ,
3897
- job_id = job_id ,
3898
- follow = True ,
3899
- controller = False )
3911
+ returncode = managed_jobs .tail_logs (name = None ,
3912
+ job_id = job_id ,
3913
+ follow = True ,
3914
+ controller = False )
3915
+ sys .exit (returncode )
3900
3916
3901
3917
3902
3918
@jobs .command ('queue' , cls = _DocumentedCodeCommand )
@@ -4127,11 +4143,12 @@ def jobs_logs(name: Optional[str], job_id: Optional[int], follow: bool,
4127
4143
logger .info (f'{ fore .CYAN } Job { job } logs{ controller_str } : '
4128
4144
f'{ log_local_path } { style .RESET_ALL } ' )
4129
4145
else :
4130
- managed_jobs .tail_logs (name = name ,
4131
- job_id = job_id ,
4132
- follow = follow ,
4133
- controller = controller ,
4134
- refresh = refresh )
4146
+ returncode = managed_jobs .tail_logs (name = name ,
4147
+ job_id = job_id ,
4148
+ follow = follow ,
4149
+ controller = controller ,
4150
+ refresh = refresh )
4151
+ sys .exit (returncode )
4135
4152
except exceptions .ClusterNotUpError :
4136
4153
with ux_utils .print_exception_no_traceback ():
4137
4154
raise
0 commit comments