diff --git a/builder/docker/driver_mock.go b/builder/docker/driver_mock.go index 4ffc69299..71af7f9a0 100644 --- a/builder/docker/driver_mock.go +++ b/builder/docker/driver_mock.go @@ -51,9 +51,9 @@ type MockDriver struct { SaveImageReader io.Reader SaveImageError error - TagImageCalled bool + TagImageCalled int TagImageImageId string - TagImageRepo string + TagImageRepo []string TagImageForce bool TagImageErr error @@ -177,9 +177,9 @@ func (d *MockDriver) StopContainer(id string) error { } func (d *MockDriver) TagImage(id string, repo string, force bool) error { - d.TagImageCalled = true + d.TagImageCalled += 1 d.TagImageImageId = id - d.TagImageRepo = repo + d.TagImageRepo = append(d.TagImageRepo, repo) d.TagImageForce = force return d.TagImageErr } diff --git a/post-processor/docker-tag/post-processor.go b/post-processor/docker-tag/post-processor.go index 1712efbda..f2ba1beb3 100644 --- a/post-processor/docker-tag/post-processor.go +++ b/post-processor/docker-tag/post-processor.go @@ -19,8 +19,8 @@ const BuilderId = "packer.post-processor.docker-tag" type Config struct { common.PackerConfig `mapstructure:",squash"` - Repository string `mapstructure:"repository"` - Tag string `mapstructure:"tag"` + Repository string `mapstructure:"repository"` + Tag []string `mapstructure:"tag"` Force bool ctx interpolate.Context @@ -64,22 +64,25 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact } importRepo := p.config.Repository - if p.config.Tag != "" { - importRepo += ":" + p.config.Tag - } + var lastTaggedRepo = importRepo + for _, tag := range p.config.Tag { + local := importRepo + ":" + tag + ui.Message("Tagging image: " + artifact.Id()) + ui.Message("Repository: " + local) - ui.Message("Tagging image: " + artifact.Id()) - ui.Message("Repository: " + importRepo) - err := driver.TagImage(artifact.Id(), importRepo, p.config.Force) - if err != nil { - return nil, false, true, err + err := driver.TagImage(artifact.Id(), local, p.config.Force) + if err != nil { + return nil, false, true, err + } + + lastTaggedRepo = local } // Build the artifact artifact = &docker.ImportArtifact{ BuilderIdValue: BuilderId, Driver: driver, - IdValue: importRepo, + IdValue: lastTaggedRepo, } // If we tag an image and then delete it, there was no point in creating the diff --git a/post-processor/docker-tag/post-processor.hcl2spec.go b/post-processor/docker-tag/post-processor.hcl2spec.go index 3df25724b..22c20a420 100644 --- a/post-processor/docker-tag/post-processor.hcl2spec.go +++ b/post-processor/docker-tag/post-processor.hcl2spec.go @@ -17,7 +17,7 @@ type FlatConfig struct { PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"` PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"` Repository *string `mapstructure:"repository" cty:"repository"` - Tag *string `mapstructure:"tag" cty:"tag"` + Tag []string `mapstructure:"tag" cty:"tag"` Force *bool `cty:"force"` } @@ -38,7 +38,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "packer_user_variables": &hcldec.BlockAttrsSpec{TypeName: "packer_user_variables", ElementType: cty.String, Required: false}, "packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false}, "repository": &hcldec.AttrSpec{Name: "repository", Type: cty.String, Required: false}, - "tag": &hcldec.AttrSpec{Name: "tag", Type: cty.String, Required: false}, + "tag": &hcldec.AttrSpec{Name: "tag", Type: cty.List(cty.String), Required: false}, "force": &hcldec.AttrSpec{Name: "force", Type: cty.Bool, Required: false}, } return s diff --git a/post-processor/docker-tag/post-processor_test.go b/post-processor/docker-tag/post-processor_test.go index 8c9c9c920..0c4fa9857 100644 --- a/post-processor/docker-tag/post-processor_test.go +++ b/post-processor/docker-tag/post-processor_test.go @@ -13,7 +13,7 @@ import ( func testConfig() map[string]interface{} { return map[string]interface{}{ "repository": "foo", - "tag": "bar", + "tag": "bar,buzz", } } @@ -63,15 +63,21 @@ func TestPostProcessor_PostProcess(t *testing.T) { t.Fatalf("err: %s", err) } - if !driver.TagImageCalled { + if driver.TagImageCalled != 2 { t.Fatal("should call TagImage") } if driver.TagImageImageId != "1234567890abcdef" { t.Fatal("bad image id") } - if driver.TagImageRepo != "foo:bar" { + + if driver.TagImageRepo[0] != "foo:bar" { t.Fatal("bad repo") } + + if driver.TagImageRepo[1] != "foo:buzz" { + t.Fatal("bad repo") + } + if driver.TagImageForce { t.Fatal("bad force. force=false in default") } @@ -105,13 +111,16 @@ func TestPostProcessor_PostProcess_Force(t *testing.T) { t.Fatalf("err: %s", err) } - if !driver.TagImageCalled { + if driver.TagImageCalled != 2 { t.Fatal("should call TagImage") } if driver.TagImageImageId != "1234567890abcdef" { t.Fatal("bad image id") } - if driver.TagImageRepo != "foo:bar" { + if driver.TagImageRepo[0] != "foo:bar" { + t.Fatal("bad repo") + } + if driver.TagImageRepo[1] != "foo:buzz" { t.Fatal("bad repo") } if !driver.TagImageForce {