From 8d6719e71fe5fb6b9a31c031c2e5b5849c8b8030 Mon Sep 17 00:00:00 2001 From: Chris Bednarski Date: Mon, 3 Aug 2015 16:34:24 -0700 Subject: [PATCH 1/5] Add failing test for compress interpolation --- .../compress/post-processor_test.go | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/post-processor/compress/post-processor_test.go b/post-processor/compress/post-processor_test.go index db23cf3b1..fec3b7a72 100644 --- a/post-processor/compress/post-processor_test.go +++ b/post-processor/compress/post-processor_test.go @@ -150,6 +150,35 @@ func TestCompressOptions(t *testing.T) { } } +func TestCompressInterpolation(t *testing.T) { + const config = ` + { + "post-processors": [ + { + "type": "compress", + "output": "{{ .BuildName }}.gz" + } + ] + } + ` + + artifact := testArchive(t, config) + defer artifact.Destroy() + + filename := "file.gz" + archive, err := os.Open(filename) + if err != nil { + t.Fatalf("Unable to read %s: %s", filename, err) + } + + gzipReader, _ := gzip.NewReader(archive) + data, _ := ioutil.ReadAll(gzipReader) + + if string(data) != expectedFileContents { + t.Errorf("Expected:\n%s\nFound:\n%s\n", expectedFileContents, data) + } +} + // Test Helpers func setup(t *testing.T) (packer.Ui, packer.Artifact, error) { From 4ef3baa3eedfc171cd3d66ab7542030693084d24 Mon Sep 17 00:00:00 2001 From: Chris Bednarski Date: Tue, 4 Aug 2015 19:30:57 -0700 Subject: [PATCH 2/5] Update test to include some interpolation configs --- post-processor/compress/post-processor_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/post-processor/compress/post-processor_test.go b/post-processor/compress/post-processor_test.go index fec3b7a72..ea1d973eb 100644 --- a/post-processor/compress/post-processor_test.go +++ b/post-processor/compress/post-processor_test.go @@ -156,7 +156,7 @@ func TestCompressInterpolation(t *testing.T) { "post-processors": [ { "type": "compress", - "output": "{{ .BuildName }}.gz" + "output": "{{ build_name}}-{{ .BuildName }}-{{.BuilderType}}.gz" } ] } @@ -165,7 +165,9 @@ func TestCompressInterpolation(t *testing.T) { artifact := testArchive(t, config) defer artifact.Destroy() - filename := "file.gz" + // You can interpolate using the .BuildName variable or build_name global + // function. We'll check both. + filename := "chocolate-vanilla-file.gz" archive, err := os.Open(filename) if err != nil { t.Fatalf("Unable to read %s: %s", filename, err) @@ -230,6 +232,13 @@ func testArchive(t *testing.T, config string) packer.Artifact { compressor := PostProcessor{} compressor.Configure(tpl.PostProcessors[0][0].Config) + + // I get the feeling these should be automatically available somewhere, but + // some of the post-processors construct this manually. + compressor.config.ctx.BuildName = "chocolate" + compressor.config.PackerBuildName = "vanilla" + compressor.config.PackerBuilderType = "file" + artifactOut, _, err := compressor.PostProcess(ui, artifact) if err != nil { t.Fatalf("Failed to compress artifact: %s", err) From 8f2a9de28e24d76aef02a9863fcf30d7e8623b25 Mon Sep 17 00:00:00 2001 From: Chris Bednarski Date: Tue, 4 Aug 2015 19:46:14 -0700 Subject: [PATCH 3/5] Updated documentation explaining how to use variables in compress post-processor filenames --- .../post-processors/compress.html.markdown | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/website/source/docs/post-processors/compress.html.markdown b/website/source/docs/post-processors/compress.html.markdown index ad78a9315..9236dd0e7 100644 --- a/website/source/docs/post-processors/compress.html.markdown +++ b/website/source/docs/post-processors/compress.html.markdown @@ -15,10 +15,11 @@ VMware or VirtualBox) and compresses the artifact into a single archive. ## Configuration -### Required: +### Optional: -You must specify the output filename. The archive format is derived from the -filename. +By default, packer will build archives in `.tar.gz` format with the following +filename: `packer_{{.BuildName}}_{{.BuilderType}}`. If you want to change this +you will need to specify the `output` option. - `output` (string) - The path to save the compressed archive. The archive format is inferred from the filename. E.g. `.tar.gz` will be a @@ -26,13 +27,9 @@ filename. detected packer defaults to `.tar.gz` behavior but will not change the filename. -If you are executing multiple builders in parallel you should make sure `output` -is unique for each one. For example `packer_{{.BuildName}}_{{.Provider}}.zip`. - -### Optional: - -If you want more control over how the archive is created you can specify the -following settings: + You can use `{{.BuildName}}` and ``{{.BuilderType}}` in your output path. + If you are executing multiple builders in parallel you should make sure + `output` is unique for each one. For example `packer_{{.BuildName}}.zip`. - `compression_level` (integer) - Specify the compression level, for algorithms that support it, from 1 through 9 inclusive. Typically higher @@ -61,14 +58,14 @@ configuration: ``` {.json} { "type": "compress", - "output": "archive.zip" + "output": "{{.BuildName}}_bundle.zip" } ``` ``` {.json} { "type": "compress", - "output": "archive.gz", + "output": "log_{{.BuildName}}.gz", "compression": 9 } ``` From fbb24d4acfa7746a416d48a0556043807a2130e5 Mon Sep 17 00:00:00 2001 From: Chris Bednarski Date: Tue, 4 Aug 2015 19:49:41 -0700 Subject: [PATCH 4/5] Changed interpolation logic so .BuildName can be used in the output config option --- post-processor/compress/post-processor.go | 44 +++++++++++------------ 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/post-processor/compress/post-processor.go b/post-processor/compress/post-processor.go index bb6ce27bf..b95b27bde 100644 --- a/post-processor/compress/post-processor.go +++ b/post-processor/compress/post-processor.go @@ -55,9 +55,12 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { Interpolate: true, InterpolateContext: &p.config.ctx, InterpolateFilter: &interpolate.RenderFilter{ - Exclude: []string{}, + Exclude: []string{"output"}, }, }, raws...) + if err != nil { + return err + } errs := new(packer.MultiError) @@ -67,16 +70,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { } if p.config.OutputPath == "" { - p.config.OutputPath = "packer_{{.BuildName}}_{{.Provider}}" - } - - if err = interpolate.Validate(p.config.OutputPath, &p.config.ctx); err != nil { - errs = packer.MultiErrorAppend( - errs, fmt.Errorf("Error parsing target template: %s", err)) - } - - templates := map[string]*string{ - "output": &p.config.OutputPath, + p.config.OutputPath = "packer_{{.BuildName}}_{{.BuilderType}}" } if p.config.CompressionLevel > pgzip.BestCompression { @@ -89,17 +83,9 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { p.config.CompressionLevel = pgzip.DefaultCompression } - for key, ptr := range templates { - if *ptr == "" { - errs = packer.MultiErrorAppend( - errs, fmt.Errorf("%s must be set", key)) - } - - *ptr, err = interpolate.Render(p.config.OutputPath, &p.config.ctx) - if err != nil { - errs = packer.MultiErrorAppend( - errs, fmt.Errorf("Error processing %s: %s", key, err)) - } + if err = interpolate.Validate(p.config.OutputPath, &p.config.ctx); err != nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("Error parsing target template: %s", err)) } p.config.detectFromFilename() @@ -113,7 +99,19 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { - target := p.config.OutputPath + // These are extra variables that will be made available for interpolation. + p.config.ctx.Data = map[string]string{ + "BuildName": p.config.PackerBuildName, + "BuilderType": p.config.PackerBuilderType, + } + + target, err := interpolate.Render(p.config.OutputPath, &p.config.ctx) + if err != nil { + return nil, false, fmt.Errorf("Error interpolating output value: %s", err) + } else { + fmt.Println(target) + } + keep := p.config.KeepInputArtifact newArtifact := &Artifact{Path: target} From 1c956ff406c8d03c88cd6f4af90b5e09c5256463 Mon Sep 17 00:00:00 2001 From: Chris Bednarski Date: Tue, 4 Aug 2015 20:11:53 -0700 Subject: [PATCH 5/5] Removed errant backtick --- website/source/docs/post-processors/compress.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/post-processors/compress.html.markdown b/website/source/docs/post-processors/compress.html.markdown index 9236dd0e7..3834ffc72 100644 --- a/website/source/docs/post-processors/compress.html.markdown +++ b/website/source/docs/post-processors/compress.html.markdown @@ -27,7 +27,7 @@ you will need to specify the `output` option. detected packer defaults to `.tar.gz` behavior but will not change the filename. - You can use `{{.BuildName}}` and ``{{.BuilderType}}` in your output path. + You can use `{{.BuildName}}` and `{{.BuilderType}}` in your output path. If you are executing multiple builders in parallel you should make sure `output` is unique for each one. For example `packer_{{.BuildName}}.zip`.