diff --git a/provisioner/file/provisioner.go b/provisioner/file/provisioner.go index b3283b20c..a0e8d2465 100644 --- a/provisioner/file/provisioner.go +++ b/provisioner/file/provisioner.go @@ -26,6 +26,9 @@ type Config struct { // Direction Direction string + // False if the sources have to exist. + Generated bool + ctx interpolate.Context } @@ -61,7 +64,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { if p.config.Direction == "upload" { for _, src := range p.config.Sources { - if _, err := os.Stat(src); err != nil { + if _, err := os.Stat(src); p.config.Generated == false && err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("Bad source '%s': %s", src, err)) } diff --git a/provisioner/file/provisioner_test.go b/provisioner/file/provisioner_test.go index 762eb83f8..175082aae 100644 --- a/provisioner/file/provisioner_test.go +++ b/provisioner/file/provisioner_test.go @@ -45,6 +45,12 @@ func TestProvisionerPrepare_InvalidSource(t *testing.T) { if err == nil { t.Fatalf("should require existing file") } + + config["generated"] = false + err = p.Prepare(config) + if err == nil { + t.Fatalf("should required existing file") + } } func TestProvisionerPrepare_ValidSource(t *testing.T) { @@ -58,13 +64,30 @@ func TestProvisionerPrepare_ValidSource(t *testing.T) { config := testConfig() config["source"] = tf.Name() + err = p.Prepare(config) + if err != nil { + t.Fatalf("should allow valid file: %s", err) + } + config["generated"] = false err = p.Prepare(config) if err != nil { t.Fatalf("should allow valid file: %s", err) } } +func TestProvisionerPrepare_GeneratedSource(t *testing.T) { + var p Provisioner + + config := testConfig() + config["source"] = "/this/should/not/exist" + config["generated"] = true + err := p.Prepare(config) + if err != nil { + t.Fatalf("should allow non-existing file: %s", err) + } +} + func TestProvisionerPrepare_EmptyDestination(t *testing.T) { var p Provisioner diff --git a/website/source/docs/provisioners/file.html.md b/website/source/docs/provisioners/file.html.md index 0405e8db5..0dc2e1d01 100644 --- a/website/source/docs/provisioners/file.html.md +++ b/website/source/docs/provisioners/file.html.md @@ -48,6 +48,9 @@ The available configuration options are listed below. All elements are required. "upload". If it is set to "download" then the file "source" in the machine will be downloaded locally to "destination" +- `generated` (boolean) - If true, check the file existence only before uploading. + This allows to upload files created on-the-fly. This defaults to false. + ## Directory Uploads The file provisioner is also able to upload a complete directory to the remote