Repository: skypilot-org/skypilot
Pull request: [UX] Skip `STOPPED` cluster when calling `sky stop`
<!-- Describe the changes in this PR -->
Fixes #4090 

Simple fix to skip clusters that have `ClusterStatus.STOPPED`

<!-- Describe the tests ran -->
<!-- Unit tests (tests/test_*.py) are part of GitHub CI; below are tests that launch on the cloud. -->

Tested (run the relevant ones):

- [X] Code formatting: install pre-commit (auto-check on commit) or `bash format.sh`
- [X] Any manual or new tests for this PR (please specify below)
- [ ] All smoke tests: `/smoke-test` (CI) or `pytest tests/test_smoke.py` (local)
- [ ] Relevant individual tests: `/smoke-test -k test_name` (CI) or `pytest tests/test_smoke.py::test_name` (local)
- [ ] Backward compatibility: `/quicktest-core` (CI) or `pytest tests/smoke_tests/test_backward_compat.py` (local)

<!-- CI commands (/-prefixed) can only be triggered by repo members -->


Problem statement:
[UX] Skip `STOPPED` cluster when calling `sky stop`
<!-- Describe the bug report / feature request here -->

We should filter out those clusters in `STOPPED` status  when calling `sky stop`. e.g. for the example below, `sky stop -a` should only stop 2 clusters `lmf-l4-4-machine-image` and `lmf-gcp-l4-4`.

```bash
$ sky status
Clusters
NAME                    LAUNCHED     RESOURCES                                                                  STATUS   AUTOSTOP  COMMAND                        
lmf-l4-4-machine-image  14 mins ago  1x GCP(g2-standard-48, {'L4': 4}, image_id={'us-east4': 'projects/skyp...  UP       -         sky launch -c lmf-l4-4-ma...   
lmf-gcp-l4-4            31 mins ago  1x GCP(g2-standard-48, {'L4': 4})                                          UP       -         sky launch -c lmf-gcp-l4-4...  
lmf-machine-image       2 hrs ago    1x GCP(g2-standard-24, {'L4': 2}, image_id={'us-east4': 'projects/skyp...  STOPPED  -         sky launch -c lmf-machine...   
lmf-1-epoch             4 hrs ago    1x GCP(g2-standard-24, {'L4': 2})                                          STOPPED  -         sky launch -c lmf-1-epoch...   
lmf                     18 hrs ago   1x GCP(g2-standard-24, {'L4': 2})                                          STOPPED  -         sky start lmf                  
sky-344a-txia           1 month ago  1x Azure(Standard_NV18ads_A10_v5, {'A10': 0.5})                            STOPPED  -         sky exec sky-344a-txia sl...   

Managed jobs
No in-progress managed jobs. (See: sky jobs -h)

Services
No live services. (See: sky serve -h)
$ sky stop -a                     
Stopping 6 clusters: lmf-l4-4-machine-image, lmf-gcp-l4-4, lmf-machine-image, lmf-1-epoch, lmf, sky-344a-txia. Proceed? [Y/n]:
```

Hints from issue discussion:

Commit message: ignore condition when down

Patch to review:
diff --git a/sky/cli.py b/sky/cli.py
index 9a8ce8c7267..7d680dd5c45 100644
--- a/sky/cli.py
+++ b/sky/cli.py
@@ -3065,6 +3065,7 @@ def _down_or_stop_clusters(
             record['name']
             for record in all_clusters
             if controller_utils.Controllers.from_name(record['name']) is None
+            and (down or record['status'] != status_lib.ClusterStatus.STOPPED)
         ]
 
     clusters = names


Code review comments:
diff_hunk: @@ -3065,6 +3065,7 @@ def _down_or_stop_clusters(
             record['name']
             for record in all_clusters
             if controller_utils.Controllers.from_name(record['name']) is None
+            and (down or record['status'] != status_lib.ClusterStatus.STOPPED)
path: sky/cli.py
text: @user2:
```suggestion
             # do not select already stopped clusters if the action is to stop clusters.
             # stopped clusters are still included for down or autostop commands.
            and (down or idle_minutes_to_autostop is not None or record['status'] != status_lib.ClusterStatus.STOPPED)
```
i.e. I think we should still let (cancel) autostop/autodown operation to also act on stopped clusters - since those settings could apply when the cluster is brought back up again. I think this condition will do the job.
cc @user1 

@author:
done!