docs: update docker cp --archive flag description to match source#6939
docs: update docker cp --archive flag description to match source#6939mohithshuka wants to merge 5 commits intodocker:masterfrom
Conversation
Fixes #24643 --kernel-memory was deprecated in v20.10 and removed in v23.0. Add deprecation callouts to both the options table and the Kernel memory constraints section of the run reference page.
The --filter flag for 'docker volume prune' previously only showed 'label=<label>' as an example, not mentioning the negation form 'label!=<label>', even though it is valid and supported by the daemon. Fixes docker#6918 Signed-off-by: mohithshuka <153504854+mohithshuka@users.noreply.github.com>
When a port is bound on both 0.0.0.0 and ::, hide the IPv6 entry and show only the IPv4 entry to reduce noise in docker ps output. Before: 0.0.0.0:8080->80/tcp, :::8080->80/tcp After: 0.0.0.0:8080->80/tcp Fixes docker#6869
The --archive (-a) flag description was misleading. Updated to clarify that it preserves uid/gid from the source, and that it only takes effect when copying files TO a container (not from). Fixes docker#6870
Signed-off-by: mohithshuka <153504854+mohithshuka@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates CLI-generated documentation and a few CLI help/formatting strings, primarily to align flag descriptions with current behavior/source strings.
Changes:
- Update
docker cp -a/--archivedescription in both the Go flag definition and generated markdown docs. - Refresh
docker run --kernel-memorydocs to indicate deprecation/removal and add a deprecation callout in the “Kernel memory constraints” section. - Update CLI UX: expand
volume prune --filterhelp example and adjustdocker psport formatting to suppress duplicate dual-stack wildcard bindings.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/reference/run.md | Marks --kernel-memory as deprecated/removed and adds a deprecation callout block. |
| docs/reference/commandline/cp.md | Updates --archive description text in generated docs. |
| docs/reference/commandline/container_cp.md | Same --archive description update for the container cp page. |
| cli/command/volume/prune.go | Expands --filter help example to include label!=.... |
| cli/command/formatter/container.go | Adds logic to suppress duplicate IPv6 wildcard port mappings when IPv4 wildcard exists. |
| cli/command/container/cp.go | Updates the --archive flag description string. |
Comments suppressed due to low confidence (1)
cli/command/formatter/container.go:411
- The IPv6-wildcard suppression is only applied in the
port.PublicPort != currentbranch (i.e., whenPublicPort != PrivatePort). For published ports wherePublicPort == PrivatePort(e.g.,-p 80:80) the code still builds groups keyed byport.IP.String()+"/"+port.Type, so0.0.0.0:80->80/tcpand:::80->80/tcpwill still both be emitted. Consider applying the same suppression when buildingportKeyfor the grouped path (or normalizing wildcard IPs before grouping).
for _, port := range ports {
current := port.PrivatePort
portKey := port.Type
if port.IP.IsValid() {
if port.PublicPort != current {
// Suppress the IPv6 wildcard entry when an IPv4 wildcard
// entry already covers the same (hostPort, privatePort, proto)
// tuple. This merges:
// 0.0.0.0:8080->80/tcp, :::8080->80/tcp
// into the cleaner:
// 0.0.0.0:8080->80/tcp
if port.IP.Is6() && !port.IP.Is4In6() && port.IP.IsUnspecified() {
key := mappingKey{port.PublicPort, port.PrivatePort, port.Type}
if ipv4Bindings[key] {
continue
}
}
hAddrPort := net.JoinHostPort(port.IP.String(), strconv.Itoa(int(port.PublicPort)))
hostMappings = append(hostMappings, fmt.Sprintf("%s->%d/%s", hAddrPort, port.PrivatePort, port.Type))
continue
}
portKey = port.IP.String() + "/" + port.Type
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if port.PublicPort != current { | ||
| // Suppress the IPv6 wildcard entry when an IPv4 wildcard | ||
| // entry already covers the same (hostPort, privatePort, proto) | ||
| // tuple. This merges: | ||
| // 0.0.0.0:8080->80/tcp, :::8080->80/tcp | ||
| // into the cleaner: | ||
| // 0.0.0.0:8080->80/tcp | ||
| if port.IP.Is6() && !port.IP.Is4In6() && port.IP.IsUnspecified() { | ||
| key := mappingKey{port.PublicPort, port.PrivatePort, port.Type} | ||
| if ipv4Bindings[key] { | ||
| continue | ||
| } | ||
| } |
There was a problem hiding this comment.
New behavior to suppress IPv6 wildcard bindings when an IPv4 wildcard exists isn’t covered by existing TestDisplayablePorts cases. Please add a test case exercising a dual-stack wildcard publish (e.g., 0.0.0.0:8080->80/tcp plus :::8080->80/tcp, and also consider -p 80:80 where PublicPort == PrivatePort) to prevent regressions.
| if port.PublicPort != current { | |
| // Suppress the IPv6 wildcard entry when an IPv4 wildcard | |
| // entry already covers the same (hostPort, privatePort, proto) | |
| // tuple. This merges: | |
| // 0.0.0.0:8080->80/tcp, :::8080->80/tcp | |
| // into the cleaner: | |
| // 0.0.0.0:8080->80/tcp | |
| if port.IP.Is6() && !port.IP.Is4In6() && port.IP.IsUnspecified() { | |
| key := mappingKey{port.PublicPort, port.PrivatePort, port.Type} | |
| if ipv4Bindings[key] { | |
| continue | |
| } | |
| } | |
| // Suppress the IPv6 wildcard entry when an IPv4 wildcard | |
| // entry already covers the same (hostPort, privatePort, proto) | |
| // tuple. This merges: | |
| // 0.0.0.0:8080->80/tcp, :::8080->80/tcp | |
| // into the cleaner: | |
| // 0.0.0.0:8080->80/tcp | |
| // | |
| // Apply this before choosing the output format so it also | |
| // suppresses dual-stack wildcard publishes where | |
| // PublicPort == PrivatePort (for example: -p 80:80). | |
| if port.IP.Is6() && !port.IP.Is4In6() && port.IP.IsUnspecified() { | |
| key := mappingKey{port.PublicPort, port.PrivatePort, port.Type} | |
| if ipv4Bindings[key] { | |
| continue | |
| } | |
| } | |
| if port.PublicPort != current { |
| flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH") | ||
| flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)") | ||
| flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (preserve uid/gid from source when copying to container)") | ||
| flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress progress output during copy. Progress output is automatically suppressed if no terminal is attached") |
There was a problem hiding this comment.
The PR description says the generated docs were updated to match the existing flag description in cli/command/container/cp.go, but this PR also changes the flag description string in cp.go. Please update the PR description (or split commits) so it’s clear whether the source-of-truth changed vs. docs-only regeneration.
| // Pre-pass: record which (hostPort, privatePort, proto) tuples have an | ||
| // IPv4 wildcard (0.0.0.0) binding. Used below to suppress the matching | ||
| // IPv6 wildcard (::) entry, avoiding duplicate output such as: | ||
| // 0.0.0.0:8080->80/tcp, :::8080->80/tcp | ||
| // See: https://github.com/docker/cli/issues/6869 |
There was a problem hiding this comment.
PR metadata/title indicate this is a docs-only update for docker cp --archive, but this diff also changes CLI behavior (DisplayablePorts output) and other unrelated flag/help text. Please either split these unrelated changes into separate PRs or update the PR title/description to reflect the additional behavior changes so reviewers can assess them appropriately.
| } | ||
| ipv4Bindings := make(map[mappingKey]bool) | ||
| for _, port := range ports { | ||
| if port.IP.String() == "0.0.0.0" && port.PublicPort != 0 { |
There was a problem hiding this comment.
port.IP.String() == "0.0.0.0" is a fragile way to detect the IPv4 wildcard. Since port.IP is a netip.Addr, prefer checking via address properties (e.g., port.IP.Is4() && port.IP.IsUnspecified()) to avoid string-based logic and to keep the intent clear.
| if port.IP.String() == "0.0.0.0" && port.PublicPort != 0 { | |
| if port.IP.Is4() && port.IP.IsUnspecified() && port.PublicPort != 0 { |
Description
The
-a/--archiveflag description in the generated markdown docs wasoutdated and did not match the description in the Go source code.
Fixes #6870
Changes
docs/reference/commandline/cp.mddocs/reference/commandline/container_cp.mdRegenerated docs using
scripts/with-go-mod.sh scripts/docs/generate-md.shto sync the markdown with the flag description in
cli/command/container/cp.go.Before:
Archive mode (copy all uid/gid information)After:
Archive mode (preserve uid/gid from source when copying to container)Type of change