Просмотр исходного кода

Add support for DNS options

Signed-off-by: Tim Hockin <thockin@google.com>
Tim Hockin 10 лет назад
Родитель
Сommit
3d4685e258

+ 2 - 0
contrib/completion/bash/docker

@@ -533,6 +533,7 @@ _docker_daemon() {
 		--default-ulimit
 		--dns
 		--dns-search
+		--dns-opt
 		--exec-driver -e
 		--exec-opt
 		--exec-root
@@ -1124,6 +1125,7 @@ _docker_run() {
 		--cpu-shares -c
 		--device
 		--dns
+		--dns-opt
 		--dns-search
 		--entrypoint
 		--env -e

+ 3 - 0
contrib/completion/fish/docker.fish

@@ -49,6 +49,7 @@ complete -c docker -f -n '__fish_docker_no_subcommand' -l bip -d "Use this CIDR
 complete -c docker -f -n '__fish_docker_no_subcommand' -s D -l debug -d 'Enable debug mode'
 complete -c docker -f -n '__fish_docker_no_subcommand' -s d -l daemon -d 'Enable daemon mode'
 complete -c docker -f -n '__fish_docker_no_subcommand' -l dns -d 'Force Docker to use specific DNS servers'
+complete -c docker -f -n '__fish_docker_no_subcommand' -l dns-opt -d 'Force Docker to use specific DNS options'
 complete -c docker -f -n '__fish_docker_no_subcommand' -l dns-search -d 'Force Docker to use specific DNS search domains'
 complete -c docker -f -n '__fish_docker_no_subcommand' -s e -l exec-driver -d 'Force the Docker runtime to use a specific exec driver'
 complete -c docker -f -n '__fish_docker_no_subcommand' -l exec-opt -d 'Set exec driver options'
@@ -122,6 +123,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l cidfile -d '
 complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l cpuset -d 'CPUs in which to allow execution (0-3, 0,1)'
 complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l device -d 'Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)'
 complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l dns -d 'Set custom DNS servers'
+complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l dns-opt -d "Set custom DNS options (Use --dns-opt='' if you don't wish to set options)"
 complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l dns-search -d "Set custom DNS search domains (Use --dns-search=. if you don't wish to set the search domain)"
 complete -c docker -A -f -n '__fish_seen_subcommand_from create' -s e -l env -d 'Set environment variables'
 complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l entrypoint -d 'Overwrite the default ENTRYPOINT of the image'
@@ -309,6 +311,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l cpuset -d 'CPUs
 complete -c docker -A -f -n '__fish_seen_subcommand_from run' -s d -l detach -d 'Detached mode: run the container in the background and print the new container ID'
 complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l device -d 'Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)'
 complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l dns -d 'Set custom DNS servers'
+complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l dns-opt -d "Set custom DNS options (Use --dns-opt='' if you don't wish to set options)"
 complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l dns-search -d "Set custom DNS search domains (Use --dns-search=. if you don't wish to set the search domain)"
 complete -c docker -A -f -n '__fish_seen_subcommand_from run' -s e -l env -d 'Set environment variables'
 complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l entrypoint -d 'Overwrite the default ENTRYPOINT of the image'

+ 5 - 3
contrib/completion/zsh/_docker

@@ -226,8 +226,9 @@ __docker_subcommand() {
         "($help)*--cap-drop=-[Drop Linux capabilities]:capability: "
         "($help)--cidfile=-[Write the container ID to the file]:CID file:_files"
         "($help)*--device=-[Add a host device to the container]:device:_files"
-        "($help)*--dns=-[Set custom dns servers]:dns server: "
-        "($help)*--dns-search=-[Set custom DNS search domains]:dns domains: "
+        "($help)*--dns=-[Set custom DNS servers]:DNS server: "
+        "($help)*--dns-opt=-[Set custom DNS options]:DNS option: "
+        "($help)*--dns-search=-[Set custom DNS search domains]:DNS domains: "
         "($help)*"{-e,--env=-}"[Set environment variables]:environment variable: "
         "($help)--entrypoint=-[Overwrite the default entrypoint of the image]:entry point: "
         "($help)*--env-file=-[Read environment variables from a file]:environment file:_files"
@@ -599,7 +600,8 @@ _docker() {
         "($help)--default-gateway[Container default gateway IPv4 address]:IPv4 address: " \
         "($help)--default-gateway-v6[Container default gateway IPv6 address]:IPv6 address: " \
         "($help)*--dns=-[DNS server to use]:DNS: " \
-        "($help)*--dns-search=-[DNS search domains to use]" \
+        "($help)*--dns-search=-[DNS search domains to use]:DNS search: " \
+        "($help)*--dns-opt=-[DNS options to use]:DNS option: " \
         "($help)*--default-ulimit=-[Set default ulimit settings for containers]:ulimit: " \
         "($help -e --exec-driver)"{-e,--exec-driver=-}"[Exec driver to use]:driver:(native lxc windows)" \
         "($help)*--exec-opt=-[Set exec driver options]:exec driver options: " \

+ 2 - 0
daemon/config.go

@@ -19,6 +19,7 @@ type CommonConfig struct {
 	Context        map[string][]string
 	DisableBridge  bool
 	DNS            []string
+	DNSOptions     []string
 	DNSSearch      []string
 	ExecDriver     string
 	ExecOptions    []string
@@ -51,6 +52,7 @@ func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string)
 	cmd.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, usageFn("Set the containers network MTU"))
 	// FIXME: why the inconsistency between "hosts" and "sockets"?
 	cmd.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), []string{"#dns", "-dns"}, usageFn("DNS server to use"))
+	cmd.Var(opts.NewListOptsRef(&config.DNSOptions, nil), []string{"-dns-opt"}, usageFn("DNS options to use"))
 	cmd.Var(opts.NewListOptsRef(&config.DNSSearch, opts.ValidateDNSSearch), []string{"-dns-search"}, usageFn("DNS search domains to use"))
 	cmd.Var(opts.NewListOptsRef(&config.Labels, opts.ValidateLabel), []string{"-label"}, usageFn("Set key=value labels to the daemon"))
 	cmd.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", usageFn("Default driver for container logs"))

+ 11 - 0
daemon/container_unix.go

@@ -397,6 +397,7 @@ func (container *Container) buildSandboxOptions() ([]libnetwork.SandboxOption, e
 		err         error
 		dns         []string
 		dnsSearch   []string
+		dnsOptions  []string
 	)
 
 	sboxOptions = append(sboxOptions, libnetwork.OptionHostname(container.Config.Hostname),
@@ -444,6 +445,16 @@ func (container *Container) buildSandboxOptions() ([]libnetwork.SandboxOption, e
 		sboxOptions = append(sboxOptions, libnetwork.OptionDNSSearch(ds))
 	}
 
+	if len(container.hostConfig.DNSOptions) > 0 {
+		dnsOptions = container.hostConfig.DNSOptions
+	} else if len(container.daemon.configStore.DNSOptions) > 0 {
+		dnsOptions = container.daemon.configStore.DNSOptions
+	}
+
+	for _, ds := range dnsOptions {
+		sboxOptions = append(sboxOptions, libnetwork.OptionDNSOptions(ds))
+	}
+
 	if container.NetworkSettings.SecondaryIPAddresses != nil {
 		name := container.Config.Hostname
 		if container.Config.Domainname != "" {

+ 4 - 4
daemon/daemon_test.go

@@ -174,7 +174,7 @@ func TestLoadWithVolume(t *testing.T) {
 	}
 
 	hostConfig := `{"Binds":[],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
-"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
+"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsOptions":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
 "Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
 "SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
 	if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {
@@ -262,7 +262,7 @@ func TestLoadWithBindMount(t *testing.T) {
 	}
 
 	hostConfig := `{"Binds":["/vol1:/vol1"],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
-"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
+"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsOptions":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
 "Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
 "SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
 	if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {
@@ -353,7 +353,7 @@ func TestLoadWithVolume17RC(t *testing.T) {
 	}
 
 	hostConfig := `{"Binds":[],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
-"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
+"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsOptions":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
 "Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
 "SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
 	if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {
@@ -458,7 +458,7 @@ func TestRemoveLocalVolumesFollowingSymlinks(t *testing.T) {
 	}
 
 	hostConfig := `{"Binds":[],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
-"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
+"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsOptions":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
 "Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
 "SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
 	if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {

+ 17 - 10
docs/articles/networking.md

@@ -102,7 +102,7 @@ server when it starts up, and cannot be changed once it is running:
  *  `--userland-proxy=true|false` — see
     [Binding container ports](#binding-ports)
 
-There are two networking options that can be supplied either at startup
+There are three networking options that can be supplied either at startup
 or when `docker run` is invoked.  When provided at startup, set the
 default value that `docker run` will later use if the options are not
 specified:
@@ -113,6 +113,9 @@ specified:
  *  `--dns-search=DOMAIN...` — see
     [Configuring DNS](#dns)
 
+ *  `--dns-opt=OPTION...` — see
+    [Configuring DNS](#dns)
+
 Finally, several networking options can only be provided when calling
 `docker run` because they specify something specific to one container:
 
@@ -215,12 +218,16 @@ Four different options affect container domain name services.
     only look up `host` but also `host.example.com`.
     Use `--dns-search=.` if you don't wish to set the search domain.
 
-Regarding DNS settings, in the absence of either the `--dns=IP_ADDRESS...`
-or the `--dns-search=DOMAIN...` option, Docker makes each container's
-`/etc/resolv.conf` look like the `/etc/resolv.conf` of the host machine (where
-the `docker` daemon runs).  When creating the container's `/etc/resolv.conf`,
-the daemon filters out all localhost IP address `nameserver` entries from
-the host's original file.
+ *  `--dns-opt=OPTION...` — sets the options used by DNS resolvers
+    by writing an `options` line into the container's `/etc/resolv.conf`.
+    See documentation for `resolv.conf` for a list of valid options.
+
+Regarding DNS settings, in the absence of the `--dns=IP_ADDRESS...`,
+`--dns-search=DOMAIN...`, or `--dns-opt=OPTION...` options, Docker makes
+each container's `/etc/resolv.conf` look like the `/etc/resolv.conf` of the
+host machine (where the `docker` daemon runs).  When creating the container's
+`/etc/resolv.conf`, the daemon filters out all localhost IP address
+`nameserver` entries from the host's original file.
 
 Filtering is necessary because all localhost addresses on the host are
 unreachable from the container's network.  After this filtering, if there 
@@ -253,9 +260,9 @@ of a facility to ensure atomic writes of the `resolv.conf` file while the
 container is running. If the container's `resolv.conf` has been edited since
 it was started with the default configuration, no replacement will be
 attempted as it would overwrite the changes performed by the container.
-If the options (`--dns` or `--dns-search`) have been used to modify the 
-default host configuration, then the replacement with an updated host's
-`/etc/resolv.conf` will not happen as well.
+If the options (`--dns`, `--dns-search`, or `--dns-opt`) have been used to
+modify the default host configuration, then the replacement with an updated
+host's `/etc/resolv.conf` will not happen as well.
 
 > **Note**:
 > For containers which were created prior to the implementation of

+ 2 - 0
docs/reference/api/docker_remote_api.md

@@ -84,6 +84,8 @@ This section lists each version from latest to oldest.  Each listing includes a
 * `GET /images/(name)/json` now returns information about tags of the image.
 * The `config` option now accepts the field `StopSignal`, which specifies the signal to use to kill a container.
 * `GET /containers/(id)/stats` will return networking information respectively for each interface.
+* The `hostConfig` option now accepts the field `DnsOptions`, which specifies a
+list of DNS options to be used in the container.
 
 
 ### v1.20 API changes

+ 3 - 0
docs/reference/api/docker_remote_api_v1.21.md

@@ -186,6 +186,7 @@ Create a container
              "Privileged": false,
              "ReadonlyRootfs": false,
              "Dns": ["8.8.8.8"],
+             "DnsOptions": [""],
              "DnsSearch": [""],
              "ExtraHosts": null,
              "VolumesFrom": ["parent", "other:ro"],
@@ -272,6 +273,7 @@ Json Parameters:
     -   **ReadonlyRootfs** - Mount the container's root filesystem as read only.
           Specified as a boolean value.
     -   **Dns** - A list of DNS servers for the container to use.
+    -   **DnsOptions** - A list of DNS options
     -   **DnsSearch** - A list of DNS search domains
     -   **ExtraHosts** - A list of hostnames/IP mappings to add to the
         container's `/etc/hosts` file. Specified in the form `["hostname:IP"]`.
@@ -388,6 +390,7 @@ Return low-level information on the container `id`
 			"CpuPeriod": 100000,
 			"Devices": [],
 			"Dns": null,
+			"DnsOptions": null,
 			"DnsSearch": null,
 			"ExtraHosts": null,
 			"IpcMode": "",

+ 1 - 0
docs/reference/commandline/create.md

@@ -31,6 +31,7 @@ Creates a new container.
       --cpuset-mems=""              Memory nodes (MEMs) in which to allow execution (0-3, 0,1)
       --device=[]                   Add a host device to the container
       --dns=[]                      Set custom DNS servers
+      --dns-opt=[]                  Set custom DNS options
       --dns-search=[]               Set custom DNS search domains
       -e, --env=[]                  Set environment variables
       --entrypoint=""               Overwrite the default ENTRYPOINT of the image

+ 1 - 0
docs/reference/commandline/daemon.md

@@ -23,6 +23,7 @@ weight=1
       --default-gateway=""                   Container default gateway IPv4 address
       --default-gateway-v6=""                Container default gateway IPv6 address
       --dns=[]                               DNS server to use
+      --dns-opt=[]                           DNS options to use
       --dns-search=[]                        DNS search domains to use
       --default-ulimit=[]                    Set default ulimit settings for containers
       -e, --exec-driver="native"             Exec driver to use

+ 1 - 0
docs/reference/commandline/run.md

@@ -30,6 +30,7 @@ weight=1
       -d, --detach=false            Run container in background and print container ID
       --device=[]                   Add a host device to the container
       --dns=[]                      Set custom DNS servers
+      --dns-opt=[]                  Set custom DNS options
       --dns-search=[]               Set custom DNS search domains
       -e, --env=[]                  Set environment variables
       --entrypoint=""               Overwrite the default ENTRYPOINT of the image

+ 5 - 5
docs/reference/run.md

@@ -330,8 +330,8 @@ traffic will be routed though this bridge to the container.
 With the networking mode set to `host` a container will share the host's
 network stack and all interfaces from the host will be available to the
 container.  The container's hostname will match the hostname on the host
-system.  Note that `--add-host` `--hostname`  `--dns` `--dns-search` and
-`--mac-address` is invalid in `host` netmode.
+system.  Note that `--add-host` `--hostname`  `--dns` `--dns-search`
+`--dns-opt` and `--mac-address` are invalid in `host` netmode.
 
 Compared to the default `bridge` mode, the `host` mode gives *significantly*
 better networking performance since it uses the host's native networking stack
@@ -348,9 +348,9 @@ or a High Performance Web Server.
 With the networking mode set to `container` a container will share the
 network stack of another container.  The other container's name must be
 provided in the format of `--net container:<name|id>`. Note that `--add-host`
-`--hostname` `--dns` `--dns-search` and `--mac-address` is invalid
-in `container` netmode, and `--publish` `--publish-all` `--expose` are also
-invalid in `container` netmode.
+`--hostname` `--dns` `--dns-search` `--dns-opt` and `--mac-address` are
+invalid in `container` netmode, and `--publish` `--publish-all` `--expose` are
+also invalid in `container` netmode.
 
 Example running a Redis container with Redis binding to `localhost` then
 running the `redis-cli` command and connecting to the Redis server over the

+ 16 - 6
integration-cli/docker_cli_run_test.go

@@ -940,7 +940,7 @@ func (s *DockerSuite) TestRunDnsDefaultOptions(c *check.C) {
 
 func (s *DockerSuite) TestRunDnsOptions(c *check.C) {
 	testRequires(c, DaemonIsLinux)
-	out, stderr, _ := dockerCmdWithStdoutStderr(c, "run", "--dns=127.0.0.1", "--dns-search=mydomain", "busybox", "cat", "/etc/resolv.conf")
+	out, stderr, _ := dockerCmdWithStdoutStderr(c, "run", "--dns=127.0.0.1", "--dns-search=mydomain", "--dns-opt=ndots:9", "busybox", "cat", "/etc/resolv.conf")
 
 	// The client will get a warning on stderr when setting DNS to a localhost address; verify this:
 	if !strings.Contains(stderr, "Localhost DNS setting") {
@@ -948,15 +948,25 @@ func (s *DockerSuite) TestRunDnsOptions(c *check.C) {
 	}
 
 	actual := strings.Replace(strings.Trim(out, "\r\n"), "\n", " ", -1)
-	if actual != "search mydomain nameserver 127.0.0.1" {
-		c.Fatalf("expected 'nameserver 127.0.0.1 search mydomain', but says: %q", actual)
+	if actual != "search mydomain nameserver 127.0.0.1 options ndots:9" {
+		c.Fatalf("expected 'search mydomain nameserver 127.0.0.1 options ndots:9', but says: %q", actual)
 	}
 
-	out, stderr, _ = dockerCmdWithStdoutStderr(c, "run", "--dns=127.0.0.1", "--dns-search=.", "busybox", "cat", "/etc/resolv.conf")
+	out, stderr, _ = dockerCmdWithStdoutStderr(c, "run", "--dns=127.0.0.1", "--dns-search=.", "--dns-opt=ndots:3", "busybox", "cat", "/etc/resolv.conf")
 
 	actual = strings.Replace(strings.Trim(strings.Trim(out, "\r\n"), " "), "\n", " ", -1)
-	if actual != "nameserver 127.0.0.1" {
-		c.Fatalf("expected 'nameserver 127.0.0.1', but says: %q", actual)
+	if actual != "nameserver 127.0.0.1 options ndots:3" {
+		c.Fatalf("expected 'nameserver 127.0.0.1 options ndots:3', but says: %q", actual)
+	}
+}
+
+func (s *DockerSuite) TestRunDnsRepeatOptions(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	out, _, _ := dockerCmdWithStdoutStderr(c, "run", "--dns=1.1.1.1", "--dns=2.2.2.2", "--dns-search=mydomain", "--dns-search=mydomain2", "--dns-opt=ndots:9", "--dns-opt=timeout:3", "busybox", "cat", "/etc/resolv.conf")
+
+	actual := strings.Replace(strings.Trim(out, "\r\n"), "\n", " ", -1)
+	if actual != "search mydomain mydomain2 nameserver 1.1.1.1 nameserver 2.2.2.2 options ndots:9 timeout:3" {
+		c.Fatalf("expected 'search mydomain mydomain2 nameserver 1.1.1.1 nameserver 2.2.2.2 options ndots:9 timeout:3', but says: %q", actual)
 	}
 }
 

+ 4 - 0
man/docker-create.1.md

@@ -21,6 +21,7 @@ docker-create - Create a new container
 [**--device**[=*[]*]]
 [**--dns**[=*[]*]]
 [**--dns-search**[=*[]*]]
+[**--dns-opt**[=*[]*]]
 [**-e**|**--env**[=*[]*]]
 [**--entrypoint**[=*ENTRYPOINT*]]
 [**--env-file**[=*[]*]]
@@ -118,6 +119,9 @@ two memory nodes.
 **--dns**=[]
    Set custom DNS servers
 
+**--dns-opt**=[]
+   Set custom DNS options
+
 **--dns-search**=[]
    Set custom DNS search domains (Use --dns-search=. if you don't wish to set the search domain)
 

+ 1 - 0
man/docker-inspect.1.md

@@ -123,6 +123,7 @@ To get information on a container use its ID or instance name:
         "PublishAllPorts": false,
         "Dns": null,
         "DnsSearch": null,
+        "DnsOptions": null,
         "ExtraHosts": null,
         "VolumesFrom": null,
         "Devices": [],

+ 4 - 0
man/docker-run.1.md

@@ -21,6 +21,7 @@ docker-run - Run a command in a new container
 [**-d**|**--detach**[=*false*]]
 [**--device**[=*[]*]]
 [**--dns**[=*[]*]]
+[**--dns-opt**[=*[]*]]
 [**--dns-search**[=*[]*]]
 [**-e**|**--env**[=*[]*]]
 [**--entrypoint**[=*ENTRYPOINT*]]
@@ -185,6 +186,9 @@ stopping the process by pressing the keys CTRL-P CTRL-Q.
 **--dns-search**=[]
    Set custom DNS search domains (Use --dns-search=. if you don't wish to set the search domain)
 
+**--dns-opt**=[]
+   Set custom DNS options
+
 **--dns**=[]
    Set custom DNS servers
 

+ 3 - 0
man/docker.1.md

@@ -56,6 +56,9 @@ To see the man page for a command run **man docker <command>**.
 **--dns**=""
   Force Docker to use specific DNS servers
 
+**--dns-opt**=[]
+  DNS options to use.
+
 **--dns-search**=[]
   DNS search domains to use.
 

+ 1 - 0
runconfig/fixtures/container_config_1_17.json

@@ -38,6 +38,7 @@
        "ReadonlyRootfs": false,
        "Dns": ["8.8.8.8"],
        "DnsSearch": [""],
+       "DnsOptions": [""],
        "ExtraHosts": null,
        "VolumesFrom": ["parent", "other:ro"],
        "CapAdd": ["NET_ADMIN"],

+ 1 - 0
runconfig/fixtures/container_config_1_19.json

@@ -42,6 +42,7 @@
        "ReadonlyRootfs": false,
        "Dns": ["8.8.8.8"],
        "DnsSearch": [""],
+       "DnsOptions": [""],
        "ExtraHosts": null,
        "VolumesFrom": ["parent", "other:ro"],
        "CapAdd": ["NET_ADMIN"],

+ 3 - 2
runconfig/hostconfig.go

@@ -232,8 +232,9 @@ type HostConfig struct {
 	PortBindings     nat.PortMap           // Port mapping between the exposed port (container) and the host
 	Links            []string              // List of links (in the name:alias form)
 	PublishAllPorts  bool                  // Should docker publish all exposed port for the container
-	DNS              []string              `json:"Dns"`       // List of DNS server to lookup
-	DNSSearch        []string              `json:"DnsSearch"` // List of DNSSearch to look for
+	DNS              []string              `json:"Dns"`        // List of DNS server to lookup
+	DNSOptions       []string              `json:"DnsOptions"` // List of DNSOption to look for
+	DNSSearch        []string              `json:"DnsSearch"`  // List of DNSSearch to look for
 	ExtraHosts       []string              // List of extra hosts
 	VolumesFrom      []string              // List of volumes to take from other container
 	Devices          []DeviceMapping       // List of devices to map inside the container

+ 3 - 0
runconfig/parse.go

@@ -52,6 +52,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		flExpose      = opts.NewListOpts(nil)
 		flDNS         = opts.NewListOpts(opts.ValidateIPAddress)
 		flDNSSearch   = opts.NewListOpts(opts.ValidateDNSSearch)
+		flDNSOptions  = opts.NewListOpts(nil)
 		flExtraHosts  = opts.NewListOpts(opts.ValidateExtraHost)
 		flVolumesFrom = opts.NewListOpts(nil)
 		flLxcOpts     = opts.NewListOpts(nil)
@@ -109,6 +110,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 	cmd.Var(&flExpose, []string{"#expose", "-expose"}, "Expose a port or a range of ports")
 	cmd.Var(&flDNS, []string{"#dns", "-dns"}, "Set custom DNS servers")
 	cmd.Var(&flDNSSearch, []string{"-dns-search"}, "Set custom DNS search domains")
+	cmd.Var(&flDNSOptions, []string{"-dns-opt"}, "Set DNS options")
 	cmd.Var(&flExtraHosts, []string{"-add-host"}, "Add a custom host-to-IP mapping (host:ip)")
 	cmd.Var(&flVolumesFrom, []string{"#volumes-from", "-volumes-from"}, "Mount volumes from the specified container(s)")
 	cmd.Var(&flLxcOpts, []string{"#lxc-conf", "-lxc-conf"}, "Add custom lxc options")
@@ -347,6 +349,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		PublishAllPorts:  *flPublishAll,
 		DNS:              flDNS.GetAll(),
 		DNSSearch:        flDNSSearch.GetAll(),
+		DNSOptions:       flDNSOptions.GetAll(),
 		ExtraHosts:       flExtraHosts.GetAll(),
 		VolumesFrom:      flVolumesFrom.GetAll(),
 		NetworkMode:      NetworkMode(*flNetMode),