Commit 8250755a authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

Merge pull request #1228 from jmassara/enhanced_networking

builder/amazon: support for enhanced networking
parents 46a12f2e 4b6b504d
...@@ -7,13 +7,14 @@ package chroot ...@@ -7,13 +7,14 @@ package chroot
import ( import (
"errors" "errors"
"fmt" "fmt"
"log"
"runtime"
"github.com/mitchellh/goamz/ec2" "github.com/mitchellh/goamz/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"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"log"
"runtime"
) )
// The unique ID for this builder // The unique ID for this builder
...@@ -182,7 +183,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -182,7 +183,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
// Build the steps // Build the steps
steps := []multistep.Step{ steps := []multistep.Step{
&StepInstanceInfo{}, &StepInstanceInfo{},
&StepSourceAMIInfo{}, &awscommon.StepSourceAMIInfo{
SourceAmi: b.config.SourceAmi,
EnhancedNetworking: b.config.AMIEnhancedNetworking,
},
&StepCheckRootDevice{},
&StepFlock{}, &StepFlock{},
&StepPrepareDevice{}, &StepPrepareDevice{},
&StepCreateVolume{}, &StepCreateVolume{},
......
package chroot
import (
"fmt"
"github.com/mitchellh/goamz/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
)
// StepCheckRootDevice makes sure the root device on the AMI is EBS-backed.
type StepCheckRootDevice struct{}
func (s *StepCheckRootDevice) Run(state multistep.StateBag) multistep.StepAction {
image := state.Get("ec2").(*ec2.Image)
ui := state.Get("ui").(packer.Ui)
ui.Say("Checking the root device on source AMI...")
// It must be EBS-backed otherwise the build won't work
if image.RootDeviceType != "ebs" {
err := fmt.Errorf("The root device of the source AMI must be EBS-backed.")
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
return multistep.ActionContinue
}
func (s *StepCheckRootDevice) Cleanup(multistep.StateBag) {}
...@@ -2,6 +2,7 @@ package chroot ...@@ -2,6 +2,7 @@ package chroot
import ( import (
"fmt" "fmt"
"github.com/mitchellh/goamz/ec2" "github.com/mitchellh/goamz/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"
...@@ -38,6 +39,11 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { ...@@ -38,6 +39,11 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
BlockDevices: blockDevices, BlockDevices: blockDevices,
} }
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
if config.AMIEnhancedNetworking {
registerOpts.SriovNetSupport = "simple"
}
registerResp, err := ec2conn.RegisterImage(registerOpts) registerResp, err := ec2conn.RegisterImage(registerOpts)
if err != nil { if err != nil {
state.Put("error", fmt.Errorf("Error registering AMI: %s", err)) state.Put("error", fmt.Errorf("Error registering AMI: %s", err))
......
...@@ -2,6 +2,7 @@ package common ...@@ -2,6 +2,7 @@ package common
import ( import (
"fmt" "fmt"
"github.com/mitchellh/goamz/aws" "github.com/mitchellh/goamz/aws"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
) )
...@@ -16,6 +17,7 @@ type AMIConfig struct { ...@@ -16,6 +17,7 @@ type AMIConfig struct {
AMIProductCodes []string `mapstructure:"ami_product_codes"` AMIProductCodes []string `mapstructure:"ami_product_codes"`
AMIRegions []string `mapstructure:"ami_regions"` AMIRegions []string `mapstructure:"ami_regions"`
AMITags map[string]string `mapstructure:"tags"` AMITags map[string]string `mapstructure:"tags"`
AMIEnhancedNetworking bool `mapstructure:"enhanced_networking"`
} }
func (c *AMIConfig) Prepare(t *packer.ConfigTemplate) []error { func (c *AMIConfig) Prepare(t *packer.ConfigTemplate) []error {
......
package chroot package common
import ( import (
"fmt" "fmt"
"github.com/mitchellh/goamz/ec2" "github.com/mitchellh/goamz/ec2"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
...@@ -12,15 +13,17 @@ import ( ...@@ -12,15 +13,17 @@ import (
// //
// Produces: // Produces:
// source_image *ec2.Image - the source AMI info // source_image *ec2.Image - the source AMI info
type StepSourceAMIInfo struct{} type StepSourceAMIInfo struct {
SourceAmi string
EnhancedNetworking bool
}
func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction { func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
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("Inspecting the source AMI...") ui.Say("Inspecting the source AMI...")
imageResp, err := ec2conn.Images([]string{config.SourceAmi}, ec2.NewFilter()) imageResp, err := ec2conn.Images([]string{s.SourceAmi}, ec2.NewFilter())
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)
...@@ -29,7 +32,7 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction { ...@@ -29,7 +32,7 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
} }
if len(imageResp.Images) == 0 { if len(imageResp.Images) == 0 {
err := fmt.Errorf("Source AMI '%s' was not found!", config.SourceAmi) err := fmt.Errorf("Source AMI '%s' was not found!", s.SourceAmi)
state.Put("error", err) state.Put("error", err)
ui.Error(err.Error()) ui.Error(err.Error())
return multistep.ActionHalt return multistep.ActionHalt
...@@ -37,9 +40,10 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction { ...@@ -37,9 +40,10 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
image := &imageResp.Images[0] image := &imageResp.Images[0]
// It must be EBS-backed otherwise the build won't work // Enhanced Networking (SriovNetSupport) can only be enabled on HVM AMIs.
if image.RootDeviceType != "ebs" { // See http://goo.gl/icuXh5
err := fmt.Errorf("The root device of the source AMI must be EBS-backed.") if s.EnhancedNetworking && image.VirtualizationType != "hvm" {
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())
return multistep.ActionHalt return multistep.ActionHalt
......
...@@ -7,12 +7,13 @@ package ebs ...@@ -7,12 +7,13 @@ package ebs
import ( import (
"fmt" "fmt"
"log"
"github.com/mitchellh/goamz/ec2" "github.com/mitchellh/goamz/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"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"log"
) )
// The unique ID for this builder // The unique ID for this builder
...@@ -82,6 +83,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -82,6 +83,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
// Build the steps // Build the steps
steps := []multistep.Step{ steps := []multistep.Step{
&awscommon.StepSourceAMIInfo{
SourceAmi: b.config.SourceAmi,
EnhancedNetworking: b.config.AMIEnhancedNetworking,
},
&awscommon.StepKeyPair{ &awscommon.StepKeyPair{
Debug: b.config.PackerDebug, Debug: b.config.PackerDebug,
DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName), DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName),
...@@ -114,6 +119,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -114,6 +119,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
}, },
&common.StepProvision{}, &common.StepProvision{},
&stepStopInstance{}, &stepStopInstance{},
&stepModifyInstance{},
&stepCreateAMI{}, &stepCreateAMI{},
&awscommon.StepAMIRegionCopy{ &awscommon.StepAMIRegionCopy{
Regions: b.config.AMIRegions, Regions: b.config.AMIRegions,
......
package ebs
import (
"fmt"
"github.com/mitchellh/goamz/ec2"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
)
type stepModifyInstance struct{}
func (s *stepModifyInstance) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(config)
ec2conn := state.Get("ec2").(*ec2.EC2)
instance := state.Get("instance").(*ec2.Instance)
ui := state.Get("ui").(packer.Ui)
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
if config.AMIEnhancedNetworking {
ui.Say("Enabling Enhanced Networking...")
_, err := ec2conn.ModifyInstance(
instance.InstanceId,
&ec2.ModifyInstance{SriovNetSupport: true},
)
if err != nil {
err := fmt.Errorf("Error enabling Enhanced Networking on %s: %s", instance.InstanceId, err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
}
return multistep.ActionContinue
}
func (s *stepModifyInstance) Cleanup(state multistep.StateBag) {
// No cleanup...
}
...@@ -5,14 +5,15 @@ package instance ...@@ -5,14 +5,15 @@ package instance
import ( import (
"errors" "errors"
"fmt" "fmt"
"log"
"os"
"strings"
"github.com/mitchellh/goamz/ec2" "github.com/mitchellh/goamz/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"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"log"
"os"
"strings"
) )
// The unique ID for this builder // The unique ID for this builder
...@@ -186,6 +187,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -186,6 +187,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
// Build the steps // Build the steps
steps := []multistep.Step{ steps := []multistep.Step{
&awscommon.StepSourceAMIInfo{
SourceAmi: b.config.SourceAmi,
EnhancedNetworking: b.config.AMIEnhancedNetworking,
},
&awscommon.StepKeyPair{ &awscommon.StepKeyPair{
Debug: b.config.PackerDebug, Debug: b.config.PackerDebug,
DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName), DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName),
......
...@@ -2,6 +2,7 @@ package instance ...@@ -2,6 +2,7 @@ package instance
import ( import (
"fmt" "fmt"
"github.com/mitchellh/goamz/ec2" "github.com/mitchellh/goamz/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"
...@@ -24,6 +25,11 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { ...@@ -24,6 +25,11 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
VirtType: config.AMIVirtType, VirtType: config.AMIVirtType,
} }
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
if config.AMIEnhancedNetworking {
registerOpts.SriovNetSupport = "simple"
}
registerResp, err := ec2conn.RegisterImage(registerOpts) registerResp, err := ec2conn.RegisterImage(registerOpts)
if err != nil { if err != nil {
state.Put("error", fmt.Errorf("Error registering AMI: %s", err)) state.Put("error", fmt.Errorf("Error registering AMI: %s", err))
......
...@@ -121,6 +121,9 @@ each category, the available configuration keys are alphabetized. ...@@ -121,6 +121,9 @@ each category, the available configuration keys are alphabetized.
of the source AMI will be attached. This defaults to "" (empty string), of the source AMI will be attached. This defaults to "" (empty string),
which forces Packer to find an open device automatically. which forces Packer to find an open device automatically.
* `enhanced_networking` (boolean) - Enable enhanced networking (SriovNetSupport) on
HVM-compatible AMIs.
* `mount_path` (string) - The path where the volume will be mounted. This is * `mount_path` (string) - The path where the volume will be mounted. This is
where the chroot environment will be. This defaults to where the chroot environment will be. This defaults to
`packer-amazon-chroot-volumes/{{.Device}}`. This is a configuration `packer-amazon-chroot-volumes/{{.Device}}`. This is a configuration
......
...@@ -95,6 +95,9 @@ each category, the available configuration keys are alphabetized. ...@@ -95,6 +95,9 @@ each category, the available configuration keys are alphabetized.
* `availability_zone` (string) - Destination availability zone to launch instance in. * `availability_zone` (string) - Destination availability zone to launch instance in.
Leave this empty to allow Amazon to auto-assign. Leave this empty to allow Amazon to auto-assign.
* `enhanced_networking` (boolean) - Enable enhanced networking (SriovNetSupport) on
HVM-compatible AMIs.
* `iam_instance_profile` (string) - The name of an * `iam_instance_profile` (string) - The name of an
[IAM instance profile](http://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html) [IAM instance profile](http://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html)
to launch the EC2 instance with. to launch the EC2 instance with.
......
...@@ -133,6 +133,9 @@ each category, the available configuration keys are alphabetized. ...@@ -133,6 +133,9 @@ each category, the available configuration keys are alphabetized.
* `bundle_vol_command` (string) - The command to use to bundle the volume. * `bundle_vol_command` (string) - The command to use to bundle the volume.
See the "custom bundle commands" section below for more information. See the "custom bundle commands" section below for more information.
* `enhanced_networking` (boolean) - Enable enhanced networking (SriovNetSupport) on
HVM-compatible AMIs.
* `iam_instance_profile` (string) - The name of an * `iam_instance_profile` (string) - The name of an
[IAM instance profile](http://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html) [IAM instance profile](http://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html)
to launch the EC2 instance with. to launch the EC2 instance with.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment