Merge branch 'master' of https://github.com/mitchellh/packer
This commit is contained in:
commit
935fa3a590
|
@ -9,6 +9,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/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"
|
||||||
|
@ -131,7 +132,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ec2conn := ec2.New(config)
|
session := session.New(config)
|
||||||
|
ec2conn := ec2.New(session)
|
||||||
|
|
||||||
wrappedCommand := func(command string) (string, error) {
|
wrappedCommand := func(command string) (string, error) {
|
||||||
ctx := b.config.ctx
|
ctx := b.config.ctx
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
)
|
)
|
||||||
|
@ -72,7 +73,8 @@ func (a *Artifact) Destroy() error {
|
||||||
Credentials: a.Conn.Config.Credentials,
|
Credentials: a.Conn.Config.Credentials,
|
||||||
Region: aws.String(region),
|
Region: aws.String(region),
|
||||||
}
|
}
|
||||||
regionConn := ec2.New(regionConfig)
|
sess := session.New(regionConfig)
|
||||||
|
regionConn := ec2.New(sess)
|
||||||
|
|
||||||
input := &ec2.DeregisterImageInput{
|
input := &ec2.DeregisterImageInput{
|
||||||
ImageId: &imageId,
|
ImageId: &imageId,
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
|
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
|
@ -87,7 +88,9 @@ func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string,
|
||||||
}
|
}
|
||||||
awsConfig.Region = aws.String(target)
|
awsConfig.Region = aws.String(target)
|
||||||
|
|
||||||
regionconn := ec2.New(awsConfig)
|
sess := session.New(awsConfig)
|
||||||
|
regionconn := ec2.New(sess)
|
||||||
|
|
||||||
resp, err := regionconn.CopyImage(&ec2.CopyImageInput{
|
resp, err := regionconn.CopyImage(&ec2.CopyImageInput{
|
||||||
SourceRegion: &source,
|
SourceRegion: &source,
|
||||||
SourceImageId: &imageId,
|
SourceImageId: &imageId,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
|
@ -33,11 +34,13 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
|
||||||
// Declare list of resources to tag
|
// Declare list of resources to tag
|
||||||
resourceIds := []*string{&ami}
|
resourceIds := []*string{&ami}
|
||||||
|
awsConfig := aws.Config{
|
||||||
regionconn := ec2.New(&aws.Config{
|
|
||||||
Credentials: ec2conn.Config.Credentials,
|
Credentials: ec2conn.Config.Credentials,
|
||||||
Region: aws.String(region),
|
Region: aws.String(region),
|
||||||
})
|
}
|
||||||
|
session := session.New(&awsConfig)
|
||||||
|
|
||||||
|
regionconn := ec2.New(session)
|
||||||
|
|
||||||
// Retrieve image list for given AMI
|
// Retrieve image list for given AMI
|
||||||
imageResp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{
|
imageResp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
|
@ -88,10 +89,12 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc
|
||||||
|
|
||||||
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(&aws.Config{
|
awsConfig := aws.Config{
|
||||||
Credentials: ec2conn.Config.Credentials,
|
Credentials: ec2conn.Config.Credentials,
|
||||||
Region: aws.String(region),
|
Region: aws.String(region),
|
||||||
})
|
}
|
||||||
|
session := session.New(&awsConfig)
|
||||||
|
regionconn := ec2.New(session)
|
||||||
for name, input := range options {
|
for name, input := range options {
|
||||||
ui.Message(fmt.Sprintf("Modifying: %s", name))
|
ui.Message(fmt.Sprintf("Modifying: %s", name))
|
||||||
input.ImageId = &ami
|
input.ImageId = &ami
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/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"
|
||||||
|
@ -68,7 +69,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ec2conn := ec2.New(config)
|
session := session.New(config)
|
||||||
|
ec2conn := ec2.New(session)
|
||||||
|
|
||||||
// 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)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/mitchellh/packer/builder/amazon/common"
|
"github.com/mitchellh/packer/builder/amazon/common"
|
||||||
builderT "github.com/mitchellh/packer/helper/builder/testing"
|
builderT "github.com/mitchellh/packer/helper/builder/testing"
|
||||||
|
@ -160,7 +161,8 @@ func testEC2Conn() (*ec2.EC2, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ec2.New(config), nil
|
session := session.New(config)
|
||||||
|
return ec2.New(session), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const testBuilderAccBasic = `
|
const testBuilderAccBasic = `
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/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"
|
||||||
|
@ -159,7 +160,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ec2conn := ec2.New(config)
|
session := session.New(config)
|
||||||
|
ec2conn := ec2.New(session)
|
||||||
|
|
||||||
// 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)
|
||||||
|
|
|
@ -88,6 +88,8 @@ type Config struct {
|
||||||
DiskSize uint `mapstructure:"disk_size"`
|
DiskSize uint `mapstructure:"disk_size"`
|
||||||
DiskCache string `mapstructure:"disk_cache"`
|
DiskCache string `mapstructure:"disk_cache"`
|
||||||
DiskDiscard string `mapstructure:"disk_discard"`
|
DiskDiscard string `mapstructure:"disk_discard"`
|
||||||
|
SkipCompaction bool `mapstructure:"skip_compaction"`
|
||||||
|
DiskCompression bool `mapstructure:"disk_compression"`
|
||||||
FloppyFiles []string `mapstructure:"floppy_files"`
|
FloppyFiles []string `mapstructure:"floppy_files"`
|
||||||
Format string `mapstructure:"format"`
|
Format string `mapstructure:"format"`
|
||||||
Headless bool `mapstructure:"headless"`
|
Headless bool `mapstructure:"headless"`
|
||||||
|
@ -242,6 +244,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
errs, errors.New("invalid format, only 'qcow2' or 'raw' are allowed"))
|
errs, errors.New("invalid format, only 'qcow2' or 'raw' are allowed"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.config.Format != "qcow2" {
|
||||||
|
b.config.SkipCompaction = true
|
||||||
|
b.config.DiskCompression = false
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := accels[b.config.Accelerator]; !ok {
|
if _, ok := accels[b.config.Accelerator]; !ok {
|
||||||
errs = packer.MultiErrorAppend(
|
errs = packer.MultiErrorAppend(
|
||||||
errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', or 'none' are allowed"))
|
errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', or 'none' are allowed"))
|
||||||
|
@ -364,6 +371,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
},
|
},
|
||||||
new(common.StepProvision),
|
new(common.StepProvision),
|
||||||
new(stepShutdown),
|
new(stepShutdown),
|
||||||
|
new(stepConvertDisk),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the state bag
|
// Setup the state bag
|
||||||
|
|
|
@ -132,6 +132,48 @@ func TestBuilderPrepare_BootWait(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuilderPrepare_DiskCompaction(t *testing.T) {
|
||||||
|
var b Builder
|
||||||
|
config := testConfig()
|
||||||
|
|
||||||
|
// Bad
|
||||||
|
config["skip_compaction"] = false
|
||||||
|
config["disk_compression"] = true
|
||||||
|
config["format"] = "img"
|
||||||
|
warns, err := b.Prepare(config)
|
||||||
|
if len(warns) > 0 {
|
||||||
|
t.Fatalf("bad: %#v", warns)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should have error")
|
||||||
|
}
|
||||||
|
if b.config.SkipCompaction != true {
|
||||||
|
t.Fatalf("SkipCompaction should be true")
|
||||||
|
}
|
||||||
|
if b.config.DiskCompression != false {
|
||||||
|
t.Fatalf("DiskCompression should be false")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Good
|
||||||
|
config["skip_compaction"] = false
|
||||||
|
config["disk_compression"] = true
|
||||||
|
config["format"] = "qcow2"
|
||||||
|
b = Builder{}
|
||||||
|
warns, err = b.Prepare(config)
|
||||||
|
if len(warns) > 0 {
|
||||||
|
t.Fatalf("bad: %#v", warns)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("should not have error: %s", err)
|
||||||
|
}
|
||||||
|
if b.config.SkipCompaction != false {
|
||||||
|
t.Fatalf("SkipCompaction should be false")
|
||||||
|
}
|
||||||
|
if b.config.DiskCompression != true {
|
||||||
|
t.Fatalf("DiskCompression should be true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBuilderPrepare_DiskSize(t *testing.T) {
|
func TestBuilderPrepare_DiskSize(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package qemu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
|
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This step converts the virtual disk that was used as the
|
||||||
|
// hard drive for the virtual machine.
|
||||||
|
type stepConvertDisk struct{}
|
||||||
|
|
||||||
|
func (s *stepConvertDisk) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
config := state.Get("config").(*Config)
|
||||||
|
driver := state.Get("driver").(Driver)
|
||||||
|
diskName := state.Get("disk_filename").(string)
|
||||||
|
ui := state.Get("ui").(packer.Ui)
|
||||||
|
|
||||||
|
if config.SkipCompaction && !config.DiskCompression {
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
name := diskName + ".convert"
|
||||||
|
|
||||||
|
sourcePath := filepath.Join(config.OutputDir, diskName)
|
||||||
|
targetPath := filepath.Join(config.OutputDir, name)
|
||||||
|
|
||||||
|
command := []string{
|
||||||
|
"convert",
|
||||||
|
"-q",
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.DiskCompression {
|
||||||
|
command = append(command, "-c")
|
||||||
|
}
|
||||||
|
|
||||||
|
command = append(command, []string{
|
||||||
|
"-f", config.Format,
|
||||||
|
"-O", config.Format,
|
||||||
|
sourcePath,
|
||||||
|
targetPath,
|
||||||
|
}...,
|
||||||
|
)
|
||||||
|
|
||||||
|
ui.Say("Converting hard drive...")
|
||||||
|
if err := driver.QemuImg(command...); err != nil {
|
||||||
|
err := fmt.Errorf("Error converting hard drive: %s", err)
|
||||||
|
state.Put("error", err)
|
||||||
|
ui.Error(err.Error())
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Rename(targetPath, sourcePath); err != nil {
|
||||||
|
err := fmt.Errorf("Error moving converted hard drive: %s", err)
|
||||||
|
state.Put("error", err)
|
||||||
|
ui.Error(err.Error())
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stepConvertDisk) Cleanup(state multistep.StateBag) {}
|
|
@ -40,7 +40,7 @@ type Config struct {
|
||||||
DiskSize uint `mapstructure:"disk_size"`
|
DiskSize uint `mapstructure:"disk_size"`
|
||||||
DiskTypeId string `mapstructure:"disk_type_id"`
|
DiskTypeId string `mapstructure:"disk_type_id"`
|
||||||
FloppyFiles []string `mapstructure:"floppy_files"`
|
FloppyFiles []string `mapstructure:"floppy_files"`
|
||||||
Format string `mapstruture:"format"`
|
Format string `mapstructure:"format"`
|
||||||
GuestOSType string `mapstructure:"guest_os_type"`
|
GuestOSType string `mapstructure:"guest_os_type"`
|
||||||
Version string `mapstructure:"version"`
|
Version string `mapstructure:"version"`
|
||||||
VMName string `mapstructure:"vm_name"`
|
VMName string `mapstructure:"vm_name"`
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/osext"
|
"github.com/kardianos/osext"
|
||||||
"github.com/mitchellh/packer/command"
|
"github.com/mitchellh/packer/command"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"github.com/mitchellh/packer/packer/plugin"
|
"github.com/mitchellh/packer/packer/plugin"
|
||||||
|
|
|
@ -22,6 +22,9 @@ type Config struct {
|
||||||
// The command used to execute Puppet.
|
// The command used to execute Puppet.
|
||||||
ExecuteCommand string `mapstructure:"execute_command"`
|
ExecuteCommand string `mapstructure:"execute_command"`
|
||||||
|
|
||||||
|
// Additional arguments to pass when executing Puppet
|
||||||
|
ExtraArguments []string `mapstructure:"extra_arguments"`
|
||||||
|
|
||||||
// Additional facts to set when executing Puppet
|
// Additional facts to set when executing Puppet
|
||||||
Facter map[string]string
|
Facter map[string]string
|
||||||
|
|
||||||
|
@ -62,6 +65,7 @@ type ExecuteTemplate struct {
|
||||||
ManifestFile string
|
ManifestFile string
|
||||||
ManifestDir string
|
ManifestDir string
|
||||||
Sudo bool
|
Sudo bool
|
||||||
|
ExtraArguments string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provisioner) Prepare(raws ...interface{}) error {
|
func (p *Provisioner) Prepare(raws ...interface{}) error {
|
||||||
|
@ -86,6 +90,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
||||||
"{{if ne .HieraConfigPath \"\"}}--hiera_config='{{.HieraConfigPath}}' {{end}}" +
|
"{{if ne .HieraConfigPath \"\"}}--hiera_config='{{.HieraConfigPath}}' {{end}}" +
|
||||||
"{{if ne .ManifestDir \"\"}}--manifestdir='{{.ManifestDir}}' {{end}}" +
|
"{{if ne .ManifestDir \"\"}}--manifestdir='{{.ManifestDir}}' {{end}}" +
|
||||||
"--detailed-exitcodes " +
|
"--detailed-exitcodes " +
|
||||||
|
"{{if ne .ExtraArguments \"\"}}{{.ExtraArguments}} {{end}}" +
|
||||||
"{{.ManifestFile}}"
|
"{{.ManifestFile}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +223,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
||||||
ModulePath: strings.Join(modulePaths, ":"),
|
ModulePath: strings.Join(modulePaths, ":"),
|
||||||
Sudo: !p.config.PreventSudo,
|
Sudo: !p.config.PreventSudo,
|
||||||
WorkingDir: p.config.WorkingDir,
|
WorkingDir: p.config.WorkingDir,
|
||||||
|
ExtraArguments: strings.Join(p.config.ExtraArguments, " "),
|
||||||
}
|
}
|
||||||
command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx)
|
command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package puppetmasterless
|
package puppetmasterless
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testConfig() map[string]interface{} {
|
func testConfig() map[string]interface{} {
|
||||||
|
@ -177,3 +179,86 @@ func TestProvisionerPrepare_facterFacts(t *testing.T) {
|
||||||
t.Fatalf("err: Default facts are not set in the Puppet provisioner!")
|
t.Fatalf("err: Default facts are not set in the Puppet provisioner!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProvisionerPrepare_extraArguments(t *testing.T) {
|
||||||
|
config := testConfig()
|
||||||
|
|
||||||
|
// Test with missing parameter
|
||||||
|
delete(config, "extra_arguments")
|
||||||
|
p := new(Provisioner)
|
||||||
|
err := p.Prepare(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with malformed value
|
||||||
|
config["extra_arguments"] = "{{}}"
|
||||||
|
p = new(Provisioner)
|
||||||
|
err = p.Prepare(config)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should be an error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with valid values
|
||||||
|
config["extra_arguments"] = []string{
|
||||||
|
"arg",
|
||||||
|
}
|
||||||
|
|
||||||
|
p = new(Provisioner)
|
||||||
|
err = p.Prepare(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvisionerProvision_extraArguments(t *testing.T) {
|
||||||
|
config := testConfig()
|
||||||
|
ui := &packer.MachineReadableUi{
|
||||||
|
Writer: ioutil.Discard,
|
||||||
|
}
|
||||||
|
comm := new(packer.MockCommunicator)
|
||||||
|
|
||||||
|
extraArguments := []string{
|
||||||
|
"--some-arg=yup",
|
||||||
|
"--some-other-arg",
|
||||||
|
}
|
||||||
|
config["extra_arguments"] = extraArguments
|
||||||
|
|
||||||
|
// Test with valid values
|
||||||
|
p := new(Provisioner)
|
||||||
|
err := p.Prepare(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.Provision(ui, comm)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedArgs := strings.Join(extraArguments, " ")
|
||||||
|
|
||||||
|
if !strings.Contains(comm.StartCmd.Command, expectedArgs) {
|
||||||
|
t.Fatalf("Command %q doesn't contain the expected arguments %q", comm.StartCmd.Command, expectedArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with missing parameter
|
||||||
|
delete(config, "extra_arguments")
|
||||||
|
|
||||||
|
p = new(Provisioner)
|
||||||
|
err = p.Prepare(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.Provision(ui, comm)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the expected `extra_arguments` position for an empty value
|
||||||
|
splitCommand := strings.Split(comm.StartCmd.Command, " ")
|
||||||
|
if "" == splitCommand[len(splitCommand)-2] {
|
||||||
|
t.Fatalf("Command %q contains an extra-space which may cause arg parsing issues", comm.StartCmd.Command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
# This script builds the application from source for multiple platforms.
|
# This script builds the application from source for multiple platforms.
|
||||||
set -e
|
set -e
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Get the parent directory of where this script is.
|
# Get the parent directory of where this script is.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Get the parent directory of where this script is.
|
# Get the parent directory of where this script is.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Set the tmpdir
|
# Set the tmpdir
|
||||||
if [ -z "$TMPDIR" ]; then
|
if [ -z "$TMPDIR" ]; then
|
||||||
|
|
|
@ -278,7 +278,7 @@ Here is an example using the optional AMI tags. This will add the tags
|
||||||
|
|
||||||
-> **Note:** Packer uses pre-built AMIs as the source for building images.
|
-> **Note:** Packer uses pre-built AMIs as the source for building images.
|
||||||
These source AMIs may include volumes that are not flagged to be destroyed on
|
These source AMIs may include volumes that are not flagged to be destroyed on
|
||||||
termiation of the instance building the new image. Packer will attempt to clean
|
termination of the instance building the new image. Packer will attempt to clean
|
||||||
up all residual volumes that are not designated by the user to remain after
|
up all residual volumes that are not designated by the user to remain after
|
||||||
termination. If you need to preserve those source volumes, you can overwrite the
|
termination. If you need to preserve those source volumes, you can overwrite the
|
||||||
termination setting by specifying `delete_on_termination=false` in the
|
termination setting by specifying `delete_on_termination=false` in the
|
||||||
|
|
|
@ -101,6 +101,7 @@ Packer to work:
|
||||||
"ec2:DeleteSecurityGroup",
|
"ec2:DeleteSecurityGroup",
|
||||||
"ec2:AuthorizeSecurityGroupIngress",
|
"ec2:AuthorizeSecurityGroupIngress",
|
||||||
"ec2:CreateImage",
|
"ec2:CreateImage",
|
||||||
|
"ec2:CopyImage",
|
||||||
"ec2:RunInstances",
|
"ec2:RunInstances",
|
||||||
"ec2:TerminateInstances",
|
"ec2:TerminateInstances",
|
||||||
"ec2:StopInstances",
|
"ec2:StopInstances",
|
||||||
|
|
|
@ -136,6 +136,12 @@ builder.
|
||||||
- `disk_size` (integer) - The size, in megabytes, of the hard disk to create
|
- `disk_size` (integer) - The size, in megabytes, of the hard disk to create
|
||||||
for the VM. By default, this is 40000 (about 40 GB).
|
for the VM. By default, this is 40000 (about 40 GB).
|
||||||
|
|
||||||
|
- `skip_compaction` (boolean) - Packer compacts the QCOW2 image using `qemu-img convert`.
|
||||||
|
Set this option to `true` to disable compacting. Defaults to `false`.
|
||||||
|
|
||||||
|
- `disk_compression` (boolean) - Apply compression to the QCOW2 disk file
|
||||||
|
using `qemu-img convert`. Defaults to `false`.
|
||||||
|
|
||||||
- `floppy_files` (array of strings) - A list of files to place onto a floppy
|
- `floppy_files` (array of strings) - A list of files to place onto a floppy
|
||||||
disk that is attached when the VM is booted. This is most useful for
|
disk that is attached when the VM is booted. This is most useful for
|
||||||
unattended Windows installs, which look for an `Autounattend.xml` file on
|
unattended Windows installs, which look for an `Autounattend.xml` file on
|
||||||
|
|
|
@ -58,10 +58,36 @@ any logging to be enabled.
|
||||||
### Debugging Packer in Powershell/Windows
|
### Debugging Packer in Powershell/Windows
|
||||||
|
|
||||||
In Windows you can set the detailed logs environmental variable `PACKER_LOG` or
|
In Windows you can set the detailed logs environmental variable `PACKER_LOG` or
|
||||||
the log variable `PACKER_LOG_PATH` using powershell environment variables. For example:
|
the log variable `PACKER_LOG_PATH` using powershell environment variables. For
|
||||||
|
example:
|
||||||
|
|
||||||
$env:PACKER_LOG=1
|
$env:PACKER_LOG=1
|
||||||
$env:PACKER_LOG_PATH="packerlog.txt"
|
$env:PACKER_LOG_PATH="packerlog.txt"
|
||||||
|
|
||||||
If you find a bug with Packer, please include the detailed log by using a
|
If you find a bug with Packer, please include the detailed log by using a
|
||||||
service such as [gist](http://gist.github.com).
|
service such as [gist](http://gist.github.com).
|
||||||
|
|
||||||
|
## Issues Installing Ubuntu Packages
|
||||||
|
|
||||||
|
Issues may arise using and building Ubuntu AMIs where common packages that
|
||||||
|
*should* be installed from Ubuntu's Main repository are not found during a
|
||||||
|
provisioner step:
|
||||||
|
|
||||||
|
amazon-ebs: No candidate version found for build-essential
|
||||||
|
amazon-ebs: No candidate version found for build-essential
|
||||||
|
|
||||||
|
This, obviously can cause problems where a build is unable to finish
|
||||||
|
successfully as the proper packages cannot be provisioned correctly. The problem
|
||||||
|
arises when cloud-init has not finished fully running on the source AMI by the
|
||||||
|
time that packer starts any provisioning steps.
|
||||||
|
|
||||||
|
Adding the following provisioner to the packer template, allows for the
|
||||||
|
cloud-init process to fully finish before packer starts provisioning the source
|
||||||
|
AMI.
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"inline": [
|
||||||
|
"while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo 'Waiting for cloud-init...'; sleep 1; done"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -59,6 +59,12 @@ Optional parameters:
|
||||||
variables](/docs/templates/configuration-templates.html) available. See
|
variables](/docs/templates/configuration-templates.html) available. See
|
||||||
below for more information.
|
below for more information.
|
||||||
|
|
||||||
|
- `extra_arguments` (array of strings) - This is an array of additional options to
|
||||||
|
pass to the puppet command when executing puppet. This allows for
|
||||||
|
customization of the `execute_command` without having to completely replace
|
||||||
|
or include it's contents, making forward-compatible customizations much
|
||||||
|
easier.
|
||||||
|
|
||||||
- `facter` (object of key/value strings) - Additional
|
- `facter` (object of key/value strings) - Additional
|
||||||
[facts](http://puppetlabs.com/puppet/related-projects/facter) to make
|
[facts](http://puppetlabs.com/puppet/related-projects/facter) to make
|
||||||
available when Puppet is running.
|
available when Puppet is running.
|
||||||
|
|
|
@ -38,6 +38,9 @@ Optional:
|
||||||
has more detailed usage instructions. By default, no arguments are sent to
|
has more detailed usage instructions. By default, no arguments are sent to
|
||||||
the script.
|
the script.
|
||||||
|
|
||||||
|
- `disable_sudo` (boolean) - By default, the bootstrap install command is prefixed with `sudo`. When using a
|
||||||
|
Docker builder, you will likely want to pass `true` since `sudo` is often not pre-installed.
|
||||||
|
|
||||||
- `remote_pillar_roots` (string) - The path to your remote [pillar
|
- `remote_pillar_roots` (string) - The path to your remote [pillar
|
||||||
roots](http://docs.saltstack.com/ref/configuration/master.html#pillar-configuration).
|
roots](http://docs.saltstack.com/ref/configuration/master.html#pillar-configuration).
|
||||||
default: `/srv/pillar`.
|
default: `/srv/pillar`.
|
||||||
|
|
Loading…
Reference in New Issue