Merge pull request #5842 from KohlsTechnology/googlecompute-licenses

Support specifying licenses for Google Compute images
This commit is contained in:
Matthew Hooker 2018-02-05 09:52:07 -08:00 committed by GitHub
commit 79ef50327b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 59 additions and 25 deletions

View File

@ -36,6 +36,7 @@ type Config struct {
ImageDescription string `mapstructure:"image_description"`
ImageFamily string `mapstructure:"image_family"`
ImageLabels map[string]string `mapstructure:"image_labels"`
ImageLicenses []string `mapstructure:"image_licenses"`
InstanceName string `mapstructure:"instance_name"`
Labels map[string]string `mapstructure:"labels"`
MachineType string `mapstructure:"machine_type"`

View File

@ -309,6 +309,9 @@ func testConfig(t *testing.T) map[string]interface{} {
"label-1": "value-1",
"label-2": "value-2",
},
"image_licenses": []string{
"test-license",
},
"zone": "us-east1-a",
}
}

View File

@ -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, image_labels map[string]string) (<-chan *Image, <-chan error)
CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string) (<-chan *Image, <-chan error)
// DeleteImage deletes the image with the given name.
DeleteImage(name string) <-chan error

View File

@ -97,12 +97,13 @@ func NewDriverGCE(ui packer.Ui, p string, a *AccountFile) (Driver, error) {
}, nil
}
func (d *driverGCE) CreateImage(name, description, family, zone, disk string, image_labels map[string]string) (<-chan *Image, <-chan error) {
func (d *driverGCE) CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string) (<-chan *Image, <-chan error) {
gce_image := &compute.Image{
Description: description,
Name: name,
Family: family,
Labels: image_labels,
Licenses: image_licenses,
SourceDisk: fmt.Sprintf("%s%s/zones/%s/disks/%s", d.service.BasePath, d.projectId, zone, disk),
SourceType: "RAW",
}

View File

@ -9,9 +9,9 @@ type DriverMock struct {
CreateImageDesc string
CreateImageFamily string
CreateImageLabels map[string]string
CreateImageLicenses []string
CreateImageZone string
CreateImageDisk string
CreateImageResultLicenses []string
CreateImageResultProjectId string
CreateImageResultSelfLink string
CreateImageResultSizeGb int64
@ -82,11 +82,12 @@ type DriverMock struct {
WaitForInstanceErrCh <-chan error
}
func (d *DriverMock) CreateImage(name, description, family, zone, disk string, image_labels map[string]string) (<-chan *Image, <-chan error) {
func (d *DriverMock) CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string) (<-chan *Image, <-chan error) {
d.CreateImageName = name
d.CreateImageDesc = description
d.CreateImageFamily = family
d.CreateImageLabels = image_labels
d.CreateImageLicenses = image_licenses
d.CreateImageZone = zone
d.CreateImageDisk = disk
if d.CreateImageResultProjectId == "" {
@ -106,7 +107,7 @@ func (d *DriverMock) CreateImage(name, description, family, zone, disk string, i
ch := make(chan *Image, 1)
ch <- &Image{
Labels: d.CreateImageLabels,
Licenses: d.CreateImageResultLicenses,
Licenses: d.CreateImageLicenses,
Name: name,
ProjectId: d.CreateImageResultProjectId,
SelfLink: d.CreateImageResultSelfLink,

View File

@ -40,7 +40,7 @@ func (s *StepCreateImage) Run(_ context.Context, state multistep.StateBag) multi
imageCh, errCh := driver.CreateImage(
config.ImageName, config.ImageDescription, config.ImageFamily, config.Zone,
config.DiskName, config.ImageLabels)
config.DiskName, config.ImageLabels, config.ImageLicenses)
var err error
select {
case err = <-errCh:

View File

@ -22,7 +22,6 @@ func TestStepCreateImage(t *testing.T) {
d := state.Get("driver").(*DriverMock)
// These are the values of the image the driver will return.
d.CreateImageResultLicenses = []string{"test-license"}
d.CreateImageResultProjectId = "test-project"
d.CreateImageResultSizeGb = 100
@ -36,7 +35,6 @@ func TestStepCreateImage(t *testing.T) {
assert.True(t, ok, "Image in state is not an Image.")
// Verify created Image results.
assert.Equal(t, image.Licenses, d.CreateImageResultLicenses, "Created image licenses don't match the licenses returned by the driver.")
assert.Equal(t, image.Name, c.ImageName, "Created image does not match config name.")
assert.Equal(t, image.ProjectId, d.CreateImageResultProjectId, "Created image project does not match driver project.")
assert.Equal(t, image.SizeGb, d.CreateImageResultSizeGb, "Created image size does not match the size returned by the driver.")
@ -48,6 +46,7 @@ func TestStepCreateImage(t *testing.T) {
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.")
assert.Equal(t, d.CreateImageLicenses, c.ImageLicenses, "Incorrect image_licenses passed to driver.")
}
func TestStepCreateImage_errorOnChannel(t *testing.T) {

View File

@ -93,7 +93,9 @@ Packer looks for credentials in the following places, preferring the first locat
4. On Google Compute Engine and Google App Engine Managed VMs, it fetches credentials from the metadata server. (Needs a correct VM authentication scope configuration, see above)
## Basic Example
## Examples
### Basic Example
Below is a fully functioning example. It doesn't do anything useful, since no
provisioners or startup-script metadata are defined, but it will effectively
@ -109,6 +111,7 @@ is assumed to be the path to the file containing the JSON.
"account_file": "account.json",
"project_id": "my project",
"source_image": "debian-7-wheezy-v20150127",
"ssh_username": "packer",
"zone": "us-central1-a"
}
]
@ -122,22 +125,46 @@ user used to connect in a startup-script.
``` {.json}
{
"builders": [{
"type": "googlecompute",
"account_file": "account.json",
"project_id": "my project",
"source_image": "windows-server-2016-dc-v20170227",
"disk_size": "50",
"machine_type": "n1-standard-1",
"communicator": "winrm",
"winrm_username": "packer_user",
"winrm_insecure": true,
"winrm_use_ssl": true,
"metadata": {
"windows-startup-script-cmd": "winrm quickconfig -quiet & net user /add packer_user & net localgroup administrators packer_user /add & winrm set winrm/config/service/auth @{Basic=\"true\"}"
},
"zone": "us-central1-a"
}]
"builders": [
{
"type": "googlecompute",
"account_file": "account.json",
"project_id": "my project",
"source_image": "windows-server-2016-dc-v20170227",
"disk_size": "50",
"machine_type": "n1-standard-1",
"communicator": "winrm",
"winrm_username": "packer_user",
"winrm_insecure": true,
"winrm_use_ssl": true,
"metadata": {
"windows-startup-script-cmd": "winrm quickconfig -quiet & net user /add packer_user & net localgroup administrators packer_user /add & winrm set winrm/config/service/auth @{Basic=\"true\"}"
},
"zone": "us-central1-a"
}
]
}
```
### Nested Hypervisor Example
This is an example of using the `image_licenses` configuration option to create a GCE image that has nested virtualization enabled. See
[Enabling Nested Virtualization for VM Instances](https://cloud.google.com/compute/docs/instances/enable-nested-virtualization-vm-instances)
for details.
``` json
{
"builders": [
{
"type": "googlecompute",
"account_file": "account.json",
"project_id": "my project",
"source_image_family": "centos-7",
"ssh_username": "packer",
"zone": "us-central1-a",
"image_licenses": ["projects/vm-options/global/licenses/enable-vmx"]
}
]
}
```
@ -201,6 +228,8 @@ builder.
- `image_labels` (object of key/value strings) - Key/value pair labels to
apply to the created image.
- `image_licenses` (array of strings) - Licenses to apply to the created image.
- `image_name` (string) - The unique name of the resulting image. Defaults to
`"packer-{{timestamp}}"`.