diff --git a/command/fix/command.go b/command/fix/command.go index 9d4cc8115..e77a928bb 100644 --- a/command/fix/command.go +++ b/command/fix/command.go @@ -52,6 +52,7 @@ func (c Command) Run(env packer.Environment, args []string) int { // Run the template through the various fixers fixers := []string{ "iso-md5", + "createtime", } input := templateData diff --git a/command/fix/fixer.go b/command/fix/fixer.go index 7a754225a..58e172800 100644 --- a/command/fix/fixer.go +++ b/command/fix/fixer.go @@ -13,6 +13,7 @@ var Fixers map[string]Fixer func init() { Fixers = map[string]Fixer{ - "iso-md5": new(FixerISOMD5), + "iso-md5": new(FixerISOMD5), + "createtime": new(FixerCreateTime), } } diff --git a/command/fix/fixer_createtime.go b/command/fix/fixer_createtime.go new file mode 100644 index 000000000..b2640619c --- /dev/null +++ b/command/fix/fixer_createtime.go @@ -0,0 +1,51 @@ +package fix + +import ( + "github.com/mitchellh/mapstructure" + "regexp" +) + +// FixerCreateTime is a Fixer that replaces the ".CreateTime" template +// calls with "{{timestamp}" +type FixerCreateTime struct{} + +func (FixerCreateTime) Fix(input map[string]interface{}) (map[string]interface{}, error) { + // Our template type we'll use for this fixer only + type template struct { + Builders []map[string]interface{} + } + + // Decode the input into our structure, if we can + var tpl template + if err := mapstructure.Decode(input, &tpl); err != nil { + return nil, err + } + + badKeys := []string{ + "ami_name", + "bundle_prefix", + "snapshot_name", + } + + re := regexp.MustCompile(`{{\s*\.CreateTime\s*}}`) + + // Go through each builder and replace CreateTime if we can + for _, builder := range tpl.Builders { + for _, key := range badKeys { + raw, ok := builder[key] + if !ok { + continue + } + + v, ok := raw.(string) + if !ok { + continue + } + + builder[key] = re.ReplaceAllString(v, "{{timestamp}}") + } + } + + input["builders"] = tpl.Builders + return input, nil +} diff --git a/command/fix/fixer_createtime_test.go b/command/fix/fixer_createtime_test.go new file mode 100644 index 000000000..23736aa0f --- /dev/null +++ b/command/fix/fixer_createtime_test.go @@ -0,0 +1,45 @@ +package fix + +import ( + "reflect" + "testing" +) + +func TestFixerCreateTime_Impl(t *testing.T) { + var raw interface{} + raw = new(FixerCreateTime) + if _, ok := raw.(Fixer); !ok { + t.Fatalf("must be a Fixer") + } +} + +func TestFixerCreateTime_Fix(t *testing.T) { + var f FixerCreateTime + + input := map[string]interface{}{ + "builders": []interface{}{ + map[string]string{ + "type": "foo", + "ami_name": "{{.CreateTime}} foo", + }, + }, + } + + expected := map[string]interface{}{ + "builders": []map[string]interface{}{ + map[string]interface{}{ + "type": "foo", + "ami_name": "{{timestamp}} foo", + }, + }, + } + + output, err := f.Fix(input) + if err != nil { + t.Fatalf("err: %s", err) + } + + if !reflect.DeepEqual(output, expected) { + t.Fatalf("unexpected: %#v\nexpected: %#v\n", output, expected) + } +}