Compare commits

...

18 commits

Author SHA1 Message Date
Miloslav Trmač
48ecddf2a2
Merge pull request #29383 from lsm5/tf-compose-skips
Some checks are pending
ci / sys local root fedora-prior (push) Blocked by required conditions
ci / int local rootless fedora-prior (push) Blocked by required conditions
ci / sys local rootless fedora-prior (push) Blocked by required conditions
ci / int remote root fedora-prior (push) Blocked by required conditions
ci / sys remote root fedora-prior (push) Blocked by required conditions
ci / int local root fedora-rawhide (push) Blocked by required conditions
ci / sys local root fedora-rawhide (push) Blocked by required conditions
ci / int local rootless fedora-rawhide (push) Blocked by required conditions
ci / sys local rootless fedora-rawhide (push) Blocked by required conditions
ci / int remote root fedora-rawhide (push) Blocked by required conditions
ci / sys remote root fedora-rawhide (push) Blocked by required conditions
ci / apiv2 root fedora-current (push) Blocked by required conditions
ci / bindings root fedora-current (push) Blocked by required conditions
ci / compose_v2 root fedora-current (push) Blocked by required conditions
ci / docker_py root fedora-current (push) Blocked by required conditions
ci / unit root fedora-current (push) Blocked by required conditions
ci / apiv2 rootless fedora-current (push) Blocked by required conditions
ci / compose_v2 rootless fedora-current (push) Blocked by required conditions
ci / unit rootless fedora-current (push) Blocked by required conditions
ci / upgrade v5.3.1 root fedora-current (push) Blocked by required conditions
ci / upgrade v5.6.2 root fedora-current (push) Blocked by required conditions
ci / machine linux amd64 (push) Blocked by required conditions
ci / windows unit (push) Blocked by required conditions
ci / windows e2e (push) Blocked by required conditions
ci / windows machine hyperv (push) Blocked by required conditions
ci / windows machine wsl (push) Blocked by required conditions
ci / macos machine applehv (push) Blocked by required conditions
ci / macos machine libkrun (push) Blocked by required conditions
ci / Total Success (push) Blocked by required conditions
zizmor: GitHub Actions Security Analysis / Zizmor (push) Waiting to run
Packit/TF config update and skip jobs on unavailable composes
2026-08-04 17:40:47 +02:00
Brent Baude
80bf6e6a10
Merge pull request #29227 from ashley-cui/dnsnames
Add dnsnames field & fix alias field
2026-08-04 08:49:33 -05:00
Brent Baude
8e037c2ac3
Merge pull request #29385 from Luap99/llm-policy
link org wide LLM_POLICY
2026-08-04 08:44:52 -05:00
Ashley Cui
d05eddd683 Add dnsnames field & fix alias field
Docker now reserves alias specfically for user-defined aliases, and uses another field, dnsnames, to hold all aliases, including container ID and name.
Part of docker v1.45 compat work, but this touches the cli too, since they updated it there too.

Signed-off-by: Ashley Cui <acui@redhat.com>
2026-08-03 16:19:14 -04:00
Paul Holzinger
7187fe18ec
link org wide LLM_POLICY
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2026-08-03 19:50:16 +02:00
Paul Holzinger
f382980924
Merge pull request #29359 from podmanbot/bump-main-6.2.0-dev
Some checks are pending
ci / sys local root fedora-prior (push) Blocked by required conditions
ci / int local rootless fedora-prior (push) Blocked by required conditions
ci / sys local rootless fedora-prior (push) Blocked by required conditions
ci / int remote root fedora-prior (push) Blocked by required conditions
ci / sys remote root fedora-prior (push) Blocked by required conditions
ci / int local root fedora-rawhide (push) Blocked by required conditions
ci / sys local root fedora-rawhide (push) Blocked by required conditions
ci / int local rootless fedora-rawhide (push) Blocked by required conditions
ci / sys local rootless fedora-rawhide (push) Blocked by required conditions
ci / int remote root fedora-rawhide (push) Blocked by required conditions
ci / sys remote root fedora-rawhide (push) Blocked by required conditions
ci / apiv2 root fedora-current (push) Blocked by required conditions
ci / bindings root fedora-current (push) Blocked by required conditions
ci / compose_v2 root fedora-current (push) Blocked by required conditions
ci / docker_py root fedora-current (push) Blocked by required conditions
ci / unit root fedora-current (push) Blocked by required conditions
ci / apiv2 rootless fedora-current (push) Blocked by required conditions
ci / compose_v2 rootless fedora-current (push) Blocked by required conditions
ci / unit rootless fedora-current (push) Blocked by required conditions
ci / upgrade v5.3.1 root fedora-current (push) Blocked by required conditions
ci / upgrade v5.6.2 root fedora-current (push) Blocked by required conditions
ci / machine linux amd64 (push) Blocked by required conditions
ci / windows unit (push) Blocked by required conditions
ci / windows e2e (push) Blocked by required conditions
ci / windows machine hyperv (push) Blocked by required conditions
ci / windows machine wsl (push) Blocked by required conditions
ci / macos machine applehv (push) Blocked by required conditions
ci / macos machine libkrun (push) Blocked by required conditions
ci / Total Success (push) Blocked by required conditions
zizmor: GitHub Actions Security Analysis / Zizmor (push) Waiting to run
Bump main to v6.2.0-dev
2026-08-03 19:32:46 +02:00
Paul Holzinger
67aa9604b5
Merge pull request #28980 from stefan8/fix/image-volume-default-anonymous
docs: fix --image-volume default and accepted values
2026-08-03 18:56:39 +02:00
Paul Holzinger
7b8254d544
Merge pull request #29381 from ricardobranco777/skipnoamd64
test/e2e/healthcheck: skip ignore-result test on non-amd64
2026-08-03 17:43:32 +02:00
Lokesh Mandvekar
09737e1534
packit: Add fedora-45 to downstream targets
Fedora 45 will be branching from rawhide soon.

Signed-off-by: Lokesh Mandvekar <lsm5@redhat.com>
2026-08-03 11:39:55 -04:00
Lokesh Mandvekar
312a1f7e51
packit: Skip tests when branched composes are unavailable
Add skip_missing_branched_composes to test jobs to skip Testing Farm
runs when freshly branched Fedora versions don't have composes ready.

Ref: https://github.com/packit/packit-service/issues/2992
Signed-off-by: Lokesh Mandvekar <lsm5@redhat.com>
2026-08-03 11:38:06 -04:00
Brent Baude
962496a154
Merge pull request #29346 from podman-container-tools/renovate/google.golang.org-grpc-1.x
Some checks are pending
ci / sys local root fedora-prior (push) Blocked by required conditions
ci / int local rootless fedora-prior (push) Blocked by required conditions
ci / sys local rootless fedora-prior (push) Blocked by required conditions
ci / int remote root fedora-prior (push) Blocked by required conditions
ci / sys remote root fedora-prior (push) Blocked by required conditions
ci / int local root fedora-rawhide (push) Blocked by required conditions
ci / sys local root fedora-rawhide (push) Blocked by required conditions
ci / int local rootless fedora-rawhide (push) Blocked by required conditions
ci / sys local rootless fedora-rawhide (push) Blocked by required conditions
ci / int remote root fedora-rawhide (push) Blocked by required conditions
ci / sys remote root fedora-rawhide (push) Blocked by required conditions
ci / apiv2 root fedora-current (push) Blocked by required conditions
ci / bindings root fedora-current (push) Blocked by required conditions
ci / compose_v2 root fedora-current (push) Blocked by required conditions
ci / docker_py root fedora-current (push) Blocked by required conditions
ci / unit root fedora-current (push) Blocked by required conditions
ci / apiv2 rootless fedora-current (push) Blocked by required conditions
ci / compose_v2 rootless fedora-current (push) Blocked by required conditions
ci / unit rootless fedora-current (push) Blocked by required conditions
ci / upgrade v5.3.1 root fedora-current (push) Blocked by required conditions
ci / upgrade v5.6.2 root fedora-current (push) Blocked by required conditions
ci / machine linux amd64 (push) Blocked by required conditions
ci / windows unit (push) Blocked by required conditions
ci / windows e2e (push) Blocked by required conditions
ci / windows machine hyperv (push) Blocked by required conditions
ci / windows machine wsl (push) Blocked by required conditions
ci / macos machine applehv (push) Blocked by required conditions
ci / macos machine libkrun (push) Blocked by required conditions
ci / Total Success (push) Blocked by required conditions
zizmor: GitHub Actions Security Analysis / Zizmor (push) Waiting to run
Update module google.golang.org/grpc to v1.83.0
2026-08-03 10:09:23 -05:00
Ricardo Branco
e421a366f5
test/e2e/healthcheck: skip ignore-result test on non-amd64
The badhealthcheck image is available only on amd64.

Skip the test on non-amd64 hosts.

Signed-off-by: Ricardo Branco <rbranco@suse.de>
2026-08-03 15:10:35 +02:00
Paul Holzinger
f0b3c87e3b
Merge pull request #29371 from podman-container-tools/renovate/zizmorcore-zizmor-action-0.x
Update zizmorcore/zizmor-action action to v0.6.2
2026-08-03 11:58:58 +02:00
renovate[bot]
49fa7ef55f
Update zizmorcore/zizmor-action action to v0.6.2
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-01 21:49:30 +00:00
mheon
fc1c8d7309 Bump main to v6.2.0-dev
Signed-off-by: mheon <7735048+mheon@users.noreply.github.com>
2026-07-31 17:59:57 +00:00
renovate[bot]
92e1d18a9f
Update module google.golang.org/grpc to v1.83.0
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-30 05:32:35 +00:00
Grzegorz Szczepanczyk
44284406aa podman: warn on deprecated --image-volume=bind
"bind" is a deprecated alias for "anonymous" (documented in the preceding
commit). Emit a warning from CreateInit so that "podman create" and "podman
run" nudge users who pass --image-volume=bind toward --image-volume=anonymous.

The warning only fires when the value is explicitly set to "bind"; the
resulting behavior is otherwise unchanged.

Signed-off-by: Grzegorz Szczepanczyk <g.szczepanczyk@getprintbox.com>
2026-06-29 16:20:47 +02:00
Grzegorz Szczepanczyk
da5b172766 docs: fix --image-volume default and accepted values
The docs, the create/run --help text and the shell completion all show
"bind" as the main/default value for --image-volume. That's wrong: the
accepted values are ignore | tmpfs | anonymous
(pkg/specgen/container_validate.go), the default is anonymous
(pkg/specgen/specgen.go), and "bind" is only a deprecated alias the code
maps to anonymous (pkg/specgenutil/specgen.go,
pkg/specgen/generate/kube/kube.go).

Show "anonymous" everywhere (options man page, the Quadlet ImageVolume=
key, --help, completion) and note that "bind" still works as a deprecated
alias. Behavior is unchanged.

Fixes: #27674

Signed-off-by: Grzegorz Szczepanczyk <g.szczepanczyk@getprintbox.com>
2026-06-29 12:35:25 +02:00
31 changed files with 286 additions and 229 deletions

View file

@ -27,4 +27,4 @@ jobs:
persist-credentials: false
- name: Run zizmor 🌈
uses: zizmorcore/zizmor-action@6fc4b006235f201fdab3722e17240ab420d580e5 # v0.6.1
uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2

View file

@ -103,6 +103,7 @@ jobs:
- job: tests
trigger: pull_request
packages: [podman-fedora]
skip_missing_branched_composes: true
notifications: *packit_generic_failure_notification
targets:
- fedora-all
@ -117,6 +118,7 @@ jobs:
identifier: cockpit-revdeps
trigger: pull_request
packages: [podman-fedora]
skip_missing_branched_composes: true
notifications:
failure_comment:
message: "Cockpit tests failed for commit {commit_sha}. @jelly, @mvollmer please check."
@ -164,6 +166,7 @@ jobs:
packages: [podman-fedora]
dist_git_branches: &fedora_targets
- fedora-rawhide
- fedora-45
- job: koji_build
trigger: commit

View file

@ -1,81 +1,3 @@
![PODMAN logo](https://raw.githubusercontent.com/containers/common/main/logos/podman-logo-full-vert.png)
# Podman LLM (AI) Development Policy
# Podman Container Tools LLM (AI) Development Policy
This document is based on [Jellyfin LLM Policy](https://jellyfin.org/docs/general/contributing/llm-policies/)
and licensed under [CC-BY-ND-4.0](http://creativecommons.org/licenses/by-nd/4.0/).
LLMs such as Claude and ChatGPT are powerful development tools. They can
help both experienced and new developers. However, they also introduce risks.
Podman has always prioritized code quality (readability, simplicity, and conciseness)
and friendly communication. Our small team maintains these standards manually. As LLM
usage grows within the Podman community, this policy clarifies our expectations for
contributions and communication across all official projects and spaces.
## No LLM-Generated Direct Communication
LLM output must **not** be used verbatim in:
* Issues or comments
* Pull request bodies, comments, or commit messages.
* Forum or chat posts
* Security and vulnerability reports
All communication must be written in your own words. You must understand what you are submitting.
LLM-written content is often long, impersonal, and error-prone. As a small team with limited
resources, we are unable to spend time reviewing unclear submissions or responding to impersonal
comments.
* Exception: If you use an LLM to translate your thoughts into English, clearly state this
(e.g., “Translated with an LLM from MyLanguage”).
* Exception: The LLM-based bot can be configured by the maintainers to review the PRs
and suggest changes. These changes are only suggestions and might be wrong. Its up
to the contributor and maintainer to decide whether the particular suggestion makes sense.
Repeated violations may result in the closure or deletion of the submission or in a permanent ban from Podman projects.
## LLM Code Contributions
LLMs may assist with code, but you are fully responsible for what you submit.
### Requirements
* Follow all guidelines in [CONTRIBUTING.md](CONTRIBUTING.md).
* Keep changes concise and focused.
* Match existing formatting and quality standards.
* Remove unnecessary comments, poor structure, whitespace issues, and editor/LLM metadata files (e.g., .claude configs).
* The code must build, run, and pass tests before review begins.
* Explicitly test the functionality you modify.
### Understanding and Ownership
You must:
* Review all generated code.
* Clearly explain (in your own words) what the change does and why in both the PR body and commit message.
* Be able to discuss and justify your changes during review.
Submitting “vibe-coded” or poorly understood changes will result in rejection after a few attempts to correct them.
### Handling Review Feedback
Do not paste reviewer feedback into an LLM and resubmit whatever it generates.
Please engage in the review process by:
* Responding thoughtfully to feedback using your own words.
* Making minimal, targeted changes to address comments.
* Understanding the implementation of required changes.
### Final Discretion
Maintainers have final discretion. PRs that are too large, overly complex, poorly structured,
or difficult to review may be rejected after a few attempts to correct them — regardless
of whether LLMs were used.
Violations may result in the closure or deletion of the submission, or in a permanent ban from Podman projects.
## The Golden Rule
Do not prompt an LLM vaguely. Do not commit the LLM results unchanged. And do not submit them as-is.
Using LLMs as a tool is completely fine. Using them as a replacement for understanding,
responsibility, and craftsmanship is not.
Please read our organization wide policy here: https://github.com/podman-container-tools/community/blob/main/LLM_POLICY.md

View file

@ -1151,9 +1151,9 @@ func AutocompleteCgroupMode(_ *cobra.Command, _ []string, _ string) ([]string, c
}
// AutocompleteImageVolume - Autocomplete image volume options.
// -> "bind", "tmpfs", "ignore"
// -> "anonymous", "tmpfs", "ignore"
func AutocompleteImageVolume(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
imageVolumes := []string{"bind", "tmpfs", "ignore"}
imageVolumes := []string{"anonymous", "tmpfs", "ignore"}
return imageVolumes, cobra.ShellCompDirectiveNoFileComp
}

View file

@ -174,7 +174,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
imageVolumeFlagName := "image-volume"
createFlags.String(
imageVolumeFlagName, cf.ImageVolume,
`Tells podman how to handle the builtin image volumes ("bind"|"tmpfs"|"ignore")`,
`Tells podman how to handle the builtin image volumes ("anonymous"|"tmpfs"|"ignore")`,
)
_ = cmd.RegisterFlagCompletionFunc(imageVolumeFlagName, AutocompleteImageVolume)

View file

@ -243,6 +243,10 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
logrus.Warnf("The --kernel-memory flag is no longer supported. This flag is a noop.")
}
if c.Flag("image-volume") != nil && c.Flag("image-volume").Changed && c.Flag("image-volume").Value.String() == "bind" {
logrus.Warnf("The --image-volume=bind value is deprecated, use --image-volume=anonymous instead")
}
if cliVals.LogDriver == define.PassthroughLogging {
if term.IsTerminal(0) || term.IsTerminal(1) || term.IsTerminal(2) {
return vals, errors.New("the '--log-driver passthrough' option cannot be used on a TTY. If you really want it, use '--log-driver passthrough-tty'")

View file

@ -5,12 +5,14 @@
<< if is_quadlet >>
### `ImageVolume=mode`
<< else >>
#### **--image-volume**=**bind** | *tmpfs* | *ignore*
#### **--image-volume**=**anonymous** | *tmpfs* | *ignore*
<< endif >>
Tells Podman how to handle the builtin image volumes. Default is **bind**.
Tells Podman how to handle the builtin image volumes. Default is **anonymous**.
- **bind**: An anonymous named volume is created and mounted into the container.
- **anonymous**: An anonymous named volume is created and mounted into the container.
- **tmpfs**: The volume is mounted onto the container as a tmpfs, which allows the users to create
content that disappears when the container is stopped.
- **ignore**: All volumes are just ignored and no action is taken.
In the past, a **bind** option was accepted as well. This is deprecated, and currently aliased to **anonymous**.

View file

@ -724,7 +724,8 @@ Special Cases:
### `ImageVolume=`
Tells Podman how to handle the builtin image volumes. Default is **bind**.
Tells Podman how to handle the builtin image volumes. Default is **anonymous**.
In the past, a **bind** option was accepted as well. This is deprecated, and currently aliased to **anonymous**.
Equivalent to the Podman `--image-volume` option.
### `IP=`

2
go.mod
View file

@ -73,7 +73,7 @@ require (
golang.org/x/sync v0.22.0
golang.org/x/sys v0.47.0
golang.org/x/term v0.45.0
google.golang.org/grpc v1.82.1
google.golang.org/grpc v1.83.0
google.golang.org/protobuf v1.36.11
gopkg.in/inf.v0 v0.9.1
gopkg.in/yaml.v3 v3.0.1

4
go.sum
View file

@ -554,8 +554,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ=
google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -739,8 +739,11 @@ type InspectAdditionalNetwork struct {
// Links is presently unused and maintained exclusively for
// compatibility.
Links []string `json:"Links"`
// Aliases are any network aliases the container has in this network.
// Aliases are user-provided network aliases the container has in this network.
Aliases []string `json:"Aliases,omitempty"`
// DNSNames contains the complete list of DNS names that resolve to this
// container, including the container name, user aliases, short ID, and hostname.
DNSNames []string `json:"DNSNames,omitempty"`
}
// InspectNetworkSettings holds information about the network settings of the

View file

@ -70,6 +70,14 @@ func (c *Container) getNetworkOptions(networkOpts []types.NamedPerNetworkOptions
} else {
opts.Networks = networkOpts
}
// Alias should only include user-provided aliases. Append the auto-generated
// aliases (short ID, hostname) so the network backend creates DNS records
// for them. Concat allocates a new slice, avoiding mutation of the stored config.
for i := range opts.Networks {
opts.Networks[i].Aliases = slices.Concat(opts.Networks[i].Aliases, getExtraNetworkAliases(c))
}
return opts
}
@ -273,6 +281,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
netInfo := new(define.InspectAdditionalNetwork)
netInfo.NetworkID = getNetworkID(net.Name)
netInfo.Aliases = net.Aliases
netInfo.DNSNames = c.dnsNamesForNetwork(net.Aliases)
settings.Networks[net.Name] = netInfo
}
} else {
@ -305,6 +314,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
addedNet := new(define.InspectAdditionalNetwork)
addedNet.NetworkID = getNetworkID(network.Name)
addedNet.Aliases = network.Aliases
addedNet.DNSNames = c.dnsNamesForNetwork(network.Aliases)
addedNet.InspectBasicNetworkConfig = resultToBasicNetworkConfig(result)
settings.Networks[network.Name] = addedNet
@ -545,8 +555,6 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe
// get network status before we connect
networkStatus := c.getNetworkStatus()
netOpts.Aliases = append(netOpts.Aliases, getExtraNetworkAliases(c)...)
// check whether interface is to be named as the network_interface
// when name left unspecified
if netOpts.InterfaceName == "" {
@ -560,6 +568,7 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe
return errors.New("could not find free network interface name")
}
}
netOpts.Aliases = slices.Compact(slices.Sorted(slices.Values(netOpts.Aliases)))
namedOpts := types.NamedPerNetworkOptions{
Name: netName,
PerNetworkOptions: netOpts,
@ -597,7 +606,9 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe
NetworkOrder: append(networkNamesFromOpts(networks), netName),
}
opts.PortMappings = c.convertPortMappings()
opts.Networks = []types.NamedPerNetworkOptions{namedOpts}
setupOpts := namedOpts
setupOpts.Aliases = slices.Concat(setupOpts.Aliases, getExtraNetworkAliases(c))
opts.Networks = []types.NamedPerNetworkOptions{setupOpts}
results, err := c.runtime.setUpNetwork(c.state.NetNS, opts)
if err != nil {
@ -701,6 +712,17 @@ func getExtraNetworkAliases(c *Container) []string {
return alias
}
func (c *Container) dnsNamesForNetwork(aliases []string) []string {
all := slices.Concat([]string{c.Name()}, aliases, getExtraNetworkAliases(c))
names := all[:0]
for _, n := range all {
if !slices.Contains(names, n) {
names = append(names, n)
}
}
return names
}
// DisconnectContainerFromNetwork removes a container from its network
func (r *Runtime) DisconnectContainerFromNetwork(nameOrID, netName string, force bool) error {
ctr, err := r.LookupContainer(nameOrID)

View file

@ -11,6 +11,7 @@ import (
"os"
"path"
"path/filepath"
"slices"
"strings"
"time"
@ -298,9 +299,8 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
return nil, errors.New("failed to find free network interface name")
}
}
network.Aliases = append(network.Aliases, getExtraNetworkAliases(ctr)...)
network.Name = netName
network.Aliases = slices.Compact(slices.Sorted(slices.Values(network.Aliases)))
normalizeNetworks = append(normalizeNetworks, network)
}
ctr.config.Networks = normalizeNetworks

View file

@ -1007,3 +1007,32 @@ t GET containers/healthcheck-test-running/json 200 \
.State.Health.Status="healthy"
podman rm -f healthcheck-test-running
#
# Test DNSNames / Aliases field in container inspect
#
podman network create dnstest
podman create --name dnscontainer --network dnstest --hostname myhostname --network-alias myalias $IMAGE top
t GET containers/dnscontainer/json 200
cid=$(jq -r '.Id' <<<"$output")
short_id=${cid:0:12}
# Compat API should return DNSNames and user-only Aliases
t GET containers/dnscontainer/json 200 \
.NetworkSettings.Networks.dnstest.Aliases[0]=myalias \
.NetworkSettings.Networks.dnstest.DNSNames[0]=dnscontainer \
.NetworkSettings.Networks.dnstest.DNSNames[1]=myalias \
.NetworkSettings.Networks.dnstest.DNSNames[2]=$short_id \
.NetworkSettings.Networks.dnstest.DNSNames[3]=myhostname
# Test network connect adds DNSNames but not short ID/hostname to Aliases
podman network create dnstest2
t POST networks/dnstest2/connect Container=dnscontainer 200
t GET containers/dnscontainer/json 200 \
.NetworkSettings.Networks.dnstest2.Aliases=null \
.NetworkSettings.Networks.dnstest2.DNSNames[0]=dnscontainer \
.NetworkSettings.Networks.dnstest2.DNSNames[1]=$short_id
# cleanup
podman rm -f dnscontainer
podman network rm -f dnstest dnstest2

View file

@ -140,4 +140,31 @@ var _ = Describe("Podman container inspect", func() {
Expect(data).To(HaveLen(1))
Expect(data[0].Config.Env).To(ContainElement(Equal(secretName + "=*******")))
})
It("podman inspect NetworkSettings DNSNames and Aliases", func() {
netName := "dnstest"
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
defer podmanTest.removeNetwork(netName)
ctrName := "testdns"
session = podmanTest.Podman([]string{"create", "--name", ctrName, "--hostname", "myhostname", "--network", netName, "--network-alias", "myalias", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
cid := session.OutputToString()
data := podmanTest.InspectContainer(ctrName)
Expect(data).To(HaveLen(1))
Expect(data[0].NetworkSettings.Networks).To(HaveKey(netName))
network := data[0].NetworkSettings.Networks[netName]
// Aliases should only contain user-provided alias
Expect(network.Aliases).To(Equal([]string{"myalias"}))
// DNSNames should contain container name, user alias, short ID, and hostname
Expect(network.DNSNames).To(ContainElement(ctrName))
Expect(network.DNSNames).To(ContainElement("myalias"))
Expect(network.DNSNames).To(ContainElement(cid[0:12]))
Expect(network.DNSNames).To(ContainElement("myhostname"))
})
})

View file

@ -169,6 +169,7 @@ var _ = Describe("Podman healthcheck run", func() {
})
It("podman healthcheck --ignore-result exits 0 on failing healthcheck", func() {
SkipIfNotAMD64() // https://github.com/containers/podman/issues/28269
session := podmanTest.Podman([]string{"run", "-q", "-dt", "--name", "hc", "quay.io/libpod/badhealthcheck:latest"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())

View file

@ -115,11 +115,17 @@ var _ = Describe("Podman network connect and disconnect", func() {
Expect(ctr).Should(ExitCleanly())
cid := ctr.OutputToString()
// network alias container short id is always added and shown in inspect
// Aliases should be empty (no user-provided aliases)
inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{(index .NetworkSettings.Networks \"" + netName + "\").Aliases}}"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).To(Equal("[" + cid[0:12] + "]"))
Expect(inspect.OutputToString()).To(Equal("[]"))
// DNSNames should contain the short ID
inspect = podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{(index .NetworkSettings.Networks \"" + netName + "\").DNSNames}}"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).To(ContainSubstring(cid[0:12]))
con := podmanTest.Podman([]string{"network", "connect", netName, "test"})
con.WaitWithDefaultTimeout()
@ -179,11 +185,17 @@ var _ = Describe("Podman network connect and disconnect", func() {
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).To(Equal("2"))
// network alias container short id is always added and shown in inspect
// Aliases should be empty after network connect (no user-provided aliases)
inspect = podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{(index .NetworkSettings.Networks \"" + newNetName + "\").Aliases}}"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).To(Equal("[" + cid[0:12] + "]"))
Expect(inspect.OutputToString()).To(Equal("[]"))
// DNSNames should contain the short ID
inspect = podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{(index .NetworkSettings.Networks \"" + newNetName + "\").DNSNames}}"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).To(ContainSubstring(cid[0:12]))
exec = podmanTest.Podman([]string{"exec", "test", "ip", "addr", "show", "eth1"})
exec.WaitWithDefaultTimeout()

View file

@ -552,12 +552,13 @@ EOCONF
run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}
{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}
{{(index .NetworkSettings.Networks \"$netname\").Aliases}}"
{{(index .NetworkSettings.Networks \"$netname\").DNSNames}}"
ip="${lines[0]}"
mac="${lines[1]}"
# check network alias for container short id
is "${lines[2]}" "[${cid:0:12} $hostname]" "short container id and hostname in network aliases"
# check DNSNames for container short id and hostname
assert "${lines[2]}" =~ "${cid:0:12}" "short container id in DNSNames"
assert "${lines[2]}" =~ "$hostname" "hostname in DNSNames"
# check /etc/hosts for our entry
run_podman exec $cid cat /etc/hosts
@ -615,9 +616,10 @@ EOCONF
run_podman network connect $netname2 $cid
is "$output" "" "Output should be empty (no errors)"
# check network2 alias for container short id
run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname2\").Aliases}}"
is "$output" "[${cid:0:12} $hostname]" "short container id and hostname in network2 aliases"
# check network2 DNSNames for container short id and hostname
run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname2\").DNSNames}}"
assert "$output" =~ "${cid:0:12}" "short container id in network2 DNSNames"
assert "$output" =~ "$hostname" "hostname in network2 DNSNames"
# curl should work
run curl --max-time 3 -s -S $SERVER/index.txt

View file

@ -24,12 +24,10 @@ import (
"fmt"
"math"
"net/url"
"os"
"slices"
"strings"
"sync"
"sync/atomic"
"syscall"
"time"
"google.golang.org/grpc/balancer"
@ -1573,26 +1571,13 @@ func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address,
// to the provided transport.GoAwayInfo, as specified by gRFC A94:
// https://github.com/grpc/proposal/blob/master/A94-grpc-subchannel-disconnections-metrics.md
func disconnectErrorString(info transport.GoAwayInfo) string {
err := info.Err
var sysErr syscall.Errno
switch {
case info.Reason != transport.GoAwayInvalid:
if info.Reason != transport.GoAwayInvalid {
return fmt.Sprintf("GOAWAY %s", info.GoAwayCode.String())
case err == nil:
return "unknown"
case errors.Is(err, context.Canceled):
return "subchannel shutdown"
case errors.Is(err, syscall.ECONNRESET):
return "connection reset"
case errors.Is(err, syscall.ETIMEDOUT), errors.Is(err, context.DeadlineExceeded), errors.Is(err, os.ErrDeadlineExceeded):
return "connection timed out"
case errors.Is(err, syscall.ECONNABORTED):
return "connection aborted"
case errors.As(err, &sysErr):
return "socket error"
default:
}
if info.Err == nil {
return "unknown"
}
return disconnectErrorLabel(info.Err)
}
// startHealthCheck starts the health checking stream (RPC) to watch the health

View file

@ -0,0 +1,48 @@
//go:build !plan9
/*
*
* Copyright 2026 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package grpc
import (
"context"
"errors"
"os"
"syscall"
)
// disconnectErrorLabel returns the grpc.disconnect_error metric label for a
// transport error, as specified by gRFC A94.
func disconnectErrorLabel(err error) string {
var sysErr syscall.Errno
switch {
case errors.Is(err, context.Canceled):
return "subchannel shutdown"
case errors.Is(err, syscall.ECONNRESET):
return "connection reset"
case errors.Is(err, syscall.ETIMEDOUT), errors.Is(err, context.DeadlineExceeded), errors.Is(err, os.ErrDeadlineExceeded):
return "connection timed out"
case errors.Is(err, syscall.ECONNABORTED):
return "connection aborted"
case errors.As(err, &sysErr):
return "socket error"
default:
return "unknown"
}
}

View file

@ -0,0 +1,39 @@
/*
*
* Copyright 2026 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package grpc
import (
"context"
"errors"
"os"
)
// disconnectErrorLabel returns the grpc.disconnect_error metric label for a
// transport error, as specified by gRFC A94. syscall.Errno does not exist on
// plan9, so only the portable classifications are available.
func disconnectErrorLabel(err error) string {
switch {
case errors.Is(err, context.Canceled):
return "subchannel shutdown"
case errors.Is(err, context.DeadlineExceeded), errors.Is(err, os.ErrDeadlineExceeded):
return "connection timed out"
default:
return "unknown"
}
}

View file

@ -69,9 +69,8 @@ var (
// https://github.com/grpc/proposal/blob/master/A87-mtls-spiffe-support.md
XDSSPIFFEEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_MTLS_SPIFFE", false)
// XDSHTTPConnectEnabled is true if gRPC should parse custom Metadata
// configuring use of an HTTP CONNECT proxy via xDS from cluster resources.
// For more details, see:
// XDSHTTPConnectEnabled controls support for dynamic HTTP CONNECT proxying
// configured via the xDS control plane. For more details, see:
// https://github.com/grpc/proposal/blob/master/A86-xds-http-connect.md
XDSHTTPConnectEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_HTTP_CONNECT", false)
@ -88,7 +87,7 @@ var (
// XDSORCAToLRSPropEnabled controls whether ORCA metrics are explicitly
// filtered and prefix-propagated to the LRS server. For more details, see:
// https://github.com/grpc/proposal/blob/master/A85-lrs-custom-metrics-changes.md
XDSORCAToLRSPropEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_ORCA_LRS_PROPAGATION", false)
XDSORCAToLRSPropEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_ORCA_LRS_PROPAGATION", true)
// XDSClientExtProcEnabled indicates whether ExtProc filter is enabled on
// the client side. For more details, see:

View file

@ -20,10 +20,15 @@ package grpcsync
import (
"context"
"errors"
"google.golang.org/grpc/internal/buffer"
)
// ErrSerializerClosed is returned by ScheduleAndWait if the CallbackSerializer
// was closed before the callback could be scheduled.
var ErrSerializerClosed = errors.New("callback serializer is closed")
// CallbackSerializer provides a mechanism to schedule callbacks in a
// synchronized manner. It provides a FIFO guarantee on the order of execution
// of scheduled callbacks. New callbacks can be scheduled by invoking the
@ -77,6 +82,27 @@ func (cs *CallbackSerializer) ScheduleOr(f func(ctx context.Context), onFailure
}
}
// ScheduleAndWait schedules the provided callback function f to be executed in
// the order it was added and blocks until f has run. If the context passed to
// NewCallbackSerializer was canceled before this method is called, f is not run
// and ScheduleAndWait returns ErrSerializerClosed.
//
// Callbacks are expected to honor the context when performing any blocking
// operations, and should return early when the context is canceled.
func (cs *CallbackSerializer) ScheduleAndWait(f func(ctx context.Context)) error {
done := make(chan struct{})
var err error
cs.ScheduleOr(func(ctx context.Context) {
f(ctx)
close(done)
}, func() {
err = ErrSerializerClosed
close(done)
})
<-done
return err
}
func (cs *CallbackSerializer) run(ctx context.Context) {
defer close(cs.done)

View file

@ -24,7 +24,6 @@ import (
"sync"
"google.golang.org/grpc/internal/serviceconfig"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/resolver"
)
@ -52,82 +51,7 @@ type RPCConfig struct {
Context context.Context
MethodConfig serviceconfig.MethodConfig // configuration to use for this RPC
OnCommitted func() // Called when the RPC has been committed (retries no longer possible)
Interceptor ClientInterceptor
}
// ClientStream is the same as grpc.ClientStream, but defined here for circular
// dependency reasons.
type ClientStream interface {
// Header returns the header metadata received from the server if there
// is any. It blocks if the metadata is not ready to read.
Header() (metadata.MD, error)
// Trailer returns the trailer metadata from the server, if there is any.
// It must only be called after stream.CloseAndRecv has returned, or
// stream.Recv has returned a non-nil error (including io.EOF).
Trailer() metadata.MD
// CloseSend closes the send direction of the stream. It closes the stream
// when non-nil error is met. It is also not safe to call CloseSend
// concurrently with SendMsg.
CloseSend() error
// Context returns the context for this stream.
//
// It should not be called until after Header or RecvMsg has returned. Once
// called, subsequent client-side retries are disabled.
Context() context.Context
// SendMsg is generally called by generated code. On error, SendMsg aborts
// the stream. If the error was generated by the client, the status is
// returned directly; otherwise, io.EOF is returned and the status of
// the stream may be discovered using RecvMsg.
//
// SendMsg blocks until:
// - There is sufficient flow control to schedule m with the transport, or
// - The stream is done, or
// - The stream breaks.
//
// SendMsg does not wait until the message is received by the server. An
// untimely stream closure may result in lost messages. To ensure delivery,
// users should ensure the RPC completed successfully using RecvMsg.
//
// It is safe to have a goroutine calling SendMsg and another goroutine
// calling RecvMsg on the same stream at the same time, but it is not safe
// to call SendMsg on the same stream in different goroutines. It is also
// not safe to call CloseSend concurrently with SendMsg.
SendMsg(m any) error
// RecvMsg blocks until it receives a message into m or the stream is
// done. It returns io.EOF when the stream completes successfully. On
// any other error, the stream is aborted and the error contains the RPC
// status.
//
// It is safe to have a goroutine calling SendMsg and another goroutine
// calling RecvMsg on the same stream at the same time, but it is not
// safe to call RecvMsg on the same stream in different goroutines.
RecvMsg(m any) error
}
// ClientInterceptor is an interceptor for gRPC client streams.
type ClientInterceptor interface {
// NewStream creates a ClientStream for an RPC.
//
// Implementations must delegate stream creation to the provided newStream
// function. To intercept or override stream behavior, implementations
// may wrap the ClientStream returned by the delegate.
//
// Note: RPCInfo.Context is currently unused and will be nil.
//
// The done function is invoked when the RPC has finished using its
// underlying connection or if a connection could not be assigned. Because
// interceptors operate at the application layer, RPC operations may
// continue on the ClientStream even after done has been called. The
// caller must ensure done is non-nil.
//
// To ensure RPC completion notifications propagate through the entire
// interceptor chain, implementations must ensure that the done function
// passed to the delegate newStream invokes the done function passed to
// NewStream.
NewStream(ctx context.Context, ri RPCInfo, done func(), newStream func(ctx context.Context, done func()) (ClientStream, error)) (ClientStream, error)
// Close closes the interceptor. Once called, no new calls to NewStream are
// accepted. Ongoing calls to NewStream are allowed to complete.
Close()
Interceptor any
}
// ServerInterceptor is an interceptor for incoming RPC's on gRPC server side.

View file

@ -39,9 +39,8 @@ const nonGRPCDataMaxLen = 1024
type ClientStream struct {
Stream // Embed for common stream functionality.
ct *http2Client
done chan struct{} // closed at the end of stream to unblock writers.
doneFunc func() // invoked at the end of stream.
ct *http2Client
done chan struct{} // closed at the end of stream to unblock writers.
headerChan chan struct{} // closed to indicate the end of header metadata.
header metadata.MD // the received header metadata

View file

@ -498,7 +498,6 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr, handler s
ct: t,
done: make(chan struct{}),
headerChan: make(chan struct{}),
doneFunc: callHdr.DoneFunc,
statsHandler: handler,
}
s.Stream.buf.init()
@ -998,9 +997,6 @@ func (t *http2Client) closeStream(s *ClientStream, err error, rst bool, rstCode
t.controlBuf.executeAndPut(addBackStreamQuota, cleanup)
// This will unblock write.
close(s.done)
if s.doneFunc != nil {
s.doneFunc()
}
}
// Close kicks off the shutdown process of the transport. This should be called

View file

@ -594,8 +594,6 @@ type CallHdr struct {
PreviousAttempts int // value of grpc-previous-rpc-attempts header to set
DoneFunc func() // called when the stream is finished
// Authority is used to explicitly override the `:authority` header.
//
// This value comes from one of two sources:

View file

@ -201,6 +201,15 @@ func endOfClientStream(cc *ClientConn, err error, opts ...CallOption) {
}
}
// clientInterceptor is structurally identical to the ClientInterceptor defined
// in internal/xds/httpfilter/httpfilter.go. It is defined locally here so that
// we can type-assert the generic Interceptor field in iresolver.RPCConfig
// without introducing a dependency on xDS packages.
type clientInterceptor interface {
NewStream(ctx context.Context, ri iresolver.RPCInfo, newStream func(ctx context.Context, opts ...CallOption) (ClientStream, error), opts ...CallOption) (ClientStream, error)
Close()
}
func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) {
if channelz.IsOn() {
cc.incrCallsStarted()
@ -244,8 +253,11 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
mc := &emptyMethodConfig
var onCommit func()
newStream := func(ctx context.Context, done func()) (iresolver.ClientStream, error) {
return newClientStreamWithParams(ctx, desc, cc, method, mc, onCommit, done, nameResolutionDelayed, opts...)
newStream := func(ctx context.Context, filterOpts ...CallOption) (ClientStream, error) {
if filterOpts != nil {
opts = combine(opts, filterOpts)
}
return newClientStreamWithParams(ctx, desc, cc, method, mc, onCommit, nameResolutionDelayed, opts...)
}
rpcInfo := iresolver.RPCInfo{Context: ctx, Method: method}
@ -270,20 +282,24 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
if rpcConfig.Interceptor != nil {
rpcInfo.Context = nil
ns := newStream
newStream = func(ctx context.Context, done func()) (iresolver.ClientStream, error) {
cs, err := rpcConfig.Interceptor.NewStream(ctx, rpcInfo, done, ns)
if err != nil {
return nil, toRPCErr(err)
if interceptor, ok := rpcConfig.Interceptor.(clientInterceptor); ok {
newStream = func(ctx context.Context, filterOpts ...CallOption) (ClientStream, error) {
cs, err := interceptor.NewStream(ctx, rpcInfo, ns, filterOpts...)
if err != nil {
return nil, toRPCErr(err)
}
return cs, nil
}
return cs, nil
} else {
return nil, status.Errorf(codes.Internal, "invalid client interceptor type %T", rpcConfig.Interceptor)
}
}
}
return newStream(ctx, func() {})
return newStream(ctx)
}
func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, mc *serviceconfig.MethodConfig, onCommit, doneFunc func(), nameResolutionDelayed bool, opts ...CallOption) (_ iresolver.ClientStream, err error) {
func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, mc *serviceconfig.MethodConfig, onCommit func(), nameResolutionDelayed bool, opts ...CallOption) (_ ClientStream, err error) {
callInfo := defaultCallInfo()
if mc.WaitForReady != nil {
callInfo.failFast = !*mc.WaitForReady
@ -321,7 +337,6 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client
Host: cc.authority,
Method: method,
ContentSubtype: callInfo.contentSubtype,
DoneFunc: doneFunc,
Authority: callInfo.authority,
}
if allowed := callInfo.acceptedResponseCompressors; len(allowed) > 0 {

View file

@ -19,4 +19,4 @@
package grpc
// Version is the current grpc version.
const Version = "1.82.1"
const Version = "1.83.0"

2
vendor/modules.txt vendored
View file

@ -1091,7 +1091,7 @@ google.golang.org/genproto/googleapis/api/annotations
# google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa
## explicit; go 1.25.0
google.golang.org/genproto/googleapis/rpc/status
# google.golang.org/grpc v1.82.1
# google.golang.org/grpc v1.83.0
## explicit; go 1.25.0
google.golang.org/grpc
google.golang.org/grpc/attributes

View file

@ -4,4 +4,4 @@ package rawversion
//
// This indirection is needed to prevent semver packages from bloating
// Quadlet's binary size.
const RawVersion = "6.1.0-dev"
const RawVersion = "6.2.0-dev"