Skip to content

[Core] Add sky debug-dump command for troubleshooting#8868

Merged
cg505 merged 91 commits into
skypilot-org:masterfrom
cg505:debug-dump
Mar 30, 2026
Merged

[Core] Add sky debug-dump command for troubleshooting#8868
cg505 merged 91 commits into
skypilot-org:masterfrom
cg505:debug-dump

Conversation

@cg505

@cg505 cg505 commented Feb 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a new sky debug-dump command that creates a comprehensive zip archive for troubleshooting SkyPilot issues. The dump collects server state, logs, and configuration into a single downloadable file, making it easy for users to share debugging information with the SkyPilot team.

What gets collected:

  • Server info: SkyPilot version, API version, Python/platform info, cloud credentials status, enabled clouds, SKYPILOT_*/SKY_* environment variables (sensitive values redacted)
  • Client info: Client-side version, config, and environment
  • Request history: API request logs with statuses and errors
  • Cluster state: Cluster records, events, status, SSH logs, and provisioning logs
  • Managed jobs: Job records, events, controller logs (fetched from controller via rsync), and cross-linked request history
  • Errors: Any collection errors are tracked and included in the dump rather than failing the whole operation

Targeting options (at least one required):

  • --cluster-names / -c: Specific clusters
  • --job-ids / -j: Specific managed job IDs
  • --request-ids / -r: Specific API request IDs
  • --recent-minutes N: Everything active within the last N minutes

Architecture:

  • Server-side: sky/utils/debug_utils.py orchestrates the dump, collecting data from the DB and cluster/controller logs
  • Controller-side: sky/jobs/utils.py:collect_debug_dump_manifest() runs on managed job controllers to gather job-specific data (DB records inline, log file paths for rsync)
  • Client-side: SDK sends client info with the request, then downloads the resulting zip
  • Shared helpers in sky/utils/debug_dump_helpers.py avoid circular imports between debug_utils and jobs.utils

Security:

  • Debug dump endpoints require admin role (added to RBAC blocklist)
  • Sensitive env vars (SKYPILOT_DB_CONNECTION_URI, SKYPILOT_INITIAL_BASIC_AUTH, etc.) are redacted to true/false
  • last_creation_yaml and user_yaml are redacted (secrets, Docker passwords)
  • Request bodies are allowlisted and task/dag YAML fields are redacted
  • Path traversal protection on both the download endpoint (resolve().relative_to()) and manifest processing
  • Download endpoint checks path traversal before file existence to avoid information leaks
  • Stack traces captured in all error handlers for easier debugging

Test plan

Unit tests (tests/unit_tests/test_sky/utils/test_debug_utils.py):

  • Context population from request IDs, cluster names, job IDs, and --recent
  • Cross-linking between requests, clusters, and managed jobs (including return_value matching)
  • RequestTaskFilter.finished_after SQL generation
  • Manifest path traversal validation (inline data + rsync targets)
  • Sensitive env var redaction
  • last_creation_yaml redaction in serialize_cluster_record
  • Individual dump component functions (server info, cluster info, request info, managed jobs)
  • _dump_request_id_info: happy path, not-found, DB failure, log file copying
  • _dump_cluster_info: happy path, not-found, DB failure, events, associated requests

Smoke tests (tests/smoke_tests/test_cli.py):

  • CLI validation (missing args, negative --recent)
  • End-to-end dump creation and download (--recent, -c, -r, -j)
  • Nonexistent resource IDs produce valid dump with errors
  • Zip contents verification

Manual testing:

sky api stop && sky api start

# Basic dump
sky debug-dump --recent 1
unzip -l <output.zip>

# Validation
sky debug-dump --recent -1   # → usage error
sky debug-dump --recent 0    # → usage error

# Cluster-specific
sky debug-dump -c <cluster-name>

# Nonexistent resources (should succeed with empty results)
sky debug-dump -c nonexistent -r nonexistent

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

Review detail

close review: all changes in sky/ except sky/utils/debug_utils.py and sky/utils/debug_dump_helpers.py

quick check:

  • new functions in sky/jobs/utils.py
  • sky/utils/debug_utils.py (new file)
  • sky/utils/debug_dump_helpers.py (new file)
  • tests

cg505 and others added 7 commits January 13, 2026 12:01
Add `sky debug-dump` command to collect diagnostic information for
troubleshooting SkyPilot issues. Creates a zip file containing logs,
state, and configuration for specified clusters, requests, and/or
managed jobs.

Key implementation decisions:

1. Persistent storage: Debug dumps are stored in ~/.sky/debug_dumps/
   rather than temp directories to allow re-downloading and prevent
   accidental deletion. This fixed a bug in the skeleton where the
   zip was created inside tempdir() context but returned after exit.

2. Cross-linking: When dumping a cluster, we automatically include
   associated requests, and vice versa. This ensures complete context
   without requiring users to manually specify all related resources.

3. --recent flag: Added `--recent N` option to dump all resources
   active within the last N hours, making it easy to capture recent
   activity without knowing specific IDs.

4. Server-side collection: Dumps are created on the API server and
   downloaded to the client, ensuring access to server-side logs and
   state even for remote API server deployments.

5. Graceful degradation: Each collection function catches exceptions
   and continues, creating partial dumps when some data is unavailable.

6. Debug logging: Added comprehensive debug logs throughout the dump
   flow to help troubleshoot issues with debug-dump itself.

Files changed:
- sky/utils/debug_utils.py: Core dump logic with 8 collection functions
- sky/server/server.py: /debug/dump-download and /debug/dump-list endpoints
- sky/client/sdk.py: create_debug_dump, download_debug_dump, list_debug_dumps
- sky/client/cli/command.py: `sky debug-dump` command with full CLI
- sky/core.py: Updated create_debug_dump with recent_hours param
- sky/server/requests/payloads.py: Added recent_hours to request body

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bump API_VERSION to 27 and add @versions.minimal_api_version(27)
decorator to all debug dump SDK functions. This ensures users get
a clear error message if they try to use these new functions against
an older server that doesn't support the debug dump endpoints.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Simplify debug dump lifecycle with 1:1 create-download model:
- Delete dump file automatically after successful download using
  starlette BackgroundTask
- Remove list_debug_dumps SDK function and /debug/dump-list endpoint
  since dumps are ephemeral and don't accumulate

This avoids the need for a separate cleanup/retention policy.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Include a summary file at the root of each debug dump containing:
- requested: Original input parameters (request_ids, cluster_names,
  managed_job_ids, recent_hours)
- collected: What was actually gathered after cross-linking, including
  counts and full lists of IDs/names
- timing: Elapsed time and timestamp

This helps users quickly understand the scope of the dump without
manually inspecting each subdirectory.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Include client_info.json in debug dumps with:
- SkyPilot version and commit
- Python version and platform
- User hash
- Environment variables (SKYPILOT_DEBUG, SKYPILOT_DEV)
- User config and merged config (with API endpoints redacted)

The client gathers this info and sends it to the server in the
request payload. This helps diagnose issues where client and server
environments differ (e.g., remote API server scenarios).

API endpoints in config are replaced with "<redacted>" to avoid
exposing HTTP basic auth credentials or other sensitive info.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add SYSTEM_REQUEST_IDS constant and automatically include these
requests in every debug dump:
- skypilot-status-refresh-daemon
- skypilot-volume-status-refresh-daemon
- skypilot-server-on-boot-check

These system requests are relevant for troubleshooting regardless
of which specific resources the user requested to dump.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @cg505, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new debug-dump command and associated backend infrastructure to enable users to generate comprehensive debug archives for troubleshooting SkyPilot issues. It allows for flexible specification of resources (requests, clusters, jobs, or recent activity) to include in the dump, which is then created on the server and can be downloaded by the client. This feature significantly enhances diagnostic capabilities by centralizing relevant logs, state, and configuration information.

Highlights

  • New debug-dump CLI command: A new command sky debug-dump is introduced, allowing users to create a zip file containing logs, state, and configuration for troubleshooting.
  • Flexible targeting for debug dumps: The debug-dump command supports targeting by request IDs, cluster names, managed job IDs, or resources active within a recent time window.
  • Client-side SDK integration: New SDK functions create_debug_dump and download_debug_dump are added to facilitate the creation and retrieval of debug dumps from the SkyPilot server.
  • Server-side API endpoints: Corresponding API endpoints /debug/dump-create (POST) and /debug/dump-download/{dump_filename} (GET) are added to the SkyPilot server to handle debug dump requests and serve the generated files.
  • Comprehensive data collection: The debug dump utility collects server info, request logs and metadata, cluster state and events, and managed job state and logs, including cross-linking related resources.
  • API Version Bump: The API version is incremented from 26 to 27 to reflect the new API changes.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • sky/client/cli/command.py
    • Added debug-dump CLI command with options for request IDs, cluster names, job IDs, recent activity, and output path.
    • Implemented logic to call SDK functions for creating and downloading the debug dump.
  • sky/client/sdk.py
    • Imported platform module.
    • Added _build_client_info function to gather client-side system and SkyPilot configuration details for the dump.
    • Added create_debug_dump SDK function to send a request to the server to initiate a debug dump.
    • Added download_debug_dump SDK function to retrieve the generated debug dump file from the server.
  • sky/core.py
    • Imported debug_utils module.
    • Added create_debug_dump core function which orchestrates the debug dump creation process by calling debug_utils.
  • sky/server/constants.py
    • Updated API_VERSION from 26 to 27.
  • sky/server/requests/payloads.py
    • Added CreateDebugDumpBody class to define the request body structure for creating a debug dump, including client-side info.
  • sky/server/requests/request_names.py
    • Added CREATE_DEBUG_DUMP to RequestName enum.
  • sky/server/server.py
    • Imported starlette.background.
    • Added new FastAPI endpoints: @app.post('/debug/dump-create') to handle requests for creating debug dumps and @app.get('/debug/dump-download/{dump_filename}') to handle requests for downloading debug dump files, with automatic deletion after download.
  • sky/utils/debug_utils.py
    • Added new file debug_utils.py containing the core logic for debug dump creation.
    • Defined DEBUG_DUMP_DIR for persistent storage.
    • Implemented functions to collect requests, clusters, and managed job information, including cross-linking related resources.
    • Added _populate_recent_context to include resources active within a specified time window.
    • Added _dump_server_info, _dump_request_id_info, _dump_cluster_info, and _dump_managed_job_info to gather specific types of data.
    • Implemented create_debug_dump to orchestrate the collection, packaging into a zip file, and storage of the debug information.
Activity
  • The pull request introduces a new feature, so there is no prior activity to summarize. The changes represent the initial implementation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new sky debug-dump command, which is a valuable tool for troubleshooting. The implementation is comprehensive, collecting logs, state, and configuration for specified resources. The code is well-structured, with a new debug_utils.py module containing the core logic. Security considerations, such as preventing path traversal, have been taken into account. I have one suggestion for code simplification in sky/utils/debug_utils.py to improve maintainability. Overall, this is a solid contribution.

Comment thread sky/utils/debug_utils.py Outdated
cg505 and others added 3 commits February 17, 2026 22:44
Resolve API_VERSION conflict: bump to 32 for debug dump endpoints.
Update minimal_api_version decorators from 27 to 32.
- Fix managed job data access for remote controllers by using queue_v2()
  instead of direct DB queries
- Change debug dump schedule type from SHORT to LONG for credential checks
- Add orphan cleanup for dumps older than 1 hour
- Enrich server_info.json with python version, OS platform, DB backend,
  and server uptime (via boot check request)
- Surface collection errors in errors.json and summary.json warnings
- Add human-readable timestamps alongside epoch values
- Improve config redaction using config_utils.Config pattern
- Add debug logging throughout dump creation
- Dump all tasks for multi-task managed jobs
- Add 48 unit tests for cross-linking and dump creation functions
- Add 5 smoke tests covering --recent, -c, -r, -j flags and no-args error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts:
#	sky/server/constants.py
#	sky/server/server.py

@cg505 cg505 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if there is a way for us to pull the helm values for the API deployment if possible as well.

Comment thread sky/utils/debug_utils.py Outdated
Comment thread sky/utils/debug_utils.py Outdated
Comment thread sky/utils/debug_utils.py Outdated
Comment thread sky/utils/debug_utils.py Outdated
Comment thread sky/utils/debug_utils.py Outdated
Comment thread sky/utils/debug_utils.py Outdated
Comment thread sky/utils/debug_utils.py
Comment thread sky/utils/debug_utils.py Outdated
Comment thread sky/utils/debug_utils.py Outdated
Comment thread sky/utils/debug_utils.py Outdated
cg505 and others added 7 commits February 19, 2026 23:33
…quest IDs

Replace hardcoded SYSTEM_REQUEST_IDS list with dynamic construction from
INTERNAL_REQUEST_DAEMONS and a new ON_BOOT_CHECK_REQUEST_ID constant,
so debug dumps automatically include any new daemon request IDs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove read-only JOBS_QUEUE from request filter. Add matching for
cancel-by-name, cancel-all (with user check), and cancel-all-users
requests by fetching job details via queue_v2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove unnecessary try/except around JOB_CONTROLLER_NAME
- Simplify _get_clusters_from_managed_jobs to just add controller name
  (actual job cluster info handled by _dump_managed_job_info)
- Remove redundant created_at check in _populate_recent_context
- Remove cluster_name gathering from _populate_recent_context
  (handled by _get_clusters_from_requests during cross-linking)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…oss-link to debug dump

Address review comments: add server environment variables to dump,
copy debug log files from _DEBUG_LOG_DIR, add requests→jobs cross-linking
via _get_managed_jobs_from_requests, wire errors through DebugDumpContext
so cross-linking and recent-context functions record failures, rename
'warnings' to 'errors' in summary, add debug log for missing client info.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move all import-outside-toplevel imports to top-level (debug_utils is
only imported server-side so no circular import risk). Remove inner
try/except in _get_requests_from_managed_jobs since all attribute
access uses getattr with defaults. Add error recording to debug log
copy except block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract _build_debug_dump helper for cross-linking, dumping all
sections, and writing summary. Add a FileHandler at DEBUG level on
the debug_utils logger during dump creation so all debug logs are
captured into debug_dump.log in the zip. Handler is cleaned up in
a finally block (remove, flush, close) to avoid clobbering existing
loggers. No logger level changes needed since effective level is
already DEBUG via inheritance from root sky logger.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a new gRPC RPC to ManagedJobsService that collects debug dump data
(controller logs, job events, run logs, cluster info) from the jobs
controller. This enables the debug dump to work in non-consolidation
mode where the controller runs on a separate VM.

The implementation uses a unified code path: gRPC when available, with
CodeGen/SSH fallback. In consolidation mode, LocalResourcesHandle runs
the CodeGen locally via LocalProcessCommandRunner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cg505

cg505 commented Feb 21, 2026

Copy link
Copy Markdown
Collaborator Author

/quicktest-core

@cg505

cg505 commented Feb 21, 2026

Copy link
Copy Markdown
Collaborator Author

/smoke-test -k test_debug_dump_recent

@cg505

cg505 commented Feb 21, 2026

Copy link
Copy Markdown
Collaborator Author

/smoke-test -k test_debug_dump_job

@cg505

cg505 commented Feb 21, 2026

Copy link
Copy Markdown
Collaborator Author

/quicktest-core

@cg505

cg505 commented Feb 21, 2026

Copy link
Copy Markdown
Collaborator Author

/smoke-test -k test_debug_dump_recent
/smoke-test -k test_debug_dump_job

cg505 and others added 2 commits February 21, 2026 02:22
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…oke tests

Fix string escaping in python3 -c assertions that are embedded in bash
commands: use \\\" to produce \" in bash (which becomes " in Python),
instead of \" which becomes " directly (breaking bash double-quote
parsing). Also remove assert for 'timing' key which does not exist
in summary.json.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cg505

cg505 commented Feb 21, 2026

Copy link
Copy Markdown
Collaborator Author

/smoke-test -k test_debug_dump_recent

@cg505

cg505 commented Feb 21, 2026

Copy link
Copy Markdown
Collaborator Author

/smoke-test -k test_debug_dump_job

Comment thread agent/skills/skypilot/references/cli-reference.md Outdated
Comment thread agent/skills/skypilot/references/python-sdk.md
Comment thread sky/client/cli/command.py Outdated
Comment thread sky/jobs/utils.py Outdated
Comment thread sky/jobs/utils.py Outdated
Comment thread sky/jobs/utils.py Outdated
Comment thread sky/jobs/utils.py Outdated
Comment thread sky/jobs/utils.py Outdated
Comment thread sky/utils/debug_utils.py
Comment thread sky/utils/debug_utils.py
Comment thread sky/utils/debug_utils.py
Comment thread sky/utils/debug_utils.py Outdated
cg505 and others added 8 commits March 25, 2026 19:05
Use ThreadPoolExecutor to collect per-job debug data concurrently
instead of sequentially. Cluster info collection remains sequential
for deduplication.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… unneeded \b

Update debug-dump docstrings so the "at least one filter required" note
appears in both CLI reference and Python SDK reference docs. Remove
unnecessary \b before "Example usage:" in CLI help.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract the repeated try/except/errors.append pattern into a reusable
context manager. Apply early returns in _collect_cluster_debug_manifest
and _collect_controller_system_log_paths to reduce nesting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…sk_yaml

Replace the hardcoded frozenset with a programmatic derivation from
RequestName, so new jobs.* request types are automatically included.
Remove the one-line _redact_task_yaml wrapper — callers now call
debug_dump_helpers.redact_task_yaml directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Master merged with API_VERSION=45 (jobs.wait). Re-bump to 46 for our
debug dump endpoints and update minimal_api_version checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the one-line _redact_task_yaml wrapper — callers now call
debug_dump_helpers.redact_task_yaml directly. Add new jobs.wait
request to _REQUEST_BODY_ALLOWLIST.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cg505

cg505 commented Mar 25, 2026

Copy link
Copy Markdown
Collaborator Author

/smoke-test -k test_debug_dump
/smoke-test --kubernetes -k test_debug_dump
/smoke-test -k basic
/quicktest-core

…edact_task_yaml

Fix smoke test failure: the "requested" section in summary.json now shows
the original user-provided request IDs/prefixes, even if they don't match
any existing requests. Previously, nonexistent request ID prefixes were
silently dropped during resolution.

Also inline _redact_task_yaml wrapper and add jobs.wait to allowlist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cg505

cg505 commented Mar 26, 2026

Copy link
Copy Markdown
Collaborator Author

/smoke-test -k test_debug_dump
/smoke-test --kubernetes -k test_debug_dump
/smoke-test -k basic
/quicktest-core

@cg505 cg505 requested a review from SeungjinYang March 27, 2026 01:22
@cg505 cg505 merged commit cc595ca into skypilot-org:master Mar 30, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants