968 Commits
Author SHA1 Message Date
Samuel Karp acbdd57f0d ctr: preserve args after "-" in images export
urfave/cli/v3 breaks out of its flag parsing loop when it encounters a
"-" positional argument without appending the remaining arguments,
causing "ctr images export - <image>" to drop all image references and
flags following "-".

When <out> is "-", recover the un-truncated arguments from the parent
"images" command lineage and re-parse the tail starting at "-" with a
sentinel placeholder so trailing image references and flags are
preserved.

This workaround can be removed after the bug is fixed upstream:

* https://github.com/urfave/cli/issues/2418
* https://github.com/urfave/cli/pull/2419

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
2026-09-24 01:15:18 +00:00
Samuel Karp 2d0e53474d ctr: stop flag parsing before container command
urfave/cli/v3 scans for flags across all positional arguments by
default, which causes flags meant for the container process to be
parsed as ctr flags.

Configure StopOnNthArg to stop flag parsing before the container
command and its arguments:
- "ctr run" and "ctr containers create": after Image|RootFS and
  CONTAINER (2 args)
- "ctr tasks exec": after CONTAINER (1 arg)

Fixes #14208

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
2026-09-23 21:02:42 +00:00
Samuel Karp 2543d23905 ctr: disable slice flag separator on commands
In urfave/cli/v3, child commands do not inherit
DisableSliceFlagSeparator from the root command, unlike in
urfave/cli/v2. When containerd migrated to v3 in commit f72829f36,
subcommands inadvertently reverted to splitting slice flags on commas,
breaking flags that expect comma-separated values such as
--mount type=bind,src=/tmp,dst=/host,options=rbind:ro.

Explicitly set DisableSliceFlagSeparator on all cli.Command structs in
cmd/ctr/commands, restoring the behavior where slice flags are not
split on commas.

Fixes #14181

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
2026-09-17 19:27:36 +00:00
Sebastiaan van Stijn f72829f36b migrate to github.com/urfave/cli/v3
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-10 01:14:31 +02:00
Sebastiaan van Stijn b178103a4f use log.Level consts for log-levels
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-09 08:47:44 +02:00
Sebastiaan van Stijn 861dc7ed7a cmd: commands.NewClient: explicitly pass context
urfave/cli/v3 no longer passes the context through the Command; pass
it explicitly to prepare for the v3 migration.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-05 10:41:31 +02:00
Sebastiaan van Stijn 324866a884 cmd: commands.AppContext: explicitly pass context
urfave/cli/v3 no longer passes the context through the Command; pass
it explicitly to prepare for the v3 migration.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-05 10:41:31 +02:00
Sebastiaan van Stijn bd954e4e2c cmd: initialize CLI apps with struct literals
Although urfave/cli v2 recommends constructing apps with cli.NewApp,
App.Run initializes unset fields through App.Setup, making the zero
value usable. Use struct literals to define the application fields
directly without changing behavior.

This prepares for urfave/cli v3, which removes cli.NewApp and replaces
cli.App with cli.Command.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-05 10:41:29 +02:00
Sebastiaan van Stijn ba71234151 cmd: rename cliContext -> cmd in preparation of v3 migration
In urfave/cli/v3, cli.Context is replaced with cli.Command, making cmd
a more logical name. Rename the vars ahead of time to make the v3
migration a more mechanical change.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-05 10:40:41 +02:00
Sebastiaan van Stijn de193f2059 cmd: edit: pass editor name instead of cli.Context
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-05 10:40:41 +02:00
Sebastiaan van Stijn e6be784a71 cmd: use urfave/cli RunContext
This allows explicitly setting up the context inside main, and makes the
transition to urfave/cli/v3 more transparent.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-05 10:40:33 +02:00
Sebastiaan van Stijn 4d13856983 cmd: remove redundant empty slice flag values
Leave the Value field unset for slice flags without default values. The CLI
initializes these flags with an empty value when they are applied, making
the explicit initializations unnecessary.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-05 03:12:58 +02:00
Sebastiaan van Stijn 211cde9039 cmd: remove uses of urfave/cli.Commands
The `Commands` type is removed in v3 and already identical to `[]*Command`
in v2; remove its uses to ease the transition to v3.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-05 03:12:58 +02:00
Sebastiaan van Stijn c52e77eccd cmd/ctr: remove unused pluginCmds
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-09-05 03:12:55 +02:00
Paweł Gronowski 3c10e5f0be all: Address G702 command execution findings
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-09-02 19:22:23 +02:00
Paweł Gronowski 2e587fd358 ctr: Use context-aware pprof dialing
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-09-02 18:51:15 +02:00
Chris Ayoub 3778cc36f4 ctr: drain exec output before cleanup
Wait for stdout and stderr copying to complete after validating process exit so deferred process deletion does not cancel readers with output still in flight.

Signed-off-by: Chris Ayoub <cayoub@openai.com>
2026-08-09 20:25:31 +00:00
Maksym Pavlenko 7df6bb0a67 erofs: allow multiple layer content cache directories
The layer content cache was a single directory, so every source of
pre-converted blobs had to be merged into one tree. A shared read-only fleet
cache, a host-local cache, and a per-image warm cache could not coexist.

Replace layer_content_cache with layer_content_caches, a list. Each directory
is checked in order and the first hit is staged into the snapshot; a layer
found in none of them falls back to the normal download-and-convert path.

Cache directories are no longer required to exist at startup. A missing one is
indistinguishable from an empty one at lookup time (both are simply a miss),
and it may well be mounted after the daemon starts, so the only check left is
that each path is absolute -- a relative one would be symlinked into the
snapshot dir and dangle.

Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
2026-08-03 13:14:44 -07:00
Chris Ayoub 0d37ad2683 ctr: register EROFS fsview
ctr resolves named users and groups for run and task exec in the
client process. Since EROFS fsview support moved behind registration,
the ctr application does not link the handler and falls back to a
temporary host mount.

Register the handler with the ctr application so EROFS snapshots can
be inspected directly. Non-EROFS mounts continue through the existing
handlers unchanged.

Signed-off-by: Chris Ayoub <cayoub@openai.com>
2026-08-01 22:01:17 +00:00
Samuel Karp 18a01c0020 ctr: add --scrub-logs flag for Windows
Adds a new --scrub-logs flag to ctr run on Windows. This flag enables
the ScrubLogs option for the io.containerd.runhcs.v1 shim.

Assisted-by: gemini-cli
Signed-off-by: Samuel Karp <samuelkarp@google.com>
2026-07-24 00:07:43 -07:00
Maksym Pavlenko 82a47efe92 Support dmverity
Add a --dmverity flag to `ctr images build-erofs-cache`. When set, each cached
erofs blob is dm-verity formatted (the hash tree is appended in place) and a
.dmverity sidecar is written alongside it. This is required when the erofs
snapshotter runs with dmverity_mode=on, which rejects cache hits that lack a
sidecar; without it such layers would have to be formatted out-of-band.

Extract the differ's dm-verity formatting into a shared dmverity.FormatLayer so
the differ and the cache builder share one implementation; the differ's
formatDmverityLayer now delegates to it.

Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
2026-07-21 10:07:08 -07:00
Maksym Pavlenko f52e748f16 ctr: add build-erofs-cache to populate the erofs layer cache
Add `ctr images build-erofs-cache <image> <cache_dir>`, which reads an
already-pulled image's layers from the content store, converts each into a
directly-mountable erofs blob, and writes them under
<cache_dir>/<algorithm>/<hex>.erofs keyed by the layer's diffID. This
populates the directory the erofs snapshotter's layer_content_cache reads
on pull; because the key is the source diffID, layers shared across images
converge on one blob. No converted image is produced.

Extract the per-layer uncompress + mkfs.erofs step out of LayerConvertFunc
into an exported ConvertLayerToErofs so the image converter and the cache
builder share a single conversion path.

Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
2026-07-21 09:43:41 -07:00
ChengyuZhu6 64a2e62b52 erofs: wire os.features into conversion and selection
Mark converted EROFS manifests with the erofs OS feature and cover
feature-aware manifest selection and unpack routing for erofs images.

Signed-off-by: ChengyuZhu6 <hudson@cyzhu.com>
2026-04-15 10:28:54 +08:00
ChengyuZhu6 b320d3c855 ctr: add EROFS image conversion support
Add EROFS conversion support to ctr convert command with configurable
options for tar-index mode and mkfs parameters.

Usage:
  ctr image convert --erofs src:tag dst:tag
  ctr image convert --erofs --erofs-compression='lz4hc,12' src:tag dst:tag

Signed-off-by: ChengyuZhu6 <hudson@cyzhu.com>
2026-04-15 10:28:47 +08:00
Sebastiaan van Stijn a122afe13b cmd: modernize: any
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-17 13:36:16 +01:00
Derek McGowan 489b653034 Merge pull request #13022 from thaJeztah/modernize
*: modernize code
2026-03-16 22:23:04 +00:00
Sebastiaan van Stijn 29030ff927 cmd: modernize: any
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -any -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-15 18:24:14 +01:00
Sebastiaan van Stijn 09f7154dbd *: modernize: mapsloop
go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -mapsloop -fix ./...

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-15 15:01:38 +01:00
majianhan aa600f65dd fix: correct typos found by codespell
Fix various typos across source code, tests, and documentation:
- README.md: Preforming → Performing
- pull.go: commpleted → completed
- server_test.go: unxpected → unexpected
- diff.go: atleast → at least
- content.go: desciptor → descriptor
- remote.go: requst → request
- imagestore_test.go: expeceted → expected
- pull_test.go: shoule → should

Signed-off-by: majianhan <majianhan@kylinos.cn>
2026-03-12 08:54:56 +08:00
majianhan 01d094d663 docs: update outdated content fetch help text
The 'content fetch' command description has been unchanged since it was
first added over 8 years ago. It described the feature as "experimental"
with "few leaps to make this work", which no longer reflects reality.

Update the help text to accurately describe what the command does: it
pulls image content into the content store without unpacking, and can
be used to pre-fetch images.

Fixes #11754

Signed-off-by: Crawford Ma <crawfordxx@users.noreply.github.com>
2026-03-11 20:20:20 +08:00
Maksym Pavlenko f4681e01d0 Merge pull request #12839 from shiv-tyagi/vendor-discovery-gpus
Detect vendor in cdi specs to generate deviceIDs for --gpus
2026-02-20 04:13:12 +00:00
Shiv Tyagi 090def0567 Remove vendor lister and update tests
Signed-off-by: Shiv Tyagi <Shiv.Tyagi@amd.com>
2026-02-19 09:28:50 -06:00
Shiv Tyagi 7035fe813d Add unit tests for gpuDeviceNames anddetectGPUVendor
Signed-off-by: Shiv Tyagi <Shiv.Tyagi@amd.com>
2026-02-19 09:28:50 -06:00
Shiv Tyagi ab1a24989f Detect vendor in cdi specs to generate deviceIDs for --gpus
This adds GPU vendor auto-detection from CDI specs instead of hardcoding nvidia.com.
This allows the --gpus flag to work with both NVIDIA and AMD GPUs by detecting the vendor from available CDI spec files.

Signed-off-by: Shiv Tyagi <Shiv.Tyagi@amd.com>
2026-02-19 09:28:50 -06:00
Sebastiaan van Stijn 5fde7662f1 cmd/*: don't print default value for '--help' and '--version'
Remove the confusing `(default: false)` that's printed.

Before this:

    ctr --help | tail -n2
       --help, -h                   Show help (default: false)
       --version, -v                Print the version (default: false)

After this:

    ctr --help | tail -n2
       --help, -h                   Show help
       --version, -v                Print the version

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-02-07 13:10:13 +01:00
Maksym Pavlenko 992597bfe9 Fix TTRPC prefix
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
2026-01-15 13:06:50 -08:00
Evan Lezar f5cd8d56f4 Map ctr --gpus requests to NVIDIA CDI device requests
This change maps ctr --gpus requests to CDI device requests.
This is done by mapping --gpus ID to a nvidia.com/gpu=ID device
request.

This removes the dependence on the nvidia-container-cli and instead
uses existing CDI specifications for nvidia devices if available on
the system.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
2025-11-25 11:22:22 +01:00
Maksym Pavlenko 4c32f5f73b Merge pull request #12531 from samuelkarp/ctr-dump-config
ctr run: dump OCI config to a file
2025-11-18 18:43:48 +00:00
Maksym Pavlenko a1a6229699 Merge pull request #12532 from samuelkarp/ctr-rlimit-nofile
ctr: allow rlimit-nofile override
2025-11-18 18:41:13 +00:00
Derek McGowan c2b22d6bd6 Update the ctr pull defaults when using the transfer service
Match the defaults set by the transfer service which will configure
linux by default on darwin hosts.

Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-11-18 08:51:51 -08:00
Samuel Karp ee1f94e4d1 ctr: allow rlimit-nofile override
Signed-off-by: Samuel Karp <samuelkarp@google.com>
2025-11-17 21:50:12 -08:00
Samuel Karp 3b899aa111 ctr run: dump OCI config to a file
Signed-off-by: Samuel Karp <samuelkarp@google.com>
2025-11-17 15:39:21 -08:00
Wei Fu 2042e805b8 cri/server/podsandbox: disable event subscriber
We have individual goroutine for each sandbox container. If there is any
error in handler, that goroutine will put event in that backoff queue.
So we don't need event subscriber for podsandbox. Otherwise, there will
be two goroutines to cleanup sandbox container.

```
>>>> From EventMonitor
  time="2025-10-23T19:30:59.626254404Z" level=debug msg="Received containerd event timestamp - 2025-10-23 19:30:59.624494674 +0000 UTC, namespace - \"k8s.io\", topic - \"/tasks/exit\""
  time="2025-10-23T19:30:59.626301912Z" level=debug msg="TaskExit event in podsandbox handler container_id:\"22e15114133e4d461ab380654fb76f3e73d3e0323989c422fa17882762979ccf\" id:\"22e15114133e4d461ab380654fb76f3e73d3e0323989c422fa17882762979ccf\" pid:203121 exit_status:137 exited_at:{seconds:1761247859 nanos:624467824}"

>>> If EventMonitor handles task exit well, it will close ttrpc
connection and then waitSandboxExit could encounter ttrpc-closed error

  time="2025-10-23T19:30:59.688031150Z" level=error msg="failed to delete task" error="ttrpc: closed" id=22e15114133e4d461ab380654fb76f3e73d3e0323989c422fa17882762979ccf
```

If both task.Delete calls fail but the shim has already been shut down, it
could trigger a new task.Exit event sent by cleanupAfterDeadShim. This would
result in three events in the EventMonitor's backoff queue, which is unnecessary
and could cause confusion due to duplicate events.

The worst-case scenario caused by two concurrent task.Delete calls is a shim
leak. The timeline for this scenario is as follows:

| Timestamp | Component       | Action                        | Result                                                                                           |
| ------    | -----------     | --------                      | --------                                                                                         |
| T1        | EventMonitor    | Sends `task.Delete`           | Marked as Req-1                                                                                  |
| T2        | waitSandboxExit | Sends `task.Delete`           | Marked as Req-2                                                                                  |
| T3        | containerd-shim | Handles Req-2                 | Container transitions from stopped to deleted                                                    |
| T4        | containerd-shim | Handles Req-1                 | Fails - container already deleted<br>Returns error: `cannot delete a deleted process: not found` |
| T5        | EventMonitor    | Receives `not found` error    | -                                                                                                |
| T6        | EventMonitor    | Sends `shim.Shutdown` request | No-op (active container record still exists)                                                     |
| T7        | EventMonitor    | Closes ttrpc connection       | Clean container state dir                                                                        |
| T8        | containerd-shim | Handles Req-2                 | Removes container record from memory                                                             |
| T9        | waitSandboxExit | Receives error                | Error: `ttrpc: closed`                                                                           |
| T10       | waitSandboxExit | Sends `shim.Shutdown` request | Fails (connection already closed)                                                                |
| T11       | waitSandboxExit | Closes ttrpc connection       | No-op (already closed)                                                                           |

The containerd-shim is still running because shim.Shutdown was sent at T6
before T8. Because container's state dir is deleted at T7, it's unable to clean
it up after containerd restarted.

We should avoid concurrent task.Delete calls here.

I also add subcommand - shutdown - in `ctr shim` for debug.

Fixed: #12344

Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-10-24 12:19:52 -04:00
Derek McGowan 2a8d301177 Set default run platform in ctr
Currently run will generate invalid specifications on non-Linux Unix
platforms. Linux should be the default container platform for run when
the platform is not explicitly provided.

Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-10-15 17:06:39 -07:00
Derek McGowan 49634889f8 Update ctr image mounts to use mount manager
Updates the image mounts to use temporary mounts and no longer require
passing in a target directory.

Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-09-29 17:08:33 -07:00
Derek McGowan 62062902f5 Add support for mount manager to ctr snapshots mount
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-09-29 17:08:33 -07:00
Derek McGowan 479cf42ca2 Add extraction progress to transfer service
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-09-10 20:07:40 -07:00
Chenyang Yan bd9e577c26 Fix ctr snapshot mount produce invalid mount command for empty option
snapshotter.Mounts() maybe get empty Options for different snapshot service.

Empty Options will produce invalid mount command from printMounts:
```
$ ctr -n flintlock snapshot --snapshotter devmapper mount /mnt flintlock/flintlock/demo-2/01K24ZRN9EFAVQVNGXQS26BYVG/root
mount -t ext4 /dev/mapper/fc-dev-thinpool-snap-19 /mnt -o
$ cmd=$(ctr -n flintlock snapshot --snapshotter devmapper mount /mnt flintlock/flintlock/demo-2/01K24ZRN9EFAVQVNGXQS26BYVG/root)
$ $cmd
mount: option requires an argument -- 'o'
Try 'mount --help' for more information.
```

Signed-off-by: Chenyang Yan <memory.yancy@gmail.com>
2025-08-09 15:06:07 +08:00
Sebastiaan van Stijn ed174c9145 cmd/ctr: rename vars that shadowed builtin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-21 09:36:22 +02:00
Akihiro Suda d455980d36 Merge pull request #12017 from caoruidong/sandbox_info_com
ctr:add sandbox info command to print sandbox info
2025-07-09 10:15:49 +00:00