mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2026-06-20 23:09:20 +08:00
fca7ef149d
8 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fca7ef149d
|
feat(security): dedicated install flags decouple git_url/pip install from security_level (#2962)
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
* feat(security): dedicated install flags decouple git_url/pip from security_level
Install via git URL and pip install are no longer gated by
security_level. Each surface gets a dedicated config.ini flag —
allow_git_url_install / allow_pip_install (both default false, secure
by default) — that fully REPLACES the security-level term for these two
features. The network-position invariant is retained: a non-local
listener stays denied regardless of the flags unless
network_mode = personal_cloud.
- New pure predicate is_dedicated_install_allowed() in
common/manager_security (no config access; callers resolve config)
- Legacy endpoints /v2/customnode/install/git_url and .../pip switch
from is_allowed_security_level('high+') to the flag gate; batch
installs of unknown git URLs likewise (middle+ entry gate unchanged,
unknown-pip 'block' stays unconditional; response shapes preserved)
- Config readers/writers (glob + legacy) parse and persist the flags;
denial logs and frontend 403 messages name the responsible flag and
note the non-local-listener requirement (network_mode=personal_cloud)
- No auto-seed from security_level — users previously on weak/normal-
must opt in explicitly (see CHANGELOG migration notes; README
documents the new contract)
- Update the pre-existing permissive E2E harness
(start_comfyui_permissive.sh + test_e2e_legacy_real_ops.py) to the
new contract: it now also sets allow_git_url_install /
allow_pip_install = true, since security_level = normal- alone no
longer opens the git_url/pip endpoints
Tests: predicate truth table proving security_level independence in
both directions, dual-reader config contract, security-level-matrix
freeze guards, legacy gate regression guards (121 unit), plus 22
real-server E2E tests incl. URL-form pip install with self-clean.
* test(e2e): fix fresh-env failures in customnode_info and git_clone harnesses
Two pre-existing harness defects that fail deterministically on a fresh
E2E environment (unrelated to the dedicated-install-flags change):
- test_e2e_customnode_info: TestInstalledPacks asserted the seed pack
ComfyUI_SigmoidOffsetScheduler is installed, but nothing seeded it —
the installing module (test_e2e_endpoint) runs alphabetically later
and uninstalls it at the end. Add a module-scoped autouse fixture
that installs the pack via cm-cli BEFORE the server starts (the
imported-mode test asserts against the startup-frozen snapshot, so
API-based seeding after boot cannot work) and removes it on teardown
only if the fixture installed it.
- test_e2e_git_clone: _ensure_cache ran cm-cli update-cache with a
120s timeout; the full DB download routinely exceeds that on slow
links, erroring the whole module at setup. Raise to 600s.
Verified from a fresh state (seed pack absent): both modules pass
(13 tests, incl. previously-failing TestInstalledPacks 2 and
TestNightlyInstallCycle 3).
|
||
|
|
8b98723b42
|
fix(git_compat): follow-ups for pygit2 fallback hardening (#2974)
- Route list_remotes() fetch through _fetch_remote so the proxy and SSH-to-HTTPS rewrite apply to every fetch entry point, and provide pull on its proxies (parity with get_remote and the GitPython proxy) via a shared _pull_remote helper - Rework _to_https_url: handle ssh://git@host:port/... URLs (drop the custom SSH port instead of mangling it into the path) and collapse leading slashes so git@host:/abs/path no longer yields a double-slash URL. Behavior narrowing: colon-less git@host/path (not a valid scp-form URL), ssh:// URLs with a port but no path, and IPv6 ssh:// URLs are now returned unchanged instead of being wrongly converted - clone_repo: omit the proxy= kwarg when no proxy is configured, so proxy-less installs keep working on pygit2 older than 1.18 - Simplify redundant except (KeyError, Exception) clause - Require pygit2>=1.18 (clone_repository proxy= parameter) - Add unit tests for _to_https_url (incl. negative cases pinning the narrowing) and a regression test that list_remotes proxies route fetch/pull through their own remote (late-binding guard) |
||
|
|
4410ebc6a6
|
fix(security): harden CSRF with Content-Type gate and expand E2E coverage (#2818)
Defense-in-depth over GET→POST alone: reject the three CORS-safelisted simple-form Content-Types (x-www-form-urlencoded, multipart/form-data, text/plain) on 16 no-body POST handlers (glob + legacy) to block <form method=POST> CSRF that bypasses method-only gating. Move comfyui_switch_version to a JSON body so the preflight requirement applies. Split db_mode/policy/update/channel_url_list into GET(read) + POST(write). Tighten do_fix (high → high+) and gate three previously-ungated config setters at middle. Resynchronize openapi.yaml (27 paths, 30 operations, ComfyUISwitchVersionParams as a shared $ref component). Add E2E harness variants, Playwright config, CSRF/secgate suites, 39-endpoint coverage, and a CHANGELOG. Breaking: legacy per-op POST routes (install/uninstall/fix/disable/update/ reinstall/abort_current) are removed; callers already use queue/batch. Legacy /manager/notice (v1) is removed; /v2/manager/notice is retained. Reported-by: XlabAI Team of Tencent Xuanwu Lab CVSS: 8.1 (AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H) |
||
|
|
49e205acd4
|
feat: add pygit2 compatibility wrapper for standalone Desktop 2.0 installs (#2719)
* feat: add pygit2 compatibility wrapper for standalone Desktop 2.0 installs Add git_compat.py abstraction layer that wraps both GitPython and pygit2 behind a unified GitRepo interface. When CM_USE_PYGIT2=1 is set (by the Desktop 2.0 Launcher for standalone installs), or when system git is not available, the pygit2 backend is used automatically. Key changes: - New comfyui_manager/common/git_compat.py with abstract GitRepo base class, _GitPythonRepo (1:1 pass-throughs) and _Pygit2Repo implementations - All 6 non-legacy files updated to use the wrapper: - comfyui_manager/glob/manager_core.py (14 git.Repo usages) - comfyui_manager/common/git_helper.py (7 git.Repo usages) - comfyui_manager/common/context.py (1 usage) - comfyui_manager/glob/utils/environment_utils.py (2 usages) - cm_cli/__main__.py (1 usage) - comfyui_manager/common/timestamp_utils.py (repo.heads usage) - get_script_env() propagates CM_USE_PYGIT2 to subprocesses - git_helper.py uses sys.path.insert to find git_compat as standalone script - All repo handles wrapped in context managers to prevent resource leaks - get_head_by_name returns _HeadProxy for interface consistency - Submodule fallback logs clear message when system git is absent - 47 tests comparing both backends via subprocess isolation Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019d0ec5-cb9f-74df-a1a2-0c8154a330b3 * fix(pygit2): address review findings + bump version to 4.2b1 - C1: add submodule_update() after pygit2 clone for recursive parity - C2: check subprocess returncode in submodule_update fallback - C3: move GIT_OPT_SET_OWNER_VALIDATION to module-level (once at import) - H1: use context manager in git_pull() to prevent resource leaks - Bump version to 4.2b1, version_code to [4, 2] - Add pygit2 to dev dependencies and requirements.txt * style: fix ruff F841 unused variable and F541 unnecessary f-string --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Dr.Lt.Data <dr.lt.data@gmail.com> |
||
|
|
099aed1ad4
|
fix(git_helper): Windows subprocess crash fix + multiplatform E2E CI (#2717)
* fix(git_helper): surface git stderr and use portable exit code - Redirect exception output to stderr for diagnostic visibility - Surface GitCommandError.stderr when available - Use sys.exit(1) instead of sys.exit(-1) for portable exit codes - Remove debug print statements * fix(e2e): cross-platform E2E tests with file-based stdout capture - Cross-platform cm-cli path (Scripts/cm-cli.exe vs bin/cm-cli) - File-based stdout/stderr capture to avoid Windows pipe buffer loss - Rename uv-compile → uv-sync for standalone command refs - Update conflict test packs: ansible → python-slugify/text-unidecode - Add .trash_* cleanup and retry+rename for Windows file locks - Add test_e2e_git_clone.py for nightly install via ComfyUI server - Add setup_e2e_env.py cross-platform setup script * feat(ci): add multiplatform E2E workflow (ubuntu/windows/macos) Matrix: ubuntu-latest, windows-latest, macos-latest × Python 3.10 Triggers on push to main/feat/*/fix/* and PRs to main. * bump version to 4.1b7 |
||
|
|
cd60f33f6d
|
fix(git_helper): remove comfyui_manager import to fix Windows subprocess crash (#2703)
git_helper.py is spawned as a standalone subprocess on Windows (manager_core.py:1342). The import of comfyui_manager.common.timestamp_utils triggered comfyui_manager/__init__.py which imports from comfy.cli_args — unavailable in the subprocess environment, causing ModuleNotFoundError. Inline get_backup_branch_name() using only stdlib (time, uuid), preserving the original collision-detection and UUID-fallback semantics. Add 9 tests covering standalone subprocess loading, behavioral equivalence, edge cases (repo.heads exception, 99-suffix exhaustion with UUID fallback). |
||
|
|
d7a2277017
|
feat(cli): expand --uv-compile to all node management commands with conflict attribution (#2682)
* feat(cli): expand --uv-compile to all node management commands with conflict attribution Add --uv-compile flag to reinstall, update, fix, restore-snapshot, restore-dependencies, and install-deps commands. Each skips per-node pip installs and runs batch uv pip compile after all operations. Change CollectedDeps.sources type to dict[str, list[tuple[str, str]]] to store (pack_path, pkg_spec) per requester. On resolution failure, _run_unified_resolve() cross-references conflict packages with sources using word-boundary regex and displays which node packs requested each conflicting package. Update EN/KO user docs and DESIGN/PRD developer docs to cover the expanded commands and conflict attribution output. Strengthen unit tests for sources tuple format and compile failure attribution. Bump version to 4.1b3. * refactor(cli): extract _finalize_resolve helper, add CNR nightly fallback and pydantic guard - Extract `_finalize_resolve()` to eliminate 7x duplicated uv-compile error handling blocks in cm_cli (~-85 lines) - Move conflict attribution regex to `attribute_conflicts()` in unified_dep_resolver.py for direct testability - Update 4 attribution tests to call production function instead of re-implementing regex - Add CNR nightly fallback: when node is absent from nightly manifest, fall back to cnr_map repository URL (glob + legacy) - Add pydantic Union guard: use getattr for is_unknown in uninstall and disable handlers to prevent Union type mismatch - Add E2E test suites for endpoint install/uninstall and uv-compile CLI commands (conflict + success cases) - Add nightly CNR fallback regression tests |
||
|
|
f042d73b72
|
feat(deps): add unified dependency resolver using uv pip compile (#2589)
* feat(deps): add unified dependency resolver using uv pip compile - Add UnifiedDepResolver module with 7 FRs: collect, compile, install pipeline - Integrate startup batch resolution in prestartup_script.py (module scope) - Skip per-node pip install in execute_install_script() when unified mode active - Add use_unified_resolver config flag following use_uv pattern - Input sanitization: reject -r, -e, --find-links, @ file://, path separators - Handle --index-url/--extra-index-url separation with credential redaction - Fallback to per-node pip on resolver failure or uv unavailability - Add 98 unit tests across 20 test classes - Add PRD and Design docs with cm_global integration marked as DEFERRED * fix(deps): reset use_unified_resolver flag on startup fallback When the unified resolver fails at startup (compile error, install error, uv unavailable, or generic exception), the runtime flag was not being reset to False. This caused subsequent runtime installs to incorrectly defer pip dependencies instead of falling back to per-node pip install. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test(deps): add manual test cases for unified dependency resolver Add environment setup guide and 16 test cases covering: - Normal batch resolution (TC-1), disabled state (TC-2) - Fallback paths: uv unavailable (TC-3), compile fail (TC-4), install fail (TC-5), generic exception (TC-16) - install.py preservation (TC-6), runtime defer (TC-13) - Input sanitization: dangerous patterns (TC-7), path separators (TC-8), index-url separation (TC-9), credential redaction (TC-10) - Disabled pack exclusion (TC-11), no-deps path (TC-12) - Both unified resolver guard paths (TC-14), post-fallback (TC-15) Includes API reference, traceability matrix, and out-of-scope items. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(deps): prevent read_config() from overriding resolver fallback state read_config() in manager_core.py unconditionally re-read use_unified_resolver from config.ini, undoing the False set by prestartup_script.py on resolver fallback. This caused runtime installs to still defer deps even after a startup batch failure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(deps): support multiple index URLs per line and optimize downgrade check - Rewrite _split_index_url() to handle multiple --index-url / --extra-index-url options on a single requirements.txt line using regex-based parsing instead of single split. - Cache installed_packages snapshot in collect_requirements() to avoid repeated subprocess calls during downgrade blacklist checks. - Add unit tests for multi-URL lines and bare --index-url edge case. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test(deps): add E2E scripts and update test documentation Add automated E2E test scripts for unified dependency resolver: - setup_e2e_env.sh: idempotent environment setup (clone ComfyUI, create venv, install deps, symlink Manager, write config.ini) - start_comfyui.sh: foreground-blocking launcher using tail -f | grep -q readiness detection - stop_comfyui.sh: graceful SIGTERM → SIGKILL shutdown Update test documentation reflecting E2E testing findings: - TEST-environment-setup.md: add automated script usage, document caveats (PYTHONPATH, config.ini path, Manager v4 /v2/ prefix, Blocked by policy, bash ((var++)) trap, git+https:// rejection) - TEST-unified-dep-resolver.md: add TC-17 (restart dependency detection), TC-18 (real node pack integration), Validated Behaviors section, normalize API port to 8199 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(deps): harden input sanitization, expand test coverage, bump version Security: - Add _INLINE_DANGEROUS_OPTIONS regex to catch pip options after package names (--find-links, --constraint, --requirement, --editable, --trusted-host, --global-option, --install-option and short forms) - Stage index URLs in pending_urls, commit only after full line validation to prevent URL injection from rejected lines Tests: - Add 50 new tests: inline sanitization, false-positive guards, parse helpers (_parse_conflicts, _parse_install_output), exception paths (91 → 141 total, all pass) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(cli): add uv-compile command and --uv-compile flag for batch dependency resolution Add two CLI entry points for the unified dependency resolver: - `cm_cli uv-compile`: standalone batch resolution of all installed node pack dependencies via uv pip compile - `cm_cli install --uv-compile`: skip per-node pip, batch-resolve all deps after install completes (mutually exclusive with --no-deps) Both use a shared `_run_unified_resolve()` helper that passes real cm_global values (pip_blacklist, pip_overrides, pip_downgrade_blacklist) and guarantees PIPFixer.fix_broken() runs via try/finally. Update DESIGN, PRD, and TEST docs for consistency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |