diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index c4aa79d22..020ec9ab8 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -35,6 +35,7 @@ type Config struct { ImageName string `mapstructure:"image_name"` ImageDescription string `mapstructure:"image_description"` ImageFamily string `mapstructure:"image_family"` + ImageLabels map[string]string `mapstructure:"image_labels"` InstanceName string `mapstructure:"instance_name"` Labels map[string]string `mapstructure:"labels"` MachineType string `mapstructure:"machine_type"` diff --git a/builder/googlecompute/config_test.go b/builder/googlecompute/config_test.go index 7255add30..551692b29 100644 --- a/builder/googlecompute/config_test.go +++ b/builder/googlecompute/config_test.go @@ -305,7 +305,11 @@ func testConfig(t *testing.T) map[string]interface{} { "source_image": "foo", "ssh_username": "root", "image_family": "bar", - "zone": "us-east1-a", + "image_labels": map[string]string{ + "label-1": "value-1", + "label-2": "value-2", + }, + "zone": "us-east1-a", } } diff --git a/builder/googlecompute/driver.go b/builder/googlecompute/driver.go index 60707ac84..bd302ddc0 100644 --- a/builder/googlecompute/driver.go +++ b/builder/googlecompute/driver.go @@ -11,7 +11,7 @@ import ( type Driver interface { // CreateImage creates an image from the given disk in Google Compute // Engine. - CreateImage(name, description, family, zone, disk string) (<-chan *Image, <-chan error) + CreateImage(name, description, family, zone, disk string, image_labels map[string]string) (<-chan *Image, <-chan error) // DeleteImage deletes the image with the given name. DeleteImage(name string) <-chan error diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index 0df21eba6..02a230cfe 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -98,11 +98,12 @@ func NewDriverGCE(ui packer.Ui, p string, a *AccountFile) (Driver, error) { }, nil } -func (d *driverGCE) CreateImage(name, description, family, zone, disk string) (<-chan *Image, <-chan error) { +func (d *driverGCE) CreateImage(name, description, family, zone, disk string, image_labels map[string]string) (<-chan *Image, <-chan error) { gce_image := &compute.Image{ Description: description, Name: name, Family: family, + Labels: image_labels, SourceDisk: fmt.Sprintf("%s%s/zones/%s/disks/%s", d.service.BasePath, d.projectId, zone, disk), SourceType: "RAW", } diff --git a/builder/googlecompute/driver_mock.go b/builder/googlecompute/driver_mock.go index f9423b8aa..895775da5 100644 --- a/builder/googlecompute/driver_mock.go +++ b/builder/googlecompute/driver_mock.go @@ -8,6 +8,7 @@ type DriverMock struct { CreateImageName string CreateImageDesc string CreateImageFamily string + CreateImageLabels map[string]string CreateImageZone string CreateImageDisk string CreateImageResultLicenses []string @@ -81,10 +82,11 @@ type DriverMock struct { WaitForInstanceErrCh <-chan error } -func (d *DriverMock) CreateImage(name, description, family, zone, disk string) (<-chan *Image, <-chan error) { +func (d *DriverMock) CreateImage(name, description, family, zone, disk string, image_labels map[string]string) (<-chan *Image, <-chan error) { d.CreateImageName = name d.CreateImageDesc = description d.CreateImageFamily = family + d.CreateImageLabels = image_labels d.CreateImageZone = zone d.CreateImageDisk = disk if d.CreateImageResultProjectId == "" { @@ -103,6 +105,7 @@ func (d *DriverMock) CreateImage(name, description, family, zone, disk string) ( if resultCh == nil { ch := make(chan *Image, 1) ch <- &Image{ + Labels: d.CreateImageLabels, Licenses: d.CreateImageResultLicenses, Name: name, ProjectId: d.CreateImageResultProjectId, diff --git a/builder/googlecompute/image.go b/builder/googlecompute/image.go index 11fe7df55..fae69db75 100644 --- a/builder/googlecompute/image.go +++ b/builder/googlecompute/image.go @@ -5,6 +5,7 @@ import ( ) type Image struct { + Labels map[string]string Licenses []string Name string ProjectId string diff --git a/builder/googlecompute/step_create_image.go b/builder/googlecompute/step_create_image.go index 13339d82f..bcb840e78 100644 --- a/builder/googlecompute/step_create_image.go +++ b/builder/googlecompute/step_create_image.go @@ -39,7 +39,7 @@ func (s *StepCreateImage) Run(state multistep.StateBag) multistep.StepAction { imageCh, errCh := driver.CreateImage( config.ImageName, config.ImageDescription, config.ImageFamily, config.Zone, - config.DiskName) + config.DiskName, config.ImageLabels) var err error select { case err = <-errCh: diff --git a/builder/googlecompute/step_create_image_test.go b/builder/googlecompute/step_create_image_test.go index 63c962904..639b25255 100644 --- a/builder/googlecompute/step_create_image_test.go +++ b/builder/googlecompute/step_create_image_test.go @@ -46,6 +46,7 @@ func TestStepCreateImage(t *testing.T) { assert.Equal(t, d.CreateImageFamily, c.ImageFamily, "Incorrect image family passed to driver.") assert.Equal(t, d.CreateImageZone, c.Zone, "Incorrect image zone passed to driver.") assert.Equal(t, d.CreateImageDisk, c.DiskName, "Incorrect disk passed to driver.") + assert.Equal(t, d.CreateImageLabels, c.ImageLabels, "Incorrect image_labels passed to driver.") } func TestStepCreateImage_errorOnChannel(t *testing.T) { diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index dda8841dd..12db018c4 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -198,6 +198,9 @@ builder. instead of a specific image name. The image family always returns its latest image that is not deprecated. +- `image_labels` (object of key/value strings) - Key/value pair labels to + apply to the created image. + - `image_name` (string) - The unique name of the resulting image. Defaults to `"packer-{{timestamp}}"`.