Replace the delete-before-start workaround with the real mechanism:
SYNO.Docker.Project/build_stream is what the DSM "Erstellen" button calls
(confirmed via DevTools). It pulls updated images and starts the project.
DsmClient.trigger_build_stream(project_id): fires a streaming GET to
build_stream, reads the first SSE chunk to confirm DSM accepted the
request, then closes. ReadTimeout is swallowed (build running server-side).
Immediate JSON error responses are parsed and raised as SynologyError.
redeploy_project simplified from 4 steps to 3:
1. Stop (skip for STOPPED, suppress for BUILD_FAILED)
2. trigger_build_stream — DSM pulls images + starts project
3. Poll for RUNNING (timeout raised from 30s → 5min for large pulls)
build_stream errors are now fatal (abort with clear message).
Removes _read_compose_images_for_project, _try_delete_image and their
json/yaml/re imports — no longer needed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
redeploy_project: replace broken SYNO.Docker.Image/pull with a unified
4-step delete-before-start flow for all project states (RUNNING, STOPPED,
BUILD_FAILED). Reads image tags from the project's compose.yaml via
FileStation before stopping, deletes each cached image (non-fatal), then
starts the project so DSM auto-pulls the latest version. Polls for RUNNING
as before.
update_image_tag: auto-update env vars whose value equals the numeric
version prefix of the old tag when the new tag shares the same
<digits>-<suffix> pattern (e.g. JENKINS_VERSION=2.558 → 2.560 when tag
changes 2.558-jdk21 → 2.560-jdk21). Preview mode lists the pending
auto-updates. Only triggers when the var exists and the pattern matches.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove contextlib.suppress from the image pull step in the BUILD_FAILED
redeploy path. A failed pull (e.g. non-existent tag) now immediately
returns an actionable error pointing to update_image_tag instead of
silently continuing and starting the project with stale/missing image.
Also bumps version 0.2.1 → 0.2.2 and adds CHANGELOG entry.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DSM starts containers asynchronously - start_project returns immediately
while containers are still initialising. Adds _wait_for_project_running:
polls SYNO.Docker.Project/list every 2s up to 30s after issuing start.
Reports RUNNING on success; emits a warning instead of failure on timeout
so callers can still verify with get_project_status.
Applies to all three redeploy paths (RUNNING, STOPPED, BUILD_FAILED).
Also bumps version 0.2.0 → 0.2.1 and adds CHANGELOG entry.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Bug fixes from product test:
1. redeploy_project: BUILD_FAILED now includes explicit image pull (stop → pull → start)
2. delete_image: Distinguishes running vs stopped containers, suggests system_prune for stopped refs
3. New tool delete_container: Verify stopped state before deletion, confirmation required
Tests added for all three paths plus stopped-container edge cases.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Bug 1: Container name hash-prefix (e.g. f93cb8b504f7_jenkins)
- _strip_hash_prefix(): strips 12-char hex prefix and leading slash
- _resolve_container_name(): looks up actual DSM name from container list
- Applied in list_containers (display), container_stats (matching),
get_container_status/get_container_logs/exec_in_container (lookup)
Bug 2: redeploy_project DSM 2101/1202 on wrong project state
- Fetch project status before acting
- RUNNING → stop then start
- STOPPED → start directly (nothing to stop)
- BUILD_FAILED → suppress stop error, then start
- Other → return error with workaround hint
36 tests all passing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>