-
Notifications
You must be signed in to change notification settings - Fork 640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for CDI devices to device flag #2280
base: main
Are you sure you want to change the base?
Conversation
73defce
to
bde1b0a
Compare
/cc @mikebrow Do you know who should have a look at this? Changes are similar to containerd/containerd#8525. |
go.mod
Outdated
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect | ||
gopkg.in/yaml.v2 v2.4.0 // indirect | ||
sigs.k8s.io/yaml v1.3.0 // indirect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we minimize these dependencies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code for loading the CDI specifications reads YAML files -- and contains the functionaility to set up watchers on the filesystem that updates the spec in daemonized cases. We are looking to reduce the set of dependencies required, but that work has not yet been started.
Are there any dependencies in particular that you are concerned about? (To be clear, this should be a similar set to those for containerd
which includes the same feature when using CRI).
cmd/nerdctl/container_create.go
Outdated
if err != nil { | ||
return | ||
} | ||
for _, device := range allDevices { | ||
if cdi.IsQualifiedName(device) { | ||
opt.CDIDevices = append(opt.CDIDevices, device) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we want to keep this experimental until the syntax gets accepted in Docker CLI
https://github.com/containerd/nerdctl/blob/main/docs/experimental.md?plain=1
https://github.com/search?q=repo%3Acontainerd%2Fnerdctl+checkExperimental&type=code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have an integration test too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I will add an integration test and also gate this behind an experimental flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Docker CLI PR has been merged, so I will pick up this PR again in the next couple of days.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elezar ping?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay. I will look at this again this week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AkihiroSuda do we still need to make this feature experimental?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is consistent with Docker's behavior, it does not need to stay experimental
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is consistent, but requries an op-in feature flag in the docker config.
The --cdi-spec-dirs
folder is also not a docker command line option, but I assume that that is ok.
Needs rebase |
bde1b0a
to
b6931e4
Compare
c00e0f5
to
0d4ec2a
Compare
Sorry, needs another rebase |
ping @elezar |
I will look into this today. |
e44d28d
to
0fdf318
Compare
assert.NilError(t, err) | ||
cdiSpecDir := filepath.Join(cwd, "testdata", "cdi") | ||
|
||
os.Setenv("CDI_SPEC_DIRS", cdiSpecDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added a basic test that sets the CDI_SPEC_DIRS
option via an envvar. Do you want me to add one that sets it via the command line argument too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that would be nice.
It should be also supported via TOML: https://github.com/containerd/nerdctl/blob/main/docs/config.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an example of a test that sets the config via toml?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nerdctl/cmd/nerdctl/main_test.go
Lines 46 to 73 in 370cab6
// TestNerdctlConfig validates the configuration precedence [CLI, Env, TOML, Default]. | |
func TestNerdctlConfig(t *testing.T) { | |
testutil.DockerIncompatible(t) | |
t.Parallel() | |
tomlPath := filepath.Join(t.TempDir(), "nerdctl.toml") | |
err := os.WriteFile(tomlPath, []byte(` | |
snapshotter = "dummy-snapshotter-via-toml" | |
`), 0400) | |
assert.NilError(t, err) | |
base := testutil.NewBase(t) | |
// [Default] | |
base.Cmd("info", "-f", "{{.Driver}}").AssertOutExactly(containerd.DefaultSnapshotter + "\n") | |
// [TOML, Default] | |
base.Env = append(base.Env, "NERDCTL_TOML="+tomlPath) | |
base.Cmd("info", "-f", "{{.Driver}}").AssertOutExactly("dummy-snapshotter-via-toml\n") | |
// [CLI, TOML, Default] | |
base.Cmd("info", "-f", "{{.Driver}}", "--snapshotter=dummy-snapshotter-via-cli").AssertOutExactly("dummy-snapshotter-via-cli\n") | |
// [Env, TOML, Default] | |
base.Env = append(base.Env, "CONTAINERD_SNAPSHOTTER=dummy-snapshotter-via-env") | |
base.Cmd("info", "-f", "{{.Driver}}").AssertOutExactly("dummy-snapshotter-via-env\n") | |
// [CLI, Env, TOML, Default] | |
base.Cmd("info", "-f", "{{.Driver}}", "--snapshotter=dummy-snapshotter-via-cli").AssertOutExactly("dummy-snapshotter-via-cli\n") | |
} |
cmd/nerdctl/main.go
Outdated
@@ -175,6 +175,7 @@ func initRootCmdFlags(rootCmd *cobra.Command, tomlPath string) (*pflag.FlagSet, | |||
// Experimental enable experimental feature, see in https://github.com/containerd/nerdctl/blob/main/docs/experimental.md | |||
AddPersistentBoolFlag(rootCmd, "experimental", nil, nil, cfg.Experimental, "NERDCTL_EXPERIMENTAL", "Control experimental: https://github.com/containerd/nerdctl/blob/main/docs/experimental.md") | |||
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") | |||
AddPersistentStringSliceFlag(rootCmd, "cdi-spec-dirs", nil, nil, cfg.CDISpecDirs, "CDI_SPEC_DIRS", "The directories to search for CDI spec files. Defaults to /etc/cdi,/var/run/cdi") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to use the existing AddPersistentStringArrayFlag
here instead, but then we need to change the command line argument to --cdi-spec-dir
and make it clear that it's repeatable. I'm not sure whether the envvar would be split on commas then either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this env var specific to the nerdctl implementation, or is it part of the CDI specification?
I guess the env var should use :
on Linux and ;
on Windows as the separator, just like $PATH
(%PATH%
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The envvar is not part of the CDI specification and is a nerdctl
-specific implementation detail. I'm happy to defer to you on how to implement this though. Should both the command line argument --cdi-spec-dirs
and the CDI_SPEC_DIRS
envvar accept a :
(or ;
)-separated list of paths instead of a comma-separated list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CLI flag should not use colon separators.
Also I wonder if the env var is really necessary. Maybe it should be revisited in a separate PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I can remove the envvar for now and only use the CLI flags. It is probably cleaner for the time being.
docs/config.md
Outdated
@@ -45,6 +45,7 @@ experimental = true | |||
| `hosts_dir` | `--hosts-dir` | | `certs.d` directory | Since 0.16.0 | | |||
| `experimental` | `--experimental` | `NERDCTL_EXPERIMENTAL` | Enable [experimental features](experimental.md) | Since 0.22.3 | | |||
| `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 | | |||
| `cdi_spec_dirs` | `--cdi-spec-dirs` | `CDI_SPEC_DIRS` | The folders to use when searching for CDI specifications.| experimental | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could drop the experimental
.
go.mod
Outdated
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect | ||
gopkg.in/yaml.v2 v2.4.0 // indirect | ||
sigs.k8s.io/yaml v1.3.0 // indirect | ||
tags.cncf.io/container-device-interface v0.8.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is see that there are multiple require
sections in the module file. Are there specific sections where I should add these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sections are being unified:
Looking at the failing tests these are:
For the first the question I would have is whether the For Docker compatibility, we would need to enable the cdi feature that has been available in Docker since v25. We would also need to configure the Docker daemon to use the same CDI folder as for the tests. Do you have any guidance on how to address these failures? |
This might be being fixed in:
Yes, you can update nerdctl/.github/workflows/test.yml Line 225 in 0c3c28a
|
39182f4
to
ffecb94
Compare
.github/workflows/test.yml
Outdated
- name: Enable CDI in the Docker daemon. | ||
run: | | ||
sudo mkdir -p /etc/docker | ||
echo '{ "features": {"cdi": true} }' | sudo tee /etc/docker/daemon.json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be merged into daemon.json
without overwriting its existing content (if any)
@@ -58,5 +60,6 @@ func New() *Config { | |||
HostsDir: ncdefaults.HostsDirs(), | |||
Experimental: true, | |||
HostGatewayIP: ncdefaults.HostGatewayIP(), | |||
CDISpecDirs: []string{"/etc/cdi", "/var/run/cdi"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should respect XDG dirs for rootless
https://github.com/containerd/nerdctl/blob/main/pkg/rootlessutil/xdg_linux.go
@@ -39,6 +39,8 @@ type Config struct { | |||
HostsDir []string `toml:"hosts_dir"` | |||
Experimental bool `toml:"experimental"` | |||
HostGatewayIP string `toml:"host_gateway_ip"` | |||
// CDISpecDirs is a list of directories in which CDI specifications can be found. | |||
CDISpecDirs []string `toml:"cdi_spec_dirs,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bike shedding: "Dirs" vs "Path"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"CDIPath" might be more consistent with the existing "CNIPath"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is that these are specifically directories and not files. Furthermore, the naming is consistent with this setting in other projects: containerd, cri-o, docker, singularity.
I'm happy to change if you feel strongly about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the naming is consistent with this setting in other projects: containerd, cri-o, docker, singularity.
👍
Needs rebase |
ping @elezar |
@elezar Do you plan to rebase this ? |
Yes, I do need to get to it. I have been focussing on a security issue of late. I will pick this up again in the next couple of days. |
ffecb94
to
007d138
Compare
CI failing |
Needs rebase |
Moved to v2.1 milestone |
Hi @elezar 👋 any plan to pick this up? If not I can probably carry it over (no rush). |
Hi @djdongjin I have to pick this up again, but have been busy with a couple of high-priority tasks otherwise. I will make time for this over the next month though. |
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 <[email protected]>
Signed-off-by: Evan Lezar <[email protected]>
Signed-off-by: Evan Lezar <[email protected]>
007d138
to
558eeed
Compare
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.
This mirrors the support recently added to
ctr
(see containerd/containerd#8525) and under review for the Docker CLI (see docker/cli#4084).Note that this assumes that the CLI is used to inject devices and additional work would be required for other mechanisms such as compose files.