Skip to content

Commit efe0417

Browse files
elezardjdongjin
authored andcommitted
Add support for CDI devices to device flag
This change adds support for specifying fully-qualified CDI device names in the --device flag. This allows the Container Device Interface (CDI) to be used to inject devices into container being run. Signed-off-by: Evan Lezar <elezar@nvidia.com> Enable cdi feature for Docker Signed-off-by: Evan Lezar <elezar@nvidia.com> Update go mod Signed-off-by: Evan Lezar <elezar@nvidia.com> Signed-off-by: Jin Dong <djdongjin95@gmail.com> use containerd cdi.WithCDIDevices Signed-off-by: Jin Dong <djdongjin95@gmail.com>
1 parent b8b59a9 commit efe0417

File tree

16 files changed

+196
-1
lines changed

16 files changed

+196
-1
lines changed

.github/workflows/test.yml

+5
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,11 @@ jobs:
339339
# FIXME: remove expect when we are done removing unbuffer from tests
340340
sudo apt-get install -qq expect
341341
make install-dev-tools
342+
- name: Enable CDI in the Docker daemon.
343+
run: |
344+
sudo mkdir -p /etc/docker
345+
sudo jq '.features.cdi = true' /etc/docker/daemon.json | sudo tee /etc/docker/daemon.json.tmp && sudo mv /etc/docker/daemon.json.tmp /etc/docker/daemon.json
346+
sudo systemctl restart docker
342347
- name: "Ensure that the integration test suite is compatible with Docker"
343348
run: WITH_SUDO=true ./hack/test-integration.sh -test.target=docker
344349
- name: "Ensure that the IPv6 integration test suite is compatible with Docker"

cmd/nerdctl/container/container_create.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"runtime"
2222

2323
"github.com/spf13/cobra"
24+
cdiparser "tags.cncf.io/container-device-interface/pkg/parser"
2425

2526
"github.com/containerd/nerdctl/v2/cmd/nerdctl/helpers"
2627
"github.com/containerd/nerdctl/v2/pkg/api/types"
@@ -55,6 +56,7 @@ func CreateCommand() *cobra.Command {
5556
return cmd
5657
}
5758

59+
//revive:disable:function-length
5860
func createOptions(cmd *cobra.Command) (types.ContainerCreateOptions, error) {
5961
var err error
6062
opt := types.ContainerCreateOptions{
@@ -215,10 +217,18 @@ func createOptions(cmd *cobra.Command) (types.ContainerCreateOptions, error) {
215217
if err != nil {
216218
return opt, err
217219
}
218-
opt.Device, err = cmd.Flags().GetStringSlice("device")
220+
221+
allDevices, err := cmd.Flags().GetStringSlice("device")
219222
if err != nil {
220223
return opt, err
221224
}
225+
for _, device := range allDevices {
226+
if cdiparser.IsQualifiedName(device) {
227+
opt.CDIDevices = append(opt.CDIDevices, device)
228+
} else {
229+
opt.Device = append(opt.Device, device)
230+
}
231+
}
222232
// #endregion
223233

224234
// #region for blkio flags

cmd/nerdctl/container/container_run_linux_test.go

+57
Original file line numberDiff line numberDiff line change
@@ -659,3 +659,60 @@ func TestPortBindingWithCustomHost(t *testing.T) {
659659

660660
testCase.Run(t)
661661
}
662+
663+
func TestRunDeviceCDI(t *testing.T) {
664+
// Although CDI injection is supported by Docker, specifying the --cdi-spec-dirs on the command line is not.
665+
testutil.DockerIncompatible(t)
666+
cdiSpecDir := filepath.Join(t.TempDir(), "cdi")
667+
writeTestCDISpec(t, cdiSpecDir)
668+
669+
base := testutil.NewBase(t)
670+
containerName := testutil.Identifier(t)
671+
defer base.Cmd("rm", "-f", containerName).AssertOK()
672+
base.Cmd("--cdi-spec-dirs", cdiSpecDir, "run",
673+
"--rm",
674+
"--device", "vendor1.com/device=foo",
675+
testutil.AlpineImage, "env",
676+
).AssertOutContains("FOO=injected")
677+
}
678+
679+
func TestRunDeviceCDIWithNerdctlConfig(t *testing.T) {
680+
// Although CDI injection is supported by Docker, specifying the --cdi-spec-dirs on the command line is not.
681+
testutil.DockerIncompatible(t)
682+
cdiSpecDir := filepath.Join(t.TempDir(), "cdi")
683+
writeTestCDISpec(t, cdiSpecDir)
684+
685+
tomlPath := filepath.Join(t.TempDir(), "nerdctl.toml")
686+
err := os.WriteFile(tomlPath, []byte(fmt.Sprintf(`
687+
cdi_spec_dirs = ["%s"]
688+
`, cdiSpecDir)), 0400)
689+
assert.NilError(t, err)
690+
691+
base := testutil.NewBase(t)
692+
base.Env = append(base.Env, "NERDCTL_TOML="+tomlPath)
693+
containerName := testutil.Identifier(t)
694+
defer base.Cmd("rm", "-f", containerName).AssertOK()
695+
base.Cmd("run",
696+
"--rm",
697+
"--device", "vendor1.com/device=foo",
698+
testutil.AlpineImage, "env",
699+
).AssertOutContains("FOO=injected")
700+
}
701+
702+
func writeTestCDISpec(t *testing.T, cdiSpecDir string) {
703+
const testCDIVendor1 = `
704+
cdiVersion: "0.3.0"
705+
kind: "vendor1.com/device"
706+
devices:
707+
- name: foo
708+
containerEdits:
709+
env:
710+
- FOO=injected
711+
`
712+
713+
err := os.MkdirAll(cdiSpecDir, 0700)
714+
assert.NilError(t, err)
715+
cdiSpecPath := filepath.Join(cdiSpecDir, "vendor1.yaml")
716+
err = os.WriteFile(cdiSpecPath, []byte(testCDIVendor1), 0400)
717+
assert.NilError(t, err)
718+
}

cmd/nerdctl/helpers/flagutil.go

+6
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ func ProcessRootCmdFlags(cmd *cobra.Command) (types.GlobalCommandOptions, error)
107107
if err != nil {
108108
return types.GlobalCommandOptions{}, err
109109
}
110+
cdiSpecDirs, err := cmd.Flags().GetStringSlice("cdi-spec-dirs")
111+
if err != nil {
112+
return types.GlobalCommandOptions{}, err
113+
}
114+
110115
return types.GlobalCommandOptions{
111116
Debug: debug,
112117
DebugFull: debugFull,
@@ -123,6 +128,7 @@ func ProcessRootCmdFlags(cmd *cobra.Command) (types.GlobalCommandOptions, error)
123128
HostGatewayIP: hostGatewayIP,
124129
BridgeIP: bridgeIP,
125130
KubeHideDupe: kubeHideDupe,
131+
CDISpecDirs: cdiSpecDirs,
126132
}, nil
127133
}
128134

cmd/nerdctl/main.go

+1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ func initRootCmdFlags(rootCmd *cobra.Command, tomlPath string) (*pflag.FlagSet,
186186
helpers.AddPersistentStringFlag(rootCmd, "host-gateway-ip", nil, nil, nil, aliasToBeInherited, cfg.HostGatewayIP, "NERDCTL_HOST_GATEWAY_IP", "IP address that the special 'host-gateway' string in --add-host resolves to. Defaults to the IP address of the host. It has no effect without setting --add-host")
187187
helpers.AddPersistentStringFlag(rootCmd, "bridge-ip", nil, nil, nil, aliasToBeInherited, cfg.BridgeIP, "NERDCTL_BRIDGE_IP", "IP address for the default nerdctl bridge network")
188188
rootCmd.PersistentFlags().Bool("kube-hide-dupe", cfg.KubeHideDupe, "Deduplicate images for Kubernetes with namespace k8s.io")
189+
rootCmd.PersistentFlags().StringSlice("cdi-spec-dirs", cfg.CDISpecDirs, "The directories to search for CDI spec files. Defaults to /etc/cdi,/var/run/cdi")
189190
return aliasToBeInherited, nil
190191
}
191192

docs/config.md

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ experimental = true
4747
| `host_gateway_ip` | `--host-gateway-ip` | `NERDCTL_HOST_GATEWAY_IP` | IP address that the special 'host-gateway' string in --add-host resolves to. Defaults to the IP address of the host. It has no effect without setting --add-host | Since 1.3.0 |
4848
| `bridge_ip` | `--bridge-ip` | `NERDCTL_BRIDGE_IP` | IP address for the default nerdctl bridge network, e.g., 10.1.100.1/24 | Since 2.0.1 |
4949
| `kube_hide_dupe` | `--kube-hide-dupe` | | Deduplicate images for Kubernetes with namespace k8s.io, no more redundant <none> ones are displayed | Since 2.0.3 |
50+
| `cdi_spec_dirs` | `--cdi-spec-dirs` | | The folders to use when searching for CDI specifications. | Since 2.0.5 |
5051

5152
The properties are parsed in the following precedence:
5253
1. CLI flag

go.mod

+6
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ require (
6868
golang.org/x/text v0.24.0
6969
gopkg.in/yaml.v3 v3.0.1
7070
gotest.tools/v3 v3.5.2
71+
tags.cncf.io/container-device-interface v1.0.1
7172
)
7273

7374
require (
@@ -113,6 +114,7 @@ require (
113114
github.com/multiformats/go-multibase v0.2.0 // indirect
114115
github.com/multiformats/go-multihash v0.2.3 // indirect
115116
github.com/multiformats/go-varint v0.0.7 // indirect
117+
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 // indirect
116118
github.com/opencontainers/selinux v1.12.0 // indirect
117119
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
118120
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 // indirect
@@ -122,6 +124,7 @@ require (
122124
github.com/smallstep/pkcs7 v0.1.1 // indirect
123125
github.com/spaolacci/murmur3 v1.1.0 // indirect
124126
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect
127+
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
125128
github.com/tinylib/msgp v1.2.0 // indirect
126129
github.com/vbatts/tar-split v0.11.6 // indirect
127130
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
@@ -134,10 +137,13 @@ require (
134137
go.opentelemetry.io/otel/metric v1.31.0 // indirect
135138
go.opentelemetry.io/otel/trace v1.31.0 // indirect
136139
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
140+
golang.org/x/mod v0.22.0 // indirect
137141
google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 // indirect
138142
google.golang.org/grpc v1.69.4 // indirect
139143
google.golang.org/protobuf v1.36.5 // indirect
140144
lukechampine.com/blake3 v1.3.0 // indirect
145+
sigs.k8s.io/yaml v1.4.0 // indirect
146+
tags.cncf.io/container-device-interface/specs-go v1.0.0 // indirect
141147
)
142148

143149
replace github.com/containerd/nerdctl/mod/tigron v0.0.0 => ./mod/tigron

go.sum

+30
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
1414
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
1515
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
1616
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
17+
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
18+
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
1719
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
1820
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
1921
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -152,14 +154,21 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
152154
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
153155
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
154156
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
157+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
155158
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
156159
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
157160
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
158161
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
159162
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
160163
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
164+
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
161165
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
162166
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
167+
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
168+
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
169+
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
170+
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
171+
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
163172
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
164173
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
165174
github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg=
@@ -195,6 +204,7 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz
195204
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
196205
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
197206
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
207+
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
198208
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
199209
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
200210
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
@@ -217,6 +227,7 @@ github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
217227
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
218228
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
219229
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
230+
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
220231
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
221232
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
222233
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
@@ -239,8 +250,12 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
239250
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
240251
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
241252
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
253+
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
242254
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
243255
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
256+
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0=
257+
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
258+
github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
244259
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8=
245260
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U=
246261
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
@@ -266,6 +281,7 @@ github.com/rootless-containers/rootlesskit/v2 v2.3.4/go.mod h1:AJNM4jS0jFIF8GvBf
266281
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
267282
github.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU=
268283
github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U=
284+
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
269285
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
270286
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
271287
github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU=
@@ -282,15 +298,19 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
282298
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
283299
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
284300
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
301+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
285302
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
286303
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
287304
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
288305
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
289306
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
290307
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
291308
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
309+
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
310+
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
292311
github.com/tinylib/msgp v1.2.0 h1:0uKB/662twsVBpYUPbokj4sTSKhWFKB7LopO2kWK8lY=
293312
github.com/tinylib/msgp v1.2.0/go.mod h1:2vIGs3lcUo8izAATNobrCHevYZC/LMsJtw4JPiYPHro=
313+
github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
294314
github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs=
295315
github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI=
296316
github.com/vishvananda/netlink v1.3.1-0.20250303224720-0e7078ed04c8 h1:Y4egeTrP7sccowz2GWTJVtHlwkZippgBTpUmMteFUWQ=
@@ -355,6 +375,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
355375
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
356376
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
357377
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
378+
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
379+
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
358380
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
359381
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
360382
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -390,6 +412,8 @@ golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
390412
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
391413
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
392414
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
415+
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
416+
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
393417
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
394418
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
395419
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -489,3 +513,9 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
489513
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
490514
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
491515
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
516+
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
517+
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
518+
tags.cncf.io/container-device-interface v1.0.1 h1:KqQDr4vIlxwfYh0Ed/uJGVgX+CHAkahrgabg6Q8GYxc=
519+
tags.cncf.io/container-device-interface v1.0.1/go.mod h1:JojJIOeW3hNbcnOH2q0NrWNha/JuHoDZcmYxAZwb2i0=
520+
tags.cncf.io/container-device-interface/specs-go v1.0.0 h1:8gLw29hH1ZQP9K1YtAzpvkHCjjyIxHZYzBAvlQ+0vD8=
521+
tags.cncf.io/container-device-interface/specs-go v1.0.0/go.mod h1:u86hoFWqnh3hWz3esofRFKbI261bUlvUfLKGrDhJkgQ=

pkg/api/types/container_types.go

+2
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ type ContainerCreateOptions struct {
150150
CgroupParent string
151151
// Device specifies add a host device to the container
152152
Device []string
153+
// CDIDevices specifies the CDI devices to add to the container
154+
CDIDevices []string
153155
// #endregion
154156

155157
// #region for blkio related flags

pkg/cmd/container/create.go

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
124124
}
125125
opts = append(opts, platformOpts...)
126126

127+
opts = append(opts, withCDIDevices(options.GOptions.CDISpecDirs, options.CDIDevices...))
128+
127129
if _, err := referenceutil.Parse(args[0]); errors.Is(err, referenceutil.ErrLoadOCIArchiveRequired) {
128130
imageRef := args[0]
129131

0 commit comments

Comments
 (0)