mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-03-14 05:37:42 +08:00
Adds opt-in process isolation for custom nodes using pyisolate's bwrap sandbox and JSON-RPC bridge. Each isolated node pack runs in its own child process with zero-copy tensor transfer via shared memory. Core infrastructure: - CLI flag --use-process-isolation to enable isolation - Host/child startup fencing via PYISOLATE_CHILD env var - Manifest-driven node discovery and extension loading - JSON-RPC bridge between host and child processes - Shared memory forensics for leak detection Proxy layer: - ModelPatcher, CLIP, VAE, and ModelSampling proxies - Host service proxies (folder_paths, model_management, progress, etc.) - Proxy base with automatic method forwarding Execution integration: - Extension wrapper with V3 hidden param mapping - Runtime helpers for isolated node execution - Host policy for node isolation decisions - Fenced sampler device handling and model ejection parity Serializers for cross-process data transfer: - File3D (GLB), PLY (structured + gaussian), NPZ (streaming frames), VIDEO (VideoFromFile + VideoFromComponents) serializers - data_type flag in SerializerRegistry for type-aware dispatch - Isolated get_temp_directory() fence New core save nodes: - SavePLY and SaveNPZ with comfytype registrations (Ply, Npz) DynamicVRAM compatibility: - comfy-aimdo early init gated by isolation fence Tests: - Integration and policy tests for isolation lifecycle - Manifest loader, host policy, proxy, and adapter unit tests Depends on: pyisolate >= 0.9.2
73 lines
2.0 KiB
Python
73 lines
2.0 KiB
Python
from pathlib import Path
|
|
|
|
|
|
def _write_pyproject(path: Path, content: str) -> None:
|
|
path.write_text(content, encoding="utf-8")
|
|
|
|
|
|
def test_load_host_policy_defaults_when_pyproject_missing(tmp_path):
|
|
from comfy.isolation.host_policy import DEFAULT_POLICY, load_host_policy
|
|
|
|
policy = load_host_policy(tmp_path)
|
|
|
|
assert policy["allow_network"] == DEFAULT_POLICY["allow_network"]
|
|
assert policy["writable_paths"] == DEFAULT_POLICY["writable_paths"]
|
|
assert policy["readonly_paths"] == DEFAULT_POLICY["readonly_paths"]
|
|
assert policy["whitelist"] == DEFAULT_POLICY["whitelist"]
|
|
|
|
|
|
def test_load_host_policy_defaults_when_section_missing(tmp_path):
|
|
from comfy.isolation.host_policy import DEFAULT_POLICY, load_host_policy
|
|
|
|
_write_pyproject(
|
|
tmp_path / "pyproject.toml",
|
|
"""
|
|
[project]
|
|
name = "ComfyUI"
|
|
""".strip(),
|
|
)
|
|
|
|
policy = load_host_policy(tmp_path)
|
|
assert policy["allow_network"] == DEFAULT_POLICY["allow_network"]
|
|
assert policy["whitelist"] == {}
|
|
|
|
|
|
def test_load_host_policy_reads_values(tmp_path):
|
|
from comfy.isolation.host_policy import load_host_policy
|
|
|
|
_write_pyproject(
|
|
tmp_path / "pyproject.toml",
|
|
"""
|
|
[tool.comfy.host]
|
|
allow_network = true
|
|
writable_paths = ["/tmp/a", "/tmp/b"]
|
|
readonly_paths = ["/opt/readonly"]
|
|
|
|
[tool.comfy.host.whitelist]
|
|
ExampleNode = "*"
|
|
""".strip(),
|
|
)
|
|
|
|
policy = load_host_policy(tmp_path)
|
|
assert policy["allow_network"] is True
|
|
assert policy["writable_paths"] == ["/tmp/a", "/tmp/b"]
|
|
assert policy["readonly_paths"] == ["/opt/readonly"]
|
|
assert policy["whitelist"] == {"ExampleNode": "*"}
|
|
|
|
|
|
def test_load_host_policy_ignores_invalid_whitelist_type(tmp_path):
|
|
from comfy.isolation.host_policy import DEFAULT_POLICY, load_host_policy
|
|
|
|
_write_pyproject(
|
|
tmp_path / "pyproject.toml",
|
|
"""
|
|
[tool.comfy.host]
|
|
allow_network = true
|
|
whitelist = ["bad"]
|
|
""".strip(),
|
|
)
|
|
|
|
policy = load_host_policy(tmp_path)
|
|
assert policy["allow_network"] is True
|
|
assert policy["whitelist"] == DEFAULT_POLICY["whitelist"]
|