Browse Source

Merge pull request #30383 from TDAbboud/30096-add-host-docker-build

Add --add-host for docker build
Sebastiaan van Stijn 8 years ago
parent
commit
a64ea37753

+ 1 - 0
api/server/router/build/build_routes.go

@@ -53,6 +53,7 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui
 	options.CgroupParent = r.FormValue("cgroupparent")
 	options.CgroupParent = r.FormValue("cgroupparent")
 	options.NetworkMode = r.FormValue("networkmode")
 	options.NetworkMode = r.FormValue("networkmode")
 	options.Tags = r.Form["t"]
 	options.Tags = r.Form["t"]
+	options.ExtraHosts = r.Form["extrahosts"]
 	options.SecurityOpt = r.Form["securityopt"]
 	options.SecurityOpt = r.Form["securityopt"]
 	options.Squash = httputils.BoolValue(r, "squash")
 	options.Squash = httputils.BoolValue(r, "squash")
 
 

+ 4 - 0
api/swagger.yaml

@@ -4417,6 +4417,10 @@ paths:
           in: "query"
           in: "query"
           description: "A name and optional tag to apply to the image in the `name:tag` format. If you omit the tag the default `latest` value is assumed. You can provide several `t` parameters."
           description: "A name and optional tag to apply to the image in the `name:tag` format. If you omit the tag the default `latest` value is assumed. You can provide several `t` parameters."
           type: "string"
           type: "string"
+        - name: "extrahosts"
+          in: "query"
+          description: "Extra hosts to add to /etc/hosts"
+          type: "string"
         - name: "remote"
         - name: "remote"
           in: "query"
           in: "query"
           description: "A Git repository URI or HTTP/HTTPS context URI. If the URI points to a single text file, the file’s contents are placed into a file called `Dockerfile` and the image is built from that file. If the URI points to a tarball, the file is downloaded by the daemon and the contents therein used as the context for the build. If the URI points to a tarball and the `dockerfile` parameter is also specified, there must be a file with the corresponding path inside the tarball."
           description: "A Git repository URI or HTTP/HTTPS context URI. If the URI points to a single text file, the file’s contents are placed into a file called `Dockerfile` and the image is built from that file. If the URI points to a tarball, the file is downloaded by the daemon and the contents therein used as the context for the build. If the URI points to a tarball and the `dockerfile` parameter is also specified, there must be a file with the corresponding path inside the tarball."

+ 1 - 0
api/types/client.go

@@ -176,6 +176,7 @@ type ImageBuildOptions struct {
 	// specified here do not need to have a valid parent chain to match cache.
 	// specified here do not need to have a valid parent chain to match cache.
 	CacheFrom   []string
 	CacheFrom   []string
 	SecurityOpt []string
 	SecurityOpt []string
+	ExtraHosts  []string // List of extra hosts
 }
 }
 
 
 // ImageBuildResponse holds information
 // ImageBuildResponse holds information

+ 2 - 1
builder/dockerfile/internals.go

@@ -498,7 +498,8 @@ func (b *Builder) create() (string, error) {
 		Resources:   resources,
 		Resources:   resources,
 		NetworkMode: container.NetworkMode(b.options.NetworkMode),
 		NetworkMode: container.NetworkMode(b.options.NetworkMode),
 		// Set a log config to override any default value set on the daemon
 		// Set a log config to override any default value set on the daemon
-		LogConfig: defaultLogConfig,
+		LogConfig:  defaultLogConfig,
+		ExtraHosts: b.options.ExtraHosts,
 	}
 	}
 
 
 	config := *b.runConfig
 	config := *b.runConfig

+ 8 - 4
cli/command/image/build.go

@@ -38,6 +38,7 @@ type buildOptions struct {
 	tags           opts.ListOpts
 	tags           opts.ListOpts
 	labels         opts.ListOpts
 	labels         opts.ListOpts
 	buildArgs      opts.ListOpts
 	buildArgs      opts.ListOpts
+	extraHosts     opts.ListOpts
 	ulimits        *opts.UlimitOpt
 	ulimits        *opts.UlimitOpt
 	memory         string
 	memory         string
 	memorySwap     string
 	memorySwap     string
@@ -65,10 +66,11 @@ type buildOptions struct {
 func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command {
 func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command {
 	ulimits := make(map[string]*units.Ulimit)
 	ulimits := make(map[string]*units.Ulimit)
 	options := buildOptions{
 	options := buildOptions{
-		tags:      opts.NewListOpts(validateTag),
-		buildArgs: opts.NewListOpts(opts.ValidateEnv),
-		ulimits:   opts.NewUlimitOpt(&ulimits),
-		labels:    opts.NewListOpts(opts.ValidateEnv),
+		tags:       opts.NewListOpts(validateTag),
+		buildArgs:  opts.NewListOpts(opts.ValidateEnv),
+		ulimits:    opts.NewUlimitOpt(&ulimits),
+		labels:     opts.NewListOpts(opts.ValidateEnv),
+		extraHosts: opts.NewListOpts(opts.ValidateExtraHost),
 	}
 	}
 
 
 	cmd := &cobra.Command{
 	cmd := &cobra.Command{
@@ -108,6 +110,7 @@ func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command {
 	flags.StringSliceVar(&options.securityOpt, "security-opt", []string{}, "Security options")
 	flags.StringSliceVar(&options.securityOpt, "security-opt", []string{}, "Security options")
 	flags.StringVar(&options.networkMode, "network", "default", "Set the networking mode for the RUN instructions during build")
 	flags.StringVar(&options.networkMode, "network", "default", "Set the networking mode for the RUN instructions during build")
 	flags.SetAnnotation("network", "version", []string{"1.25"})
 	flags.SetAnnotation("network", "version", []string{"1.25"})
+	flags.Var(&options.extraHosts, "add-host", "Add a custom host-to-IP mapping (host:ip)")
 
 
 	command.AddTrustVerificationFlags(flags)
 	command.AddTrustVerificationFlags(flags)
 
 
@@ -301,6 +304,7 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
 		SecurityOpt:    options.securityOpt,
 		SecurityOpt:    options.securityOpt,
 		NetworkMode:    options.networkMode,
 		NetworkMode:    options.networkMode,
 		Squash:         options.squash,
 		Squash:         options.squash,
+		ExtraHosts:     options.extraHosts.GetAll(),
 	}
 	}
 
 
 	response, err := dockerCli.Client().ImageBuild(ctx, body, buildOptions)
 	response, err := dockerCli.Client().ImageBuild(ctx, body, buildOptions)

+ 1 - 0
client/image_build.go

@@ -48,6 +48,7 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur
 	query := url.Values{
 	query := url.Values{
 		"t":           options.Tags,
 		"t":           options.Tags,
 		"securityopt": options.SecurityOpt,
 		"securityopt": options.SecurityOpt,
+		"extrahosts":  options.ExtraHosts,
 	}
 	}
 	if options.SuppressOutput {
 	if options.SuppressOutput {
 		query.Set("q", "1")
 		query.Set("q", "1")

+ 1 - 0
docs/api/version-history.md

@@ -21,6 +21,7 @@ keywords: "API, Docker, rcli, REST, documentation"
 * `GET /networks` is optimised only to return list of all networks and network specific information. List of all containers attached to a specific network is removed from this API and is only available using the network specific `GET /networks/{network-id}.
 * `GET /networks` is optimised only to return list of all networks and network specific information. List of all containers attached to a specific network is removed from this API and is only available using the network specific `GET /networks/{network-id}.
 * `GET /containers/json` now supports `publish` and `expose` filters to filter containers that expose or publish certain ports.
 * `GET /containers/json` now supports `publish` and `expose` filters to filter containers that expose or publish certain ports.
 * `POST /services/create` and `POST /services/(id or name)/update` now accept the `ReadOnly` parameter, which mounts the container's root filesystem as read only.
 * `POST /services/create` and `POST /services/(id or name)/update` now accept the `ReadOnly` parameter, which mounts the container's root filesystem as read only.
+* `POST /build` now accepts `extrahosts` parameter to specify a host to ip mapping to use during the build.
 
 
 ## v1.26 API changes
 ## v1.26 API changes
 
 

+ 9 - 0
docs/reference/commandline/build.md

@@ -21,6 +21,7 @@ Usage:  docker build [OPTIONS] PATH | URL | -
 Build an image from a Dockerfile
 Build an image from a Dockerfile
 
 
 Options:
 Options:
+      --add-host value          Add a custom host-to-IP mapping (host:ip) (default [])
       --build-arg value         Set build-time variables (default [])
       --build-arg value         Set build-time variables (default [])
       --cache-from value        Images to consider as cache sources (default [])
       --cache-from value        Images to consider as cache sources (default [])
       --cgroup-parent string    Optional parent cgroup for the container
       --cgroup-parent string    Optional parent cgroup for the container
@@ -435,6 +436,13 @@ Linux namespaces. On Microsoft Windows, you can specify these values:
 
 
 Specifying the `--isolation` flag without a value is the same as setting `--isolation="default"`.
 Specifying the `--isolation` flag without a value is the same as setting `--isolation="default"`.
 
 
+### Add entries to container hosts file (--add-host)
+
+You can add other hosts into a container's `/etc/hosts` file by using one or
+more `--add-host` flags. This example adds a static address for a host named
+`docker`:
+
+    $ docker build --add-host=docker:10.180.0.1 .
 
 
 ### Squash an image's layers (--squash) **Experimental Only**
 ### Squash an image's layers (--squash) **Experimental Only**
 
 
@@ -451,3 +459,4 @@ space.
 **Note**: using this option you may see significantly more space used due to
 **Note**: using this option you may see significantly more space used due to
 storing two copies of the image, one for the build cache with all the cache
 storing two copies of the image, one for the build cache with all the cache
 layers in tact, and one for the squashed version.
 layers in tact, and one for the squashed version.
+

+ 43 - 0
integration-cli/docker_cli_build_test.go

@@ -5567,6 +5567,49 @@ func (s *DockerSuite) TestBuildNetContainer(c *check.C) {
 	c.Assert(strings.TrimSpace(host), check.Equals, "foobar")
 	c.Assert(strings.TrimSpace(host), check.Equals, "foobar")
 }
 }
 
 
+func (s *DockerSuite) TestBuildWithExtraHost(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+
+	name := "testbuildwithextrahost"
+	buildImageSuccessfully(c, name,
+		withBuildFlags(
+			"--add-host", "foo:127.0.0.1",
+			"--add-host", "bar:127.0.0.1",
+		),
+		withDockerfile(`
+  FROM busybox
+  RUN ping -c 1 foo
+  RUN ping -c 1 bar
+  `))
+}
+
+func (s *DockerSuite) TestBuildWithExtraHostInvalidFormat(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	dockerfile := `
+		FROM busybox
+		RUN ping -c 1 foo`
+
+	testCases := []struct {
+		testName   string
+		dockerfile string
+		buildFlag  string
+	}{
+		{"extra_host_missing_ip", dockerfile, "--add-host=foo"},
+		{"extra_host_missing_ip_with_delimeter", dockerfile, "--add-host=foo:"},
+		{"extra_host_missing_hostname", dockerfile, "--add-host=:127.0.0.1"},
+		{"extra_host_invalid_ipv4", dockerfile, "--add-host=foo:101.10.2"},
+		{"extra_host_invalid_ipv6", dockerfile, "--add-host=foo:2001::1::3F"},
+	}
+
+	for _, tc := range testCases {
+		result := buildImage(tc.testName, withBuildFlags(tc.buildFlag), withDockerfile(tc.dockerfile))
+		result.Assert(c, icmd.Expected{
+			ExitCode: 125,
+		})
+	}
+
+}
+
 func (s *DockerSuite) TestBuildSquashParent(c *check.C) {
 func (s *DockerSuite) TestBuildSquashParent(c *check.C) {
 	testRequires(c, ExperimentalDaemon)
 	testRequires(c, ExperimentalDaemon)
 	dockerFile := `
 	dockerFile := `

+ 7 - 0
man/docker-build.1.md

@@ -6,6 +6,7 @@ docker-build - Build an image from a Dockerfile
 
 
 # SYNOPSIS
 # SYNOPSIS
 **docker build**
 **docker build**
+[**--add-host**[=*[]*]]
 [**--build-arg**[=*[]*]]
 [**--build-arg**[=*[]*]]
 [**--cpu-shares**[=*0*]]
 [**--cpu-shares**[=*0*]]
 [**--cgroup-parent**[=*CGROUP-PARENT*]]
 [**--cgroup-parent**[=*CGROUP-PARENT*]]
@@ -74,6 +75,12 @@ set as the **URL**, the repository is cloned locally and then sent as the contex
    storing two copies of the image, one for the build cache with all the cache
    storing two copies of the image, one for the build cache with all the cache
    layers in tact, and one for the squashed version.
    layers in tact, and one for the squashed version.
 
 
+**--add-host**=[]
+   Add a custom host-to-IP mapping (host:ip)
+
+   Add a line to /etc/hosts. The format is hostname:ip.  The **--add-host**
+option can be set multiple times.
+
 **--build-arg**=*variable*
 **--build-arg**=*variable*
    name and value of a **buildarg**.
    name and value of a **buildarg**.