Changed file builder to support content or source file operation
This commit is contained in:
parent
f7d85eb49c
commit
e60b22d48f
|
@ -6,7 +6,10 @@ any virutalization or network resources, it's very fast and useful for testing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
|
@ -47,7 +50,35 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
|
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
|
||||||
artifact := new(FileArtifact)
|
artifact := new(FileArtifact)
|
||||||
|
|
||||||
ioutil.WriteFile(b.config.Filename, []byte(b.config.Contents), 0600)
|
if b.config.Source != "" {
|
||||||
|
source, err := os.Open(b.config.Source)
|
||||||
|
defer source.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
target, err := os.OpenFile(b.config.Target, os.O_WRONLY, 0600)
|
||||||
|
defer target.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Say(fmt.Sprintf("Copying %s to %s", source.Name(), target.Name()))
|
||||||
|
bytes, err := io.Copy(source, target)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ui.Say(fmt.Sprintf("Copied %d bytes", bytes))
|
||||||
|
artifact.filename = target.Name()
|
||||||
|
} else {
|
||||||
|
// We're going to write Contents; if it's empty we'll just create an
|
||||||
|
// empty file.
|
||||||
|
err := ioutil.WriteFile(b.config.Target, []byte(b.config.Content), 0600)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
artifact.filename = b.config.Target
|
||||||
|
}
|
||||||
|
|
||||||
return artifact, nil
|
return artifact, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,15 @@ import (
|
||||||
"github.com/mitchellh/packer/template/interpolate"
|
"github.com/mitchellh/packer/template/interpolate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrTargetRequired = fmt.Errorf("target required")
|
||||||
|
var ErrContentSourceConflict = fmt.Errorf("Cannot specify source file AND content")
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
common.PackerConfig `mapstructure:",squash"`
|
common.PackerConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
Filename string `mapstructure:"filename"`
|
Source string `mapstructure:"source"`
|
||||||
Contents string `mapstructure:"contents"`
|
Target string `mapstructure:"target"`
|
||||||
|
Content string `mapstructure:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||||
|
@ -32,12 +36,16 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||||
|
|
||||||
var errs *packer.MultiError
|
var errs *packer.MultiError
|
||||||
|
|
||||||
if c.Filename == "" {
|
if c.Target == "" {
|
||||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("filename is required"))
|
errs = packer.MultiErrorAppend(errs, ErrTargetRequired)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Contents == "" {
|
if c.Content == "" && c.Source == "" {
|
||||||
warnings = append(warnings, "contents is empty")
|
warnings = append(warnings, "Both source file and contents are blank; target will have no content")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Content != "" && c.Source != "" {
|
||||||
|
errs = packer.MultiErrorAppend(errs, ErrContentSourceConflict)
|
||||||
}
|
}
|
||||||
|
|
||||||
if errs != nil && len(errs.Errors) > 0 {
|
if errs != nil && len(errs.Errors) > 0 {
|
||||||
|
|
|
@ -2,13 +2,24 @@ package file
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testConfig() map[string]interface{} {
|
func testConfig() map[string]interface{} {
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"filename": "test.txt",
|
"source": "src.txt",
|
||||||
"contents": "Hello, world!",
|
"target": "dst.txt",
|
||||||
|
"content": "Hello, world!",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContentSourceConflict(t *testing.T) {
|
||||||
|
raw := testConfig()
|
||||||
|
|
||||||
|
_, _, errs := NewConfig(raw)
|
||||||
|
if !strings.Contains(errs.Error(), ErrContentSourceConflict.Error()) {
|
||||||
|
t.Errorf("Expected config error: %s", ErrContentSourceConflict.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,18 +29,19 @@ func TestNoFilename(t *testing.T) {
|
||||||
delete(raw, "filename")
|
delete(raw, "filename")
|
||||||
_, _, errs := NewConfig(raw)
|
_, _, errs := NewConfig(raw)
|
||||||
if errs == nil {
|
if errs == nil {
|
||||||
t.Error("Expected config to error without a filename")
|
t.Errorf("Expected config error: %s", ErrTargetRequired.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNoContent(t *testing.T) {
|
func TestNoContent(t *testing.T) {
|
||||||
raw := testConfig()
|
raw := testConfig()
|
||||||
|
|
||||||
delete(raw, "contents")
|
delete(raw, "content")
|
||||||
|
delete(raw, "source")
|
||||||
_, warns, _ := NewConfig(raw)
|
_, warns, _ := NewConfig(raw)
|
||||||
fmt.Println(len(warns))
|
fmt.Println(len(warns))
|
||||||
fmt.Printf("%#v\n", warns)
|
fmt.Printf("%#v\n", warns)
|
||||||
if len(warns) == 0 {
|
if len(warns) == 0 {
|
||||||
t.Error("Expected config to warn without any content")
|
t.Error("Expected config warning without any content")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue