Skip to content

pkg/specgen: fix port conflict on host assignment#28889

Merged
Honny1 merged 1 commit into
podman-container-tools:mainfrom
Luap99:port-conflict
Jun 10, 2026
Merged

pkg/specgen: fix port conflict on host assignment#28889
Honny1 merged 1 commit into
podman-container-tools:mainfrom
Luap99:port-conflict

Conversation

@Luap99

@Luap99 Luap99 commented Jun 8, 2026

Copy link
Copy Markdown
Member

This fixes two problems when parsing ports.

First, check for host port conflicts. When we are given the same ip:host port combo twice then we need to reject that as invalid, the backend cannot bind the same port twice and thus we always get a runtime failure. Failing early in the create code path is much better.

Second, when assigning random ports for expose we still have to check for proper conflicts. The first error was using allUsedContainerPortsMap to check for conflicts but this holds container side ports, we need to ensure there are no conflicts on the host port.

Then there was the other issue that the array in the map was copied and accessed by value on lookup. And because the code did not reassign the value it then failed to actually update the correct ports. To address that I switch the map to store the array by reference which will avoid the bigger copies as we only need to update the pointer now.

Does this PR introduce a user-facing change?

Fixed a problem where duplicated host ports were not rejected when validating the given ports on container creation causing to failures on startup

@Luap99 Luap99 mentioned this pull request Jun 8, 2026
6 tasks

@baude baude left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@baude

baude commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

I approved this but given the host port test failures, which I didn't look at very deeply, I'm not sure if something isnt quite right.

@packit-as-a-service

Copy link
Copy Markdown

[NON-BLOCKING] Packit jobs failed. @containers/packit-build please check. Everyone else, feel free to ignore.

@Luap99

Luap99 commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

I approved this but given the host port test failures, which I didn't look at very deeply, I'm not sure if something isnt quite right.

Which failure, this one?

not ok 411 |505| TCP/IPv6 small transfer, loopback in 2733ms
# tags: ci:parallel
# (from function `bail-now' in file test/system/helpers.bash, line 230,
#  from function `die' in file test/system/helpers.bash, line 967,
#  from function `run_podman' in file test/system/helpers.bash, line 608,
#  from function `pasta_test_do' in file test/system/505-networking-pasta.bats, line 217,
#  in test file test/system/505-networking-pasta.bats, line 728)
#   `pasta_test_do' failed
# 1+0 records in
# 1+0 records out
# 2048 bytes (2.0 kB, 2.0 KiB) copied, 2.2775e-05 s, 89.9 MB/s
#
# [19:23:04.694628253] $ /var/tmp/podman/bin/podman  run -i --rm quay.io/libpod/testimage:20241011 /home/podman/bytecheck
# [19:23:06.291931422] size=2048 hash=db2533aee456df7282f926f54d181b72 - head= 6b db 9a 4c a3 c1 cf 3f tail= 6d 76 b4 91 e6 15 1a 07
#
# [19:23:06.310133900] $ /var/tmp/podman/bin/podman  run -d --name=c-socat-t411-0t9q6elp --net=pasta -p [::1]:5355:5355/tcp quay.io/libpod/testimage:20241011 sh -c for port in $(seq 5355 5355); do                              socat -u TCP6-LISTEN:${port} EXEC:/home/podman/bytecheck &                          done; wait
# [19:23:06.554964513] Error: pasta failed with exit code 1:
# Listen failed for HOST TCP port ::1/5355: Address already in use
# Couldn't listen on requested ports
# [19:23:06.558853441] [ rc=126 (** EXPECTED 0 **) ]
# #/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# #| FAIL: exit code is 126; expected 0
# #\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # [teardown]

That is unrelated and has flaked before I have not looked into into what is going on with that.

@giuseppe giuseppe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Honny1 Honny1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just one non-blocking comment.

Comment thread pkg/specgen/generate/ports.go Outdated
h := port.HostPort + i
allHostPorts[h] = true
if currentHostPorts[h] {
return fmt.Errorf("host port %q was already assigned in another port mapping", net.JoinHostPort(port.HostIP, strconv.Itoa(int(port.HostPort)))+"/"+port.Protocol)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: This error msg will contain port.HostPort. That could be misleading if the port is used in range.

Suggested change
return fmt.Errorf("host port %q was already assigned in another port mapping", net.JoinHostPort(port.HostIP, strconv.Itoa(int(port.HostPort)))+"/"+port.Protocol)
return fmt.Errorf("host port %q was already assigned in another port mapping", net.JoinHostPort(port.HostIP, strconv.Itoa(int(h)))+"/"+port.Protocol)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, let me repush and add a test for it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I can fix this inconsistency but I cannot add a test because we never get here in this case
We are failing before that with "conflicting port mappings for host port "

And if there are overlapping ranges we accept and merge them into one

@Honny1

Honny1 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

I think you should rebase on upstream main. At least, that fixed the same failure for me on my PR.

This fixes two problems when parsing ports.

First, check for host port conflicts. When we are given the same ip:host
port combo twice then we need to reject that as invalid, the backend
cannot bind the same port twice and thus we always get a runtime
failure. Failing early in the create code path is much better.

Second, when assigning random ports for expose we still have to check
for proper conflicts. The first error was using allUsedContainerPortsMap
to check for conflicts but this holds container side ports, we need to
ensure there are no conflicts on the host port.

Then there was the other issue that the array in the map was copied and
accessed by value on lookup. And because the code did not reassign the
value it then failed to actually update the correct ports.
To address that I switch the map to store the array by reference which
will avoid the bigger copies as we only need to update the pointer now.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
@Luap99

Luap99 commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

I think you should rebase on upstream main. At least, that fixed the same failure for me on my PR.

I thought I did but I guess not, I really do not get the random golangci-lint failures like that.

@Honny1

Honny1 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

I think you should rebase on upstream main. At least, that fixed the same failure for me on my PR.

I thought I did but I guess not, I really do not get the random golangci-lint failures like that.

Me neither, but it seems very strange. I'm not sure where the problem could be.

@Honny1 Honny1 merged commit d55b0a0 into podman-container-tools:main Jun 10, 2026
117 of 120 checks passed
@Luap99 Luap99 deleted the port-conflict branch June 10, 2026 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants