Browse code

Add --add-host for docker build

Signed-off-by: Tony Abboud <tdabboud@hotmail.com>

Tony Abboud authored on 2017/01/14 00:01:58
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
 
... ...
@@ -4365,6 +4365,10 @@ paths:
4365 4365
           in: "query"
4366 4366
           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."
4367 4367
           type: "string"
4368
+        - name: "extrahosts"
4369
+          in: "query"
4370
+          description: "Extra hosts to add to /etc/hosts"
4371
+          type: "string"
4368 4372
         - name: "remote"
4369 4373
           in: "query"
4370 4374
           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."
... ...
@@ -175,6 +175,7 @@ type ImageBuildOptions struct {
175 175
 	// specified here do not need to have a valid parent chain to match cache.
176 176
 	CacheFrom   []string
177 177
 	SecurityOpt []string
178
+	ExtraHosts  []string // List of extra hosts
178 179
 }
179 180
 
180 181
 // 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
+
... ...
@@ -5546,6 +5546,49 @@ func (s *DockerSuite) TestBuildNetContainer(c *check.C) {
5546 5546
 	c.Assert(strings.TrimSpace(host), check.Equals, "foobar")
5547 5547
 }
5548 5548
 
5549
+func (s *DockerSuite) TestBuildWithExtraHost(c *check.C) {
5550
+	testRequires(c, DaemonIsLinux)
5551
+
5552
+	name := "testbuildwithextrahost"
5553
+	buildImageSuccessfully(c, name,
5554
+		withBuildFlags(
5555
+			"--add-host", "foo:127.0.0.1",
5556
+			"--add-host", "bar:127.0.0.1",
5557
+		),
5558
+		withDockerfile(`
5559
+  FROM busybox
5560
+  RUN ping -c 1 foo
5561
+  RUN ping -c 1 bar
5562
+  `))
5563
+}
5564
+
5565
+func (s *DockerSuite) TestBuildWithExtraHostInvalidFormat(c *check.C) {
5566
+	testRequires(c, DaemonIsLinux)
5567
+	dockerfile := `
5568
+		FROM busybox
5569
+		RUN ping -c 1 foo`
5570
+
5571
+	testCases := []struct {
5572
+		testName   string
5573
+		dockerfile string
5574
+		buildFlag  string
5575
+	}{
5576
+		{"extra_host_missing_ip", dockerfile, "--add-host=foo"},
5577
+		{"extra_host_missing_ip_with_delimeter", dockerfile, "--add-host=foo:"},
5578
+		{"extra_host_missing_hostname", dockerfile, "--add-host=:127.0.0.1"},
5579
+		{"extra_host_invalid_ipv4", dockerfile, "--add-host=foo:101.10.2"},
5580
+		{"extra_host_invalid_ipv6", dockerfile, "--add-host=foo:2001::1::3F"},
5581
+	}
5582
+
5583
+	for _, tc := range testCases {
5584
+		result := buildImage(tc.testName, withBuildFlags(tc.buildFlag), withDockerfile(tc.dockerfile))
5585
+		result.Assert(c, icmd.Expected{
5586
+			ExitCode: 125,
5587
+		})
5588
+	}
5589
+
5590
+}
5591
+
5549 5592
 func (s *DockerSuite) TestBuildSquashParent(c *check.C) {
5550 5593
 	testRequires(c, ExperimentalDaemon)
5551 5594
 	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