diff --git a/CHANGELOG.md b/CHANGELOG.md index 172589cd4..90529ef1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,53 @@ +## (Unreleased) + +IMPROVEMENTS: + + * builder/docker: Now supports Download so it can be used with the file + provisioner to download a file from a container. [GH-2585] + * post-processor/vagrant: Like the compress post-processor, vagrant now uses a + parallel gzip algorithm to compress vagrant boxes. [GH-2590] + +BUG FIXES: + + * builded/parallels: Fix interpolation in parallels_tools_guest_path [GH-2543] + +## 0.8.5 (Aug 10, 2015) + +FEATURES: + + * **[Beta]** Artifice post-processor: Override packer artifacts during post- + processing. This allows you to extract artifacts from a packer builder + and use them with other post-processors like compress, docker, and Atlas. + +IMPROVEMENTS: + + * Many docs have been updated and corrected; big thanks to our contributors! + * builder/openstack: Add debug logging for IP addresses used for SSH [GH-2513] + * builder/openstack: Add option to use existing SSH keypair [GH-2512] + * builder/openstack: Add support for Glance metadata [GH-2434] + * builder/qemu and builder/vmware: Packer's VNC connection no longer asks for + an exclusive connection [GH-2522] + * provisioner/salt-masterless: Can now customize salt remote directories [GH-2519] + +BUG FIXES: + + * builder/amazon: Improve instance cleanup by storing id sooner [GH-2404] + * builder/amazon: Only fetch windows password when using WinRM communicator [GH-2538] + * builder/openstack: Support IPv6 SSH address [GH-2450] + * builder/openstack: Track new IP address discovered during RackConnect [GH-2514] + * builder/qemu: Add 100ms delay between VNC key events. [GH-2415] + * post-processor/atlas: atlas_url configuration option works now [GH-2478] + * post-processor/compress: Now supports interpolation in output config [GH-2414] + * provisioner/powershell: Elevated runs now receive environment variables [GH-2378] + * provisioner/salt-masterless: Clarify error messages when we can't create or + write to the temp directory [GH-2518] + * provisioner/salt-masterless: Copy state even if /srv/salt exists already [GH-1699] + * provisioner/salt-masterless: Make sure /etc/salt exists before writing to it [GH-2520] + * provisioner/winrm: Connect to the correct port when using NAT with + VirtualBox / VMware [GH-2399] + +Note: 0.8.3 was pulled and 0.8.4 was skipped. + ## 0.8.2 (July 17, 2015) IMPROVEMENTS: diff --git a/builder/amazon/chroot/step_attach_volume.go b/builder/amazon/chroot/step_attach_volume.go index c450d3b02..486948c27 100644 --- a/builder/amazon/chroot/step_attach_volume.go +++ b/builder/amazon/chroot/step_attach_volume.go @@ -35,8 +35,8 @@ func (s *StepAttachVolume) Run(state multistep.StateBag) multistep.StepAction { ui.Say(fmt.Sprintf("Attaching the root volume to %s", attachVolume)) _, err := ec2conn.AttachVolume(&ec2.AttachVolumeInput{ - InstanceID: instance.InstanceID, - VolumeID: &volumeId, + InstanceId: instance.InstanceId, + VolumeId: &volumeId, Device: &attachVolume, }) if err != nil { @@ -58,7 +58,7 @@ func (s *StepAttachVolume) Run(state multistep.StateBag) multistep.StepAction { Refresh: func() (interface{}, string, error) { attempts := 0 for attempts < 30 { - resp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIDs: []*string{&volumeId}}) + resp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIds: []*string{&volumeId}}) if err != nil { return nil, "", err } @@ -107,7 +107,7 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error { ui := state.Get("ui").(packer.Ui) ui.Say("Detaching EBS volume...") - _, err := ec2conn.DetachVolume(&ec2.DetachVolumeInput{VolumeID: &s.volumeId}) + _, err := ec2conn.DetachVolume(&ec2.DetachVolumeInput{VolumeId: &s.volumeId}) if err != nil { return fmt.Errorf("Error detaching EBS volume: %s", err) } @@ -120,7 +120,7 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error { StepState: state, Target: "detached", Refresh: func() (interface{}, string, error) { - resp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIDs: []*string{&s.volumeId}}) + resp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIds: []*string{&s.volumeId}}) if err != nil { return nil, "", err } diff --git a/builder/amazon/chroot/step_create_volume.go b/builder/amazon/chroot/step_create_volume.go index 9db99163a..a79e22c47 100644 --- a/builder/amazon/chroot/step_create_volume.go +++ b/builder/amazon/chroot/step_create_volume.go @@ -45,16 +45,16 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction { } ui.Say("Creating the root volume...") - vs := *rootDevice.EBS.VolumeSize - if s.RootVolumeSize > *rootDevice.EBS.VolumeSize { + vs := *rootDevice.Ebs.VolumeSize + if s.RootVolumeSize > *rootDevice.Ebs.VolumeSize { vs = s.RootVolumeSize } createVolume := &ec2.CreateVolumeInput{ AvailabilityZone: instance.Placement.AvailabilityZone, Size: aws.Int64(vs), - SnapshotID: rootDevice.EBS.SnapshotID, - VolumeType: rootDevice.EBS.VolumeType, - IOPS: rootDevice.EBS.IOPS, + SnapshotId: rootDevice.Ebs.SnapshotId, + VolumeType: rootDevice.Ebs.VolumeType, + Iops: rootDevice.Ebs.Iops, } log.Printf("Create args: %s", createVolume) @@ -67,7 +67,7 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction { } // Set the volume ID so we remember to delete it later - s.volumeId = *createVolumeResp.VolumeID + s.volumeId = *createVolumeResp.VolumeId log.Printf("Volume ID: %s", s.volumeId) // Wait for the volume to become ready @@ -76,7 +76,7 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction { StepState: state, Target: "available", Refresh: func() (interface{}, string, error) { - resp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIDs: []*string{&s.volumeId}}) + resp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIds: []*string{&s.volumeId}}) if err != nil { return nil, "", err } @@ -107,7 +107,7 @@ func (s *StepCreateVolume) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) ui.Say("Deleting the created EBS volume...") - _, err := ec2conn.DeleteVolume(&ec2.DeleteVolumeInput{VolumeID: &s.volumeId}) + _, err := ec2conn.DeleteVolume(&ec2.DeleteVolumeInput{VolumeId: &s.volumeId}) if err != nil { ui.Error(fmt.Sprintf("Error deleting EBS volume: %s", err)) } diff --git a/builder/amazon/chroot/step_instance_info.go b/builder/amazon/chroot/step_instance_info.go index b77c9e8a1..ceba307cc 100644 --- a/builder/amazon/chroot/step_instance_info.go +++ b/builder/amazon/chroot/step_instance_info.go @@ -34,7 +34,7 @@ func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction { log.Printf("Instance ID: %s", instanceId) // Query the entire instance metadata - instancesResp, err := ec2conn.DescribeInstances(&ec2.DescribeInstancesInput{InstanceIDs: []*string{&instanceId}}) + instancesResp, err := ec2conn.DescribeInstances(&ec2.DescribeInstancesInput{InstanceIds: []*string{&instanceId}}) if err != nil { err := fmt.Errorf("Error getting instance data: %s", err) state.Put("error", err) diff --git a/builder/amazon/chroot/step_register_ami.go b/builder/amazon/chroot/step_register_ami.go index 8ed4df9b9..f2a59ae01 100644 --- a/builder/amazon/chroot/step_register_ami.go +++ b/builder/amazon/chroot/step_register_ami.go @@ -27,21 +27,21 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { for i, device := range image.BlockDeviceMappings { newDevice := device if *newDevice.DeviceName == *image.RootDeviceName { - if newDevice.EBS != nil { - newDevice.EBS.SnapshotID = aws.String(snapshotId) + if newDevice.Ebs != nil { + newDevice.Ebs.SnapshotId = aws.String(snapshotId) } else { - newDevice.EBS = &ec2.EBSBlockDevice{SnapshotID: aws.String(snapshotId)} + newDevice.Ebs = &ec2.EbsBlockDevice{SnapshotId: aws.String(snapshotId)} } - if s.RootVolumeSize > *newDevice.EBS.VolumeSize { - newDevice.EBS.VolumeSize = aws.Int64(s.RootVolumeSize) + if s.RootVolumeSize > *newDevice.Ebs.VolumeSize { + newDevice.Ebs.VolumeSize = aws.Int64(s.RootVolumeSize) } } // assume working from a snapshot, so we unset the Encrypted field if set, // otherwise AWS API will return InvalidParameter - if newDevice.EBS != nil && newDevice.EBS.Encrypted != nil { - newDevice.EBS.Encrypted = nil + if newDevice.Ebs != nil && newDevice.Ebs.Encrypted != nil { + newDevice.Ebs.Encrypted = nil } blockDevices[i] = newDevice @@ -51,7 +51,7 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { // Set SriovNetSupport to "simple". See http://goo.gl/icuXh5 if config.AMIEnhancedNetworking { - registerOpts.SRIOVNetSupport = aws.String("simple") + registerOpts.SriovNetSupport = aws.String("simple") } registerResp, err := ec2conn.RegisterImage(registerOpts) @@ -62,16 +62,16 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { } // Set the AMI ID in the state - ui.Say(fmt.Sprintf("AMI: %s", *registerResp.ImageID)) + ui.Say(fmt.Sprintf("AMI: %s", *registerResp.ImageId)) amis := make(map[string]string) - amis[*ec2conn.Config.Region] = *registerResp.ImageID + amis[*ec2conn.Config.Region] = *registerResp.ImageId state.Put("amis", amis) // Wait for the image to become ready stateChange := awscommon.StateChangeConf{ Pending: []string{"pending"}, Target: "available", - Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *registerResp.ImageID), + Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *registerResp.ImageId), StepState: state, } @@ -102,8 +102,8 @@ func buildRegisterOpts(config *Config, image *ec2.Image, blockDevices []*ec2.Blo } if config.AMIVirtType != "hvm" { - registerOpts.KernelID = image.KernelID - registerOpts.RAMDiskID = image.RAMDiskID + registerOpts.KernelId = image.KernelId + registerOpts.RamdiskId = image.RamdiskId } return registerOpts diff --git a/builder/amazon/chroot/step_register_ami_test.go b/builder/amazon/chroot/step_register_ami_test.go index ac473b302..0cc3bc912 100644 --- a/builder/amazon/chroot/step_register_ami_test.go +++ b/builder/amazon/chroot/step_register_ami_test.go @@ -9,10 +9,10 @@ import ( func testImage() ec2.Image { return ec2.Image{ - ImageID: aws.String("ami-abcd1234"), + ImageId: aws.String("ami-abcd1234"), Name: aws.String("ami_test_name"), Architecture: aws.String("x86_64"), - KernelID: aws.String("aki-abcd1234"), + KernelId: aws.String("aki-abcd1234"), } } @@ -38,9 +38,9 @@ func TestStepRegisterAmi_buildRegisterOpts_pv(t *testing.T) { t.Fatalf("Unexpected Name value: expected %s got %s\n", expected, *opts.Name) } - expected = *image.KernelID - if *opts.KernelID != expected { - t.Fatalf("Unexpected KernelId value: expected %s got %s\n", expected, *opts.KernelID) + expected = *image.KernelId + if *opts.KernelId != expected { + t.Fatalf("Unexpected KernelId value: expected %s got %s\n", expected, *opts.KernelId) } } @@ -67,7 +67,7 @@ func TestStepRegisterAmi_buildRegisterOpts_hvm(t *testing.T) { t.Fatalf("Unexpected Name value: expected %s got %s\n", expected, *opts.Name) } - if opts.KernelID != nil { - t.Fatalf("Unexpected KernelId value: expected nil got %s\n", *opts.KernelID) + if opts.KernelId != nil { + t.Fatalf("Unexpected KernelId value: expected nil got %s\n", *opts.KernelId) } } diff --git a/builder/amazon/chroot/step_snapshot.go b/builder/amazon/chroot/step_snapshot.go index b98e10861..f003ee66a 100644 --- a/builder/amazon/chroot/step_snapshot.go +++ b/builder/amazon/chroot/step_snapshot.go @@ -28,7 +28,7 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction { description := fmt.Sprintf("Packer: %s", time.Now().String()) createSnapResp, err := ec2conn.CreateSnapshot(&ec2.CreateSnapshotInput{ - VolumeID: &volumeId, + VolumeId: &volumeId, Description: &description, }) if err != nil { @@ -39,7 +39,7 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction { } // Set the snapshot ID so we can delete it later - s.snapshotId = *createSnapResp.SnapshotID + s.snapshotId = *createSnapResp.SnapshotId ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId)) // Wait for the snapshot to be ready @@ -48,7 +48,7 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction { StepState: state, Target: "completed", Refresh: func() (interface{}, string, error) { - resp, err := ec2conn.DescribeSnapshots(&ec2.DescribeSnapshotsInput{SnapshotIDs: []*string{&s.snapshotId}}) + resp, err := ec2conn.DescribeSnapshots(&ec2.DescribeSnapshotsInput{SnapshotIds: []*string{&s.snapshotId}}) if err != nil { return nil, "", err } @@ -86,7 +86,7 @@ func (s *StepSnapshot) Cleanup(state multistep.StateBag) { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) ui.Say("Removing snapshot since we cancelled or halted...") - _, err := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{SnapshotID: &s.snapshotId}) + _, err := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{SnapshotId: &s.snapshotId}) if err != nil { ui.Error(fmt.Sprintf("Error: %s", err)) } diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 88bda0423..dccde08d4 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" "github.com/mitchellh/packer/template/interpolate" ) @@ -31,7 +32,7 @@ func (c *AccessConfig) Config() (*aws.Config, error) { }}, &credentials.EnvProvider{}, &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, - &credentials.EC2RoleProvider{}, + &ec2rolecreds.EC2RoleProvider{}, }) region, err := c.Region() diff --git a/builder/amazon/common/artifact.go b/builder/amazon/common/artifact.go index 4082b2abc..8eed0134d 100644 --- a/builder/amazon/common/artifact.go +++ b/builder/amazon/common/artifact.go @@ -75,7 +75,7 @@ func (a *Artifact) Destroy() error { regionConn := ec2.New(regionConfig) input := &ec2.DeregisterImageInput{ - ImageID: &imageId, + ImageId: &imageId, } if _, err := regionConn.DeregisterImage(input); err != nil { errors = append(errors, err) diff --git a/builder/amazon/common/block_device.go b/builder/amazon/common/block_device.go index f009cd7bc..094738869 100644 --- a/builder/amazon/common/block_device.go +++ b/builder/amazon/common/block_device.go @@ -30,7 +30,7 @@ func buildBlockDevices(b []BlockDevice) []*ec2.BlockDeviceMapping { var blockDevices []*ec2.BlockDeviceMapping for _, blockDevice := range b { - ebsBlockDevice := &ec2.EBSBlockDevice{ + ebsBlockDevice := &ec2.EbsBlockDevice{ VolumeType: aws.String(blockDevice.VolumeType), VolumeSize: aws.Int64(blockDevice.VolumeSize), DeleteOnTermination: aws.Bool(blockDevice.DeleteOnTermination), @@ -38,12 +38,12 @@ func buildBlockDevices(b []BlockDevice) []*ec2.BlockDeviceMapping { // IOPS is only valid for SSD Volumes if blockDevice.VolumeType != "" && blockDevice.VolumeType != "standard" && blockDevice.VolumeType != "gp2" { - ebsBlockDevice.IOPS = aws.Int64(blockDevice.IOPS) + ebsBlockDevice.Iops = aws.Int64(blockDevice.IOPS) } // You cannot specify Encrypted if you specify a Snapshot ID if blockDevice.SnapshotId != "" { - ebsBlockDevice.SnapshotID = aws.String(blockDevice.SnapshotId) + ebsBlockDevice.SnapshotId = aws.String(blockDevice.SnapshotId) } else if blockDevice.Encrypted { ebsBlockDevice.Encrypted = aws.Bool(blockDevice.Encrypted) } @@ -54,7 +54,7 @@ func buildBlockDevices(b []BlockDevice) []*ec2.BlockDeviceMapping { } if !strings.HasPrefix(blockDevice.VirtualName, "ephemeral") { - mapping.EBS = ebsBlockDevice + mapping.Ebs = ebsBlockDevice } if blockDevice.NoDevice { diff --git a/builder/amazon/common/block_device_test.go b/builder/amazon/common/block_device_test.go index d76cf4d07..99514009b 100644 --- a/builder/amazon/common/block_device_test.go +++ b/builder/amazon/common/block_device_test.go @@ -25,8 +25,8 @@ func TestBlockDevice(t *testing.T) { Result: &ec2.BlockDeviceMapping{ DeviceName: aws.String("/dev/sdb"), VirtualName: aws.String(""), - EBS: &ec2.EBSBlockDevice{ - SnapshotID: aws.String("snap-1234"), + Ebs: &ec2.EbsBlockDevice{ + SnapshotId: aws.String("snap-1234"), VolumeType: aws.String("standard"), VolumeSize: aws.Int64(8), DeleteOnTermination: aws.Bool(true), @@ -42,7 +42,7 @@ func TestBlockDevice(t *testing.T) { Result: &ec2.BlockDeviceMapping{ DeviceName: aws.String("/dev/sdb"), VirtualName: aws.String(""), - EBS: &ec2.EBSBlockDevice{ + Ebs: &ec2.EbsBlockDevice{ VolumeType: aws.String(""), VolumeSize: aws.Int64(8), DeleteOnTermination: aws.Bool(false), @@ -61,11 +61,11 @@ func TestBlockDevice(t *testing.T) { Result: &ec2.BlockDeviceMapping{ DeviceName: aws.String("/dev/sdb"), VirtualName: aws.String(""), - EBS: &ec2.EBSBlockDevice{ + Ebs: &ec2.EbsBlockDevice{ VolumeType: aws.String("io1"), VolumeSize: aws.Int64(8), DeleteOnTermination: aws.Bool(true), - IOPS: aws.Int64(1000), + Iops: aws.Int64(1000), }, }, }, diff --git a/builder/amazon/common/ssh.go b/builder/amazon/common/ssh.go index cf644eb25..d689d5990 100644 --- a/builder/amazon/common/ssh.go +++ b/builder/amazon/common/ssh.go @@ -17,14 +17,14 @@ func SSHHost(e *ec2.EC2, private bool) func(multistep.StateBag) (string, error) for j := 0; j < 2; j++ { var host string i := state.Get("instance").(*ec2.Instance) - if i.VPCID != nil && *i.VPCID != "" { - if i.PublicIPAddress != nil && *i.PublicIPAddress != "" && !private { - host = *i.PublicIPAddress + if i.VpcId != nil && *i.VpcId != "" { + if i.PublicIpAddress != nil && *i.PublicIpAddress != "" && !private { + host = *i.PublicIpAddress } else { - host = *i.PrivateIPAddress + host = *i.PrivateIpAddress } - } else if i.PublicDNSName != nil && *i.PublicDNSName != "" { - host = *i.PublicDNSName + } else if i.PublicDnsName != nil && *i.PublicDnsName != "" { + host = *i.PublicDnsName } if host != "" { @@ -32,14 +32,14 @@ func SSHHost(e *ec2.EC2, private bool) func(multistep.StateBag) (string, error) } r, err := e.DescribeInstances(&ec2.DescribeInstancesInput{ - InstanceIDs: []*string{i.InstanceID}, + InstanceIds: []*string{i.InstanceId}, }) if err != nil { return "", err } if len(r.Reservations) == 0 || len(r.Reservations[0].Instances) == 0 { - return "", fmt.Errorf("instance not found: %s", *i.InstanceID) + return "", fmt.Errorf("instance not found: %s", *i.InstanceId) } state.Put("instance", &r.Reservations[0].Instances[0]) diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 3b40a48d1..6c9de3eb2 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -39,7 +39,7 @@ type StateChangeConf struct { func AMIStateRefreshFunc(conn *ec2.EC2, imageId string) StateRefreshFunc { return func() (interface{}, string, error) { resp, err := conn.DescribeImages(&ec2.DescribeImagesInput{ - ImageIDs: []*string{&imageId}, + ImageIds: []*string{&imageId}, }) if err != nil { if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidAMIID.NotFound" { @@ -70,7 +70,7 @@ func AMIStateRefreshFunc(conn *ec2.EC2, imageId string) StateRefreshFunc { func InstanceStateRefreshFunc(conn *ec2.EC2, instanceId string) StateRefreshFunc { return func() (interface{}, string, error) { resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ - InstanceIDs: []*string{&instanceId}, + InstanceIds: []*string{&instanceId}, }) if err != nil { if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" { @@ -101,7 +101,7 @@ func InstanceStateRefreshFunc(conn *ec2.EC2, instanceId string) StateRefreshFunc func SpotRequestStateRefreshFunc(conn *ec2.EC2, spotRequestId string) StateRefreshFunc { return func() (interface{}, string, error) { resp, err := conn.DescribeSpotInstanceRequests(&ec2.DescribeSpotInstanceRequestsInput{ - SpotInstanceRequestIDs: []*string{&spotRequestId}, + SpotInstanceRequestIds: []*string{&spotRequestId}, }) if err != nil { diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index d19ffe5bd..0cf4d40fa 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -90,7 +90,7 @@ func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string, regionconn := ec2.New(awsConfig) resp, err := regionconn.CopyImage(&ec2.CopyImageInput{ SourceRegion: &source, - SourceImageID: &imageId, + SourceImageId: &imageId, Name: &name, }) @@ -102,14 +102,14 @@ func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string, stateChange := StateChangeConf{ Pending: []string{"pending"}, Target: "available", - Refresh: AMIStateRefreshFunc(regionconn, *resp.ImageID), + Refresh: AMIStateRefreshFunc(regionconn, *resp.ImageId), StepState: state, } if _, err := WaitForState(&stateChange); err != nil { return "", fmt.Errorf("Error waiting for AMI (%s) in region (%s): %s", - *resp.ImageID, target, err) + *resp.ImageId, target, err) } - return *resp.ImageID, nil + return *resp.ImageId, nil } diff --git a/builder/amazon/common/step_create_tags.go b/builder/amazon/common/step_create_tags.go index 220735bed..7f62d2657 100644 --- a/builder/amazon/common/step_create_tags.go +++ b/builder/amazon/common/step_create_tags.go @@ -41,7 +41,7 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction { // Retrieve image list for given AMI imageResp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{ - ImageIDs: resourceIds, + ImageIds: resourceIds, }) if err != nil { @@ -62,9 +62,9 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction { // Add only those with a Snapshot ID, i.e. not Ephemeral for _, device := range image.BlockDeviceMappings { - if device.EBS != nil && device.EBS.SnapshotID != nil { - ui.Say(fmt.Sprintf("Tagging snapshot: %s", *device.EBS.SnapshotID)) - resourceIds = append(resourceIds, device.EBS.SnapshotID) + if device.Ebs != nil && device.Ebs.SnapshotId != nil { + ui.Say(fmt.Sprintf("Tagging snapshot: %s", *device.Ebs.SnapshotId)) + resourceIds = append(resourceIds, device.Ebs.SnapshotId) } } diff --git a/builder/amazon/common/step_deregister_ami.go b/builder/amazon/common/step_deregister_ami.go index ce20a5d90..1ea4325cd 100644 --- a/builder/amazon/common/step_deregister_ami.go +++ b/builder/amazon/common/step_deregister_ami.go @@ -36,7 +36,7 @@ func (s *StepDeregisterAMI) Run(state multistep.StateBag) multistep.StepAction { // deregister image(s) by that name for _, i := range resp.Images { _, err := ec2conn.DeregisterImage(&ec2.DeregisterImageInput{ - ImageID: i.ImageID, + ImageId: i.ImageId, }) if err != nil { @@ -45,7 +45,7 @@ func (s *StepDeregisterAMI) Run(state multistep.StateBag) multistep.StepAction { ui.Error(err.Error()) return multistep.ActionHalt } - ui.Say(fmt.Sprintf("Deregistered AMI %s, id: %s", s.AMIName, *i.ImageID)) + ui.Say(fmt.Sprintf("Deregistered AMI %s, id: %s", s.AMIName, *i.ImageId)) } } diff --git a/builder/amazon/common/step_get_password.go b/builder/amazon/common/step_get_password.go index fec33891f..618e3bbb8 100644 --- a/builder/amazon/common/step_get_password.go +++ b/builder/amazon/common/step_get_password.go @@ -111,7 +111,7 @@ func (s *StepGetPassword) waitForPassword(state multistep.StateBag, cancel <-cha } resp, err := ec2conn.GetPasswordData(&ec2.GetPasswordDataInput{ - InstanceID: instance.InstanceID, + InstanceId: instance.InstanceId, }) if err != nil { err := fmt.Errorf("Error retrieving auto-generated instance password: %s", err) diff --git a/builder/amazon/common/step_modify_ami_attributes.go b/builder/amazon/common/step_modify_ami_attributes.go index df6424245..e8e7de589 100644 --- a/builder/amazon/common/step_modify_ami_attributes.go +++ b/builder/amazon/common/step_modify_ami_attributes.go @@ -66,10 +66,10 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc adds := make([]*ec2.LaunchPermission, len(s.Users)) for i, u := range s.Users { users[i] = aws.String(u) - adds[i] = &ec2.LaunchPermission{UserID: aws.String(u)} + adds[i] = &ec2.LaunchPermission{UserId: aws.String(u)} } options["users"] = &ec2.ModifyImageAttributeInput{ - UserIDs: users, + UserIds: users, LaunchPermission: &ec2.LaunchPermissionModifications{ Add: adds, }, @@ -94,7 +94,7 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc }) for name, input := range options { ui.Message(fmt.Sprintf("Modifying: %s", name)) - input.ImageID = &ami + input.ImageId = &ami _, err := regionconn.ModifyImageAttribute(input) if err != nil { err := fmt.Errorf("Error modify AMI attributes: %s", err) diff --git a/builder/amazon/common/step_pre_validate.go b/builder/amazon/common/step_pre_validate.go index bbeacea43..86bb8e23d 100644 --- a/builder/amazon/common/step_pre_validate.go +++ b/builder/amazon/common/step_pre_validate.go @@ -41,7 +41,7 @@ func (s *StepPreValidate) Run(state multistep.StateBag) multistep.StepAction { } if len(resp.Images) > 0 { - err := fmt.Errorf("Error: name conflicts with an existing AMI: %s", *resp.Images[0].ImageID) + err := fmt.Errorf("Error: name conflicts with an existing AMI: %s", *resp.Images[0].ImageId) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index fcacc4ca8..be4120c19 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -66,7 +66,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi ui.Say("Launching a source AWS instance...") imageResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ - ImageIDs: []*string{&s.SourceAMI}, + ImageIds: []*string{&s.SourceAMI}, }) if err != nil { state.Put("error", fmt.Errorf("There was a problem with the source AMI: %s", err)) @@ -138,12 +138,12 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi if spotPrice == "" { runOpts := &ec2.RunInstancesInput{ KeyName: &keyName, - ImageID: &s.SourceAMI, + ImageId: &s.SourceAMI, InstanceType: &s.InstanceType, UserData: &userData, MaxCount: aws.Int64(1), MinCount: aws.Int64(1), - IAMInstanceProfile: &ec2.IAMInstanceProfileSpecification{Name: &s.IamInstanceProfile}, + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{Name: &s.IamInstanceProfile}, BlockDeviceMappings: s.BlockDevices.BuildLaunchDevices(), Placement: &ec2.Placement{AvailabilityZone: &s.AvailabilityZone}, } @@ -152,15 +152,15 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi runOpts.NetworkInterfaces = []*ec2.InstanceNetworkInterfaceSpecification{ &ec2.InstanceNetworkInterfaceSpecification{ DeviceIndex: aws.Int64(0), - AssociatePublicIPAddress: &s.AssociatePublicIpAddress, - SubnetID: &s.SubnetId, + AssociatePublicIpAddress: &s.AssociatePublicIpAddress, + SubnetId: &s.SubnetId, Groups: securityGroupIds, DeleteOnTermination: aws.Bool(true), }, } } else { - runOpts.SubnetID = &s.SubnetId - runOpts.SecurityGroupIDs = securityGroupIds + runOpts.SubnetId = &s.SubnetId + runOpts.SecurityGroupIds = securityGroupIds } runResp, err := ec2conn.RunInstances(runOpts) @@ -170,7 +170,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi ui.Error(err.Error()) return multistep.ActionHalt } - instanceId = *runResp.Instances[0].InstanceID + instanceId = *runResp.Instances[0].InstanceId } else { ui.Message(fmt.Sprintf( "Requesting spot instance '%s' for: %s", @@ -179,15 +179,15 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi SpotPrice: &spotPrice, LaunchSpecification: &ec2.RequestSpotLaunchSpecification{ KeyName: &keyName, - ImageID: &s.SourceAMI, + ImageId: &s.SourceAMI, InstanceType: &s.InstanceType, UserData: &userData, - IAMInstanceProfile: &ec2.IAMInstanceProfileSpecification{Name: &s.IamInstanceProfile}, + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{Name: &s.IamInstanceProfile}, NetworkInterfaces: []*ec2.InstanceNetworkInterfaceSpecification{ &ec2.InstanceNetworkInterfaceSpecification{ DeviceIndex: aws.Int64(0), - AssociatePublicIPAddress: &s.AssociatePublicIpAddress, - SubnetID: &s.SubnetId, + AssociatePublicIpAddress: &s.AssociatePublicIpAddress, + SubnetId: &s.SubnetId, Groups: securityGroupIds, DeleteOnTermination: aws.Bool(true), }, @@ -207,7 +207,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi s.spotRequest = runSpotResp.SpotInstanceRequests[0] - spotRequestId := s.spotRequest.SpotInstanceRequestID + spotRequestId := s.spotRequest.SpotInstanceRequestId ui.Message(fmt.Sprintf("Waiting for spot request (%s) to become active...", *spotRequestId)) stateChange := StateChangeConf{ Pending: []string{"open"}, @@ -224,7 +224,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi } spotResp, err := ec2conn.DescribeSpotInstanceRequests(&ec2.DescribeSpotInstanceRequestsInput{ - SpotInstanceRequestIDs: []*string{spotRequestId}, + SpotInstanceRequestIds: []*string{spotRequestId}, }) if err != nil { err := fmt.Errorf("Error finding spot request (%s): %s", *spotRequestId, err) @@ -232,7 +232,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi ui.Error(err.Error()) return multistep.ActionHalt } - instanceId = *spotResp.SpotInstanceRequests[0].InstanceID + instanceId = *spotResp.SpotInstanceRequests[0].InstanceId } // Set the instance ID so that the cleanup works properly @@ -264,7 +264,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi _, err = ec2conn.CreateTags(&ec2.CreateTagsInput{ Tags: ec2Tags, - Resources: []*string{instance.InstanceID}, + Resources: []*string{instance.InstanceId}, }) if err != nil { ui.Message( @@ -272,16 +272,16 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi } if s.Debug { - if instance.PublicDNSName != nil && *instance.PublicDNSName != "" { - ui.Message(fmt.Sprintf("Public DNS: %s", *instance.PublicDNSName)) + if instance.PublicDnsName != nil && *instance.PublicDnsName != "" { + ui.Message(fmt.Sprintf("Public DNS: %s", *instance.PublicDnsName)) } - if instance.PublicIPAddress != nil && *instance.PublicIPAddress != "" { - ui.Message(fmt.Sprintf("Public IP: %s", *instance.PublicIPAddress)) + if instance.PublicIpAddress != nil && *instance.PublicIpAddress != "" { + ui.Message(fmt.Sprintf("Public IP: %s", *instance.PublicIpAddress)) } - if instance.PrivateIPAddress != nil && *instance.PrivateIPAddress != "" { - ui.Message(fmt.Sprintf("Private IP: %s", *instance.PrivateIPAddress)) + if instance.PrivateIpAddress != nil && *instance.PrivateIpAddress != "" { + ui.Message(fmt.Sprintf("Private IP: %s", *instance.PrivateIpAddress)) } } @@ -299,7 +299,7 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) { if s.spotRequest != nil { ui.Say("Cancelling the spot request...") input := &ec2.CancelSpotInstanceRequestsInput{ - SpotInstanceRequestIDs: []*string{s.spotRequest.SpotInstanceRequestID}, + SpotInstanceRequestIds: []*string{s.spotRequest.SpotInstanceRequestId}, } if _, err := ec2conn.CancelSpotInstanceRequests(input); err != nil { ui.Error(fmt.Sprintf("Error cancelling the spot request, may still be around: %s", err)) @@ -307,7 +307,7 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) { } stateChange := StateChangeConf{ Pending: []string{"active", "open"}, - Refresh: SpotRequestStateRefreshFunc(ec2conn, *s.spotRequest.SpotInstanceRequestID), + Refresh: SpotRequestStateRefreshFunc(ec2conn, *s.spotRequest.SpotInstanceRequestId), Target: "cancelled", } @@ -318,7 +318,7 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) { // Terminate the source instance if it exists if s.instanceId != "" { ui.Say("Terminating the source AWS instance...") - if _, err := ec2conn.TerminateInstances(&ec2.TerminateInstancesInput{InstanceIDs: []*string{&s.instanceId}}); err != nil { + if _, err := ec2conn.TerminateInstances(&ec2.TerminateInstancesInput{InstanceIds: []*string{&s.instanceId}}); err != nil { ui.Error(fmt.Sprintf("Error terminating instance, may still be around: %s", err)) return } diff --git a/builder/amazon/common/step_security_group.go b/builder/amazon/common/step_security_group.go index e43e866a3..43b9fd4c7 100644 --- a/builder/amazon/common/step_security_group.go +++ b/builder/amazon/common/step_security_group.go @@ -43,7 +43,7 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction { group := &ec2.CreateSecurityGroupInput{ GroupName: &groupName, Description: aws.String("Temporary group for Packer"), - VPCID: &s.VpcId, + VpcId: &s.VpcId, } groupResp, err := ec2conn.CreateSecurityGroup(group) if err != nil { @@ -53,15 +53,15 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction { } // Set the group ID so we can delete it later - s.createdGroupId = *groupResp.GroupID + s.createdGroupId = *groupResp.GroupId // Authorize the SSH access for the security group req := &ec2.AuthorizeSecurityGroupIngressInput{ - GroupID: groupResp.GroupID, - IPProtocol: aws.String("tcp"), + GroupId: groupResp.GroupId, + IpProtocol: aws.String("tcp"), FromPort: aws.Int64(int64(port)), ToPort: aws.Int64(int64(port)), - CIDRIP: aws.String("0.0.0.0/0"), + CidrIp: aws.String("0.0.0.0/0"), } // We loop and retry this a few times because sometimes the security @@ -105,7 +105,7 @@ func (s *StepSecurityGroup) Cleanup(state multistep.StateBag) { var err error for i := 0; i < 5; i++ { - _, err = ec2conn.DeleteSecurityGroup(&ec2.DeleteSecurityGroupInput{GroupID: &s.createdGroupId}) + _, err = ec2conn.DeleteSecurityGroup(&ec2.DeleteSecurityGroupInput{GroupId: &s.createdGroupId}) if err == nil { break } diff --git a/builder/amazon/common/step_source_ami_info.go b/builder/amazon/common/step_source_ami_info.go index 5ab36e5da..21fd0db8e 100644 --- a/builder/amazon/common/step_source_ami_info.go +++ b/builder/amazon/common/step_source_ami_info.go @@ -23,7 +23,7 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Inspecting the source AMI...") - imageResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIDs: []*string{&s.SourceAmi}}) + imageResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{&s.SourceAmi}}) if err != nil { err := fmt.Errorf("Error querying AMI: %s", err) state.Put("error", err) diff --git a/builder/amazon/ebs/builder_acc_test.go b/builder/amazon/ebs/builder_acc_test.go index 879f7a732..890b3228a 100644 --- a/builder/amazon/ebs/builder_acc_test.go +++ b/builder/amazon/ebs/builder_acc_test.go @@ -71,7 +71,7 @@ func checkAMISharing(count int, uid, group string) builderT.TestCheckFunc { ec2conn, _ := testEC2Conn() imageResp, err := ec2conn.DescribeImageAttribute(&ec2.DescribeImageAttributeInput{ Attribute: aws.String("launchPermission"), - ImageID: aws.String(artifact.Amis["us-east-1"]), + ImageId: aws.String(artifact.Amis["us-east-1"]), }) if err != nil { @@ -86,7 +86,7 @@ func checkAMISharing(count int, uid, group string) builderT.TestCheckFunc { userFound := false for _, lp := range imageResp.LaunchPermissions { - if lp.UserID != nil && uid == *lp.UserID { + if lp.UserId != nil && uid == *lp.UserId { userFound = true } } diff --git a/builder/amazon/ebs/step_cleanup_volumes.go b/builder/amazon/ebs/step_cleanup_volumes.go index 56ebe5527..461bb7b9d 100644 --- a/builder/amazon/ebs/step_cleanup_volumes.go +++ b/builder/amazon/ebs/step_cleanup_volumes.go @@ -62,9 +62,9 @@ func (s *stepCleanupVolumes) Cleanup(state multistep.StateBag) { var vl []*string volList := make(map[string]string) for _, bdm := range instance.BlockDeviceMappings { - if bdm.EBS != nil { - vl = append(vl, bdm.EBS.VolumeID) - volList[*bdm.EBS.VolumeID] = *bdm.DeviceName + if bdm.Ebs != nil { + vl = append(vl, bdm.Ebs.VolumeId) + volList[*bdm.Ebs.VolumeId] = *bdm.DeviceName } } @@ -88,7 +88,7 @@ func (s *stepCleanupVolumes) Cleanup(state multistep.StateBag) { // available, remove them from the list of volumes for _, v := range resp.Volumes { if v.State != nil && *v.State != "available" { - delete(volList, *v.VolumeID) + delete(volList, *v.VolumeId) } } @@ -109,7 +109,7 @@ func (s *stepCleanupVolumes) Cleanup(state multistep.StateBag) { // Destroy remaining volumes for k, _ := range volList { ui.Say(fmt.Sprintf("Destroying volume (%s)...", k)) - _, err := ec2conn.DeleteVolume(&ec2.DeleteVolumeInput{VolumeID: aws.String(k)}) + _, err := ec2conn.DeleteVolume(&ec2.DeleteVolumeInput{VolumeId: aws.String(k)}) if err != nil { ui.Say(fmt.Sprintf("Error deleting volume: %s", k)) } diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index a3980e3ee..e3e7e7026 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -22,7 +22,7 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction { // Create the image ui.Say(fmt.Sprintf("Creating the AMI: %s", config.AMIName)) createOpts := &ec2.CreateImageInput{ - InstanceID: instance.InstanceID, + InstanceId: instance.InstanceId, Name: &config.AMIName, BlockDeviceMappings: config.BlockDevices.BuildAMIDevices(), } @@ -36,16 +36,16 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction { } // Set the AMI ID in the state - ui.Message(fmt.Sprintf("AMI: %s", *createResp.ImageID)) + ui.Message(fmt.Sprintf("AMI: %s", *createResp.ImageId)) amis := make(map[string]string) - amis[*ec2conn.Config.Region] = *createResp.ImageID + amis[*ec2conn.Config.Region] = *createResp.ImageId state.Put("amis", amis) // Wait for the image to become ready stateChange := awscommon.StateChangeConf{ Pending: []string{"pending"}, Target: "available", - Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *createResp.ImageID), + Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *createResp.ImageId), StepState: state, } @@ -57,7 +57,7 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } - imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIDs: []*string{createResp.ImageID}}) + imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{createResp.ImageId}}) if err != nil { err := fmt.Errorf("Error searching for AMI: %s", err) state.Put("error", err) @@ -84,7 +84,7 @@ func (s *stepCreateAMI) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) ui.Say("Deregistering the AMI because cancelation or error...") - deregisterOpts := &ec2.DeregisterImageInput{ImageID: s.image.ImageID} + deregisterOpts := &ec2.DeregisterImageInput{ImageId: s.image.ImageId} if _, err := ec2conn.DeregisterImage(deregisterOpts); err != nil { ui.Error(fmt.Sprintf("Error deregistering AMI, may still be around: %s", err)) return diff --git a/builder/amazon/ebs/step_modify_instance.go b/builder/amazon/ebs/step_modify_instance.go index d7b30e42c..b9976db6d 100644 --- a/builder/amazon/ebs/step_modify_instance.go +++ b/builder/amazon/ebs/step_modify_instance.go @@ -21,11 +21,11 @@ func (s *stepModifyInstance) Run(state multistep.StateBag) multistep.StepAction ui.Say("Enabling Enhanced Networking...") simple := "simple" _, err := ec2conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeInput{ - InstanceID: instance.InstanceID, - SRIOVNetSupport: &ec2.AttributeValue{Value: &simple}, + InstanceId: instance.InstanceId, + SriovNetSupport: &ec2.AttributeValue{Value: &simple}, }) if err != nil { - err := fmt.Errorf("Error enabling Enhanced Networking on %s: %s", *instance.InstanceID, err) + err := fmt.Errorf("Error enabling Enhanced Networking on %s: %s", *instance.InstanceId, err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt diff --git a/builder/amazon/ebs/step_stop_instance.go b/builder/amazon/ebs/step_stop_instance.go index 967e5bbf4..77bcd2d7b 100644 --- a/builder/amazon/ebs/step_stop_instance.go +++ b/builder/amazon/ebs/step_stop_instance.go @@ -26,7 +26,7 @@ func (s *stepStopInstance) Run(state multistep.StateBag) multistep.StepAction { // Stop the instance so we can create an AMI from it ui.Say("Stopping the source instance...") _, err := ec2conn.StopInstances(&ec2.StopInstancesInput{ - InstanceIDs: []*string{instance.InstanceID}, + InstanceIds: []*string{instance.InstanceId}, }) if err != nil { err := fmt.Errorf("Error stopping instance: %s", err) @@ -40,7 +40,7 @@ func (s *stepStopInstance) Run(state multistep.StateBag) multistep.StepAction { stateChange := awscommon.StateChangeConf{ Pending: []string{"running", "stopping"}, Target: "stopped", - Refresh: awscommon.InstanceStateRefreshFunc(ec2conn, *instance.InstanceID), + Refresh: awscommon.InstanceStateRefreshFunc(ec2conn, *instance.InstanceId), StepState: state, } _, err = awscommon.WaitForState(&stateChange) diff --git a/builder/amazon/ebs/tags_acc_test.go b/builder/amazon/ebs/tags_acc_test.go index 606bb89ee..3027eff7f 100644 --- a/builder/amazon/ebs/tags_acc_test.go +++ b/builder/amazon/ebs/tags_acc_test.go @@ -40,7 +40,7 @@ func checkTags() builderT.TestCheckFunc { // describe the image, get block devices with a snapshot ec2conn, _ := testEC2Conn() imageResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ - ImageIDs: []*string{aws.String(artifact.Amis["us-east-1"])}, + ImageIds: []*string{aws.String(artifact.Amis["us-east-1"])}, }) if err != nil { @@ -56,14 +56,14 @@ func checkTags() builderT.TestCheckFunc { // Check only those with a Snapshot ID, i.e. not Ephemeral var snapshots []*string for _, device := range image.BlockDeviceMappings { - if device.EBS != nil && device.EBS.SnapshotID != nil { - snapshots = append(snapshots, device.EBS.SnapshotID) + if device.Ebs != nil && device.Ebs.SnapshotId != nil { + snapshots = append(snapshots, device.Ebs.SnapshotId) } } // grab matching snapshot info resp, err := ec2conn.DescribeSnapshots(&ec2.DescribeSnapshotsInput{ - SnapshotIDs: snapshots, + SnapshotIds: snapshots, }) if err != nil { diff --git a/builder/amazon/instance/step_register_ami.go b/builder/amazon/instance/step_register_ami.go index dc76331f8..fe6f785b8 100644 --- a/builder/amazon/instance/step_register_ami.go +++ b/builder/amazon/instance/step_register_ami.go @@ -31,7 +31,7 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { // Set SriovNetSupport to "simple". See http://goo.gl/icuXh5 if config.AMIEnhancedNetworking { - registerOpts.SRIOVNetSupport = aws.String("simple") + registerOpts.SriovNetSupport = aws.String("simple") } registerResp, err := ec2conn.RegisterImage(registerOpts) @@ -42,16 +42,16 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { } // Set the AMI ID in the state - ui.Say(fmt.Sprintf("AMI: %s", *registerResp.ImageID)) + ui.Say(fmt.Sprintf("AMI: %s", *registerResp.ImageId)) amis := make(map[string]string) - amis[*ec2conn.Config.Region] = *registerResp.ImageID + amis[*ec2conn.Config.Region] = *registerResp.ImageId state.Put("amis", amis) // Wait for the image to become ready stateChange := awscommon.StateChangeConf{ Pending: []string{"pending"}, Target: "available", - Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *registerResp.ImageID), + Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *registerResp.ImageId), StepState: state, } diff --git a/builder/docker/communicator.go b/builder/docker/communicator.go index 4fcd9b658..fb88a4491 100644 --- a/builder/docker/communicator.go +++ b/builder/docker/communicator.go @@ -1,6 +1,7 @@ package docker import ( + "archive/tar" "bytes" "fmt" "io" @@ -194,8 +195,42 @@ func (c *Communicator) UploadDir(dst string, src string, exclude []string) error return nil } +// Download pulls a file out of a container using `docker cp`. We have a source +// path and want to write to an io.Writer, not a file. We use - to make docker +// cp to write to stdout, and then copy the stream to our destination io.Writer. func (c *Communicator) Download(src string, dst io.Writer) error { - panic("not implemented") + log.Printf("Downloading file from container: %s:%s", c.ContainerId, src) + localCmd := exec.Command("docker", "cp", fmt.Sprintf("%s:%s", c.ContainerId, src), "-") + + pipe, err := localCmd.StdoutPipe() + if err != nil { + return fmt.Errorf("Failed to open pipe: %s", err) + } + + if err = localCmd.Start(); err != nil { + return fmt.Errorf("Failed to start download: %s", err) + } + + // When you use - to send docker cp to stdout it is streamed as a tar; this + // enables it to work with directories. We don't actually support + // directories in Download() but we still need to handle the tar format. + archive := tar.NewReader(pipe) + _, err = archive.Next() + if err != nil { + return fmt.Errorf("Failed to read header from tar stream: %s", err) + } + + numBytes, err := io.Copy(dst, archive) + if err != nil { + return fmt.Errorf("Failed to pipe download: %s", err) + } + log.Printf("Copied %d bytes for %s", numBytes, src) + + if err = localCmd.Wait(); err != nil { + return fmt.Errorf("Failed to download '%s' from container: %s", src, err) + } + + return nil } // canExec tells us whether `docker exec` is supported diff --git a/builder/docker/communicator_test.go b/builder/docker/communicator_test.go index f75a89d96..db0bfcfe8 100644 --- a/builder/docker/communicator_test.go +++ b/builder/docker/communicator_test.go @@ -1,10 +1,129 @@ package docker import ( - "github.com/mitchellh/packer/packer" + "crypto/sha256" + "io/ioutil" + "os" + "os/exec" + "runtime" + "strings" "testing" + + "github.com/mitchellh/packer/packer" + "github.com/mitchellh/packer/provisioner/file" + "github.com/mitchellh/packer/template" ) func TestCommunicator_impl(t *testing.T) { var _ packer.Communicator = new(Communicator) } + +func TestUploadDownload(t *testing.T) { + ui := packer.TestUi(t) + cache := &packer.FileCache{CacheDir: os.TempDir()} + + tpl, err := template.Parse(strings.NewReader(dockerBuilderConfig)) + if err != nil { + t.Fatalf("Unable to parse config: %s", err) + } + + // Make sure we only run this on linux hosts + if os.Getenv("PACKER_ACC") == "" { + t.Skip("This test is only run with PACKER_ACC=1") + } + if runtime.GOOS != "linux" { + t.Skip("This test is only supported on linux") + } + cmd := exec.Command("docker", "-v") + cmd.Run() + if !cmd.ProcessState.Success() { + t.Error("docker command not found; please make sure docker is installed") + } + + // Setup the builder + builder := &Builder{} + warnings, err := builder.Prepare(tpl.Builders["docker"].Config) + if err != nil { + t.Fatalf("Error preparing configuration %s", err) + } + if len(warnings) > 0 { + t.Fatal("Encountered configuration warnings; aborting") + } + + // Setup the provisioners + upload := &file.Provisioner{} + err = upload.Prepare(tpl.Provisioners[0].Config) + if err != nil { + t.Fatalf("Error preparing upload: %s", err) + } + download := &file.Provisioner{} + err = download.Prepare(tpl.Provisioners[1].Config) + if err != nil { + t.Fatalf("Error preparing download: %s", err) + } + // Preemptive cleanup. Honestly I don't know why you would want to get rid + // of my strawberry cake. It's so tasty! Do you not like cake? Are you a + // cake-hater? Or are you keeping all the cake all for yourself? So selfish! + defer os.Remove("my-strawberry-cake") + + // Add hooks so the provisioners run during the build + hooks := map[string][]packer.Hook{} + hooks[packer.HookProvision] = []packer.Hook{ + &packer.ProvisionHook{ + Provisioners: []packer.Provisioner{ + upload, + download, + }, + }, + } + hook := &packer.DispatchHook{Mapping: hooks} + + // Run things + artifact, err := builder.Run(ui, hook, cache) + if err != nil { + t.Fatalf("Error running build %s", err) + } + // Preemptive cleanup + defer artifact.Destroy() + + // Verify that the thing we downloaded is the same thing we sent up. + // Complain loudly if it isn't. + inputFile, err := ioutil.ReadFile("test-fixtures/onecakes/strawberry") + if err != nil { + t.Fatalf("Unable to read input file: %s", err) + } + outputFile, err := ioutil.ReadFile("my-strawberry-cake") + if err != nil { + t.Fatalf("Unable to read output file: %s", err) + } + if sha256.Sum256(inputFile) != sha256.Sum256(outputFile) { + t.Fatalf("Input and output files do not match\n"+ + "Input:\n%s\nOutput:\n%s\n", inputFile, outputFile) + } +} + +const dockerBuilderConfig = ` +{ + "builders": [ + { + "type": "docker", + "image": "alpine", + "export_path": "alpine.tar", + "run_command": ["-d", "-i", "-t", "{{.Image}}", "/bin/sh"] + } + ], + "provisioners": [ + { + "type": "file", + "source": "test-fixtures/onecakes/strawberry", + "destination": "/strawberry-cake" + }, + { + "type": "file", + "source": "/strawberry-cake", + "destination": "my-strawberry-cake", + "direction": "download" + } + ] +} +` diff --git a/builder/docker/test-fixtures/manycakes/chocolate b/builder/docker/test-fixtures/manycakes/chocolate new file mode 100644 index 000000000..a2286c928 --- /dev/null +++ b/builder/docker/test-fixtures/manycakes/chocolate @@ -0,0 +1 @@ +chocolate! diff --git a/builder/docker/test-fixtures/manycakes/vanilla b/builder/docker/test-fixtures/manycakes/vanilla new file mode 100644 index 000000000..000a45578 --- /dev/null +++ b/builder/docker/test-fixtures/manycakes/vanilla @@ -0,0 +1 @@ +vanilla! diff --git a/builder/docker/test-fixtures/onecakes/strawberry b/builder/docker/test-fixtures/onecakes/strawberry new file mode 100644 index 000000000..b663de3a9 --- /dev/null +++ b/builder/docker/test-fixtures/onecakes/strawberry @@ -0,0 +1 @@ +strawberry! diff --git a/builder/parallels/common/step_upload_parallels_tools_test.go b/builder/parallels/common/step_upload_parallels_tools_test.go new file mode 100644 index 000000000..0599912a9 --- /dev/null +++ b/builder/parallels/common/step_upload_parallels_tools_test.go @@ -0,0 +1,86 @@ +package common + +import ( + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" + "testing" +) + +func TestStepUploadParallelsTools_impl(t *testing.T) { + var _ multistep.Step = new(StepUploadParallelsTools) +} + +func TestStepUploadParallelsTools(t *testing.T) { + state := testState(t) + state.Put("parallels_tools_path", "./step_upload_parallels_tools_test.go") + step := new(StepUploadParallelsTools) + step.ParallelsToolsMode = "upload" + step.ParallelsToolsGuestPath = "/tmp/prl-lin.iso" + step.ParallelsToolsFlavor = "lin" + + comm := new(packer.MockCommunicator) + state.Put("communicator", comm) + + // Test the run + if action := step.Run(state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + if _, ok := state.GetOk("error"); ok { + t.Fatal("should NOT have error") + } + + // Verify + if comm.UploadPath != "/tmp/prl-lin.iso" { + t.Fatalf("bad: %#v", comm.UploadPath) + } +} + +func TestStepUploadParallelsTools_interpolate(t *testing.T) { + state := testState(t) + state.Put("parallels_tools_path", "./step_upload_parallels_tools_test.go") + step := new(StepUploadParallelsTools) + step.ParallelsToolsMode = "upload" + step.ParallelsToolsGuestPath = "/tmp/prl-{{ .Flavor }}.iso" + step.ParallelsToolsFlavor = "win" + + comm := new(packer.MockCommunicator) + state.Put("communicator", comm) + + // Test the run + if action := step.Run(state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + if _, ok := state.GetOk("error"); ok { + t.Fatal("should NOT have error") + } + + // Verify + if comm.UploadPath != "/tmp/prl-win.iso" { + t.Fatalf("bad: %#v", comm.UploadPath) + } +} + +func TestStepUploadParallelsTools_attach(t *testing.T) { + state := testState(t) + state.Put("parallels_tools_path", "./step_upload_parallels_tools_test.go") + step := new(StepUploadParallelsTools) + step.ParallelsToolsMode = "attach" + step.ParallelsToolsGuestPath = "/tmp/prl-lin.iso" + step.ParallelsToolsFlavor = "lin" + + comm := new(packer.MockCommunicator) + state.Put("communicator", comm) + + // Test the run + if action := step.Run(state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + if _, ok := state.GetOk("error"); ok { + t.Fatal("should NOT have error") + } + + // Verify + if comm.UploadCalled { + t.Fatal("bad") + } +} diff --git a/builder/parallels/iso/builder.go b/builder/parallels/iso/builder.go index 4a75b0b47..6b731544d 100644 --- a/builder/parallels/iso/builder.go +++ b/builder/parallels/iso/builder.go @@ -64,7 +64,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { Exclude: []string{ "boot_command", "prlctl", - "parallel_tools_guest_path", + "parallels_tools_guest_path", }, }, }, raws...) diff --git a/builder/parallels/pvm/config.go b/builder/parallels/pvm/config.go index f03584bf2..89c3ec1f9 100644 --- a/builder/parallels/pvm/config.go +++ b/builder/parallels/pvm/config.go @@ -41,7 +41,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { Exclude: []string{ "boot_command", "prlctl", - "parallel_tools_guest_path", + "parallels_tools_guest_path", }, }, }, raws...) diff --git a/builder/vmware/common/ssh.go b/builder/vmware/common/ssh.go index 9db075a71..86e184bb5 100644 --- a/builder/vmware/common/ssh.go +++ b/builder/vmware/common/ssh.go @@ -39,7 +39,7 @@ func CommHost(config *SSHConfig) func(multistep.StateBag) (string, error) { var ok bool macAddress := "" if macAddress, ok = vmxData["ethernet0.address"]; !ok || macAddress == "" { - if macAddress, ok = vmxData["ethernet0.generatedAddress"]; !ok || macAddress == "" { + if macAddress, ok = vmxData["ethernet0.generatedaddress"]; !ok || macAddress == "" { return "", errors.New("couldn't find MAC address in VMX") } } diff --git a/builder/vmware/common/step_clean_vmx.go b/builder/vmware/common/step_clean_vmx.go index 44bf4c407..e9bc51987 100755 --- a/builder/vmware/common/step_clean_vmx.go +++ b/builder/vmware/common/step_clean_vmx.go @@ -2,11 +2,12 @@ package common import ( "fmt" - "github.com/mitchellh/multistep" - "github.com/mitchellh/packer/packer" "log" "regexp" "strings" + + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" ) // This step cleans up the VMX by removing or changing this prior to @@ -51,8 +52,8 @@ func (s StepCleanVMX) Run(state multistep.StateBag) multistep.StepAction { ui.Message("Detaching ISO from CD-ROM device...") - vmxData[ide+"deviceType"] = "cdrom-raw" - vmxData[ide+"fileName"] = "auto detect" + vmxData[ide+"devicetype"] = "cdrom-raw" + vmxData[ide+"filename"] = "auto detect" } ui.Message("Disabling VNC server...") diff --git a/builder/vmware/common/step_clean_vmx_test.go b/builder/vmware/common/step_clean_vmx_test.go index 3ca6a7e23..ea30fb54a 100755 --- a/builder/vmware/common/step_clean_vmx_test.go +++ b/builder/vmware/common/step_clean_vmx_test.go @@ -61,8 +61,8 @@ func TestStepCleanVMX_floppyPath(t *testing.T) { Value string }{ {"floppy0.present", "FALSE"}, - {"floppy0.fileType", ""}, - {"floppy0.fileName", ""}, + {"floppy0.filetype", ""}, + {"floppy0.filename", ""}, } for _, tc := range cases { @@ -109,9 +109,9 @@ func TestStepCleanVMX_isoPath(t *testing.T) { Key string Value string }{ - {"ide0:0.fileName", "auto detect"}, - {"ide0:0.deviceType", "cdrom-raw"}, - {"ide0:1.fileName", "bar"}, + {"ide0:0.filename", "auto detect"}, + {"ide0:0.devicetype", "cdrom-raw"}, + {"ide0:1.filename", "bar"}, {"foo", "bar"}, } @@ -130,12 +130,12 @@ func TestStepCleanVMX_isoPath(t *testing.T) { const testVMXFloppyPath = ` floppy0.present = "TRUE" -floppy0.fileType = "file" +floppy0.filetype = "file" ` const testVMXISOPath = ` -ide0:0.deviceType = "cdrom-image" -ide0:0.fileName = "foo" -ide0:1.fileName = "bar" +ide0:0.devicetype = "cdrom-image" +ide0:0.filename = "foo" +ide0:1.filename = "bar" foo = "bar" ` diff --git a/builder/vmware/common/step_configure_vmx.go b/builder/vmware/common/step_configure_vmx.go index 14c68e76a..401d53055 100755 --- a/builder/vmware/common/step_configure_vmx.go +++ b/builder/vmware/common/step_configure_vmx.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "log" "regexp" + "strings" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" @@ -52,6 +53,7 @@ func (s *StepConfigureVMX) Run(state multistep.StateBag) multistep.StepAction { // Set custom data for k, v := range s.CustomData { log.Printf("Setting VMX: '%s' = '%s'", k, v) + k = strings.ToLower(k) vmxData[k] = v } diff --git a/builder/vmware/common/vmx.go b/builder/vmware/common/vmx.go index ab0291807..e7cdb662f 100755 --- a/builder/vmware/common/vmx.go +++ b/builder/vmware/common/vmx.go @@ -17,7 +17,7 @@ import ( func ParseVMX(contents string) map[string]string { results := make(map[string]string) - lineRe := regexp.MustCompile(`^(.+?)\s*=\s*"?(.*?)"?\s*$`) + lineRe := regexp.MustCompile(`^(.+?)\s*=\s*"(.*?)"\s*$`) for _, line := range strings.Split(contents, "\n") { matches := lineRe.FindStringSubmatch(line) @@ -25,7 +25,8 @@ func ParseVMX(contents string) map[string]string { continue } - results[matches[1]] = matches[2] + key := strings.ToLower(matches[1]) + results[key] = matches[2] } return results @@ -42,22 +43,9 @@ func EncodeVMX(contents map[string]string) string { i++ } - // a list of VMX key fragments that should not be wrapped in quotes, - // fragments because multiple disks can use the virtualSSD suffix - noQuotes := []string { - "virtualSSD", - } - sort.Strings(keys) for _, k := range keys { - pat := "%s = \"%s\"\n" - for _, q := range noQuotes { - if strings.Contains(k, q) { - pat = "%s = %s\n" - break; - } - } - buf.WriteString(fmt.Sprintf(pat, k, contents[k])) + buf.WriteString(fmt.Sprintf("%s = \"%s\"\n", k, contents[k])) } return buf.String() diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index 1dbae678a..a020e1627 100755 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -38,14 +38,14 @@ func (s *StepCloneVMX) Run(state multistep.StateBag) multistep.StepAction { } var diskName string - if _, ok := vmxData["scsi0:0.fileName"]; ok { - diskName = vmxData["scsi0:0.fileName"] + if _, ok := vmxData["scsi0:0.filename"]; ok { + diskName = vmxData["scsi0:0.filename"] } - if _, ok := vmxData["sata0:0.fileName"]; ok { - diskName = vmxData["sata0:0.fileName"] + if _, ok := vmxData["sata0:0.filename"]; ok { + diskName = vmxData["sata0:0.filename"] } - if _, ok := vmxData["ide0:0.fileName"]; ok { - diskName = vmxData["ide0:0.fileName"] + if _, ok := vmxData["ide0:0.filename"]; ok { + diskName = vmxData["ide0:0.filename"] } if diskName == "" { err := fmt.Errorf("Root disk filename could not be found!") diff --git a/post-processor/vagrant/util.go b/post-processor/vagrant/util.go index a9e745fe6..6ae2c337f 100644 --- a/post-processor/vagrant/util.go +++ b/post-processor/vagrant/util.go @@ -3,14 +3,23 @@ package vagrant import ( "archive/tar" "compress/flate" - "compress/gzip" "encoding/json" "fmt" - "github.com/mitchellh/packer/packer" "io" "log" "os" "path/filepath" + "runtime" + + "github.com/klauspost/pgzip" + "github.com/mitchellh/packer/packer" +) + +var ( + // ErrInvalidCompressionLevel is returned when the compression level passed + // to gzip is not in the expected range. See compress/flate for details. + ErrInvalidCompressionLevel = fmt.Errorf( + "Invalid compression level. Expected an integer from -1 to 9.") ) // Copies a file by copying the contents of the file to another place. @@ -60,10 +69,10 @@ func DirToBox(dst, dir string, ui packer.Ui, level int) error { } defer dstF.Close() - var dstWriter io.Writer = dstF + var dstWriter io.WriteCloser = dstF if level != flate.NoCompression { log.Printf("Compressing with gzip compression level: %d", level) - gzipWriter, err := gzip.NewWriterLevel(dstWriter, level) + gzipWriter, err := makePgzipWriter(dstWriter, level) if err != nil { return err } @@ -143,3 +152,12 @@ func WriteMetadata(dir string, contents interface{}) error { return nil } + +func makePgzipWriter(output io.WriteCloser, compressionLevel int) (io.WriteCloser, error) { + gzipWriter, err := pgzip.NewWriterLevel(output, compressionLevel) + if err != nil { + return nil, ErrInvalidCompressionLevel + } + gzipWriter.SetConcurrency(500000, runtime.GOMAXPROCS(-1)) + return gzipWriter, nil +} diff --git a/version.go b/version.go index 59a306403..a32442840 100644 --- a/version.go +++ b/version.go @@ -4,9 +4,9 @@ package main var GitCommit string // The main version number that is being run at the moment. -const Version = "0.8.3" +const Version = "0.8.6" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" diff --git a/website/source/docs/builders/vmware-iso.html.markdown b/website/source/docs/builders/vmware-iso.html.markdown index 594d77cee..39678fd5f 100644 --- a/website/source/docs/builders/vmware-iso.html.markdown +++ b/website/source/docs/builders/vmware-iso.html.markdown @@ -393,3 +393,23 @@ modify as well: - `remote_username` - The SSH username used to access the remote machine. - `remote_password` - The SSH password for access to the remote machine. + +### Using a Floppy for Linux kickstart file or preseed + +Depending on your network configuration, it may be difficult to use packer's +built-in HTTP server with ESXi. Instead, you can provide a kickstart or preseed +file by attaching a floppy disk. An example below, based on RHEL: + +``` {.javascript} +{ + "builders": [ + { + "type":"vmware-iso", + "floppy_files": [ + "folder/ks.cfg" + ], + "boot_command": " text ks=floppy " + } + ] +} +``` diff --git a/website/source/docs/post-processors/artifice.html.markdown b/website/source/docs/post-processors/artifice.html.markdown index 28255e836..2ee9abc85 100644 --- a/website/source/docs/post-processors/artifice.html.markdown +++ b/website/source/docs/post-processors/artifice.html.markdown @@ -1,8 +1,10 @@ --- description: | - The Atlas post-processor for Packer receives an artifact from a Packer build and - uploads it to Atlas. Atlas hosts and serves artifacts, allowing you to version - and distribute them in a simple way. + The artifice post-processor overrides the artifact list from an upstream builder + or post-processor. All downstream post-processors will see the new artifacts you + specify. The primary use-case is to build artifacts inside a packer builder -- + for example, spinning up an EC2 instance to build a docker container -- and then + extracting the docker container and throwing away the EC2 instance. layout: docs page_title: 'Atlas Post-Processor' ... @@ -45,8 +47,8 @@ Artifice helps you tie together a few other packer features: - Additional post-processors, which push the artifact to Atlas, Docker hub, etc. -You will want to perform as much work as possible inside the VM. Ideally -the only other post-processor you need after artifice is one that uploads your +You will want to perform as much work as possible inside the VM. Ideally the +only other post-processor you need after artifice is one that uploads your artifact to the appropriate repository. ## Configuration @@ -64,13 +66,14 @@ The configuration allows you to specify which files comprise your artifact. This minimal example: -1. Spins up a cloned VMware virtual machine -2. Installs a [consul](https://consul.io/) release -3. Downloads the consul binary -4. Packages it into a `.tar.gz` file -5. Uploads it to Atlas. +1. Spins up a cloned VMware virtual machine +2. Installs a [consul](https://consul.io/) release +3. Downloads the consul binary +4. Packages it into a `.tar.gz` file +5. Uploads it to Atlas. -VMX is a fast way to build and test locally, but you can easily substitute another builder. +VMX is a fast way to build and test locally, but you can easily substitute +another builder. ``` {.javascript} { @@ -143,5 +146,5 @@ artifact (the vmx file in this case) and it will not have the desired result. } ] -You can create multiple post-processor chains to handle multiple builders (for example, -building linux and windows binaries during the same build). +You can create multiple post-processor chains to handle multiple builders (for +example, building linux and windows binaries during the same build). diff --git a/website/source/docs/post-processors/compress.html.markdown b/website/source/docs/post-processors/compress.html.markdown index 3834ffc72..373230d44 100644 --- a/website/source/docs/post-processors/compress.html.markdown +++ b/website/source/docs/post-processors/compress.html.markdown @@ -27,8 +27,8 @@ you will need to specify the `output` option. detected packer defaults to `.tar.gz` behavior but will not change the filename. - You can use `{{.BuildName}}` and `{{.BuilderType}}` in your output path. - If you are executing multiple builders in parallel you should make sure + You can use `{{.BuildName}}` and `{{.BuilderType}}` in your output path. If + you are executing multiple builders in parallel you should make sure `output` is unique for each one. For example `packer_{{.BuildName}}.zip`. - `compression_level` (integer) - Specify the compression level, for