Browse code

emit a "tag" event when building image with "-t" parameter

This is useful for cluster systems such as swarm to sync the image
state when new images are successfully built.

Signed-off-by: Shijiang Wei <mountkin@gmail.com>

Shijiang Wei authored on 2015/10/17 00:54:05
Showing 4 changed files
... ...
@@ -462,7 +462,6 @@ func (s *router) postImagesTag(ctx context.Context, w http.ResponseWriter, r *ht
462 462
 	if err := s.daemon.TagImage(repo, tag, name, force); err != nil {
463 463
 		return err
464 464
 	}
465
-	s.daemon.EventsService.Log("tag", utils.ImageReference(repo, tag), "")
466 465
 	w.WriteHeader(http.StatusCreated)
467 466
 	return nil
468 467
 }
... ...
@@ -50,6 +50,7 @@ import (
50 50
 	"github.com/docker/docker/pkg/truncindex"
51 51
 	"github.com/docker/docker/registry"
52 52
 	"github.com/docker/docker/runconfig"
53
+	"github.com/docker/docker/utils"
53 54
 	volumedrivers "github.com/docker/docker/volume/drivers"
54 55
 	"github.com/docker/docker/volume/local"
55 56
 	"github.com/docker/docker/volume/store"
... ...
@@ -1026,7 +1027,11 @@ func (daemon *Daemon) Graph() *graph.Graph {
1026 1026
 // imageName. If force is true, an existing tag with the same name may be
1027 1027
 // overwritten.
1028 1028
 func (daemon *Daemon) TagImage(repoName, tag, imageName string, force bool) error {
1029
-	return daemon.repositories.Tag(repoName, tag, imageName, force)
1029
+	if err := daemon.repositories.Tag(repoName, tag, imageName, force); err != nil {
1030
+		return err
1031
+	}
1032
+	daemon.EventsService.Log("tag", utils.ImageReference(repoName, tag), "")
1033
+	return nil
1030 1034
 }
1031 1035
 
1032 1036
 // PullImage initiates a pull operation. image is the repository name to pull, and
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	"encoding/json"
8 8
 	"fmt"
9 9
 	"io/ioutil"
10
+	"net/http"
10 11
 	"os"
11 12
 	"os/exec"
12 13
 	"path/filepath"
... ...
@@ -6223,3 +6224,37 @@ func (s *DockerSuite) TestBuildNoNamedVolume(c *check.C) {
6223 6223
 	_, err := buildImage("test", dockerFile, false)
6224 6224
 	c.Assert(err, check.NotNil, check.Commentf("image build should have failed"))
6225 6225
 }
6226
+
6227
+func (s *DockerSuite) TestBuildTagEvent(c *check.C) {
6228
+	testRequires(c, DaemonIsLinux)
6229
+	resp, rc, err := sockRequestRaw("GET", `/events?filters={"event":["tag"]}`, nil, "application/json")
6230
+	c.Assert(err, check.IsNil)
6231
+	defer rc.Close()
6232
+	c.Assert(resp.StatusCode, check.Equals, http.StatusOK)
6233
+
6234
+	type event struct {
6235
+		Status string `json:"status"`
6236
+		ID     string `json:"id"`
6237
+	}
6238
+	ch := make(chan event)
6239
+	go func() {
6240
+		ev := event{}
6241
+		if err := json.NewDecoder(rc).Decode(&ev); err == nil {
6242
+			ch <- ev
6243
+		}
6244
+	}()
6245
+
6246
+	dockerFile := `FROM busybox
6247
+	RUN echo events
6248
+	`
6249
+	_, err = buildImage("test", dockerFile, false)
6250
+	c.Assert(err, check.IsNil)
6251
+
6252
+	select {
6253
+	case ev := <-ch:
6254
+		c.Assert(ev.Status, check.Equals, "tag")
6255
+		c.Assert(ev.ID, check.Equals, "test:")
6256
+	case <-time.After(time.Second):
6257
+		c.Fatal("The 'tag' event not heard from the server")
6258
+	}
6259
+}
... ...
@@ -414,13 +414,13 @@ func (s *DockerSuite) TestEventsFilterLabels(c *check.C) {
414 414
 func (s *DockerSuite) TestEventsFilterImageLabels(c *check.C) {
415 415
 	testRequires(c, DaemonIsLinux)
416 416
 	since := daemonTime(c).Unix()
417
-	name := "labelfilterimage"
417
+	name := "labelfiltertest"
418 418
 	label := "io.docker.testing=image"
419 419
 
420 420
 	// Build a test image.
421
-	_, err := buildImage(name, `
421
+	_, err := buildImage(name, fmt.Sprintf(`
422 422
 		FROM busybox:latest
423
-		LABEL io.docker.testing=image`, true)
423
+		LABEL %s`, label), true)
424 424
 	if err != nil {
425 425
 		c.Fatalf("Couldn't create image: %q", err)
426 426
 	}
... ...
@@ -437,7 +437,9 @@ func (s *DockerSuite) TestEventsFilterImageLabels(c *check.C) {
437 437
 		"--filter", fmt.Sprintf("label=%s", label))
438 438
 
439 439
 	events := strings.Split(strings.TrimSpace(out), "\n")
440
-	c.Assert(len(events), checker.Equals, 2, check.Commentf("Events == %s", events))
440
+
441
+	// 2 events from the "docker tag" command, another one is from "docker build"
442
+	c.Assert(len(events), checker.Equals, 3, check.Commentf("Events == %s", events))
441 443
 	for _, e := range events {
442 444
 		c.Assert(e, checker.Contains, "labelfiltertest")
443 445
 	}