builder/amazon/chroot: switch to new template stuff

This commit is contained in:
Mitchell Hashimoto 2013-08-08 14:54:37 -07:00
parent a669b4dbd0
commit 28e72c7f7b
4 changed files with 58 additions and 35 deletions

View File

@ -14,7 +14,6 @@ import (
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"log" "log"
"runtime" "runtime"
"text/template"
) )
// The unique ID for this builder // The unique ID for this builder
@ -34,6 +33,8 @@ type Config struct {
MountPath string `mapstructure:"mount_path"` MountPath string `mapstructure:"mount_path"`
SourceAmi string `mapstructure:"source_ami"` SourceAmi string `mapstructure:"source_ami"`
UnmountCommand string `mapstructure:"unmount_command"` UnmountCommand string `mapstructure:"unmount_command"`
tpl *common.Template
} }
type Builder struct { type Builder struct {
@ -47,6 +48,11 @@ func (b *Builder) Prepare(raws ...interface{}) error {
return err return err
} }
b.config.tpl, err = common.NewTemplate()
if err != nil {
return err
}
// Defaults // Defaults
if b.config.ChrootMounts == nil { if b.config.ChrootMounts == nil {
b.config.ChrootMounts = make([][]string, 0) b.config.ChrootMounts = make([][]string, 0)
@ -84,31 +90,63 @@ func (b *Builder) Prepare(raws ...interface{}) error {
// Accumulate any errors // Accumulate any errors
errs := common.CheckUnusedConfig(md) errs := common.CheckUnusedConfig(md)
errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare()...) errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(b.config.tpl)...)
if b.config.AMIName == "" { if b.config.AMIName == "" {
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
errs, errors.New("ami_name must be specified")) errs, errors.New("ami_name must be specified"))
} else { } else if b.config.AMIName, err = b.config.tpl.Process(b.config.AMIName, nil); err != nil {
_, err = template.New("ami").Parse(b.config.AMIName) errs = packer.MultiErrorAppend(
if err != nil { errs, fmt.Errorf("Error processing ami_name: %s", err))
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Failed parsing ami_name: %s", err))
}
} }
for _, mounts := range b.config.ChrootMounts { for i, mounts := range b.config.ChrootMounts {
if len(mounts) != 3 { if len(mounts) != 3 {
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
errs, errors.New("Each chroot_mounts entry should be three elements.")) errs, errors.New("Each chroot_mounts entry should be three elements."))
break break
} }
for j, entry := range mounts {
b.config.ChrootMounts[i][j], err = b.config.tpl.Process(entry, nil)
if err != nil {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("Error processing chroot_mounts[%d][%d]: %s",
i, j, err))
}
}
}
for i, file := range b.config.CopyFiles {
var err error
b.config.CopyFiles[i], err = b.config.tpl.Process(file, nil)
if err != nil {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("Error processing copy_files[%d]: %s",
i, err))
}
} }
if b.config.SourceAmi == "" { if b.config.SourceAmi == "" {
errs = packer.MultiErrorAppend(errs, errors.New("source_ami is required.")) errs = packer.MultiErrorAppend(errs, errors.New("source_ami is required."))
} }
templates := map[string]*string{
"device_path": &b.config.DevicePath,
"mount_command": &b.config.MountCommand,
"source_ami": &b.config.SourceAmi,
"unmount_command": &b.config.UnmountCommand,
}
for n, ptr := range templates {
var err error
*ptr, err = b.config.tpl.Process(*ptr, nil)
if err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Error processing %s: %s", n, err))
}
}
if errs != nil && len(errs.Errors) > 0 { if errs != nil && len(errs.Errors) > 0 {
return errs return errs
} }

View File

@ -9,7 +9,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"text/template"
) )
type mountPathData struct { type mountPathData struct {
@ -30,14 +29,17 @@ func (s *StepMountDevice) Run(state map[string]interface{}) multistep.StepAction
ui := state["ui"].(packer.Ui) ui := state["ui"].(packer.Ui)
device := state["device"].(string) device := state["device"].(string)
mountPathRaw := new(bytes.Buffer) mountPath, err := config.tpl.Process(config.MountPath, &mountPathData{
t := template.Must(template.New("mountPath").Parse(config.MountPath))
t.Execute(mountPathRaw, &mountPathData{
Device: filepath.Base(device), Device: filepath.Base(device),
}) })
var err error if err != nil {
mountPath := mountPathRaw.String() err := fmt.Errorf("Error preparing mount directory: %s", err)
state["error"] = err
ui.Error(err.Error())
return multistep.ActionHalt
}
mountPath, err = filepath.Abs(mountPath) mountPath, err = filepath.Abs(mountPath)
if err != nil { if err != nil {
err := fmt.Errorf("Error preparing mount directory: %s", err) err := fmt.Errorf("Error preparing mount directory: %s", err)

View File

@ -1,21 +1,13 @@
package chroot package chroot
import ( import (
"bytes"
"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"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"strconv"
"text/template"
"time"
) )
type amiNameData struct {
CreateTime string
}
// StepRegisterAMI creates the AMI. // StepRegisterAMI creates the AMI.
type StepRegisterAMI struct{} type StepRegisterAMI struct{}
@ -26,16 +18,6 @@ func (s *StepRegisterAMI) Run(state map[string]interface{}) multistep.StepAction
snapshotId := state["snapshot_id"].(string) snapshotId := state["snapshot_id"].(string)
ui := state["ui"].(packer.Ui) ui := state["ui"].(packer.Ui)
// Parse the name of the AMI
amiNameBuf := new(bytes.Buffer)
tData := amiNameData{
strconv.FormatInt(time.Now().UTC().Unix(), 10),
}
t := template.Must(template.New("ami").Parse(config.AMIName))
t.Execute(amiNameBuf, tData)
amiName := amiNameBuf.String()
ui.Say("Registering the AMI...") ui.Say("Registering the AMI...")
blockDevices := make([]ec2.BlockDeviceMapping, len(image.BlockDevices)) blockDevices := make([]ec2.BlockDeviceMapping, len(image.BlockDevices))
for i, device := range image.BlockDevices { for i, device := range image.BlockDevices {
@ -48,7 +30,7 @@ func (s *StepRegisterAMI) Run(state map[string]interface{}) multistep.StepAction
} }
registerOpts := &ec2.RegisterImage{ registerOpts := &ec2.RegisterImage{
Name: amiName, Name: config.AMIName,
Architecture: image.Architecture, Architecture: image.Architecture,
KernelId: image.KernelId, KernelId: image.KernelId,
RamdiskId: image.RamdiskId, RamdiskId: image.RamdiskId,

View File

@ -59,7 +59,8 @@ func (b *Builder) Prepare(raws ...interface{}) error {
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
errs, errors.New("ami_name must be specified")) errs, errors.New("ami_name must be specified"))
} else if b.config.AMIName, err = b.config.tpl.Process(b.config.AMIName, nil); err != nil { } else if b.config.AMIName, err = b.config.tpl.Process(b.config.AMIName, nil); err != nil {
errs = packer.MultiErrorAppend(errs, err) errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Error processing ami_name: %s", err))
} }
newTags := make(map[string]string) newTags := make(map[string]string)