Browse code

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

Add --add-host for docker build

Sebastiaan van Stijn authored on 2017/02/27 20:42:18
Showing 10 changed files
... ...
@@ -53,6 +53,7 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui
53 53
 	options.CgroupParent = r.FormValue("cgroupparent")
54 54
 	options.NetworkMode = r.FormValue("networkmode")
55 55
 	options.Tags = r.Form["t"]
56
+	options.ExtraHosts = r.Form["extrahosts"]
56 57
 	options.SecurityOpt = r.Form["securityopt"]
57 58
 	options.Squash = httputils.BoolValue(r, "squash")
58 59
 
... ...
@@ -4417,6 +4417,10 @@ paths:
4417 4417
           in: "query"
4418 4418
           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."
4419 4419
           type: "string"
4420
+        - name: "extrahosts"
4421
+          in: "query"
4422
+          description: "Extra hosts to add to /etc/hosts"
4423
+          type: "string"
4420 4424
         - name: "remote"
4421 4425
           in: "query"
4422 4426
           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."
... ...
@@ -176,6 +176,7 @@ type ImageBuildOptions struct {
176 176
 	// specified here do not need to have a valid parent chain to match cache.
177 177
 	CacheFrom   []string
178 178
 	SecurityOpt []string
179
+	ExtraHosts  []string // List of extra hosts
179 180
 }
180 181
 
181 182
 // ImageBuildResponse holds information
... ...
@@ -498,7 +498,8 @@ func (b *Builder) create() (string, error) {
498 498
 		Resources:   resources,
499 499
 		NetworkMode: container.NetworkMode(b.options.NetworkMode),
500 500
 		// Set a log config to override any default value set on the daemon
501
-		LogConfig: defaultLogConfig,
501
+		LogConfig:  defaultLogConfig,
502
+		ExtraHosts: b.options.ExtraHosts,
502 503
 	}
503 504
 
504 505
 	config := *b.runConfig
... ...
@@ -38,6 +38,7 @@ type buildOptions struct {
38 38
 	tags           opts.ListOpts
39 39
 	labels         opts.ListOpts
40 40
 	buildArgs      opts.ListOpts
41
+	extraHosts     opts.ListOpts
41 42
 	ulimits        *opts.UlimitOpt
42 43
 	memory         string
43 44
 	memorySwap     string
... ...
@@ -65,10 +66,11 @@ type buildOptions struct {
65 65
 func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command {
66 66
 	ulimits := make(map[string]*units.Ulimit)
67 67
 	options := buildOptions{
68
-		tags:      opts.NewListOpts(validateTag),
69
-		buildArgs: opts.NewListOpts(opts.ValidateEnv),
70
-		ulimits:   opts.NewUlimitOpt(&ulimits),
71
-		labels:    opts.NewListOpts(opts.ValidateEnv),
68
+		tags:       opts.NewListOpts(validateTag),
69
+		buildArgs:  opts.NewListOpts(opts.ValidateEnv),
70
+		ulimits:    opts.NewUlimitOpt(&ulimits),
71
+		labels:     opts.NewListOpts(opts.ValidateEnv),
72
+		extraHosts: opts.NewListOpts(opts.ValidateExtraHost),
72 73
 	}
73 74
 
74 75
 	cmd := &cobra.Command{
... ...
@@ -108,6 +110,7 @@ func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command {
108 108
 	flags.StringSliceVar(&options.securityOpt, "security-opt", []string{}, "Security options")
109 109
 	flags.StringVar(&options.networkMode, "network", "default", "Set the networking mode for the RUN instructions during build")
110 110
 	flags.SetAnnotation("network", "version", []string{"1.25"})
111
+	flags.Var(&options.extraHosts, "add-host", "Add a custom host-to-IP mapping (host:ip)")
111 112
 
112 113
 	command.AddTrustVerificationFlags(flags)
113 114
 
... ...
@@ -301,6 +304,7 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
301 301
 		SecurityOpt:    options.securityOpt,
302 302
 		NetworkMode:    options.networkMode,
303 303
 		Squash:         options.squash,
304
+		ExtraHosts:     options.extraHosts.GetAll(),
304 305
 	}
305 306
 
306 307
 	response, err := dockerCli.Client().ImageBuild(ctx, body, buildOptions)
... ...
@@ -48,6 +48,7 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur
48 48
 	query := url.Values{
49 49
 		"t":           options.Tags,
50 50
 		"securityopt": options.SecurityOpt,
51
+		"extrahosts":  options.ExtraHosts,
51 52
 	}
52 53
 	if options.SuppressOutput {
53 54
 		query.Set("q", "1")
... ...
@@ -21,6 +21,7 @@ keywords: "API, Docker, rcli, REST, documentation"
21 21
 * `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}.
22 22
 * `GET /containers/json` now supports `publish` and `expose` filters to filter containers that expose or publish certain ports.
23 23
 * `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.
24
+* `POST /build` now accepts `extrahosts` parameter to specify a host to ip mapping to use during the build.
24 25
 
25 26
 ## v1.26 API changes
26 27
 
... ...
@@ -21,6 +21,7 @@ Usage:  docker build [OPTIONS] PATH | URL | -
21 21
 Build an image from a Dockerfile
22 22
 
23 23
 Options:
24
+      --add-host value          Add a custom host-to-IP mapping (host:ip) (default [])
24 25
       --build-arg value         Set build-time variables (default [])
25 26
       --cache-from value        Images to consider as cache sources (default [])
26 27
       --cgroup-parent string    Optional parent cgroup for the container
... ...
@@ -435,6 +436,13 @@ Linux namespaces. On Microsoft Windows, you can specify these values:
435 435
 
436 436
 Specifying the `--isolation` flag without a value is the same as setting `--isolation="default"`.
437 437
 
438
+### Add entries to container hosts file (--add-host)
439
+
440
+You can add other hosts into a container's `/etc/hosts` file by using one or
441
+more `--add-host` flags. This example adds a static address for a host named
442
+`docker`:
443
+
444
+    $ docker build --add-host=docker:10.180.0.1 .
438 445
 
439 446
 ### Squash an image's layers (--squash) **Experimental Only**
440 447
 
... ...
@@ -451,3 +459,4 @@ space.
451 451
 **Note**: using this option you may see significantly more space used due to
452 452
 storing two copies of the image, one for the build cache with all the cache
453 453
 layers in tact, and one for the squashed version.
454
+
... ...
@@ -5567,6 +5567,49 @@ func (s *DockerSuite) TestBuildNetContainer(c *check.C) {
5567 5567
 	c.Assert(strings.TrimSpace(host), check.Equals, "foobar")
5568 5568
 }
5569 5569
 
5570
+func (s *DockerSuite) TestBuildWithExtraHost(c *check.C) {
5571
+	testRequires(c, DaemonIsLinux)
5572
+
5573
+	name := "testbuildwithextrahost"
5574
+	buildImageSuccessfully(c, name,
5575
+		withBuildFlags(
5576
+			"--add-host", "foo:127.0.0.1",
5577
+			"--add-host", "bar:127.0.0.1",
5578
+		),
5579
+		withDockerfile(`
5580
+  FROM busybox
5581
+  RUN ping -c 1 foo
5582
+  RUN ping -c 1 bar
5583
+  `))
5584
+}
5585
+
5586
+func (s *DockerSuite) TestBuildWithExtraHostInvalidFormat(c *check.C) {
5587
+	testRequires(c, DaemonIsLinux)
5588
+	dockerfile := `
5589
+		FROM busybox
5590
+		RUN ping -c 1 foo`
5591
+
5592
+	testCases := []struct {
5593
+		testName   string
5594
+		dockerfile string
5595
+		buildFlag  string
5596
+	}{
5597
+		{"extra_host_missing_ip", dockerfile, "--add-host=foo"},
5598
+		{"extra_host_missing_ip_with_delimeter", dockerfile, "--add-host=foo:"},
5599
+		{"extra_host_missing_hostname", dockerfile, "--add-host=:127.0.0.1"},
5600
+		{"extra_host_invalid_ipv4", dockerfile, "--add-host=foo:101.10.2"},
5601
+		{"extra_host_invalid_ipv6", dockerfile, "--add-host=foo:2001::1::3F"},
5602
+	}
5603
+
5604
+	for _, tc := range testCases {
5605
+		result := buildImage(tc.testName, withBuildFlags(tc.buildFlag), withDockerfile(tc.dockerfile))
5606
+		result.Assert(c, icmd.Expected{
5607
+			ExitCode: 125,
5608
+		})
5609
+	}
5610
+
5611
+}
5612
+
5570 5613
 func (s *DockerSuite) TestBuildSquashParent(c *check.C) {
5571 5614
 	testRequires(c, ExperimentalDaemon)
5572 5615
 	dockerFile := `
... ...
@@ -6,6 +6,7 @@ docker-build - Build an image from a Dockerfile
6 6
 
7 7
 # SYNOPSIS
8 8
 **docker build**
9
+[**--add-host**[=*[]*]]
9 10
 [**--build-arg**[=*[]*]]
10 11
 [**--cpu-shares**[=*0*]]
11 12
 [**--cgroup-parent**[=*CGROUP-PARENT*]]
... ...
@@ -74,6 +75,12 @@ set as the **URL**, the repository is cloned locally and then sent as the contex
74 74
    storing two copies of the image, one for the build cache with all the cache
75 75
    layers in tact, and one for the squashed version.
76 76
 
77
+**--add-host**=[]
78
+   Add a custom host-to-IP mapping (host:ip)
79
+
80
+   Add a line to /etc/hosts. The format is hostname:ip.  The **--add-host**
81
+option can be set multiple times.
82
+
77 83
 **--build-arg**=*variable*
78 84
    name and value of a **buildarg**.
79 85