Repository navigation
fix(updater): recognize published-port and network_mode Docker endpoints - #890
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Reviewer's GuideThe PR hardens the Docker endpoint recreate guard by modeling DOCKER_HOST as a resolved host/port endpoint, matching published TCP ports and actual container IPs, following network_mode container providers with bounded fail-closed traversal, and documenting and testing the resulting behavior. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
The Docker endpoint guard now also blocks a recreate scope whose container publishes the DOCKER_HOST port on the Docker host (LAN IP, 127.0.0.1, host.docker.internal), and checks a container that shares another container's network through that provider. When the DOCKER_HOST host resolves, containers are matched by that address instead of by name, so a same-named service on a network WUDup is not attached to is no longer blocked. Provider lookups and network_mode cycles fail closed.
Web test fixtures set DOCKER_HOST=tcp://docker:2375, so the endpoint guard queried the machine's real resolver for "docker". An autouse fixture now returns no addresses, keeping results and timing independent of the network.
Split published-port parsing into small helpers to bring its cognitive complexity under the limit, and drop UnicodeError from the resolver's handler since ValueError already covers it. No behavior change.
…network blocking Look up the DOCKER_HOST address only when a stack has a container to check, and at most once per run, so a slow resolver no longer delays runs that check nothing. The retag recreate-scope guard shares the endpoint matching and resolves the same way. Replace the narrowing assert with an explicit ValueError that the guard already treats as a failed lookup. Document that services sharing the endpoint's network are blocked even when their restart would leave the proxy running, and cover IPv6-only addresses, the network_mode hop limit, configured-only port bindings, and retag published-port and network_mode matching.
24b70f2 to
f5f2c30
Compare
Construct DockerEndpoint directly instead of through dataclasses.replace, so static analysis sees the declared return type. No behavior change.
Move the container_identity parsing and matching unit tests out of the updater end-to-end test file, which had grown past the maintainability warning threshold. No tests were added or removed.
Build settings and stack selections before the raises block so each exception test has a single call that can raise.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Exercise the retag guard's ValueError (network_mode cycle) and TypeError (non-object inspect output) paths, which previously had retag coverage only for CommandError. Document that ssh:// DOCKER_HOST values skip the Docker endpoint check, as unix sockets do.
|



Summary
Follow-up to #888. That PR blocks updates that would stop the container serving WUDup's
DOCKER_HOST, but it only matched the host against container names, aliases, IPs and ID prefixes. So it failed open when the proxy is reached through a published host port or shares another container's network withnetwork_mode. It could also falsely block a same-named service on a network WUDup is not attached to. This PR closes those gaps.DOCKER_HOSTport (fromNetworkSettings.PortsorHostConfig.PortBindings) is blocked. This covers a LAN IP,127.0.0.1andhost.docker.internal. Atcp://host with no port defaults to 2375, as the Docker CLI does. Bindings on wildcard or loopback addresses match. A binding on a different specific host address does not.network_mode: service:/container:X: the guard followsHostConfig.NetworkModeto the container that owns the network and matches that container's addresses, names and ports. If the provider cannot be inspected, or the chain loops or runs longer than 5 hops, the update is blocked (fail closed).DOCKER_HOSThost resolves from WUDup, containers are matched by that IP instead of by name, so a same-named service on another network is no longer blocked. If the host does not resolve, name matching is used as before.CONTAINER_DNS_FORMATadds only long-standing inspect fields (NetworkSettings.Ports,HostConfig.PortBindings,HostConfig.NetworkMode), so the template stays valid on older engines.DOCKER_HOSTaddress is looked up only when a stack has a container to check, at most once per run, so a slow resolver no longer delays runs that check nothing. Tests stub the lookup so they never use the machine's real resolver._docker_endpoint_servicestoo, so it now gets the same port,network_modeand address matching, with the same lookup-only-when-needed behaviour.docs/wiki/webui-container.md. Remaining limits: host-network proxies and Docker contexts. A known trade-off: matching on the port alone also blocks an unrelated service that publishes the same host port.Scope
main(which includes fix(updater): block updates that would stop WUDup's Docker endpoint #888 and fix(retag): block retags that would stop WUDup or its Docker endpoint #889). Host-network proxy andDOCKER_CONTEXTdetection remain out of scope.Checklist
README.mdordocs/updated if install, deployment, config, or user-facing behavior changeddocs/examples/template.envordocs/examples/webui.env.exampleupdated if environment variables or example config changed — N/A, no new variablesCHANGELOG.mdedit needed outside release prepTest plan
tests/run-all.sh— rantests/run-all.sh --pythoninstead (2224 passed, 1 skipped)python -m pytest tests/test_python_container_identity_endpoint.py tests/test_python_update_from_wud_docker_endpoint.py tests/test_python_web_retag_apply_scope.pytests/test-docker-update-from-wud.shruff check .CONTAINER_DNS_FORMATwithdocker inspecton Docker 29.8.2 (API 1.56): a container publishing23750->2375/tcpand a second container on--network container:<first>. Both returned valid JSON with the expectedPorts,PortBindingsandNetworkMode: container:<full id>.Serviceisnullwithout a Compose label, which the guard handles._docker_endpoint_serviceson that real output:tcp://127.0.0.1:23750andtcp://host.docker.internal:23750blocked both containers,tcp://127.0.0.1:23751blocked neither, andtcp://wudup-tpl-check:2375blocked both through the name fallback.tests/e2e-docker-compose.shfails locally on OrbStack/macOS in the stack-recreate scenario ("Could not verify whether selected services are running"). It fails the same way on unmodifiedmain, uses a unix-socketDOCKER_HOST(so this guard does not run), and passes in CI'sdocker e2ejob.Danger: docker-review-complete. The only Docker-adjacent code change is the
CONTAINER_DNS_FORMATinspect template insrc/wudup/docker_cli.py. It adds only long-standing inspect fields and was run on a real engine (Docker 29.8.2, API 1.56), as described in the test plan above. CI'sdocker buildanddocker e2ejobs pass.Danger: docker-socket-review-complete. The socket-proxy assumptions were reviewed by two read-only high-risk reviews and checked against real engine output (see above). The guard only adds blocks before mutation: every lookup failure blocks the update, and unix-socket
DOCKER_HOSTvalues skip the check. Read-only and mutation defaults are unchanged.