Skip to content

Enable setting DNS options through global nerdctl config #4378

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

swagatbora90
Copy link
Contributor

This PR adds support for configuring DNS settings globally through the nerdctl configuration file (nerdctl.toml), allowing users to set default DNS servers, search domains, and options that apply to all containers unless explicitly overridden by command-line flags.

This is for a usecase where I want all containers to use a specific dns server instead of system default. Currently, I have to use --dns flag with every container create/run commands. This functionality is available in docker which allows setting global dns config value in the daemon config file.

Testing

Added a end to end test TestDNSWithGlobalConfig() that checks 4 scenarios:

  1. Global DNS settings used when no command-line options provided
  2. Command-line DNS options override global config (precedence test)
  3. Global DNS settings apply with host networking
  4. Global DNS settings apply with none networking

@apostasie
Copy link
Contributor

Hey @swagatbora90

Noting that:

docker run -ti --dns="" debian cat /etc/resolv.conf
nerdctl run -ti --dns="" debian cat /etc/resolv.conf

Different behaviors on this ^.
(also same difference on dns-search="")

Appreciate your PR is not about that, but maybe, if you wish, this PR could fix that discrepancy as well since it is touching that part?

nerdtest.Setup()

testCase := &test.Case{
Env: map[string]string{"NERDCTL_TOML": tomlPath},
Copy link
Contributor

@apostasie apostasie Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tigron has a helper for that:

Just add this to your testCase instead of the Env:

			Config:      test.WithConfig(nerdtest.NerdctlToml, configContent),

(also takes care of writing the file in a temp location for you, and make it easier to retrieve)

{
Description: "Global DNS settings are used when command line options are not provided",
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
nerdctlTomlPath := os.Getenv("NERDCTL_TOML")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this going to work as you think?
os.Getenv points to global env, not the test / commands env.

If you use the config from above ^^^

helpers.Read(nerdtest.NerdctlToml)

Should give you what you want?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I read it correctly, the Env var should be passed to all Subtest. I need all the Subtest to use the global env, so it does work.

However, your suggestion to use Config should work too. Let me change it like you suggested.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, testCase.Env is propagated to subtests, but this is not the global os.Environ (otherwise, you would pollute other unrelated tests), so os.Getenv will not give you the test environment...

Copy link
Contributor

@apostasie apostasie Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not completely sure I was clear, so, in a shell:

  • do not rely on os.Getenv or os.Setenv - that will cross pollute other tests and is specifically frowned-upon
  • the testCase Env is private to the test, but it is inherited by subtests
  • every test has a custom nerdctl.toml, regardless of the fact you want one explicitly or not (this is to guarantee that we are isolated from a possible, pre-existing, host nerdctl.toml)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I see your point. I did check that the NERDCTL_TOML config values are correct when running the test. Anyways, I have changed to use the Config attribute like you suggested.

cmd := helpers.Command("run", "--rm", testutil.CommonImage, "cat", "/etc/resolv.conf")
return cmd
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
Copy link
Contributor

@apostasie apostasie Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More compact, using the test.Expects helper and comparators instead of naked asserts (better debugging info):

Expected: test.Expects(expect.ExitCodeSuccess, nil, expect.All(
   expect.Contains("foo"),
   expect.Contains("bla"),
)),

@apostasie
Copy link
Contributor

apostasie commented Jun 26, 2025

@swagatbora90 left a few comments on tests.

Tigron testing has some (semblance of) documentation here: https://github.com/containerd/nerdctl/blob/main/docs/testing/tools.md

Very much work in progress, so, it is what it is... but then, am always happy to cosplay "testing-helper-AI-bot" until the doc and API are settled :-) (also, feedback on Tigron is always welcome)

@swagatbora90
Copy link
Contributor Author

Hey @swagatbora90

Noting that:

docker run -ti --dns="" debian cat /etc/resolv.conf
nerdctl run -ti --dns="" debian cat /etc/resolv.conf

Different behaviors on this ^. (also same difference on dns-search="")

Appreciate your PR is not about that, but maybe, if you wish, this PR could fix that discrepancy as well since it is touching that part?

Looks like there is no validation today on the DNS servers and domain names that are being passed. I can add a follow up PR to add validation, I would prefer to keep this PR only for adding the global config.

@apostasie
Copy link
Contributor

Looks like there is no validation today on the DNS servers and domain names that are being passed. I can add a follow up PR to add validation, I would prefer to keep this PR only for adding the global config.

Fair.

@swagatbora90 swagatbora90 force-pushed the add-global-dns-config branch 2 times, most recently from 0c8bade to 7e07e0d Compare June 26, 2025 22:55
Signed-off-by: Swagat Bora <sbora@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants