6728 Commits

Author SHA1 Message Date
Jeremy Grossmann
ae2fa31c5e
Merge pull request #2721 from yueguobin/feature/list-node-files-api
feat: Add API endpoint to list node files with metadata
2026-05-09 00:04:16 +08:00
YueGuobin
b4220d55c6
fix: Import status module in project.py
Fix F821 undefined name 'status' error by importing the status
module from fastapi. This resolves build errors when using
status.HTTP_403_FORBIDDEN and status.HTTP_404_NOT_FOUND.
2026-05-08 23:58:43 +08:00
Guobin Yue
cd732ab4b5
Merge branch '3.0' into feature/list-node-files-api 2026-05-08 23:51:56 +08:00
Jeremy Grossmann
14c2172f1b
Merge pull request #2722 from yueguobin/fix/console-stopping-error
fix: Handle connection errors when stopping node console
2026-05-08 23:43:39 +08:00
YueGuobin
3752b2bac8
fix: Handle connection errors when stopping node console
Add exception handling in stop_wrap_console to gracefully handle
ConnectionResetError, BrokenPipeError, and OSError when waiting
for console writer to close.

This prevents 500 errors when stopping QEMU nodes if the console
connection is reset before the writer finishes closing.

Fixes race condition where QEMU process exits and closes connections
before the console writer cleanup completes.
2026-05-08 23:30:41 +08:00
YueGuobin
e6df144ae8
refactor: Remove MD5 calculation from node files listing
Remove MD5 checksum calculation from the node files API since
disk image files are dynamic and change frequently. MD5 calculation
was also causing significant performance overhead.

Changes:
- Remove md5sum field from NodeFile schema
- Remove MD5 calculation from list_node_files method
- Improve error handling for timestamp conversion
- Simplify code by removing lambda functions

Performance improvement:
- Response time reduced from ~0.5-1s to ~0.017s (30-60x faster)
- Especially beneficial for large files and multiple files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 23:05:40 +08:00
YueGuobin
fae7b2eabe
fix: Export NodeFile schema to schemas module
Add NodeFile to the schemas __init__.py exports to fix
import error when starting the server.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:58:45 +08:00
YueGuobin
51a4c73e21
feat: Add detailed metadata to node files listing
Enhance the node files API to include comprehensive file metadata:
- File size in bytes
- File creation time (ISO 8601 format)
- File modification time (ISO 8601 format)
- File extension

Create new NodeFile schema to support these additional fields
while keeping the existing ProjectFile schema for backward compatibility.

This provides users with better information to manage and identify
files in the Web UI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:57:19 +08:00
YueGuobin
5b75d633aa
feat: Add API endpoint to list node files
Implement issue #2719 - Add API endpoint to list project files

- Add GET /v3/projects/{project_id}/nodes/{node_id}/files endpoint
- Add list_node_files() method to Project class
- Add security checks to prevent path traversal
- Filter out .ghost temporary files
- Return file paths with MD5 checksums
- Require Node.Audit privilege

This allows users to discover dynamically created files
such as QEMU disk images created via the disk image API.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:52:17 +08:00
Jeremy Grossmann
e0860555ba
Merge pull request #2713 from yueguobin/fix/docker-container-deletion-error-handling
Fix: Improve Docker container deletion error logging
2026-05-07 22:17:23 +08:00
YueGuobin
822abbe671
Fix: Improve Docker container deletion error logging
When closing a Docker node, if container deletion fails, the error
is silently ignored. This can lead to stale containers remaining on
the system and causing 409 conflicts when reopening projects.

Changes:
- Distinguish between 404 (container already removed, normal) and
  other DockerError (deletion failed, needs attention)
- Log warning when deletion fails with error details
- Add comment explaining stale containers will be cleaned up on
  project open (via automatic 409 conflict resolution)

This improves observability without blocking project close operations.
The root cause of stale containers can now be diagnosed from logs.

Fixes #2708

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 12:45:05 +08:00
Jeremy Grossmann
3928377f80
Merge pull request #2710 from yueguobin/fix/compute-connection-timeout
Fix: Check compute connectivity before open() during project deletion
2026-05-07 11:36:45 +08:00
Jeremy Grossmann
0d88ff87e7
Merge pull request #2712 from yueguobin/fix/compute-reconnection-backoff
Fix: Add exponential backoff to compute reconnection attempts
2026-05-07 11:35:46 +08:00
YueGuobin
efe6913d69
Fix: Add exponential backoff to compute reconnection attempts
When a remote compute is unreachable, the controller now uses exponential
backoff for reconnection attempts: 5s, 10s, 20s, 40s, 80s, then caps at
300s (5 minutes). Previously it retried every 5 seconds indefinitely.

User-initiated operations (open project, start node) still trigger an
immediate connection attempt, so recovery is not delayed in practice.

Related: #2704
2026-05-07 11:17:55 +08:00
YueGuobin
f1b11e7cae
Fix: Check compute connectivity before node creation in open()
When opening a closed project with nodes on an offline remote compute,
open() would block for 120s trying to connect before eventually
failing. Now checks compute connectivity after loading the topology
file but before creating nodes, allowing immediate failure with a
clear error message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-07 10:48:18 +08:00
YueGuobin
30ebde0cb0
Fix: Check compute connectivity before open() during project deletion
Previously the disconnected compute check ran after open(), which would
block for 120s trying to connect to unreachable remote computes before
rejecting the deletion. Now reads the topology file directly to extract
compute IDs and checks connectivity before calling open(), enabling
immediate rejection of deletions involving offline computes.

Also removes the redundant post-open() check since the early check
covers both opened and closed project states.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-07 09:58:20 +08:00
YueGuobin
8ecd449dd8
Fix: Add error logging when closing/deleting projects on computes
Previously errors during close() and delete_on_computes() were silently
swallowed without any logging, making it difficult to diagnose failures
when remote computes are unreachable.

- close(): log warning instead of silent pass
- delete_on_computes(): wrap HTTP DELETE in try/except with warning log

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-07 09:37:51 +08:00
YueGuobin
4d06b2b7b6
Fix: Skip add_compute for existing computes when opening projects 2026-05-06 13:24:27 +08:00
YueGuobin
0f4b0c567e
feat: add AI provider config files to .gitignore
Add deepseek, claude, gemini, and grok settings files to .gitignore to prevent accidental commits of local AI provider configurations.
2026-05-06 13:24:13 +08:00
Jeremy Grossmann
255d1e4057
Merge pull request #2705 from yueguobin/fix/project-deletion-compute-status-check
Fix: Check compute connection status before project deletion
2026-05-06 09:39:41 +08:00
YueGuobin
a67cd66b60
Revert "Fix: Handle project deletion errors in autoidlepc"
This reverts commit c92188cad4f93a5ed0a74739f315605bf9c0488d.
2026-05-06 00:59:05 +08:00
YueGuobin
c92188cad4
Fix: Handle project deletion errors in autoidlepc
When deleting the AUTOIDLEPC project in autoidlepc(), if a remote compute
is disconnected, the deletion fails with ControllerForbiddenError due to
our compute connection status check. This causes:
- The project to remain in the controller's memory
- Subsequent autoidlepc calls to fail
- User must restart the server to recover

This fix adds exception handling to ensure the project is always removed
from the controller's memory, even if deletion fails.

Related to #2703
2026-05-06 00:47:24 +08:00
YueGuobin
9c868911e1
Fix: Use _computes instead of _project_created_on_compute for deletion check
The initial fix used _project_created_on_compute to check for disconnected
computes before deletion, but this set gets reset during project.open(),
causing the check to fail.

Now uses self._computes which is loaded from the topology file and
persists through the open() call.

Related: #2703

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 00:19:55 +08:00
YueGuobin
4444da9ffa
Fix: Check compute connection status before project deletion
This commit addresses issue #2703 where deleting a project with nodes
on remote compute nodes would result in long waits with no feedback
if those computes were unreachable.

Changes:
1. Compute connection status updates on connection failure
   - When a compute fails to connect, update connected=False and last_error
   - Send compute.updated notification to UI so users can see status
   - This allows Web UI to display real-time connection status

2. Project deletion checks compute status before attempting deletion
   - Check all computes used by the project are connected
   - If any compute is disconnected, immediately reject deletion
   - Provide clear error message indicating which computes are offline
   - This prevents long timeouts and gives users immediate feedback

Benefits:
- Immediate feedback instead of 120-second timeouts
- Clear error messages about which computes are disconnected
- Prevents orphaned resources on offline computes
- Improves user experience by avoiding silent waits

Related: #2703

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 00:05:10 +08:00
Jeremy Grossmann
ee7c5d6d59
Merge pull request #2693 from cristian-ciobanu/ssh-console-support
feat(compute): add SSH console type support
2026-05-05 19:03:57 +08:00
Jeremy Grossmann
82d630a122
Merge branch '3.0' into ssh-console-support 2026-05-04 17:17:10 +08:00
Jeremy Grossmann
56455d3a27
Merge pull request #2701 from yueguobin/fix/iou-remote-path-validation
fix: convert absolute image paths to relative paths for remote compute nodes
2026-05-04 16:36:23 +08:00
Guobin Yue
069e139d2d
Merge branch '3.0' into fix/iou-remote-path-validation 2026-05-04 15:51:30 +08:00
YueGuobin
1f5ba3cada
chore: remove internal debug documentation 2026-05-04 15:48:46 +08:00
YueGuobin
38f5e8df76
fix: extend remote compute image path conversion to all node types
Previously only the "path" field was converted to a relative path for remote computes, causing issues with QEMU and VMware nodes that use different image path fields. Now all known image path fields are converted, ensuring consistent behavior across IOU, QEMU, Dynamips, and VMware node types.
2026-05-04 15:39:16 +08:00
Jeremy Grossmann
5f9b469679
Merge pull request #2700 from yueguobin/fix/issue-2680-static-directory
fix: handle directory access for static web-ui routes
2026-05-03 17:56:50 +08:00
YueGuobin
6ff4f575bb
docs: add analysis for issue #2676 remote compute image path validation
Add detailed documentation explaining:
- Problem description and root cause
- Architecture overview (Controller vs Compute)
- Why automatic upload is not triggered
- Affected node types
- Solution implementation
- Testing scenarios

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 17:47:25 +08:00
YueGuobin
11fb5de84e
fix: send relative image path to remote compute nodes
When creating a node on a remote compute, the controller now sends
only the image filename instead of the absolute local path. The remote
compute will search for the image in its own configured images_directories.

If the image is not found, the compute returns ImageMissingError, which
triggers the controller's automatic image upload mechanism.

This fixes issue #2676 where remote computes reject paths from the
controller due to mismatched directory prefixes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 17:44:47 +08:00
YueGuobin
952ef66a6b
fix: handle directory access for static web-ui routes
When accessing /static/web-ui without trailing slash, the request would
fail with "RuntimeError: File at path ... is not a file" because:

1. The route /static/web-ui/{file_path:path} doesn't match paths without
   trailing slash (Starlette's path regex requires the /)
2. The request falls through to StaticFiles mount, which tries to serve
   the directory as a file

This fix:
- Sets html=True on StaticFiles mount to automatically redirect directory
  URLs to trailing slash versions
- Adds os.path.isdir() check to handle empty file_path gracefully

Fixes #2680

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 17:21:03 +08:00
Jeremy Grossmann
c45f6d9416
Merge pull request #2699 from yueguobin/fix/template-duplicate-name-validation
Fix duplicate template name validation when updating templates
2026-05-03 12:09:59 +08:00
YueGuobin
1d715e146b
fix: add duplicate name validation when updating templates
Fixes #1658

Add validation in the update_template method to check if a template
with the same name already exists before updating. This prevents
users from creating duplicate template names by editing existing
templates.

The check excludes the current template being edited to allow
updating other properties without changing the name.
2026-05-03 11:08:20 +08:00
Jeremy Grossmann
c3d202abc9
Merge branch '3.0' into ssh-console-support 2026-05-02 22:10:28 +08:00
Jeremy Grossmann
165209ba24
Merge pull request #2698 from yueguobin/fix/compute-update-password-none-error
fix: avoid AttributeError when password is not provided in compute update
2026-05-02 22:07:34 +08:00
Jeremy Grossmann
b87ab8f86f
Merge pull request #2696 from yueguobin/fix/rfc1123-error-message
fix: improve hostname validation error messages with allowed characters
2026-05-02 18:30:49 +08:00
YueGuobin
a6dcab8110
fix: avoid AttributeError when password is not provided in compute update
When updating a compute without providing a password field,
compute_update.password is None and calling .get_secret_value()
on it causes a 500 Internal Server Error. Only set the password
in update_values when a password is actually provided.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-02 15:37:46 +08:00
YueGuobin
ba220780a9
fix: improve hostname validation error messages with allowed characters
When a hostname validation fails, the error message now includes
the allowed character set to help users provide valid names.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-02 13:09:04 +08:00
Cristi
e6de7cb60a feat(compute): Fix Dynamips to listen on the internal port when ssh is used for auxiliary console 2026-04-30 23:50:15 +03:00
Cristi
d7c78f5744 feat(compute): Fix ambiguous log message related to the active console transport.
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 18:07:23 +03:00
Cristi
9d451eb652 feat(compute): Updated server host key to use the secure ssh-ed25519 instead of old ssh-rsa algorithm 2026-04-30 17:56:05 +03:00
Cristi
cc05eb5850 feat(compute): Fix missing SSH wrapping for auxiliary console 2026-04-30 17:47:54 +03:00
Cristi
8ff1698bfb feat(compute): Added AsyncioSSHServer dedicated tests 2026-04-30 16:35:21 +03:00
Cristi
d64eca0418 feat(compute): add SSH console type support 2026-04-30 15:52:47 +03:00
Jeremy Grossmann
f0ef65b8e8
Merge pull request #2688 from yueguobin/fix/llm-model-config-error-message
fix: include error details in LLM model config + docs: add troubleshooting guides
2026-04-25 16:30:47 +08:00
Guobin Yue
c583462d2d
Merge branch '3.0' into fix/llm-model-config-error-message 2026-04-25 16:26:59 +08:00
YueGuobin
c688223e1b
docs: add troubleshooting guide for WebSocket console authentication failure
Add documentation explaining the common issue where WebSocket console connections to remote compute nodes fail due to credential mismatch. The guide describes the error symptoms, root cause (Controller forwarding its own credentials to Compute), and solution (ensuring matching compute_username and compute_password in Compute's configuration).
2026-04-25 16:08:53 +08:00