Repository navigation
Reject top-level sections indented under services with a clear error - #1583
Open
Thanatos9404 wants to merge 1 commit into
Open
Thanatos9404 wants to merge 1 commit into
Thanatos9404 wants to merge 1 commit into
Conversation
When `networks`, `volumes`, `secrets` or `configs` is indented under `services` by mistake, YAML turns the section into a service with that name. podman-compose then failed later with a traceback that hides the cause, such as `RuntimeError: missing networks: mynet` for the compose file in the issue, or it accepted a misplaced `secrets` or `configs` section as a service. This commit adds check_misplaced_top_level_sections(), which runs in _parse_compose_file() before `extends` and the networks are resolved. When a service with one of these names has no `build` or `extends` and no string `image` or `x-podman.rootfs`, it raises a PodmanComposeError that names the section and points at the indentation. A service may be named `networks` and the like, and such a real service has one of these keys, so it keeps working. The downside of this rule: a misplaced section with an entry named `build` or `extends` is not detected and fails as before. Fixes: containers#1549 Signed-off-by: Yashvardhan Thanvi <yashvt9404@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When
networks,volumes,secretsorconfigsis indented underservicesby mistake, YAML parses the section as a service with that name. podman-compose then fails late with a traceback whose message hides the cause, or does not fail at all:networks(the compose file from the issue):RuntimeError: missing networks: mynetfrom_parse_compose_file(), althoughmynetis in the file.volumes:RuntimeError: volume [data] not defined in top level.secretsandconfigs:podman-compose configaccepts the file and prints the section as a service.Fixes: #1549
With this change,
podman-compose configon the file from the issue printsand exits with 1, without a traceback (
main()already catchesPodmanComposeError). The compose file from #552, where bothnetworksandvolumesare indented this way, gets the same message.Which services are reported
A service may legitimately be called
networks,volumes,secretsorconfigs: the Compose schema accepts any service name matching^[a-zA-Z0-9._-]+$, and Docker Compose rejects the file in the issue becausemynetis not a service attribute, not because of the service name. podman-compose has no list of service attributes to check against, so this looks at what a real service needs instead. A service with one of these four names is reported only when it has none of these keys (imageandx-podman.rootfscount only as strings):imageorbuild: Docker Compose refuses a service that has neither, apart from the newerproviderservices that podman-compose does not support (checkConsistencyin compose-go: "has neither an image nor a build context specified").extends: the image or build can come from the extended service. The check runs beforeextendsis resolved.x-podman.rootfs: podman-compose runs such a service without an image.A section moved under
servicesby mistake hasbuildorextendsonly if one of its entries is itself named that way (a volume calledbuild, say). That case is not detected and fails as before; every other misplaced section is reported, including one with an entry namedimage, since an entry is a mapping or null rather than a string. A service that Docker Compose accepts under one of these names keeps working, and services with other names are not checked. The only file that stops working is one with a service named like this that has none of the keys above, which podman-compose would run from an image named after the project and service; Docker Compose rejects that file too (apart fromproviderservices, which podman-compose does not support).The check is a new
check_misplaced_top_level_sections(), called in_parse_compose_file()once the compose files are merged, beforeextends, networks and volumes are resolved.Tests
New
tests/unit/test_misplaced_top_level_sections.py, through_parse_compose_file():networks,volumes,secretsandconfigsindented underservices, next to a service that uses it;networks,volumes,secretsandconfigswithimage, withbuild, withextendsand withx-podman.rootfs, which still parse;networksorvolumessection with an entry namedimage, which is still reported;volumesthat gets itsimagefrom a second compose file, which still parses.On
main, 7 of the 12 tests fail: the misplacednetworkscases withRuntimeError: missing networks: ..., thevolumescases withRuntimeError: volume [...] not defined in top level, andsecretsandconfigsbecause nothing is raised. The 5 tests for real services pass onmainas well and guard against rejecting them.Results on Ubuntu 24.04 (WSL), Python 3.12.3, with
requirements.txtandtest-requirements.txtinstalled:python -m unittest discover tests/unit: 509 tests OK (497 onmain, also OK).ruff format --check,ruff check,mypy .andpylint podman_compose.py(10.00/10): pass.configoutput above was checked with--dry-run, as there is no Podman on this machine, so the integration tests were not run. The change only affects parsing.Checklist
fix:prefix)newsfragments/reject_misplaced_top_level_sections.bugfixtests/unit/test_misplaced_top_level_sections.py