Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
packer
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kristopher Ruzic
packer
Commits
74bcbfa8
Commit
74bcbfa8
authored
May 28, 2015
by
Mitchell Hashimoto
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'jen20-aws-sdk-go'
parents
73bdc3fd
b78b119a
Changes
33
Show whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
518 additions
and
363 deletions
+518
-363
builder/amazon/chroot/builder.go
builder/amazon/chroot/builder.go
+3
-8
builder/amazon/chroot/step_attach_volume.go
builder/amazon/chroot/step_attach_volume.go
+11
-7
builder/amazon/chroot/step_check_root_device.go
builder/amazon/chroot/step_check_root_device.go
+2
-2
builder/amazon/chroot/step_create_volume.go
builder/amazon/chroot/step_create_volume.go
+16
-15
builder/amazon/chroot/step_instance_info.go
builder/amazon/chroot/step_instance_info.go
+6
-5
builder/amazon/chroot/step_mount_device.go
builder/amazon/chroot/step_mount_device.go
+3
-3
builder/amazon/chroot/step_register_ami.go
builder/amazon/chroot/step_register_ami.go
+22
-17
builder/amazon/chroot/step_register_ami_test.go
builder/amazon/chroot/step_register_ami_test.go
+22
-22
builder/amazon/chroot/step_snapshot.go
builder/amazon/chroot/step_snapshot.go
+11
-8
builder/amazon/common/access_config.go
builder/amazon/common/access_config.go
+56
-20
builder/amazon/common/ami_config.go
builder/amazon/common/ami_config.go
+1
-2
builder/amazon/common/artifact.go
builder/amazon/common/artifact.go
+13
-4
builder/amazon/common/block_device.go
builder/amazon/common/block_device.go
+25
-16
builder/amazon/common/block_device_test.go
builder/amazon/common/block_device_test.go
+16
-11
builder/amazon/common/regions.go
builder/amazon/common/regions.go
+16
-0
builder/amazon/common/ssh.go
builder/amazon/common/ssh.go
+14
-11
builder/amazon/common/state.go
builder/amazon/common/state.go
+23
-14
builder/amazon/common/step_ami_region_copy.go
builder/amazon/common/step_ami_region_copy.go
+25
-17
builder/amazon/common/step_create_tags.go
builder/amazon/common/step_create_tags.go
+13
-6
builder/amazon/common/step_key_pair.go
builder/amazon/common/step_key_pair.go
+8
-7
builder/amazon/common/step_modify_ami_attributes.go
builder/amazon/common/step_modify_ami_attributes.go
+31
-14
builder/amazon/common/step_run_source_instance.go
builder/amazon/common/step_run_source_instance.go
+106
-77
builder/amazon/common/step_security_group.go
builder/amazon/common/step_security_group.go
+20
-19
builder/amazon/common/step_source_ami_info.go
builder/amazon/common/step_source_ami_info.go
+4
-4
builder/amazon/ebs/builder.go
builder/amazon/ebs/builder.go
+5
-9
builder/amazon/ebs/builder_test.go
builder/amazon/ebs/builder_test.go
+2
-1
builder/amazon/ebs/step_create_ami.go
builder/amazon/ebs/step_create_ami.go
+13
-14
builder/amazon/ebs/step_modify_instance.go
builder/amazon/ebs/step_modify_instance.go
+7
-6
builder/amazon/ebs/step_stop_instance.go
builder/amazon/ebs/step_stop_instance.go
+5
-2
builder/amazon/instance/builder.go
builder/amazon/instance/builder.go
+5
-9
builder/amazon/instance/step_bundle_volume.go
builder/amazon/instance/step_bundle_volume.go
+2
-2
builder/amazon/instance/step_register_ami.go
builder/amazon/instance/step_register_ami.go
+11
-10
builder/amazon/instance/step_upload_bundle.go
builder/amazon/instance/step_upload_bundle.go
+1
-1
No files found.
builder/amazon/chroot/builder.go
View file @
74bcbfa8
...
@@ -9,7 +9,7 @@ import (
...
@@ -9,7 +9,7 @@ import (
"log"
"log"
"runtime"
"runtime"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/common"
"github.com/mitchellh/packer/common"
...
@@ -124,17 +124,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
...
@@ -124,17 +124,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
return
nil
,
errors
.
New
(
"The amazon-chroot builder only works on Linux environments."
)
return
nil
,
errors
.
New
(
"The amazon-chroot builder only works on Linux environments."
)
}
}
region
,
err
:=
b
.
config
.
Region
()
config
,
err
:=
b
.
config
.
Config
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
auth
,
err
:=
b
.
config
.
AccessConfig
.
Auth
()
ec2conn
:=
ec2
.
New
(
config
)
if
err
!=
nil
{
return
nil
,
err
}
ec2conn
:=
ec2
.
New
(
auth
,
region
)
wrappedCommand
:=
func
(
command
string
)
(
string
,
error
)
{
wrappedCommand
:=
func
(
command
string
)
(
string
,
error
)
{
ctx
:=
*
b
.
config
.
ctx
ctx
:=
*
b
.
config
.
ctx
...
...
builder/amazon/chroot/step_attach_volume.go
View file @
74bcbfa8
...
@@ -6,7 +6,7 @@ import (
...
@@ -6,7 +6,7 @@ import (
"strings"
"strings"
"time"
"time"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
...
@@ -34,7 +34,11 @@ func (s *StepAttachVolume) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -34,7 +34,11 @@ func (s *StepAttachVolume) Run(state multistep.StateBag) multistep.StepAction {
attachVolume
:=
strings
.
Replace
(
device
,
"/xvd"
,
"/sd"
,
1
)
attachVolume
:=
strings
.
Replace
(
device
,
"/xvd"
,
"/sd"
,
1
)
ui
.
Say
(
fmt
.
Sprintf
(
"Attaching the root volume to %s"
,
attachVolume
))
ui
.
Say
(
fmt
.
Sprintf
(
"Attaching the root volume to %s"
,
attachVolume
))
_
,
err
:=
ec2conn
.
AttachVolume
(
volumeId
,
instance
.
InstanceId
,
attachVolume
)
_
,
err
:=
ec2conn
.
AttachVolume
(
&
ec2
.
AttachVolumeInput
{
InstanceID
:
instance
.
InstanceID
,
VolumeID
:
&
volumeId
,
Device
:
&
attachVolume
,
})
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error attaching volume: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error attaching volume: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
...
@@ -54,13 +58,13 @@ func (s *StepAttachVolume) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -54,13 +58,13 @@ func (s *StepAttachVolume) Run(state multistep.StateBag) multistep.StepAction {
Refresh
:
func
()
(
interface
{},
string
,
error
)
{
Refresh
:
func
()
(
interface
{},
string
,
error
)
{
attempts
:=
0
attempts
:=
0
for
attempts
<
30
{
for
attempts
<
30
{
resp
,
err
:=
ec2conn
.
Volumes
([]
string
{
volumeId
},
ec2
.
NewFilter
()
)
resp
,
err
:=
ec2conn
.
DescribeVolumes
(
&
ec2
.
DescribeVolumesInput
{
VolumeIDs
:
[]
*
string
{
&
volumeId
}}
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
""
,
err
return
nil
,
""
,
err
}
}
if
len
(
resp
.
Volumes
[
0
]
.
Attachments
)
>
0
{
if
len
(
resp
.
Volumes
[
0
]
.
Attachments
)
>
0
{
a
:=
resp
.
Volumes
[
0
]
.
Attachments
[
0
]
a
:=
resp
.
Volumes
[
0
]
.
Attachments
[
0
]
return
a
,
a
.
Status
,
nil
return
a
,
*
a
.
State
,
nil
}
}
// When Attachment on volume is not present sleep for 2s and retry
// When Attachment on volume is not present sleep for 2s and retry
attempts
+=
1
attempts
+=
1
...
@@ -103,7 +107,7 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error {
...
@@ -103,7 +107,7 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error {
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
"Detaching EBS volume..."
)
ui
.
Say
(
"Detaching EBS volume..."
)
_
,
err
:=
ec2conn
.
DetachVolume
(
s
.
volumeId
)
_
,
err
:=
ec2conn
.
DetachVolume
(
&
ec2
.
DetachVolumeInput
{
VolumeID
:
&
s
.
volumeId
}
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Error detaching EBS volume: %s"
,
err
)
return
fmt
.
Errorf
(
"Error detaching EBS volume: %s"
,
err
)
}
}
...
@@ -116,14 +120,14 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error {
...
@@ -116,14 +120,14 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error {
StepState
:
state
,
StepState
:
state
,
Target
:
"detached"
,
Target
:
"detached"
,
Refresh
:
func
()
(
interface
{},
string
,
error
)
{
Refresh
:
func
()
(
interface
{},
string
,
error
)
{
resp
,
err
:=
ec2conn
.
Volumes
([]
string
{
s
.
volumeId
},
ec2
.
NewFilter
()
)
resp
,
err
:=
ec2conn
.
DescribeVolumes
(
&
ec2
.
DescribeVolumesInput
{
VolumeIDs
:
[]
*
string
{
&
s
.
volumeId
}}
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
""
,
err
return
nil
,
""
,
err
}
}
v
:=
resp
.
Volumes
[
0
]
v
:=
resp
.
Volumes
[
0
]
if
len
(
v
.
Attachments
)
>
0
{
if
len
(
v
.
Attachments
)
>
0
{
return
v
,
v
.
Attachments
[
0
]
.
Status
,
nil
return
v
,
*
v
.
Attachments
[
0
]
.
State
,
nil
}
else
{
}
else
{
return
v
,
"detached"
,
nil
return
v
,
"detached"
,
nil
}
}
...
...
builder/amazon/chroot/step_check_root_device.go
View file @
74bcbfa8
...
@@ -3,7 +3,7 @@ package chroot
...
@@ -3,7 +3,7 @@ package chroot
import
(
import
(
"fmt"
"fmt"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
)
)
...
@@ -18,7 +18,7 @@ func (s *StepCheckRootDevice) Run(state multistep.StateBag) multistep.StepAction
...
@@ -18,7 +18,7 @@ func (s *StepCheckRootDevice) Run(state multistep.StateBag) multistep.StepAction
ui
.
Say
(
"Checking the root device on source AMI..."
)
ui
.
Say
(
"Checking the root device on source AMI..."
)
// It must be EBS-backed otherwise the build won't work
// It must be EBS-backed otherwise the build won't work
if
image
.
RootDeviceType
!=
"ebs"
{
if
*
image
.
RootDeviceType
!=
"ebs"
{
err
:=
fmt
.
Errorf
(
"The root device of the source AMI must be EBS-backed."
)
err
:=
fmt
.
Errorf
(
"The root device of the source AMI must be EBS-backed."
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
...
...
builder/amazon/chroot/step_create_volume.go
View file @
74bcbfa8
...
@@ -2,11 +2,12 @@ package chroot
...
@@ -2,11 +2,12 @@ package chroot
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/ec2"
"log"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
"log"
)
)
// StepCreateVolume creates a new volume from the snapshot of the root
// StepCreateVolume creates a new volume from the snapshot of the root
...
@@ -25,11 +26,11 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -25,11 +26,11 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction {
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
// Determine the root device snapshot
// Determine the root device snapshot
log
.
Printf
(
"Searching for root device of the image (%s)"
,
image
.
RootDeviceName
)
log
.
Printf
(
"Searching for root device of the image (%s)"
,
*
image
.
RootDeviceName
)
var
rootDevice
*
ec2
.
BlockDeviceMapping
var
rootDevice
*
ec2
.
BlockDeviceMapping
for
_
,
device
:=
range
image
.
BlockDevices
{
for
_
,
device
:=
range
image
.
BlockDevice
Mapping
s
{
if
device
.
DeviceName
==
image
.
RootDeviceName
{
if
device
.
DeviceName
==
image
.
RootDeviceName
{
rootDevice
=
&
device
rootDevice
=
device
break
break
}
}
}
}
...
@@ -42,12 +43,12 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -42,12 +43,12 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction {
}
}
ui
.
Say
(
"Creating the root volume..."
)
ui
.
Say
(
"Creating the root volume..."
)
createVolume
:=
&
ec2
.
CreateVolume
{
createVolume
:=
&
ec2
.
CreateVolume
Input
{
Avail
Zone
:
instance
.
Avail
Zone
,
Avail
abilityZone
:
instance
.
Placement
.
Availability
Zone
,
Size
:
rootDevice
.
VolumeSize
,
Size
:
rootDevice
.
EBS
.
VolumeSize
,
SnapshotI
d
:
rootDevice
.
SnapshotId
,
SnapshotI
D
:
rootDevice
.
EBS
.
SnapshotID
,
VolumeType
:
rootDevice
.
VolumeType
,
VolumeType
:
rootDevice
.
EBS
.
VolumeType
,
IOPS
:
rootDevice
.
IOPS
,
IOPS
:
rootDevice
.
EBS
.
IOPS
,
}
}
log
.
Printf
(
"Create args: %#v"
,
createVolume
)
log
.
Printf
(
"Create args: %#v"
,
createVolume
)
...
@@ -60,7 +61,7 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -60,7 +61,7 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction {
}
}
// Set the volume ID so we remember to delete it later
// 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
)
log
.
Printf
(
"Volume ID: %s"
,
s
.
volumeId
)
// Wait for the volume to become ready
// Wait for the volume to become ready
...
@@ -69,13 +70,13 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -69,13 +70,13 @@ func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction {
StepState
:
state
,
StepState
:
state
,
Target
:
"available"
,
Target
:
"available"
,
Refresh
:
func
()
(
interface
{},
string
,
error
)
{
Refresh
:
func
()
(
interface
{},
string
,
error
)
{
resp
,
err
:=
ec2conn
.
Volumes
([]
string
{
s
.
volumeId
},
ec2
.
NewFilter
()
)
resp
,
err
:=
ec2conn
.
DescribeVolumes
(
&
ec2
.
DescribeVolumesInput
{
VolumeIDs
:
[]
*
string
{
&
s
.
volumeId
}}
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
""
,
err
return
nil
,
""
,
err
}
}
v
:=
resp
.
Volumes
[
0
]
v
:=
resp
.
Volumes
[
0
]
return
v
,
v
.
Status
,
nil
return
v
,
*
v
.
State
,
nil
},
},
}
}
...
@@ -100,7 +101,7 @@ func (s *StepCreateVolume) Cleanup(state multistep.StateBag) {
...
@@ -100,7 +101,7 @@ func (s *StepCreateVolume) Cleanup(state multistep.StateBag) {
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
"Deleting the created EBS volume..."
)
ui
.
Say
(
"Deleting the created EBS volume..."
)
_
,
err
:=
ec2conn
.
DeleteVolume
(
s
.
volumeId
)
_
,
err
:=
ec2conn
.
DeleteVolume
(
&
ec2
.
DeleteVolumeInput
{
VolumeID
:
&
s
.
volumeId
}
)
if
err
!=
nil
{
if
err
!=
nil
{
ui
.
Error
(
fmt
.
Sprintf
(
"Error deleting EBS volume: %s"
,
err
))
ui
.
Error
(
fmt
.
Sprintf
(
"Error deleting EBS volume: %s"
,
err
))
}
}
...
...
builder/amazon/chroot/step_instance_info.go
View file @
74bcbfa8
...
@@ -2,11 +2,12 @@ package chroot
...
@@ -2,11 +2,12 @@ package chroot
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/aws"
"log"
"github.com/mitchellh/goamz/ec2"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
"log"
)
)
// StepInstanceInfo verifies that this builder is running on an EC2 instance.
// StepInstanceInfo verifies that this builder is running on an EC2 instance.
...
@@ -18,7 +19,7 @@ func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -18,7 +19,7 @@ func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction {
// Get our own instance ID
// Get our own instance ID
ui
.
Say
(
"Gathering information about this EC2 instance..."
)
ui
.
Say
(
"Gathering information about this EC2 instance..."
)
instanceIdBytes
,
err
:=
aws
.
Get
MetaData
(
"instance-id"
)
instanceIdBytes
,
err
:=
common
.
GetInstance
MetaData
(
"instance-id"
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Printf
(
"Error: %s"
,
err
)
log
.
Printf
(
"Error: %s"
,
err
)
err
:=
fmt
.
Errorf
(
err
:=
fmt
.
Errorf
(
...
@@ -33,7 +34,7 @@ func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -33,7 +34,7 @@ func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction {
log
.
Printf
(
"Instance ID: %s"
,
instanceId
)
log
.
Printf
(
"Instance ID: %s"
,
instanceId
)
// Query the entire instance metadata
// Query the entire instance metadata
instancesResp
,
err
:=
ec2conn
.
Instances
([]
string
{
instanceId
},
ec2
.
NewFilter
()
)
instancesResp
,
err
:=
ec2conn
.
DescribeInstances
(
&
ec2
.
DescribeInstancesInput
{
InstanceIDs
:
[]
*
string
{
&
instanceId
}}
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error getting instance data: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error getting instance data: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
...
...
builder/amazon/chroot/step_mount_device.go
View file @
74bcbfa8
...
@@ -7,7 +7,7 @@ import (
...
@@ -7,7 +7,7 @@ import (
"os"
"os"
"path/filepath"
"path/filepath"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/template/interpolate"
"github.com/mitchellh/packer/template/interpolate"
...
@@ -61,9 +61,9 @@ func (s *StepMountDevice) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -61,9 +61,9 @@ func (s *StepMountDevice) Run(state multistep.StateBag) multistep.StepAction {
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
log
.
Printf
(
"Source image virtualization type is: %s"
,
image
.
VirtualizationType
)
log
.
Printf
(
"Source image virtualization type is: %s"
,
*
image
.
VirtualizationType
)
deviceMount
:=
device
deviceMount
:=
device
if
image
.
VirtualizationType
==
"hvm"
{
if
*
image
.
VirtualizationType
==
"hvm"
{
deviceMount
=
fmt
.
Sprintf
(
"%s%d"
,
device
,
1
)
deviceMount
=
fmt
.
Sprintf
(
"%s%d"
,
device
,
1
)
}
}
state
.
Put
(
"deviceMount"
,
deviceMount
)
state
.
Put
(
"deviceMount"
,
deviceMount
)
...
...
builder/amazon/chroot/step_register_ami.go
View file @
74bcbfa8
...
@@ -3,7 +3,8 @@ package chroot
...
@@ -3,7 +3,8 @@ package chroot
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/ec2"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
...
@@ -20,11 +21,15 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -20,11 +21,15 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
"Registering the AMI..."
)
ui
.
Say
(
"Registering the AMI..."
)
blockDevices
:=
make
([]
ec2
.
BlockDeviceMapping
,
len
(
image
.
BlockDevice
s
))
blockDevices
:=
make
([]
*
ec2
.
BlockDeviceMapping
,
len
(
image
.
BlockDeviceMapping
s
))
for
i
,
device
:=
range
image
.
BlockDevices
{
for
i
,
device
:=
range
image
.
BlockDevice
Mapping
s
{
newDevice
:=
device
newDevice
:=
device
if
newDevice
.
DeviceName
==
image
.
RootDeviceName
{
if
newDevice
.
DeviceName
==
image
.
RootDeviceName
{
newDevice
.
SnapshotId
=
snapshotId
if
newDevice
.
EBS
!=
nil
{
newDevice
.
EBS
.
SnapshotID
=
&
snapshotId
}
else
{
newDevice
.
EBS
=
&
ec2
.
EBSBlockDevice
{
SnapshotID
:
&
snapshotId
}
}
}
}
blockDevices
[
i
]
=
newDevice
blockDevices
[
i
]
=
newDevice
...
@@ -34,7 +39,7 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -34,7 +39,7 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
if
config
.
AMIEnhancedNetworking
{
if
config
.
AMIEnhancedNetworking
{
registerOpts
.
S
riovNetSupport
=
"simple"
registerOpts
.
S
RIOVNetSupport
=
aws
.
String
(
"simple"
)
}
}
registerResp
,
err
:=
ec2conn
.
RegisterImage
(
registerOpts
)
registerResp
,
err
:=
ec2conn
.
RegisterImage
(
registerOpts
)
...
@@ -45,16 +50,16 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -45,16 +50,16 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
}
}
// Set the AMI ID in the state
// 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
:=
make
(
map
[
string
]
string
)
amis
[
ec2conn
.
Region
.
Name
]
=
registerResp
.
ImageId
amis
[
ec2conn
.
Config
.
Region
]
=
*
registerResp
.
ImageID
state
.
Put
(
"amis"
,
amis
)
state
.
Put
(
"amis"
,
amis
)
// Wait for the image to become ready
// Wait for the image to become ready
stateChange
:=
awscommon
.
StateChangeConf
{
stateChange
:=
awscommon
.
StateChangeConf
{
Pending
:
[]
string
{
"pending"
},
Pending
:
[]
string
{
"pending"
},
Target
:
"available"
,
Target
:
"available"
,
Refresh
:
awscommon
.
AMIStateRefreshFunc
(
ec2conn
,
registerResp
.
ImageId
),
Refresh
:
awscommon
.
AMIStateRefreshFunc
(
ec2conn
,
*
registerResp
.
ImageID
),
StepState
:
state
,
StepState
:
state
,
}
}
...
@@ -71,18 +76,18 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -71,18 +76,18 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
func
(
s
*
StepRegisterAMI
)
Cleanup
(
state
multistep
.
StateBag
)
{}
func
(
s
*
StepRegisterAMI
)
Cleanup
(
state
multistep
.
StateBag
)
{}
func
buildRegisterOpts
(
config
*
Config
,
image
*
ec2
.
Image
,
blockDevices
[]
ec2
.
BlockDeviceMapping
)
*
ec2
.
RegisterImage
{
func
buildRegisterOpts
(
config
*
Config
,
image
*
ec2
.
Image
,
blockDevices
[]
*
ec2
.
BlockDeviceMapping
)
*
ec2
.
RegisterImageInput
{
registerOpts
:=
&
ec2
.
RegisterImage
{
registerOpts
:=
&
ec2
.
RegisterImage
Input
{
Name
:
config
.
AMIName
,
Name
:
&
config
.
AMIName
,
Architecture
:
image
.
Architecture
,
Architecture
:
image
.
Architecture
,
RootDeviceName
:
image
.
RootDeviceName
,
RootDeviceName
:
image
.
RootDeviceName
,
BlockDevice
s
:
blockDevices
,
BlockDevice
Mappings
:
blockDevices
,
Virt
Type
:
config
.
AMIVirtType
,
Virt
ualizationType
:
&
config
.
AMIVirtType
,
}
}
if
config
.
AMIVirtType
!=
"hvm"
{
if
config
.
AMIVirtType
!=
"hvm"
{
registerOpts
.
KernelI
d
=
image
.
KernelId
registerOpts
.
KernelI
D
=
image
.
KernelID
registerOpts
.
R
amdiskId
=
image
.
RamdiskId
registerOpts
.
R
AMDiskID
=
image
.
RAMDiskID
}
}
return
registerOpts
return
registerOpts
...
...
builder/amazon/chroot/step_register_ami_test.go
View file @
74bcbfa8
package
chroot
package
chroot
import
(
import
(
"github.com/mitchellh/goamz/ec2"
"testing"
"testing"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
)
)
func
testImage
()
ec2
.
Image
{
func
testImage
()
ec2
.
Image
{
return
ec2
.
Image
{
return
ec2
.
Image
{
I
d
:
"ami-abcd1234"
,
I
mageID
:
aws
.
String
(
"ami-abcd1234"
)
,
Name
:
"ami_test_name"
,
Name
:
aws
.
String
(
"ami_test_name"
)
,
Architecture
:
"x86_64"
,
Architecture
:
aws
.
String
(
"x86_64"
)
,
KernelI
d
:
"aki-abcd1234"
,
KernelI
D
:
aws
.
String
(
"aki-abcd1234"
)
,
}
}
}
}
...
@@ -22,23 +24,23 @@ func TestStepRegisterAmi_buildRegisterOpts_pv(t *testing.T) {
...
@@ -22,23 +24,23 @@ func TestStepRegisterAmi_buildRegisterOpts_pv(t *testing.T) {
image
:=
testImage
()
image
:=
testImage
()
blockDevices
:=
[]
ec2
.
BlockDeviceMapping
{}
blockDevices
:=
[]
*
ec2
.
BlockDeviceMapping
{}
opts
:=
buildRegisterOpts
(
&
config
,
&
image
,
blockDevices
)
opts
:=
buildRegisterOpts
(
&
config
,
&
image
,
blockDevices
)
expected
:=
config
.
AMIVirtType
expected
:=
config
.
AMIVirtType
if
opts
.
Virt
Type
!=
expected
{
if
*
opts
.
Virtualization
Type
!=
expected
{
t
.
Fatalf
(
"Unexpected VirtType value: expected %s got %s
\n
"
,
expected
,
opts
.
Virt
Type
)
t
.
Fatalf
(
"Unexpected VirtType value: expected %s got %s
\n
"
,
expected
,
*
opts
.
Virtualization
Type
)
}
}
expected
=
config
.
AMIName
expected
=
config
.
AMIName
if
opts
.
Name
!=
expected
{
if
*
opts
.
Name
!=
expected
{
t
.
Fatalf
(
"Unexpected Name value: expected %s got %s
\n
"
,
expected
,
opts
.
Name
)
t
.
Fatalf
(
"Unexpected Name value: expected %s got %s
\n
"
,
expected
,
*
opts
.
Name
)
}
}
expected
=
image
.
KernelId
expected
=
*
image
.
KernelID
if
opts
.
KernelId
!=
expected
{
if
*
opts
.
KernelID
!=
expected
{
t
.
Fatalf
(
"Unexpected KernelId value: expected %s got %s
\n
"
,
expected
,
opts
.
KernelId
)
t
.
Fatalf
(
"Unexpected KernelId value: expected %s got %s
\n
"
,
expected
,
*
opts
.
KernelID
)
}
}
}
}
...
@@ -51,23 +53,21 @@ func TestStepRegisterAmi_buildRegisterOpts_hvm(t *testing.T) {
...
@@ -51,23 +53,21 @@ func TestStepRegisterAmi_buildRegisterOpts_hvm(t *testing.T) {
image
:=
testImage
()
image
:=
testImage
()
blockDevices
:=
[]
ec2
.
BlockDeviceMapping
{}
blockDevices
:=
[]
*
ec2
.
BlockDeviceMapping
{}
opts
:=
buildRegisterOpts
(
&
config
,
&
image
,
blockDevices
)
opts
:=
buildRegisterOpts
(
&
config
,
&
image
,
blockDevices
)
expected
:=
config
.
AMIVirtType
expected
:=
config
.
AMIVirtType
if
opts
.
Virt
Type
!=
expected
{
if
*
opts
.
Virtualization
Type
!=
expected
{
t
.
Fatalf
(
"Unexpected VirtType value: expected %s got %s
\n
"
,
expected
,
opts
.
Virt
Type
)
t
.
Fatalf
(
"Unexpected VirtType value: expected %s got %s
\n
"
,
expected
,
*
opts
.
Virtualization
Type
)
}
}
expected
=
config
.
AMIName
expected
=
config
.
AMIName
if
opts
.
Name
!=
expected
{
if
*
opts
.
Name
!=
expected
{
t
.
Fatalf
(
"Unexpected Name value: expected %s got %s
\n
"
,
expected
,
opts
.
Name
)
t
.
Fatalf
(
"Unexpected Name value: expected %s got %s
\n
"
,
expected
,
*
opts
.
Name
)
}
}
expected
=
""
if
opts
.
KernelID
!=
nil
{
if
opts
.
KernelId
!=
expected
{
t
.
Fatalf
(
"Unexpected KernelId value: expected nil got %s
\n
"
,
*
opts
.
KernelID
)
t
.
Fatalf
(
"Unexpected KernelId value: expected %s got %s
\n
"
,
expected
,
opts
.
KernelId
)
}
}
}
}
builder/amazon/chroot/step_snapshot.go
View file @
74bcbfa8
...
@@ -5,7 +5,7 @@ import (
...
@@ -5,7 +5,7 @@ import (
"fmt"
"fmt"
"time"
"time"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
...
@@ -25,9 +25,12 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -25,9 +25,12 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction {
volumeId
:=
state
.
Get
(
"volume_id"
)
.
(
string
)
volumeId
:=
state
.
Get
(
"volume_id"
)
.
(
string
)
ui
.
Say
(
"Creating snapshot..."
)
ui
.
Say
(
"Creating snapshot..."
)
createSnapResp
,
err
:=
ec2conn
.
CreateSnapshot
(
description
:=
fmt
.
Sprintf
(
"Packer: %s"
,
time
.
Now
()
.
String
())
volumeId
,
fmt
.
Sprintf
(
"Packer: %s"
,
time
.
Now
()
.
String
()))
createSnapResp
,
err
:=
ec2conn
.
CreateSnapshot
(
&
ec2
.
CreateSnapshotInput
{
VolumeID
:
&
volumeId
,
Description
:
&
description
,
})
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error creating snapshot: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error creating snapshot: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
...
@@ -36,7 +39,7 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -36,7 +39,7 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction {
}
}
// Set the snapshot ID so we can delete it later
// Set the snapshot ID so we can delete it later
s
.
snapshotId
=
createSnapResp
.
Id
s
.
snapshotId
=
*
createSnapResp
.
SnapshotID
ui
.
Message
(
fmt
.
Sprintf
(
"Snapshot ID: %s"
,
s
.
snapshotId
))
ui
.
Message
(
fmt
.
Sprintf
(
"Snapshot ID: %s"
,
s
.
snapshotId
))
// Wait for the snapshot to be ready
// Wait for the snapshot to be ready
...
@@ -45,7 +48,7 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -45,7 +48,7 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction {
StepState
:
state
,
StepState
:
state
,
Target
:
"completed"
,
Target
:
"completed"
,
Refresh
:
func
()
(
interface
{},
string
,
error
)
{
Refresh
:
func
()
(
interface
{},
string
,
error
)
{
resp
,
err
:=
ec2conn
.
Snapshots
([]
string
{
s
.
snapshotId
},
ec2
.
NewFilter
()
)
resp
,
err
:=
ec2conn
.
DescribeSnapshots
(
&
ec2
.
DescribeSnapshotsInput
{
SnapshotIDs
:
[]
*
string
{
&
s
.
snapshotId
}}
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
""
,
err
return
nil
,
""
,
err
}
}
...
@@ -55,7 +58,7 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -55,7 +58,7 @@ func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction {
}
}
s
:=
resp
.
Snapshots
[
0
]
s
:=
resp
.
Snapshots
[
0
]
return
s
,
s
.
Status
,
nil
return
s
,
*
s
.
State
,
nil
},
},
}
}
...
@@ -83,7 +86,7 @@ func (s *StepSnapshot) Cleanup(state multistep.StateBag) {
...
@@ -83,7 +86,7 @@ func (s *StepSnapshot) Cleanup(state multistep.StateBag) {
ec2conn
:=
state
.
Get
(
"ec2"
)
.
(
*
ec2
.
EC2
)
ec2conn
:=
state
.
Get
(
"ec2"
)
.
(
*
ec2
.
EC2
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
"Removing snapshot since we cancelled or halted..."
)
ui
.
Say
(
"Removing snapshot since we cancelled or halted..."
)
_
,
err
:=
ec2conn
.
DeleteSnapshot
s
([]
string
{
s
.
snapshotId
})
_
,
err
:=
ec2conn
.
DeleteSnapshot
(
&
ec2
.
DeleteSnapshotInput
{
SnapshotID
:
&
s
.
snapshotId
})
if
err
!=
nil
{
if
err
!=
nil
{
ui
.
Error
(
fmt
.
Sprintf
(
"Error: %s"
,
err
))
ui
.
Error
(
fmt
.
Sprintf
(
"Error: %s"
,
err
))
}
}
...
...
builder/amazon/common/access_config.go
View file @
74bcbfa8
...
@@ -2,10 +2,13 @@ package common
...
@@ -2,10 +2,13 @@ package common
import
(
import
(
"fmt"
"fmt"
"io/ioutil"
"net/http"
"strings"
"strings"
"unicode"
"unicode"
"github.com/mitchellh/goamz/aws"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/aws/credentials"
"github.com/mitchellh/packer/template/interpolate"
"github.com/mitchellh/packer/template/interpolate"
)
)
...
@@ -17,43 +20,55 @@ type AccessConfig struct {
...
@@ -17,43 +20,55 @@ type AccessConfig struct {
Token
string
`mapstructure:"token"`
Token
string
`mapstructure:"token"`
}
}
// Auth returns a valid aws.Auth object for access to AWS services, or
// Config returns a valid aws.Config object for access to AWS services, or
// an error if the authentication couldn't be resolved.
// an error if the authentication and region couldn't be resolved
func
(
c
*
AccessConfig
)
Auth
()
(
aws
.
Auth
,
error
)
{
func
(
c
*
AccessConfig
)
Config
()
(
*
aws
.
Config
,
error
)
{
auth
,
err
:=
aws
.
GetAuth
(
c
.
AccessKey
,
c
.
SecretKey
)
creds
:=
credentials
.
NewChainCredentials
([]
credentials
.
Provider
{
if
err
==
nil
{
&
credentials
.
StaticProvider
{
Value
:
credentials
.
Value
{
// Store the accesskey and secret that we got...
AccessKeyID
:
c
.
AccessKey
,
c
.
AccessKey
=
auth
.
AccessKey
SecretAccessKey
:
c
.
SecretKey
,
c
.
SecretKey
=
auth
.
SecretKey
SessionToken
:
c
.
Token
,
c
.
Token
=
auth
.
Token
}},
}
&
credentials
.
EnvProvider
{},
if
c
.
Token
!=
""
{
&
credentials
.
SharedCredentialsProvider
{
Filename
:
""
,
Profile
:
""
},
auth
.
Token
=
c
.
Token
&
credentials
.
EC2RoleProvider
{},
})
region
,
err
:=
c
.
Region
()
if
err
!=
nil
{
return
nil
,
err
}
}
return
auth
,
err
return
&
aws
.
Config
{
Region
:
region
,
Credentials
:
creds
,
MaxRetries
:
11
,
},
nil
}
}
// Region returns the aws.Region object for access to AWS services, requesting
// Region returns the aws.Region object for access to AWS services, requesting
// the region from the instance metadata if possible.
// the region from the instance metadata if possible.
func
(
c
*
AccessConfig
)
Region
()
(
aws
.
Region
,
error
)
{
func
(
c
*
AccessConfig
)
Region
()
(
string
,
error
)
{
if
c
.
RawRegion
!=
""
{
if
c
.
RawRegion
!=
""
{
return
aws
.
Regions
[
c
.
RawRegion
],
nil
if
valid
:=
ValidateRegion
(
c
.
RawRegion
);
valid
==
false
{
return
""
,
fmt
.
Errorf
(
"Not a valid region: %s"
,
c
.
RawRegion
)
}
return
c
.
RawRegion
,
nil
}
}
md
,
err
:=
aws
.
Get
MetaData
(
"placement/availability-zone"
)
md
,
err
:=
GetInstance
MetaData
(
"placement/availability-zone"
)
if
err
!=
nil
{
if
err
!=
nil
{
return
aws
.
Region
{}
,
err
return
""
,
err
}
}
region
:=
strings
.
TrimRightFunc
(
string
(
md
),
unicode
.
IsLetter
)
region
:=
strings
.
TrimRightFunc
(
string
(
md
),
unicode
.
IsLetter
)
return
aws
.
Regions
[
region
]
,
nil
return
region
,
nil
}
}
func
(
c
*
AccessConfig
)
Prepare
(
ctx
*
interpolate
.
Context
)
[]
error
{
func
(
c
*
AccessConfig
)
Prepare
(
ctx
*
interpolate
.
Context
)
[]
error
{
var
errs
[]
error
var
errs
[]
error
if
c
.
RawRegion
!=
""
{
if
c
.
RawRegion
!=
""
{
if
_
,
ok
:=
aws
.
Regions
[
c
.
RawRegion
];
!
ok
{
if
valid
:=
ValidateRegion
(
c
.
RawRegion
);
valid
==
false
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"Unknown region: %s"
,
c
.
RawRegion
))
errs
=
append
(
errs
,
fmt
.
Errorf
(
"Unknown region: %s"
,
c
.
RawRegion
))
}
}
}
}
...
@@ -64,3 +79,24 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
...
@@ -64,3 +79,24 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
return
nil
return
nil
}
}
func
GetInstanceMetaData
(
path
string
)
(
contents
[]
byte
,
err
error
)
{
url
:=
"http://169.254.169.254/latest/meta-data/"
+
path
resp
,
err
:=
http
.
Get
(
url
)
if
err
!=
nil
{
return
}
defer
resp
.
Body
.
Close
()
if
resp
.
StatusCode
!=
200
{
err
=
fmt
.
Errorf
(
"Code %d returned for url %s"
,
resp
.
StatusCode
,
url
)
return
}
body
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
}
return
[]
byte
(
body
),
err
}
builder/amazon/common/ami_config.go
View file @
74bcbfa8
...
@@ -3,7 +3,6 @@ package common
...
@@ -3,7 +3,6 @@ package common
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/aws"
"github.com/mitchellh/packer/template/interpolate"
"github.com/mitchellh/packer/template/interpolate"
)
)
...
@@ -40,7 +39,7 @@ func (c *AMIConfig) Prepare(ctx *interpolate.Context) []error {
...
@@ -40,7 +39,7 @@ func (c *AMIConfig) Prepare(ctx *interpolate.Context) []error {
regionSet
[
region
]
=
struct
{}{}
regionSet
[
region
]
=
struct
{}{}
// Verify the region is real
// Verify the region is real
if
_
,
ok
:=
aws
.
Regions
[
region
];
!
ok
{
if
valid
:=
ValidateRegion
(
region
);
valid
==
false
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"Unknown region: %s"
,
region
))
errs
=
append
(
errs
,
fmt
.
Errorf
(
"Unknown region: %s"
,
region
))
continue
continue
}
}
...
...
builder/amazon/common/artifact.go
View file @
74bcbfa8
...
@@ -6,8 +6,8 @@ import (
...
@@ -6,8 +6,8 @@ import (
"sort"
"sort"
"strings"
"strings"
"github.com/
mitchellh/goamz
/aws"
"github.com/
awslabs/aws-sdk-go
/aws"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
)
)
...
@@ -67,8 +67,17 @@ func (a *Artifact) Destroy() error {
...
@@ -67,8 +67,17 @@ func (a *Artifact) Destroy() error {
for
region
,
imageId
:=
range
a
.
Amis
{
for
region
,
imageId
:=
range
a
.
Amis
{
log
.
Printf
(
"Deregistering image ID (%s) from region (%s)"
,
imageId
,
region
)
log
.
Printf
(
"Deregistering image ID (%s) from region (%s)"
,
imageId
,
region
)
regionconn
:=
ec2
.
New
(
a
.
Conn
.
Auth
,
aws
.
Regions
[
region
])
if
_
,
err
:=
regionconn
.
DeregisterImage
(
imageId
);
err
!=
nil
{
regionConfig
:=
&
aws
.
Config
{
Credentials
:
a
.
Conn
.
Config
.
Credentials
,
Region
:
region
,
}
regionConn
:=
ec2
.
New
(
regionConfig
)
input
:=
&
ec2
.
DeregisterImageInput
{
ImageID
:
&
imageId
,
}
if
_
,
err
:=
regionConn
.
DeregisterImage
(
input
);
err
!=
nil
{
errors
=
append
(
errors
,
err
)
errors
=
append
(
errors
,
err
)
}
}
...
...
builder/amazon/common/block_device.go
View file @
74bcbfa8
package
common
package
common
import
(
import
(
"github.com/mitchellh/goamz/ec2"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/packer/template/interpolate"
"github.com/mitchellh/packer/template/interpolate"
)
)
...
@@ -23,21 +24,29 @@ type BlockDevices struct {
...
@@ -23,21 +24,29 @@ type BlockDevices struct {
LaunchMappings
[]
BlockDevice
`mapstructure:"launch_block_device_mappings"`
LaunchMappings
[]
BlockDevice
`mapstructure:"launch_block_device_mappings"`
}
}
func
buildBlockDevices
(
b
[]
BlockDevice
)
[]
ec2
.
BlockDeviceMapping
{
func
buildBlockDevices
(
b
[]
BlockDevice
)
[]
*
ec2
.
BlockDeviceMapping
{
var
blockDevices
[]
ec2
.
BlockDeviceMapping
var
blockDevices
[]
*
ec2
.
BlockDeviceMapping
for
_
,
blockDevice
:=
range
b
{
for
_
,
blockDevice
:=
range
b
{
blockDevices
=
append
(
blockDevices
,
ec2
.
BlockDeviceMapping
{
ebsBlockDevice
:=
&
ec2
.
EBSBlockDevice
{
DeviceName
:
blockDevice
.
DeviceName
,
SnapshotID
:
&
blockDevice
.
SnapshotId
,
VirtualName
:
blockDevice
.
VirtualName
,
Encrypted
:
&
blockDevice
.
Encrypted
,
SnapshotId
:
blockDevice
.
SnapshotId
,
IOPS
:
&
blockDevice
.
IOPS
,
VolumeType
:
blockDevice
.
VolumeType
,
VolumeType
:
&
blockDevice
.
VolumeType
,
VolumeSize
:
blockDevice
.
VolumeSize
,
VolumeSize
:
&
blockDevice
.
VolumeSize
,
DeleteOnTermination
:
blockDevice
.
DeleteOnTermination
,
DeleteOnTermination
:
&
blockDevice
.
DeleteOnTermination
,
IOPS
:
blockDevice
.
IOPS
,
}
NoDevice
:
blockDevice
.
NoDevice
,
mapping
:=
&
ec2
.
BlockDeviceMapping
{
Encrypted
:
blockDevice
.
Encrypted
,
EBS
:
ebsBlockDevice
,
})
DeviceName
:
&
blockDevice
.
DeviceName
,
VirtualName
:
&
blockDevice
.
VirtualName
,
}
if
blockDevice
.
NoDevice
{
mapping
.
NoDevice
=
aws
.
String
(
""
)
}
blockDevices
=
append
(
blockDevices
,
mapping
)
}
}
return
blockDevices
return
blockDevices
}
}
...
@@ -46,10 +55,10 @@ func (b *BlockDevices) Prepare(ctx *interpolate.Context) []error {
...
@@ -46,10 +55,10 @@ func (b *BlockDevices) Prepare(ctx *interpolate.Context) []error {
return
nil
return
nil
}
}
func
(
b
*
BlockDevices
)
BuildAMIDevices
()
[]
ec2
.
BlockDeviceMapping
{
func
(
b
*
BlockDevices
)
BuildAMIDevices
()
[]
*
ec2
.
BlockDeviceMapping
{
return
buildBlockDevices
(
b
.
AMIMappings
)
return
buildBlockDevices
(
b
.
AMIMappings
)
}
}
func
(
b
*
BlockDevices
)
BuildLaunchDevices
()
[]
ec2
.
BlockDeviceMapping
{
func
(
b
*
BlockDevices
)
BuildLaunchDevices
()
[]
*
ec2
.
BlockDeviceMapping
{
return
buildBlockDevices
(
b
.
LaunchMappings
)
return
buildBlockDevices
(
b
.
LaunchMappings
)
}
}
builder/amazon/common/block_device_test.go
View file @
74bcbfa8
package
common
package
common
import
(
import
(
"github.com/mitchellh/goamz/ec2"
"reflect"
"reflect"
"testing"
"testing"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
)
)
func
TestBlockDevice
(
t
*
testing
.
T
)
{
func
TestBlockDevice
(
t
*
testing
.
T
)
{
...
@@ -23,13 +25,16 @@ func TestBlockDevice(t *testing.T) {
...
@@ -23,13 +25,16 @@ func TestBlockDevice(t *testing.T) {
},
},
Result
:
&
ec2
.
BlockDeviceMapping
{
Result
:
&
ec2
.
BlockDeviceMapping
{
DeviceName
:
"/dev/sdb"
,
DeviceName
:
aws
.
String
(
"/dev/sdb"
),
VirtualName
:
"ephemeral0"
,
VirtualName
:
aws
.
String
(
"ephemeral0"
),
SnapshotId
:
"snap-1234"
,
EBS
:
&
ec2
.
EBSBlockDevice
{
VolumeType
:
"standard"
,
Encrypted
:
aws
.
Boolean
(
false
),
VolumeSize
:
8
,
SnapshotID
:
aws
.
String
(
"snap-1234"
),
DeleteOnTermination
:
true
,
VolumeType
:
aws
.
String
(
"standard"
),
IOPS
:
1000
,
VolumeSize
:
aws
.
Long
(
8
),
DeleteOnTermination
:
aws
.
Boolean
(
true
),
IOPS
:
aws
.
Long
(
1000
),
},
},
},
},
},
}
}
...
@@ -40,9 +45,9 @@ func TestBlockDevice(t *testing.T) {
...
@@ -40,9 +45,9 @@ func TestBlockDevice(t *testing.T) {
LaunchMappings
:
[]
BlockDevice
{
*
tc
.
Config
},
LaunchMappings
:
[]
BlockDevice
{
*
tc
.
Config
},
}
}
expected
:=
[]
ec2
.
BlockDeviceMapping
{
*
tc
.
Result
}
expected
:=
[]
*
ec2
.
BlockDeviceMapping
{
tc
.
Result
}
got
:=
blockDevices
.
BuildAMIDevices
()
if
!
reflect
.
DeepEqual
(
expected
,
blockDevices
.
BuildAMIDevices
()
)
{
if
!
reflect
.
DeepEqual
(
expected
,
got
)
{
t
.
Fatalf
(
"bad: %#v"
,
expected
)
t
.
Fatalf
(
"bad: %#v"
,
expected
)
}
}
...
...
builder/amazon/common/regions.go
0 → 100644
View file @
74bcbfa8
package
common
// IsValidRegion returns true if the supplied region is a valid AWS
// region and false if it's not.
func
ValidateRegion
(
region
string
)
bool
{
var
regions
=
[
11
]
string
{
"us-east-1"
,
"us-west-2"
,
"us-west-1"
,
"eu-west-1"
,
"eu-central-1"
,
"ap-southeast-1"
,
"ap-southeast-2"
,
"ap-northeast-1"
,
"sa-east-1"
,
"cn-north-1"
,
"us-gov-west-1"
}
for
_
,
valid
:=
range
regions
{
if
region
==
valid
{
return
true
}
}
return
false
}
builder/amazon/common/ssh.go
View file @
74bcbfa8
package
common
package
common
import
(
import
(
"golang.org/x/crypto/ssh"
"errors"
"errors"
"fmt"
"fmt"
"github.com/mitchellh/goamz/ec2"
"github.com/mitchellh/multistep"
"time"
"time"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"golang.org/x/crypto/ssh"
)
)
// SSHAddress returns a function that can be given to the SSH communicator
// SSHAddress returns a function that can be given to the SSH communicator
...
@@ -16,27 +17,29 @@ func SSHAddress(e *ec2.EC2, port int, private bool) func(multistep.StateBag) (st
...
@@ -16,27 +17,29 @@ func SSHAddress(e *ec2.EC2, port int, private bool) func(multistep.StateBag) (st
for
j
:=
0
;
j
<
2
;
j
++
{
for
j
:=
0
;
j
<
2
;
j
++
{
var
host
string
var
host
string
i
:=
state
.
Get
(
"instance"
)
.
(
*
ec2
.
Instance
)
i
:=
state
.
Get
(
"instance"
)
.
(
*
ec2
.
Instance
)
if
i
.
V
pcId
!=
""
{
if
i
.
V
PCID
!=
nil
&&
*
i
.
VPCID
!=
""
{
if
i
.
PublicI
p
Address
!=
""
&&
!
private
{
if
i
.
PublicI
PAddress
!=
nil
&&
*
i
.
PublicIP
Address
!=
""
&&
!
private
{
host
=
i
.
PublicIp
Address
host
=
*
i
.
PublicIP
Address
}
else
{
}
else
{
host
=
i
.
PrivateIp
Address
host
=
*
i
.
PrivateIP
Address
}
}
}
else
if
i
.
DNSName
!=
""
{
}
else
if
i
.
PublicDNSName
!=
nil
&&
*
i
.
Public
DNSName
!=
""
{
host
=
i
.
DNSName
host
=
*
i
.
Public
DNSName
}
}
if
host
!=
""
{
if
host
!=
""
{
return
fmt
.
Sprintf
(
"%s:%d"
,
host
,
port
),
nil
return
fmt
.
Sprintf
(
"%s:%d"
,
host
,
port
),
nil
}
}
r
,
err
:=
e
.
Instances
([]
string
{
i
.
InstanceId
},
ec2
.
NewFilter
())
r
,
err
:=
e
.
DescribeInstances
(
&
ec2
.
DescribeInstancesInput
{
InstanceIDs
:
[]
*
string
{
i
.
InstanceID
},
})
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
if
len
(
r
.
Reservations
)
==
0
||
len
(
r
.
Reservations
[
0
]
.
Instances
)
==
0
{
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
])
state
.
Put
(
"instance"
,
&
r
.
Reservations
[
0
]
.
Instances
[
0
])
...
...
builder/amazon/common/state.go
View file @
74bcbfa8
...
@@ -3,13 +3,15 @@ package common
...
@@ -3,13 +3,15 @@ package common
import
(
import
(
"errors"
"errors"
"fmt"
"fmt"
"github.com/mitchellh/goamz/ec2"
"github.com/mitchellh/multistep"
"log"
"log"
"net"
"net"
"os"
"os"
"strconv"
"strconv"
"time"
"time"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
)
)
// StateRefreshFunc is a function type used for StateChangeConf that is
// StateRefreshFunc is a function type used for StateChangeConf that is
...
@@ -36,9 +38,11 @@ type StateChangeConf struct {
...
@@ -36,9 +38,11 @@ type StateChangeConf struct {
// an AMI for state changes.
// an AMI for state changes.
func
AMIStateRefreshFunc
(
conn
*
ec2
.
EC2
,
imageId
string
)
StateRefreshFunc
{
func
AMIStateRefreshFunc
(
conn
*
ec2
.
EC2
,
imageId
string
)
StateRefreshFunc
{
return
func
()
(
interface
{},
string
,
error
)
{
return
func
()
(
interface
{},
string
,
error
)
{
resp
,
err
:=
conn
.
Images
([]
string
{
imageId
},
ec2
.
NewFilter
())
resp
,
err
:=
conn
.
DescribeImages
(
&
ec2
.
DescribeImagesInput
{
ImageIDs
:
[]
*
string
{
&
imageId
},
})
if
err
!=
nil
{
if
err
!=
nil
{
if
ec2err
,
ok
:=
err
.
(
*
ec2
.
Error
);
ok
&&
ec2err
.
Code
==
"InvalidAMIID.NotFound"
{
if
ec2err
,
ok
:=
err
.
(
*
aws
.
API
Error
);
ok
&&
ec2err
.
Code
==
"InvalidAMIID.NotFound"
{
// Set this to nil as if we didn't find anything.
// Set this to nil as if we didn't find anything.
resp
=
nil
resp
=
nil
}
else
if
isTransientNetworkError
(
err
)
{
}
else
if
isTransientNetworkError
(
err
)
{
...
@@ -57,7 +61,7 @@ func AMIStateRefreshFunc(conn *ec2.EC2, imageId string) StateRefreshFunc {
...
@@ -57,7 +61,7 @@ func AMIStateRefreshFunc(conn *ec2.EC2, imageId string) StateRefreshFunc {
}
}
i
:=
resp
.
Images
[
0
]
i
:=
resp
.
Images
[
0
]
return
i
,
i
.
State
,
nil
return
i
,
*
i
.
State
,
nil
}
}
}
}
...
@@ -65,9 +69,11 @@ func AMIStateRefreshFunc(conn *ec2.EC2, imageId string) StateRefreshFunc {
...
@@ -65,9 +69,11 @@ func AMIStateRefreshFunc(conn *ec2.EC2, imageId string) StateRefreshFunc {
// an EC2 instance.
// an EC2 instance.
func
InstanceStateRefreshFunc
(
conn
*
ec2
.
EC2
,
i
*
ec2
.
Instance
)
StateRefreshFunc
{
func
InstanceStateRefreshFunc
(
conn
*
ec2
.
EC2
,
i
*
ec2
.
Instance
)
StateRefreshFunc
{
return
func
()
(
interface
{},
string
,
error
)
{
return
func
()
(
interface
{},
string
,
error
)
{
resp
,
err
:=
conn
.
Instances
([]
string
{
i
.
InstanceId
},
ec2
.
NewFilter
())
resp
,
err
:=
conn
.
DescribeInstances
(
&
ec2
.
DescribeInstancesInput
{
InstanceIDs
:
[]
*
string
{
i
.
InstanceID
},
})
if
err
!=
nil
{
if
err
!=
nil
{
if
ec2err
,
ok
:=
err
.
(
*
ec2
.
Error
);
ok
&&
ec2err
.
Code
==
"InvalidInstanceID.NotFound"
{
if
ec2err
,
ok
:=
err
.
(
*
aws
.
API
Error
);
ok
&&
ec2err
.
Code
==
"InvalidInstanceID.NotFound"
{
// Set this to nil as if we didn't find anything.
// Set this to nil as if we didn't find anything.
resp
=
nil
resp
=
nil
}
else
if
isTransientNetworkError
(
err
)
{
}
else
if
isTransientNetworkError
(
err
)
{
...
@@ -85,8 +91,8 @@ func InstanceStateRefreshFunc(conn *ec2.EC2, i *ec2.Instance) StateRefreshFunc {
...
@@ -85,8 +91,8 @@ func InstanceStateRefreshFunc(conn *ec2.EC2, i *ec2.Instance) StateRefreshFunc {
return
nil
,
""
,
nil
return
nil
,
""
,
nil
}
}
i
=
&
resp
.
Reservations
[
0
]
.
Instances
[
0
]
i
=
resp
.
Reservations
[
0
]
.
Instances
[
0
]
return
i
,
i
.
State
.
Name
,
nil
return
i
,
*
i
.
State
.
Name
,
nil
}
}
}
}
...
@@ -94,9 +100,12 @@ func InstanceStateRefreshFunc(conn *ec2.EC2, i *ec2.Instance) StateRefreshFunc {
...
@@ -94,9 +100,12 @@ func InstanceStateRefreshFunc(conn *ec2.EC2, i *ec2.Instance) StateRefreshFunc {
// a spot request for state changes.
// a spot request for state changes.
func
SpotRequestStateRefreshFunc
(
conn
*
ec2
.
EC2
,
spotRequestId
string
)
StateRefreshFunc
{
func
SpotRequestStateRefreshFunc
(
conn
*
ec2
.
EC2
,
spotRequestId
string
)
StateRefreshFunc
{
return
func
()
(
interface
{},
string
,
error
)
{
return
func
()
(
interface
{},
string
,
error
)
{
resp
,
err
:=
conn
.
DescribeSpotRequests
([]
string
{
spotRequestId
},
ec2
.
NewFilter
())
resp
,
err
:=
conn
.
DescribeSpotInstanceRequests
(
&
ec2
.
DescribeSpotInstanceRequestsInput
{
SpotInstanceRequestIDs
:
[]
*
string
{
&
spotRequestId
},
})
if
err
!=
nil
{
if
err
!=
nil
{
if
ec2err
,
ok
:=
err
.
(
*
ec2
.
Error
);
ok
&&
ec2err
.
Code
==
"InvalidSpotInstanceRequestID.NotFound"
{
if
ec2err
,
ok
:=
err
.
(
*
aws
.
API
Error
);
ok
&&
ec2err
.
Code
==
"InvalidSpotInstanceRequestID.NotFound"
{
// Set this to nil as if we didn't find anything.
// Set this to nil as if we didn't find anything.
resp
=
nil
resp
=
nil
}
else
if
isTransientNetworkError
(
err
)
{
}
else
if
isTransientNetworkError
(
err
)
{
...
@@ -108,14 +117,14 @@ func SpotRequestStateRefreshFunc(conn *ec2.EC2, spotRequestId string) StateRefre
...
@@ -108,14 +117,14 @@ func SpotRequestStateRefreshFunc(conn *ec2.EC2, spotRequestId string) StateRefre
}
}
}
}
if
resp
==
nil
||
len
(
resp
.
Spot
RequestResul
ts
)
==
0
{
if
resp
==
nil
||
len
(
resp
.
Spot
InstanceReques
ts
)
==
0
{
// Sometimes AWS has consistency issues and doesn't see the
// Sometimes AWS has consistency issues and doesn't see the
// SpotRequest. Return an empty state.
// SpotRequest. Return an empty state.
return
nil
,
""
,
nil
return
nil
,
""
,
nil
}
}
i
:=
resp
.
Spot
RequestResul
ts
[
0
]
i
:=
resp
.
Spot
InstanceReques
ts
[
0
]
return
i
,
i
.
State
,
nil
return
i
,
*
i
.
State
,
nil
}
}
}
}
...
...
builder/amazon/common/step_ami_region_copy.go
View file @
74bcbfa8
...
@@ -2,14 +2,17 @@ package common
...
@@ -2,14 +2,17 @@ package common
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/aws"
"github.com/mitchellh/goamz/ec2"
"sync"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
"sync"
)
)
type
StepAMIRegionCopy
struct
{
type
StepAMIRegionCopy
struct
{
AccessConfig
*
AccessConfig
Regions
[]
string
Regions
[]
string
}
}
...
@@ -17,7 +20,7 @@ func (s *StepAMIRegionCopy) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -17,7 +20,7 @@ func (s *StepAMIRegionCopy) Run(state multistep.StateBag) multistep.StepAction {
ec2conn
:=
state
.
Get
(
"ec2"
)
.
(
*
ec2
.
EC2
)
ec2conn
:=
state
.
Get
(
"ec2"
)
.
(
*
ec2
.
EC2
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
amis
:=
state
.
Get
(
"amis"
)
.
(
map
[
string
]
string
)
amis
:=
state
.
Get
(
"amis"
)
.
(
map
[
string
]
string
)
ami
:=
amis
[
ec2conn
.
Region
.
Name
]
ami
:=
amis
[
ec2conn
.
Config
.
Region
]
if
len
(
s
.
Regions
)
==
0
{
if
len
(
s
.
Regions
)
==
0
{
return
multistep
.
ActionContinue
return
multistep
.
ActionContinue
...
@@ -34,8 +37,7 @@ func (s *StepAMIRegionCopy) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -34,8 +37,7 @@ func (s *StepAMIRegionCopy) Run(state multistep.StateBag) multistep.StepAction {
go
func
(
region
string
)
{
go
func
(
region
string
)
{
defer
wg
.
Done
()
defer
wg
.
Done
()
id
,
err
:=
amiRegionCopy
(
state
,
ec2conn
.
Auth
,
ami
,
id
,
err
:=
amiRegionCopy
(
state
,
s
.
AccessConfig
,
ami
,
region
,
ec2conn
.
Config
.
Region
)
aws
.
Regions
[
region
],
ec2conn
.
Region
)
lock
.
Lock
()
lock
.
Lock
()
defer
lock
.
Unlock
()
defer
lock
.
Unlock
()
...
@@ -67,32 +69,38 @@ func (s *StepAMIRegionCopy) Cleanup(state multistep.StateBag) {
...
@@ -67,32 +69,38 @@ func (s *StepAMIRegionCopy) Cleanup(state multistep.StateBag) {
// amiRegionCopy does a copy for the given AMI to the target region and
// amiRegionCopy does a copy for the given AMI to the target region and
// returns the resulting ID or error.
// returns the resulting ID or error.
func
amiRegionCopy
(
state
multistep
.
StateBag
,
auth
aws
.
Auth
,
imageId
string
,
func
amiRegionCopy
(
state
multistep
.
StateBag
,
config
*
AccessConfig
,
imageId
string
,
target
aws
.
Region
,
source
aws
.
Region
)
(
string
,
error
)
{
target
string
,
source
string
)
(
string
,
error
)
{
// Connect to the region where the AMI will be copied to
// Connect to the region where the AMI will be copied to
regionconn
:=
ec2
.
New
(
auth
,
target
)
awsConfig
,
err
:=
config
.
Config
()
resp
,
err
:=
regionconn
.
CopyImage
(
&
ec2
.
CopyImage
{
if
err
!=
nil
{
SourceRegion
:
source
.
Name
,
return
""
,
err
SourceImageId
:
imageId
,
}
awsConfig
.
Region
=
target
regionconn
:=
ec2
.
New
(
awsConfig
)
resp
,
err
:=
regionconn
.
CopyImage
(
&
ec2
.
CopyImageInput
{
SourceRegion
:
&
source
,
SourceImageID
:
&
imageId
,
})
})
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"Error Copying AMI (%s) to region (%s): %s"
,
return
""
,
fmt
.
Errorf
(
"Error Copying AMI (%s) to region (%s): %s"
,
imageId
,
target
.
Name
,
err
)
imageId
,
target
,
err
)
}
}
stateChange
:=
StateChangeConf
{
stateChange
:=
StateChangeConf
{
Pending
:
[]
string
{
"pending"
},
Pending
:
[]
string
{
"pending"
},
Target
:
"available"
,
Target
:
"available"
,
Refresh
:
AMIStateRefreshFunc
(
regionconn
,
resp
.
ImageId
),
Refresh
:
AMIStateRefreshFunc
(
regionconn
,
*
resp
.
ImageID
),
StepState
:
state
,
StepState
:
state
,
}
}
if
_
,
err
:=
WaitForState
(
&
stateChange
);
err
!=
nil
{
if
_
,
err
:=
WaitForState
(
&
stateChange
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"Error waiting for AMI (%s) in region (%s): %s"
,
return
""
,
fmt
.
Errorf
(
"Error waiting for AMI (%s) in region (%s): %s"
,
resp
.
ImageId
,
target
.
Name
,
err
)
*
resp
.
ImageID
,
target
,
err
)
}
}
return
resp
.
ImageId
,
nil
return
*
resp
.
ImageID
,
nil
}
}
builder/amazon/common/step_create_tags.go
View file @
74bcbfa8
...
@@ -2,8 +2,9 @@ package common
...
@@ -2,8 +2,9 @@ package common
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/aws"
"github.com/mitchellh/goamz/ec2"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
)
)
...
@@ -21,14 +22,20 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -21,14 +22,20 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction {
for
region
,
ami
:=
range
amis
{
for
region
,
ami
:=
range
amis
{
ui
.
Say
(
fmt
.
Sprintf
(
"Adding tags to AMI (%s)..."
,
ami
))
ui
.
Say
(
fmt
.
Sprintf
(
"Adding tags to AMI (%s)..."
,
ami
))
var
ec2Tags
[]
ec2
.
Tag
var
ec2Tags
[]
*
ec2
.
Tag
for
key
,
value
:=
range
s
.
Tags
{
for
key
,
value
:=
range
s
.
Tags
{
ui
.
Message
(
fmt
.
Sprintf
(
"Adding tag:
\"
%s
\"
:
\"
%s
\"
"
,
key
,
value
))
ui
.
Message
(
fmt
.
Sprintf
(
"Adding tag:
\"
%s
\"
:
\"
%s
\"
"
,
key
,
value
))
ec2Tags
=
append
(
ec2Tags
,
ec2
.
Tag
{
key
,
value
})
ec2Tags
=
append
(
ec2Tags
,
&
ec2
.
Tag
{
Key
:
&
key
,
Value
:
&
value
})
}
}
regionconn
:=
ec2
.
New
(
ec2conn
.
Auth
,
aws
.
Regions
[
region
])
regionconn
:=
ec2
.
New
(
&
aws
.
Config
{
_
,
err
:=
regionconn
.
CreateTags
([]
string
{
ami
},
ec2Tags
)
Credentials
:
ec2conn
.
Config
.
Credentials
,
Region
:
region
,
})
_
,
err
:=
regionconn
.
CreateTags
(
&
ec2
.
CreateTagsInput
{
Resources
:
[]
*
string
{
&
ami
},
Tags
:
ec2Tags
,
})
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error adding tags to AMI (%s): %s"
,
ami
,
err
)
err
:=
fmt
.
Errorf
(
"Error adding tags to AMI (%s): %s"
,
ami
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
...
...
builder/amazon/common/step_key_pair.go
View file @
74bcbfa8
...
@@ -2,12 +2,13 @@ package common
...
@@ -2,12 +2,13 @@ package common
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"io/ioutil"
"io/ioutil"
"os"
"os"
"runtime"
"runtime"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
)
)
type
StepKeyPair
struct
{
type
StepKeyPair
struct
{
...
@@ -39,7 +40,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -39,7 +40,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
fmt
.
Sprintf
(
"Creating temporary keypair: %s"
,
s
.
KeyPairName
))
ui
.
Say
(
fmt
.
Sprintf
(
"Creating temporary keypair: %s"
,
s
.
KeyPairName
))
keyResp
,
err
:=
ec2conn
.
CreateKeyPair
(
s
.
KeyPairName
)
keyResp
,
err
:=
ec2conn
.
CreateKeyPair
(
&
ec2
.
CreateKeyPairInput
{
KeyName
:
&
s
.
KeyPairName
}
)
if
err
!=
nil
{
if
err
!=
nil
{
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"Error creating temporary keypair: %s"
,
err
))
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"Error creating temporary keypair: %s"
,
err
))
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
...
@@ -50,7 +51,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -50,7 +51,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
// Set some state data for use in future steps
// Set some state data for use in future steps
state
.
Put
(
"keyPair"
,
s
.
keyName
)
state
.
Put
(
"keyPair"
,
s
.
keyName
)
state
.
Put
(
"privateKey"
,
keyResp
.
KeyMaterial
)
state
.
Put
(
"privateKey"
,
*
keyResp
.
KeyMaterial
)
// If we're in debug mode, output the private key to the working
// If we're in debug mode, output the private key to the working
// directory.
// directory.
...
@@ -64,7 +65,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -64,7 +65,7 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
defer
f
.
Close
()
defer
f
.
Close
()
// Write the key out
// Write the key out
if
_
,
err
:=
f
.
Write
([]
byte
(
keyResp
.
KeyMaterial
));
err
!=
nil
{
if
_
,
err
:=
f
.
Write
([]
byte
(
*
keyResp
.
KeyMaterial
));
err
!=
nil
{
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"Error saving debug key: %s"
,
err
))
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"Error saving debug key: %s"
,
err
))
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
...
@@ -91,7 +92,7 @@ func (s *StepKeyPair) Cleanup(state multistep.StateBag) {
...
@@ -91,7 +92,7 @@ func (s *StepKeyPair) Cleanup(state multistep.StateBag) {
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
"Deleting temporary keypair..."
)
ui
.
Say
(
"Deleting temporary keypair..."
)
_
,
err
:=
ec2conn
.
DeleteKeyPair
(
s
.
keyName
)
_
,
err
:=
ec2conn
.
DeleteKeyPair
(
&
ec2
.
DeleteKeyPairInput
{
KeyName
:
&
s
.
keyName
}
)
if
err
!=
nil
{
if
err
!=
nil
{
ui
.
Error
(
fmt
.
Sprintf
(
ui
.
Error
(
fmt
.
Sprintf
(
"Error cleaning up keypair. Please delete the key manually: %s"
,
s
.
keyName
))
"Error cleaning up keypair. Please delete the key manually: %s"
,
s
.
keyName
))
...
...
builder/amazon/common/step_modify_ami_attributes.go
View file @
74bcbfa8
...
@@ -2,8 +2,9 @@ package common
...
@@ -2,8 +2,9 @@ package common
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/aws"
"github.com/mitchellh/goamz/ec2"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
)
)
...
@@ -34,37 +35,53 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc
...
@@ -34,37 +35,53 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc
// Construct the modify image attribute requests we're going to make.
// Construct the modify image attribute requests we're going to make.
// We need to make each separately since the EC2 API only allows changing
// We need to make each separately since the EC2 API only allows changing
// one type at a kind currently.
// one type at a kind currently.
options
:=
make
(
map
[
string
]
*
ec2
.
ModifyImageAttribute
)
options
:=
make
(
map
[
string
]
*
ec2
.
ModifyImageAttribute
Input
)
if
s
.
Description
!=
""
{
if
s
.
Description
!=
""
{
options
[
"description"
]
=
&
ec2
.
ModifyImageAttribute
{
options
[
"description"
]
=
&
ec2
.
ModifyImageAttribute
Input
{
Description
:
s
.
Description
,
Description
:
&
ec2
.
AttributeValue
{
Value
:
&
s
.
Description
}
,
}
}
}
}
if
len
(
s
.
Groups
)
>
0
{
if
len
(
s
.
Groups
)
>
0
{
options
[
"groups"
]
=
&
ec2
.
ModifyImageAttribute
{
groups
:=
make
([]
*
string
,
len
(
s
.
Groups
))
AddGroups
:
s
.
Groups
,
for
i
,
g
:=
range
s
.
Groups
{
groups
[
i
]
=
&
g
}
options
[
"groups"
]
=
&
ec2
.
ModifyImageAttributeInput
{
UserGroups
:
groups
,
}
}
}
}
if
len
(
s
.
Users
)
>
0
{
if
len
(
s
.
Users
)
>
0
{
options
[
"users"
]
=
&
ec2
.
ModifyImageAttribute
{
users
:=
make
([]
*
string
,
len
(
s
.
Users
))
AddUsers
:
s
.
Users
,
for
i
,
u
:=
range
s
.
Users
{
users
[
i
]
=
&
u
}
options
[
"users"
]
=
&
ec2
.
ModifyImageAttributeInput
{
UserIDs
:
users
,
}
}
}
}
if
len
(
s
.
ProductCodes
)
>
0
{
if
len
(
s
.
ProductCodes
)
>
0
{
options
[
"product codes"
]
=
&
ec2
.
ModifyImageAttribute
{
codes
:=
make
([]
*
string
,
len
(
s
.
ProductCodes
))
ProductCodes
:
s
.
ProductCodes
,
for
i
,
c
:=
range
s
.
ProductCodes
{
codes
[
i
]
=
&
c
}
options
[
"product codes"
]
=
&
ec2
.
ModifyImageAttributeInput
{
ProductCodes
:
codes
,
}
}
}
}
for
region
,
ami
:=
range
amis
{
for
region
,
ami
:=
range
amis
{
ui
.
Say
(
fmt
.
Sprintf
(
"Modifying attributes on AMI (%s)..."
,
ami
))
ui
.
Say
(
fmt
.
Sprintf
(
"Modifying attributes on AMI (%s)..."
,
ami
))
regionconn
:=
ec2
.
New
(
ec2conn
.
Auth
,
aws
.
Regions
[
region
])
regionconn
:=
ec2
.
New
(
&
aws
.
Config
{
for
name
,
opts
:=
range
options
{
Credentials
:
ec2conn
.
Config
.
Credentials
,
Region
:
region
,
})
for
name
,
input
:=
range
options
{
ui
.
Message
(
fmt
.
Sprintf
(
"Modifying: %s"
,
name
))
ui
.
Message
(
fmt
.
Sprintf
(
"Modifying: %s"
,
name
))
_
,
err
:=
regionconn
.
ModifyImageAttribute
(
ami
,
opts
)
input
.
ImageID
=
&
ami
_
,
err
:=
regionconn
.
ModifyImageAttribute
(
input
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error modify AMI attributes: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error modify AMI attributes: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
...
...
builder/amazon/common/step_run_source_instance.go
View file @
74bcbfa8
...
@@ -7,7 +7,9 @@ import (
...
@@ -7,7 +7,9 @@ import (
"strconv"
"strconv"
"time"
"time"
"github.com/mitchellh/goamz/ec2"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
)
)
...
@@ -29,15 +31,20 @@ type StepRunSourceInstance struct {
...
@@ -29,15 +31,20 @@ type StepRunSourceInstance struct {
UserDataFile
string
UserDataFile
string
instance
*
ec2
.
Instance
instance
*
ec2
.
Instance
spotRequest
*
ec2
.
Spot
RequestResul
t
spotRequest
*
ec2
.
Spot
InstanceReques
t
}
}
func
(
s
*
StepRunSourceInstance
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
func
(
s
*
StepRunSourceInstance
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
ec2conn
:=
state
.
Get
(
"ec2"
)
.
(
*
ec2
.
EC2
)
ec2conn
:=
state
.
Get
(
"ec2"
)
.
(
*
ec2
.
EC2
)
keyName
:=
state
.
Get
(
"keyPair"
)
.
(
string
)
keyName
:=
state
.
Get
(
"keyPair"
)
.
(
string
)
s
ecurityGroupIds
:=
state
.
Get
(
"securityGroupIds"
)
.
([]
string
)
tempS
ecurityGroupIds
:=
state
.
Get
(
"securityGroupIds"
)
.
([]
string
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
securityGroupIds
:=
make
([]
*
string
,
len
(
tempSecurityGroupIds
))
for
i
,
sg
:=
range
tempSecurityGroupIds
{
securityGroupIds
[
i
]
=
&
sg
}
userData
:=
s
.
UserData
userData
:=
s
.
UserData
if
s
.
UserDataFile
!=
""
{
if
s
.
UserDataFile
!=
""
{
contents
,
err
:=
ioutil
.
ReadFile
(
s
.
UserDataFile
)
contents
,
err
:=
ioutil
.
ReadFile
(
s
.
UserDataFile
)
...
@@ -49,13 +56,10 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -49,13 +56,10 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
userData
=
string
(
contents
)
userData
=
string
(
contents
)
}
}
securityGroups
:=
make
([]
ec2
.
SecurityGroup
,
len
(
securityGroupIds
))
for
n
,
securityGroupId
:=
range
securityGroupIds
{
securityGroups
[
n
]
=
ec2
.
SecurityGroup
{
Id
:
securityGroupId
}
}
ui
.
Say
(
"Launching a source AWS instance..."
)
ui
.
Say
(
"Launching a source AWS instance..."
)
imageResp
,
err
:=
ec2conn
.
Images
([]
string
{
s
.
SourceAMI
},
ec2
.
NewFilter
())
imageResp
,
err
:=
ec2conn
.
DescribeImages
(
&
ec2
.
DescribeImagesInput
{
ImageIDs
:
[]
*
string
{
&
s
.
SourceAMI
},
})
if
err
!=
nil
{
if
err
!=
nil
{
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"There was a problem with the source AMI: %s"
,
err
))
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"There was a problem with the source AMI: %s"
,
err
))
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
...
@@ -66,11 +70,11 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -66,11 +70,11 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
if
s
.
ExpectedRootDevice
!=
""
&&
imageResp
.
Images
[
0
]
.
RootDeviceType
!=
s
.
ExpectedRootDevice
{
if
s
.
ExpectedRootDevice
!=
""
&&
*
imageResp
.
Images
[
0
]
.
RootDeviceType
!=
s
.
ExpectedRootDevice
{
state
.
Put
(
"error"
,
fmt
.
Errorf
(
state
.
Put
(
"error"
,
fmt
.
Errorf
(
"The provided source AMI has an invalid root device type.
\n
"
+
"The provided source AMI has an invalid root device type.
\n
"
+
"Expected '%s', got '%s'."
,
"Expected '%s', got '%s'."
,
s
.
ExpectedRootDevice
,
imageResp
.
Images
[
0
]
.
RootDeviceType
))
s
.
ExpectedRootDevice
,
*
imageResp
.
Images
[
0
]
.
RootDeviceType
))
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
...
@@ -82,11 +86,11 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -82,11 +86,11 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
// Detect the spot price
// Detect the spot price
startTime
:=
time
.
Now
()
.
Add
(
-
1
*
time
.
Hour
)
startTime
:=
time
.
Now
()
.
Add
(
-
1
*
time
.
Hour
)
resp
,
err
:=
ec2conn
.
DescribeSpotPriceHistory
(
&
ec2
.
DescribeSpotPriceHistory
{
resp
,
err
:=
ec2conn
.
DescribeSpotPriceHistory
(
&
ec2
.
DescribeSpotPriceHistory
Input
{
InstanceType
:
[]
string
{
s
.
InstanceType
},
InstanceType
s
:
[]
*
string
{
&
s
.
InstanceType
},
ProductDescription
:
[]
string
{
s
.
SpotPriceProduct
},
ProductDescription
s
:
[]
*
string
{
&
s
.
SpotPriceProduct
},
AvailabilityZone
:
s
.
AvailabilityZone
,
AvailabilityZone
:
&
s
.
AvailabilityZone
,
StartTime
:
startTime
,
StartTime
:
&
startTime
,
})
})
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error finding spot price: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error finding spot price: %s"
,
err
)
...
@@ -96,9 +100,9 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -96,9 +100,9 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
}
}
var
price
float64
var
price
float64
for
_
,
history
:=
range
resp
.
History
{
for
_
,
history
:=
range
resp
.
SpotPrice
History
{
log
.
Printf
(
"[INFO] Candidate spot price: %s"
,
history
.
SpotPrice
)
log
.
Printf
(
"[INFO] Candidate spot price: %s"
,
*
history
.
SpotPrice
)
current
,
err
:=
strconv
.
ParseFloat
(
history
.
SpotPrice
,
64
)
current
,
err
:=
strconv
.
ParseFloat
(
*
history
.
SpotPrice
,
64
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Printf
(
"[ERR] Error parsing spot price: %s"
,
err
)
log
.
Printf
(
"[ERR] Error parsing spot price: %s"
,
err
)
continue
continue
...
@@ -120,20 +124,33 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -120,20 +124,33 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
var
instanceId
string
var
instanceId
string
if
spotPrice
==
""
{
if
spotPrice
==
""
{
runOpts
:=
&
ec2
.
RunInstances
{
runOpts
:=
&
ec2
.
RunInstancesInput
{
KeyName
:
keyName
,
KeyName
:
&
keyName
,
ImageId
:
s
.
SourceAMI
,
ImageID
:
&
s
.
SourceAMI
,
InstanceType
:
s
.
InstanceType
,
InstanceType
:
&
s
.
InstanceType
,
UserData
:
[]
byte
(
userData
),
UserData
:
&
userData
,
MinCount
:
0
,
MaxCount
:
aws
.
Long
(
1
),
MaxCount
:
0
,
MinCount
:
aws
.
Long
(
1
),
SecurityGroups
:
securityGroups
,
IAMInstanceProfile
:
&
ec2
.
IAMInstanceProfileSpecification
{
Name
:
&
s
.
IamInstanceProfile
},
IamInstanceProfile
:
s
.
IamInstanceProfile
,
BlockDeviceMappings
:
s
.
BlockDevices
.
BuildLaunchDevices
(),
SubnetId
:
s
.
SubnetId
,
Placement
:
&
ec2
.
Placement
{
AvailabilityZone
:
&
s
.
AvailabilityZone
},
AssociatePublicIpAddress
:
s
.
AssociatePublicIpAddress
,
}
BlockDevices
:
s
.
BlockDevices
.
BuildLaunchDevices
(),
AvailZone
:
s
.
AvailabilityZone
,
if
s
.
SubnetId
!=
""
&&
s
.
AssociatePublicIpAddress
{
runOpts
.
NetworkInterfaces
=
[]
*
ec2
.
InstanceNetworkInterfaceSpecification
{
&
ec2
.
InstanceNetworkInterfaceSpecification
{
DeviceIndex
:
aws
.
Long
(
0
),
AssociatePublicIPAddress
:
&
s
.
AssociatePublicIpAddress
,
SubnetID
:
&
s
.
SubnetId
,
Groups
:
securityGroupIds
,
DeleteOnTermination
:
aws
.
Boolean
(
true
),
},
}
}
else
{
runOpts
.
SubnetID
=
&
s
.
SubnetId
runOpts
.
SecurityGroupIDs
=
securityGroupIds
}
}
runResp
,
err
:=
ec2conn
.
RunInstances
(
runOpts
)
runResp
,
err
:=
ec2conn
.
RunInstances
(
runOpts
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error launching source instance: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error launching source instance: %s"
,
err
)
...
@@ -141,26 +158,29 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -141,26 +158,29 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
instanceId
=
runResp
.
Instances
[
0
]
.
InstanceId
instanceId
=
*
runResp
.
Instances
[
0
]
.
InstanceID
}
else
{
}
else
{
ui
.
Message
(
fmt
.
Sprintf
(
ui
.
Message
(
fmt
.
Sprintf
(
"Requesting spot instance '%s' for: %s"
,
"Requesting spot instance '%s' for: %s"
,
s
.
InstanceType
,
spotPrice
))
s
.
InstanceType
,
spotPrice
))
runOpts
:=
&
ec2
.
RequestSpotInstances
{
runSpotResp
,
err
:=
ec2conn
.
RequestSpotInstances
(
&
ec2
.
RequestSpotInstancesInput
{
SpotPrice
:
spotPrice
,
SpotPrice
:
&
spotPrice
,
KeyName
:
keyName
,
LaunchSpecification
:
&
ec2
.
RequestSpotLaunchSpecification
{
ImageId
:
s
.
SourceAMI
,
KeyName
:
&
keyName
,
InstanceType
:
s
.
InstanceType
,
ImageID
:
&
s
.
SourceAMI
,
UserData
:
[]
byte
(
userData
),
InstanceType
:
&
s
.
InstanceType
,
SecurityGroups
:
securityGroups
,
UserData
:
&
userData
,
IamInstanceProfile
:
s
.
IamInstanceProfile
,
SecurityGroupIDs
:
securityGroupIds
,
SubnetId
:
s
.
SubnetId
,
IAMInstanceProfile
:
&
ec2
.
IAMInstanceProfileSpecification
{
Name
:
&
s
.
IamInstanceProfile
},
AssociatePublicIpAddress
:
s
.
AssociatePublicIpAddress
,
SubnetID
:
&
s
.
SubnetId
,
BlockDevices
:
s
.
BlockDevices
.
BuildLaunchDevices
(),
NetworkInterfaces
:
[]
*
ec2
.
InstanceNetworkInterfaceSpecification
{
AvailZone
:
s
.
AvailabilityZone
,
&
ec2
.
InstanceNetworkInterfaceSpecification
{
AssociatePublicIPAddress
:
&
s
.
AssociatePublicIpAddress
},
}
},
runSpotResp
,
err
:=
ec2conn
.
RequestSpotInstances
(
runOpts
)
Placement
:
&
ec2
.
SpotPlacement
{
AvailabilityZone
:
&
s
.
AvailabilityZone
},
BlockDeviceMappings
:
s
.
BlockDevices
.
BuildLaunchDevices
(),
},
})
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error launching source spot instance: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error launching source spot instance: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
...
@@ -168,54 +188,57 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -168,54 +188,57 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
s
.
spotRequest
=
&
runSpotResp
.
SpotRequestResul
ts
[
0
]
s
.
spotRequest
=
runSpotResp
.
SpotInstanceReques
ts
[
0
]
spotRequestId
:=
s
.
spotRequest
.
Spot
RequestId
spotRequestId
:=
s
.
spotRequest
.
Spot
InstanceRequestID
ui
.
Message
(
fmt
.
Sprintf
(
"Waiting for spot request (%s) to become active..."
,
spotRequestId
))
ui
.
Message
(
fmt
.
Sprintf
(
"Waiting for spot request (%s) to become active..."
,
*
spotRequestId
))
stateChange
:=
StateChangeConf
{
stateChange
:=
StateChangeConf
{
Pending
:
[]
string
{
"open"
},
Pending
:
[]
string
{
"open"
},
Target
:
"active"
,
Target
:
"active"
,
Refresh
:
SpotRequestStateRefreshFunc
(
ec2conn
,
spotRequestId
),
Refresh
:
SpotRequestStateRefreshFunc
(
ec2conn
,
*
spotRequestId
),
StepState
:
state
,
StepState
:
state
,
}
}
_
,
err
=
WaitForState
(
&
stateChange
)
_
,
err
=
WaitForState
(
&
stateChange
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error waiting for spot request (%s) to become ready: %s"
,
spotRequestId
,
err
)
err
:=
fmt
.
Errorf
(
"Error waiting for spot request (%s) to become ready: %s"
,
*
spotRequestId
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
spotResp
,
err
:=
ec2conn
.
DescribeSpotRequests
([]
string
{
spotRequestId
},
nil
)
spotResp
,
err
:=
ec2conn
.
DescribeSpotInstanceRequests
(
&
ec2
.
DescribeSpotInstanceRequestsInput
{
SpotInstanceRequestIDs
:
[]
*
string
{
spotRequestId
},
})
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error finding spot request (%s): %s"
,
spotRequestId
,
err
)
err
:=
fmt
.
Errorf
(
"Error finding spot request (%s): %s"
,
*
spotRequestId
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
instanceId
=
spotResp
.
SpotRequestResults
[
0
]
.
InstanceId
instanceId
=
*
spotResp
.
SpotInstanceRequests
[
0
]
.
InstanceID
}
}
instanceResp
,
instanceErr
:=
ec2conn
.
Instances
([]
string
{
instanceId
},
nil
)
instanceResp
,
err
:=
ec2conn
.
DescribeInstances
(
&
ec2
.
DescribeInstancesInput
{
InstanceIDs
:
[]
*
string
{
&
instanceId
}})
for
i
:=
0
;
i
<
10
;
i
++
{
for
i
:=
0
;
i
<
10
;
i
++
{
if
instanceErr
==
nil
{
if
err
==
nil
{
err
=
instanceErr
break
break
}
}
time
.
Sleep
(
3
*
time
.
Second
)
time
.
Sleep
(
3
*
time
.
Second
)
instanceResp
,
err
=
ec2conn
.
Instances
([]
string
{
instanceId
},
nil
)
instanceResp
,
err
=
ec2conn
.
DescribeInstances
(
&
ec2
.
DescribeInstancesInput
{
InstanceIDs
:
[]
*
string
{
&
instanceId
}})
}
}
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error finding source instance (%s): %s"
,
instanceId
,
err
)
err
:=
fmt
.
Errorf
(
"Error finding source instance (%s): %s"
,
instanceId
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
s
.
instance
=
&
instanceResp
.
Reservations
[
0
]
.
Instances
[
0
]
s
.
instance
=
instanceResp
.
Reservations
[
0
]
.
Instances
[
0
]
ui
.
Message
(
fmt
.
Sprintf
(
"Instance ID: %s"
,
s
.
instance
.
InstanceId
))
ui
.
Message
(
fmt
.
Sprintf
(
"Instance ID: %s"
,
*
s
.
instance
.
InstanceID
))
ui
.
Say
(
fmt
.
Sprintf
(
"Waiting for instance (%s) to become ready..."
,
s
.
instance
.
InstanceId
))
ui
.
Say
(
fmt
.
Sprintf
(
"Waiting for instance (%s) to become ready..."
,
*
s
.
instance
.
InstanceID
))
stateChange
:=
StateChangeConf
{
stateChange
:=
StateChangeConf
{
Pending
:
[]
string
{
"pending"
},
Pending
:
[]
string
{
"pending"
},
Target
:
"running"
,
Target
:
"running"
,
...
@@ -224,7 +247,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -224,7 +247,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
}
}
latestInstance
,
err
:=
WaitForState
(
&
stateChange
)
latestInstance
,
err
:=
WaitForState
(
&
stateChange
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error waiting for instance (%s) to become ready: %s"
,
s
.
instance
.
InstanceId
,
err
)
err
:=
fmt
.
Errorf
(
"Error waiting for instance (%s) to become ready: %s"
,
*
s
.
instance
.
InstanceID
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
...
@@ -232,29 +255,32 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
...
@@ -232,29 +255,32 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
s
.
instance
=
latestInstance
.
(
*
ec2
.
Instance
)
s
.
instance
=
latestInstance
.
(
*
ec2
.
Instance
)
ec2Tags
:=
make
([]
ec2
.
Tag
,
1
,
len
(
s
.
Tags
)
+
1
)
ec2Tags
:=
make
([]
*
ec2
.
Tag
,
1
,
len
(
s
.
Tags
)
+
1
)
ec2Tags
[
0
]
=
ec2
.
Tag
{
"Name"
,
"Packer Builder"
}
ec2Tags
[
0
]
=
&
ec2
.
Tag
{
Key
:
aws
.
String
(
"Name"
),
Value
:
aws
.
String
(
"Packer Builder"
)
}
for
k
,
v
:=
range
s
.
Tags
{
for
k
,
v
:=
range
s
.
Tags
{
ec2Tags
=
append
(
ec2Tags
,
ec2
.
Tag
{
k
,
v
})
ec2Tags
=
append
(
ec2Tags
,
&
ec2
.
Tag
{
Key
:
&
k
,
Value
:
&
v
})
}
}
_
,
err
=
ec2conn
.
CreateTags
([]
string
{
s
.
instance
.
InstanceId
},
ec2Tags
)
_
,
err
=
ec2conn
.
CreateTags
(
&
ec2
.
CreateTagsInput
{
Tags
:
ec2Tags
,
Resources
:
[]
*
string
{
s
.
instance
.
InstanceID
},
})
if
err
!=
nil
{
if
err
!=
nil
{
ui
.
Message
(
ui
.
Message
(
fmt
.
Sprintf
(
"Failed to tag a Name on the builder instance: %s"
,
err
))
fmt
.
Sprintf
(
"Failed to tag a Name on the builder instance: %s"
,
err
))
}
}
if
s
.
Debug
{
if
s
.
Debug
{
if
s
.
instance
.
DNSName
!=
""
{
if
s
.
instance
.
PublicDNSName
!=
nil
&&
*
s
.
instance
.
Public
DNSName
!=
""
{
ui
.
Message
(
fmt
.
Sprintf
(
"Public DNS: %s"
,
s
.
instance
.
DNSName
))
ui
.
Message
(
fmt
.
Sprintf
(
"Public DNS: %s"
,
*
s
.
instance
.
Public
DNSName
))
}
}
if
s
.
instance
.
PublicI
p
Address
!=
""
{
if
s
.
instance
.
PublicI
PAddress
!=
nil
&&
*
s
.
instance
.
PublicIP
Address
!=
""
{
ui
.
Message
(
fmt
.
Sprintf
(
"Public IP: %s"
,
s
.
instance
.
PublicIp
Address
))
ui
.
Message
(
fmt
.
Sprintf
(
"Public IP: %s"
,
*
s
.
instance
.
PublicIP
Address
))
}
}
if
s
.
instance
.
PrivateI
p
Address
!=
""
{
if
s
.
instance
.
PrivateI
PAddress
!=
nil
&&
*
s
.
instance
.
PrivateIP
Address
!=
""
{
ui
.
Message
(
fmt
.
Sprintf
(
"Private IP: %s"
,
s
.
instance
.
PrivateIp
Address
))
ui
.
Message
(
fmt
.
Sprintf
(
"Private IP: %s"
,
*
s
.
instance
.
PrivateIP
Address
))
}
}
}
}
...
@@ -271,13 +297,16 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
...
@@ -271,13 +297,16 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
// Cancel the spot request if it exists
// Cancel the spot request if it exists
if
s
.
spotRequest
!=
nil
{
if
s
.
spotRequest
!=
nil
{
ui
.
Say
(
"Cancelling the spot request..."
)
ui
.
Say
(
"Cancelling the spot request..."
)
if
_
,
err
:=
ec2conn
.
CancelSpotRequests
([]
string
{
s
.
spotRequest
.
SpotRequestId
});
err
!=
nil
{
input
:=
&
ec2
.
CancelSpotInstanceRequestsInput
{
SpotInstanceRequestIDs
:
[]
*
string
{
s
.
spotRequest
.
InstanceID
},
}
if
_
,
err
:=
ec2conn
.
CancelSpotInstanceRequests
(
input
);
err
!=
nil
{
ui
.
Error
(
fmt
.
Sprintf
(
"Error cancelling the spot request, may still be around: %s"
,
err
))
ui
.
Error
(
fmt
.
Sprintf
(
"Error cancelling the spot request, may still be around: %s"
,
err
))
return
return
}
}
stateChange
:=
StateChangeConf
{
stateChange
:=
StateChangeConf
{
Pending
:
[]
string
{
"active"
,
"open"
},
Pending
:
[]
string
{
"active"
,
"open"
},
Refresh
:
SpotRequestStateRefreshFunc
(
ec2conn
,
s
.
spotRequest
.
SpotRequestId
),
Refresh
:
SpotRequestStateRefreshFunc
(
ec2conn
,
*
s
.
spotRequest
.
SpotInstanceRequestID
),
Target
:
"cancelled"
,
Target
:
"cancelled"
,
}
}
...
@@ -289,7 +318,7 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
...
@@ -289,7 +318,7 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
if
s
.
instance
!=
nil
{
if
s
.
instance
!=
nil
{
ui
.
Say
(
"Terminating the source AWS instance..."
)
ui
.
Say
(
"Terminating the source AWS instance..."
)
if
_
,
err
:=
ec2conn
.
TerminateInstances
(
[]
string
{
s
.
instance
.
InstanceId
});
err
!=
nil
{
if
_
,
err
:=
ec2conn
.
TerminateInstances
(
&
ec2
.
TerminateInstancesInput
{
InstanceIDs
:
[]
*
string
{
s
.
instance
.
InstanceID
}
});
err
!=
nil
{
ui
.
Error
(
fmt
.
Sprintf
(
"Error terminating instance, may still be around: %s"
,
err
))
ui
.
Error
(
fmt
.
Sprintf
(
"Error terminating instance, may still be around: %s"
,
err
))
return
return
}
}
...
...
builder/amazon/common/step_security_group.go
View file @
74bcbfa8
...
@@ -2,12 +2,14 @@ package common
...
@@ -2,12 +2,14 @@ package common
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/ec2"
"log"
"time"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/common/uuid"
"github.com/mitchellh/packer/common/uuid"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
"log"
"time"
)
)
type
StepSecurityGroup
struct
{
type
StepSecurityGroup
struct
{
...
@@ -36,10 +38,10 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -36,10 +38,10 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
ui
.
Say
(
"Creating temporary security group for this instance..."
)
ui
.
Say
(
"Creating temporary security group for this instance..."
)
groupName
:=
fmt
.
Sprintf
(
"packer %s"
,
uuid
.
TimeOrderedUUID
())
groupName
:=
fmt
.
Sprintf
(
"packer %s"
,
uuid
.
TimeOrderedUUID
())
log
.
Printf
(
"Temporary group name: %s"
,
groupName
)
log
.
Printf
(
"Temporary group name: %s"
,
groupName
)
group
:=
ec2
.
SecurityGroup
{
group
:=
&
ec2
.
CreateSecurityGroupInput
{
Name
:
groupName
,
GroupName
:
&
groupName
,
Description
:
"Temporary group for Packer"
,
Description
:
aws
.
String
(
"Temporary group for Packer"
)
,
V
pcId
:
s
.
VpcId
,
V
PCID
:
&
s
.
VpcId
,
}
}
groupResp
,
err
:=
ec2conn
.
CreateSecurityGroup
(
group
)
groupResp
,
err
:=
ec2conn
.
CreateSecurityGroup
(
group
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -48,16 +50,15 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -48,16 +50,15 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
}
}
// Set the group ID so we can delete it later
// Set the group ID so we can delete it later
s
.
createdGroupId
=
groupResp
.
Id
s
.
createdGroupId
=
*
groupResp
.
GroupID
// Authorize the SSH access
// Authorize the SSH access for the security group
perms
:=
[]
ec2
.
IPPerm
{
req
:=
&
ec2
.
AuthorizeSecurityGroupIngressInput
{
ec2
.
IPPerm
{
GroupID
:
groupResp
.
GroupID
,
Protocol
:
"tcp"
,
IPProtocol
:
aws
.
String
(
"tcp"
),
FromPort
:
s
.
SSHPort
,
FromPort
:
aws
.
Long
(
int64
(
s
.
SSHPort
)),
ToPort
:
s
.
SSHPort
,
ToPort
:
aws
.
Long
(
int64
(
s
.
SSHPort
)),
SourceIPs
:
[]
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
// We loop and retry this a few times because sometimes the security
...
@@ -65,7 +66,7 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -65,7 +66,7 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
// consistent.
// consistent.
ui
.
Say
(
"Authorizing SSH access on the temporary security group..."
)
ui
.
Say
(
"Authorizing SSH access on the temporary security group..."
)
for
i
:=
0
;
i
<
5
;
i
++
{
for
i
:=
0
;
i
<
5
;
i
++
{
_
,
err
=
ec2conn
.
AuthorizeSecurityGroup
(
groupResp
.
SecurityGroup
,
perms
)
_
,
err
=
ec2conn
.
AuthorizeSecurityGroup
Ingress
(
req
)
if
err
==
nil
{
if
err
==
nil
{
break
break
}
}
...
@@ -99,7 +100,7 @@ func (s *StepSecurityGroup) Cleanup(state multistep.StateBag) {
...
@@ -99,7 +100,7 @@ func (s *StepSecurityGroup) Cleanup(state multistep.StateBag) {
var
err
error
var
err
error
for
i
:=
0
;
i
<
5
;
i
++
{
for
i
:=
0
;
i
<
5
;
i
++
{
_
,
err
=
ec2conn
.
DeleteSecurityGroup
(
ec2
.
SecurityGroup
{
Id
:
s
.
createdGroupId
})
_
,
err
=
ec2conn
.
DeleteSecurityGroup
(
&
ec2
.
DeleteSecurityGroupInput
{
GroupID
:
&
s
.
createdGroupId
})
if
err
==
nil
{
if
err
==
nil
{
break
break
}
}
...
...
builder/amazon/common/step_source_ami_info.go
View file @
74bcbfa8
...
@@ -3,7 +3,7 @@ package common
...
@@ -3,7 +3,7 @@ package common
import
(
import
(
"fmt"
"fmt"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
)
)
...
@@ -23,7 +23,7 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -23,7 +23,7 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
"Inspecting the source AMI..."
)
ui
.
Say
(
"Inspecting the source AMI..."
)
imageResp
,
err
:=
ec2conn
.
Images
([]
string
{
s
.
SourceAmi
},
ec2
.
NewFilter
()
)
imageResp
,
err
:=
ec2conn
.
DescribeImages
(
&
ec2
.
DescribeImagesInput
{
ImageIDs
:
[]
*
string
{
&
s
.
SourceAmi
}}
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error querying AMI: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error querying AMI: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
...
@@ -38,11 +38,11 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -38,11 +38,11 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
image
:=
&
imageResp
.
Images
[
0
]
image
:=
imageResp
.
Images
[
0
]
// Enhanced Networking (SriovNetSupport) can only be enabled on HVM AMIs.
// Enhanced Networking (SriovNetSupport) can only be enabled on HVM AMIs.
// See http://goo.gl/icuXh5
// See http://goo.gl/icuXh5
if
s
.
EnhancedNetworking
&&
image
.
VirtualizationType
!=
"hvm"
{
if
s
.
EnhancedNetworking
&&
*
image
.
VirtualizationType
!=
"hvm"
{
err
:=
fmt
.
Errorf
(
"Cannot enable enhanced networking, source AMI '%s' is not HVM"
,
s
.
SourceAmi
)
err
:=
fmt
.
Errorf
(
"Cannot enable enhanced networking, source AMI '%s' is not HVM"
,
s
.
SourceAmi
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
...
...
builder/amazon/ebs/builder.go
View file @
74bcbfa8
...
@@ -9,7 +9,7 @@ import (
...
@@ -9,7 +9,7 @@ import (
"fmt"
"fmt"
"log"
"log"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/common"
"github.com/mitchellh/packer/common"
...
@@ -62,17 +62,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
...
@@ -62,17 +62,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
}
}
func
(
b
*
Builder
)
Run
(
ui
packer
.
Ui
,
hook
packer
.
Hook
,
cache
packer
.
Cache
)
(
packer
.
Artifact
,
error
)
{
func
(
b
*
Builder
)
Run
(
ui
packer
.
Ui
,
hook
packer
.
Hook
,
cache
packer
.
Cache
)
(
packer
.
Artifact
,
error
)
{
region
,
err
:=
b
.
config
.
Region
()
config
,
err
:=
b
.
config
.
Config
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
auth
,
err
:=
b
.
config
.
AccessConfig
.
Auth
()
ec2conn
:=
ec2
.
New
(
config
)
if
err
!=
nil
{
return
nil
,
err
}
ec2conn
:=
ec2
.
New
(
auth
,
region
)
// Setup the state bag and initial state for the steps
// Setup the state bag and initial state for the steps
state
:=
new
(
multistep
.
BasicStateBag
)
state
:=
new
(
multistep
.
BasicStateBag
)
...
@@ -126,6 +121,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
...
@@ -126,6 +121,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&
stepModifyInstance
{},
&
stepModifyInstance
{},
&
stepCreateAMI
{},
&
stepCreateAMI
{},
&
awscommon
.
StepAMIRegionCopy
{
&
awscommon
.
StepAMIRegionCopy
{
AccessConfig
:
&
b
.
config
.
AccessConfig
,
Regions
:
b
.
config
.
AMIRegions
,
Regions
:
b
.
config
.
AMIRegions
,
},
},
&
awscommon
.
StepModifyAMIAttributes
{
&
awscommon
.
StepModifyAMIAttributes
{
...
...
builder/amazon/ebs/builder_test.go
View file @
74bcbfa8
package
ebs
package
ebs
import
(
import
(
"github.com/mitchellh/packer/packer"
"testing"
"testing"
"github.com/mitchellh/packer/packer"
)
)
func
testConfig
()
map
[
string
]
interface
{}
{
func
testConfig
()
map
[
string
]
interface
{}
{
...
...
builder/amazon/ebs/step_create_ami.go
View file @
74bcbfa8
...
@@ -2,7 +2,8 @@ package ebs
...
@@ -2,7 +2,8 @@ package ebs
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/ec2"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
...
@@ -20,10 +21,10 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -20,10 +21,10 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction {
// Create the image
// Create the image
ui
.
Say
(
fmt
.
Sprintf
(
"Creating the AMI: %s"
,
config
.
AMIName
))
ui
.
Say
(
fmt
.
Sprintf
(
"Creating the AMI: %s"
,
config
.
AMIName
))
createOpts
:=
&
ec2
.
CreateImage
{
createOpts
:=
&
ec2
.
CreateImage
Input
{
InstanceI
d
:
instance
.
InstanceId
,
InstanceI
D
:
instance
.
InstanceID
,
Name
:
config
.
AMIName
,
Name
:
&
config
.
AMIName
,
BlockDevices
:
config
.
BlockDevices
.
BuildAMIDevices
(),
BlockDevice
Mapping
s
:
config
.
BlockDevices
.
BuildAMIDevices
(),
}
}
createResp
,
err
:=
ec2conn
.
CreateImage
(
createOpts
)
createResp
,
err
:=
ec2conn
.
CreateImage
(
createOpts
)
...
@@ -35,16 +36,16 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -35,16 +36,16 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction {
}
}
// Set the AMI ID in the state
// 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
:=
make
(
map
[
string
]
string
)
amis
[
ec2conn
.
Region
.
Name
]
=
createResp
.
ImageId
amis
[
ec2conn
.
Config
.
Region
]
=
*
createResp
.
ImageID
state
.
Put
(
"amis"
,
amis
)
state
.
Put
(
"amis"
,
amis
)
// Wait for the image to become ready
// Wait for the image to become ready
stateChange
:=
awscommon
.
StateChangeConf
{
stateChange
:=
awscommon
.
StateChangeConf
{
Pending
:
[]
string
{
"pending"
},
Pending
:
[]
string
{
"pending"
},
Target
:
"available"
,
Target
:
"available"
,
Refresh
:
awscommon
.
AMIStateRefreshFunc
(
ec2conn
,
createResp
.
ImageId
),
Refresh
:
awscommon
.
AMIStateRefreshFunc
(
ec2conn
,
*
createResp
.
ImageID
),
StepState
:
state
,
StepState
:
state
,
}
}
...
@@ -56,14 +57,14 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -56,14 +57,14 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction {
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
imagesResp
,
err
:=
ec2conn
.
Images
([]
string
{
createResp
.
ImageId
},
nil
)
imagesResp
,
err
:=
ec2conn
.
DescribeImages
(
&
ec2
.
DescribeImagesInput
{
ImageIDs
:
[]
*
string
{
createResp
.
ImageID
}}
)
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error searching for AMI: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error searching for AMI: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
}
}
s
.
image
=
&
imagesResp
.
Images
[
0
]
s
.
image
=
imagesResp
.
Images
[
0
]
return
multistep
.
ActionContinue
return
multistep
.
ActionContinue
}
}
...
@@ -83,11 +84,9 @@ func (s *stepCreateAMI) Cleanup(state multistep.StateBag) {
...
@@ -83,11 +84,9 @@ func (s *stepCreateAMI) Cleanup(state multistep.StateBag) {
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
"Deregistering the AMI because cancelation or error..."
)
ui
.
Say
(
"Deregistering the AMI because cancelation or error..."
)
if
resp
,
err
:=
ec2conn
.
DeregisterImage
(
s
.
image
.
Id
);
err
!=
nil
{
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
))
ui
.
Error
(
fmt
.
Sprintf
(
"Error deregistering AMI, may still be around: %s"
,
err
))
return
return
}
else
if
resp
.
Return
==
false
{
ui
.
Error
(
fmt
.
Sprintf
(
"Error deregistering AMI, may still be around: %t"
,
resp
.
Return
))
return
}
}
}
}
builder/amazon/ebs/step_modify_instance.go
View file @
74bcbfa8
...
@@ -3,7 +3,7 @@ package ebs
...
@@ -3,7 +3,7 @@ package ebs
import
(
import
(
"fmt"
"fmt"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
)
)
...
@@ -19,12 +19,13 @@ func (s *stepModifyInstance) Run(state multistep.StateBag) multistep.StepAction
...
@@ -19,12 +19,13 @@ func (s *stepModifyInstance) Run(state multistep.StateBag) multistep.StepAction
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
if
config
.
AMIEnhancedNetworking
{
if
config
.
AMIEnhancedNetworking
{
ui
.
Say
(
"Enabling Enhanced Networking..."
)
ui
.
Say
(
"Enabling Enhanced Networking..."
)
_
,
err
:=
ec2conn
.
ModifyInstance
(
simple
:=
"simple"
instance
.
InstanceId
,
_
,
err
:=
ec2conn
.
ModifyInstanceAttribute
(
&
ec2
.
ModifyInstanceAttributeInput
{
&
ec2
.
ModifyInstance
{
SriovNetSupport
:
true
},
InstanceID
:
instance
.
InstanceID
,
)
SRIOVNetSupport
:
&
ec2
.
AttributeValue
{
Value
:
&
simple
},
})
if
err
!=
nil
{
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
)
state
.
Put
(
"error"
,
err
)
ui
.
Error
(
err
.
Error
())
ui
.
Error
(
err
.
Error
())
return
multistep
.
ActionHalt
return
multistep
.
ActionHalt
...
...
builder/amazon/ebs/step_stop_instance.go
View file @
74bcbfa8
...
@@ -2,7 +2,8 @@ package ebs
...
@@ -2,7 +2,8 @@ package ebs
import
(
import
(
"fmt"
"fmt"
"github.com/mitchellh/goamz/ec2"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
...
@@ -24,7 +25,9 @@ func (s *stepStopInstance) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -24,7 +25,9 @@ func (s *stepStopInstance) Run(state multistep.StateBag) multistep.StepAction {
// Stop the instance so we can create an AMI from it
// Stop the instance so we can create an AMI from it
ui
.
Say
(
"Stopping the source instance..."
)
ui
.
Say
(
"Stopping the source instance..."
)
_
,
err
:=
ec2conn
.
StopInstances
(
instance
.
InstanceId
)
_
,
err
:=
ec2conn
.
StopInstances
(
&
ec2
.
StopInstancesInput
{
InstanceIDs
:
[]
*
string
{
instance
.
InstanceID
},
})
if
err
!=
nil
{
if
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error stopping instance: %s"
,
err
)
err
:=
fmt
.
Errorf
(
"Error stopping instance: %s"
,
err
)
state
.
Put
(
"error"
,
err
)
state
.
Put
(
"error"
,
err
)
...
...
builder/amazon/instance/builder.go
View file @
74bcbfa8
...
@@ -9,7 +9,7 @@ import (
...
@@ -9,7 +9,7 @@ import (
"os"
"os"
"strings"
"strings"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/common"
"github.com/mitchellh/packer/common"
...
@@ -141,17 +141,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
...
@@ -141,17 +141,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
}
}
func
(
b
*
Builder
)
Run
(
ui
packer
.
Ui
,
hook
packer
.
Hook
,
cache
packer
.
Cache
)
(
packer
.
Artifact
,
error
)
{
func
(
b
*
Builder
)
Run
(
ui
packer
.
Ui
,
hook
packer
.
Hook
,
cache
packer
.
Cache
)
(
packer
.
Artifact
,
error
)
{
region
,
err
:=
b
.
config
.
Region
()
config
,
err
:=
b
.
config
.
Config
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
auth
,
err
:=
b
.
config
.
AccessConfig
.
Auth
()
ec2conn
:=
ec2
.
New
(
config
)
if
err
!=
nil
{
return
nil
,
err
}
ec2conn
:=
ec2
.
New
(
auth
,
region
)
// Setup the state bag and initial state for the steps
// Setup the state bag and initial state for the steps
state
:=
new
(
multistep
.
BasicStateBag
)
state
:=
new
(
multistep
.
BasicStateBag
)
...
@@ -208,6 +203,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
...
@@ -208,6 +203,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
},
&
StepRegisterAMI
{},
&
StepRegisterAMI
{},
&
awscommon
.
StepAMIRegionCopy
{
&
awscommon
.
StepAMIRegionCopy
{
AccessConfig
:
&
b
.
config
.
AccessConfig
,
Regions
:
b
.
config
.
AMIRegions
,
Regions
:
b
.
config
.
AMIRegions
,
},
},
&
awscommon
.
StepModifyAMIAttributes
{
&
awscommon
.
StepModifyAMIAttributes
{
...
...
builder/amazon/instance/step_bundle_volume.go
View file @
74bcbfa8
...
@@ -3,7 +3,7 @@ package instance
...
@@ -3,7 +3,7 @@ package instance
import
(
import
(
"fmt"
"fmt"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/template/interpolate"
"github.com/mitchellh/packer/template/interpolate"
...
@@ -35,7 +35,7 @@ func (s *StepBundleVolume) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -35,7 +35,7 @@ func (s *StepBundleVolume) Run(state multistep.StateBag) multistep.StepAction {
var
err
error
var
err
error
config
.
ctx
.
Data
=
bundleCmdData
{
config
.
ctx
.
Data
=
bundleCmdData
{
AccountId
:
config
.
AccountId
,
AccountId
:
config
.
AccountId
,
Architecture
:
instance
.
Architecture
,
Architecture
:
*
instance
.
Architecture
,
CertPath
:
x509RemoteCertPath
,
CertPath
:
x509RemoteCertPath
,
Destination
:
config
.
BundleDestination
,
Destination
:
config
.
BundleDestination
,
KeyPath
:
x509RemoteKeyPath
,
KeyPath
:
x509RemoteKeyPath
,
...
...
builder/amazon/instance/step_register_ami.go
View file @
74bcbfa8
...
@@ -3,7 +3,7 @@ package instance
...
@@ -3,7 +3,7 @@ package instance
import
(
import
(
"fmt"
"fmt"
"github.com/
mitchellh/goamz
/ec2"
"github.com/
awslabs/aws-sdk-go/service
/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/multistep"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
awscommon
"github.com/mitchellh/packer/builder/amazon/common"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
...
@@ -18,16 +18,17 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -18,16 +18,17 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
ui
.
Say
(
"Registering the AMI..."
)
ui
.
Say
(
"Registering the AMI..."
)
registerOpts
:=
&
ec2
.
RegisterImage
{
registerOpts
:=
&
ec2
.
RegisterImage
Input
{
ImageLocation
:
manifestPath
,
ImageLocation
:
&
manifestPath
,
Name
:
config
.
AMIName
,
Name
:
&
config
.
AMIName
,
BlockDevice
s
:
config
.
BlockDevices
.
BuildAMIDevices
(),
BlockDevice
Mappings
:
config
.
BlockDevices
.
BuildAMIDevices
(),
Virt
Type
:
config
.
AMIVirtType
,
Virt
ualizationType
:
&
config
.
AMIVirtType
,
}
}
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
if
config
.
AMIEnhancedNetworking
{
if
config
.
AMIEnhancedNetworking
{
registerOpts
.
SriovNetSupport
=
"simple"
simple
:=
"simple"
registerOpts
.
SRIOVNetSupport
=
&
simple
}
}
registerResp
,
err
:=
ec2conn
.
RegisterImage
(
registerOpts
)
registerResp
,
err
:=
ec2conn
.
RegisterImage
(
registerOpts
)
...
@@ -38,16 +39,16 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -38,16 +39,16 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
}
}
// Set the AMI ID in the state
// 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
:=
make
(
map
[
string
]
string
)
amis
[
ec2conn
.
Region
.
Name
]
=
registerResp
.
ImageId
amis
[
ec2conn
.
Config
.
Region
]
=
*
registerResp
.
ImageID
state
.
Put
(
"amis"
,
amis
)
state
.
Put
(
"amis"
,
amis
)
// Wait for the image to become ready
// Wait for the image to become ready
stateChange
:=
awscommon
.
StateChangeConf
{
stateChange
:=
awscommon
.
StateChangeConf
{
Pending
:
[]
string
{
"pending"
},
Pending
:
[]
string
{
"pending"
},
Target
:
"available"
,
Target
:
"available"
,
Refresh
:
awscommon
.
AMIStateRefreshFunc
(
ec2conn
,
registerResp
.
ImageId
),
Refresh
:
awscommon
.
AMIStateRefreshFunc
(
ec2conn
,
*
registerResp
.
ImageID
),
StepState
:
state
,
StepState
:
state
,
}
}
...
...
builder/amazon/instance/step_upload_bundle.go
View file @
74bcbfa8
...
@@ -41,7 +41,7 @@ func (s *StepUploadBundle) Run(state multistep.StateBag) multistep.StepAction {
...
@@ -41,7 +41,7 @@ func (s *StepUploadBundle) Run(state multistep.StateBag) multistep.StepAction {
BucketName
:
config
.
S3Bucket
,
BucketName
:
config
.
S3Bucket
,
BundleDirectory
:
config
.
BundleDestination
,
BundleDirectory
:
config
.
BundleDestination
,
ManifestPath
:
manifestPath
,
ManifestPath
:
manifestPath
,
Region
:
region
.
Name
,
Region
:
region
,
SecretKey
:
config
.
SecretKey
,
SecretKey
:
config
.
SecretKey
,
}
}
config
.
BundleUploadCommand
,
err
=
interpolate
.
Render
(
config
.
BundleUploadCommand
,
config
.
ctx
)
config
.
BundleUploadCommand
,
err
=
interpolate
.
Render
(
config
.
BundleUploadCommand
,
config
.
ctx
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment