diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index f2f3a10e8..c940a7bfb 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -53,6 +53,7 @@ func (b *Builder) Prepare(raws ...interface{}) error { return err } b.config.tpl.UserVars = b.config.PackerUserVars + b.config.tpl.Funcs(awscommon.TemplateFuncs) // Defaults if b.config.ChrootMounts == nil { diff --git a/builder/amazon/common/template_funcs.go b/builder/amazon/common/template_funcs.go new file mode 100644 index 000000000..45f68af92 --- /dev/null +++ b/builder/amazon/common/template_funcs.go @@ -0,0 +1,38 @@ +package common + +import ( + "bytes" + "text/template" +) + +func isalphanumeric(b byte) bool { + if '0' <= b && b <= '9' { + return true + } + if 'a' <= b && b <= 'z' { + return true + } + if 'A' <= b && b <= 'Z' { + return true + } + return false +} + +// Clean up AMI name by replacing invalid characters with "-" +func templateCleanAMIName(s string) string { + allowed := []byte{'(', ')', ',', '/', '-', '_'} + b := []byte(s) + newb := make([]byte, len(b)) + for i, c := range b { + if isalphanumeric(c) || bytes.IndexByte(allowed, c) != -1 { + newb[i] = c + } else { + newb[i] = '-' + } + } + return string(newb[:]) +} + +var TemplateFuncs = template.FuncMap{ + "clean_ami_name": templateCleanAMIName, +} diff --git a/builder/amazon/common/template_funcs_test.go b/builder/amazon/common/template_funcs_test.go new file mode 100644 index 000000000..0e8c568ef --- /dev/null +++ b/builder/amazon/common/template_funcs_test.go @@ -0,0 +1,16 @@ +package common + +import ( + "testing" +) + +func TestAMITemplatePrepare_clean(t *testing.T) { + origName := "AMZamz09(),/-_:&^$%" + expected := "AMZamz09(),/-_-----" + + name := templateCleanAMIName(origName) + + if name != expected { + t.Fatalf("template names do not match: expected %s got %s\n", expected, name) + } +} diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 453102e3d..194e10bc9 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -44,6 +44,7 @@ func (b *Builder) Prepare(raws ...interface{}) error { return err } b.config.tpl.UserVars = b.config.PackerUserVars + b.config.tpl.Funcs(awscommon.TemplateFuncs) // Accumulate any errors errs := common.CheckUnusedConfig(md) diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 9b9c6d953..071e0e24e 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -56,6 +56,7 @@ func (b *Builder) Prepare(raws ...interface{}) error { return err } b.config.tpl.UserVars = b.config.PackerUserVars + b.config.tpl.Funcs(awscommon.TemplateFuncs) if b.config.BundleDestination == "" { b.config.BundleDestination = "/tmp" diff --git a/packer/config_template.go b/packer/config_template.go index 1f46cf92f..895e11682 100644 --- a/packer/config_template.go +++ b/packer/config_template.go @@ -63,6 +63,11 @@ func (t *ConfigTemplate) Validate(s string) error { return err } +// Add additional functions to the template +func (t *ConfigTemplate) Funcs(funcs template.FuncMap) { + t.root.Funcs(funcs) +} + func (t *ConfigTemplate) nextTemplateName() string { name := fmt.Sprintf("tpl%d", t.i) t.i++