github.com/mitchellh/packer@v1.3.2/builder/file/builder.go (about)

     1  package file
     2  
     3  /*
     4  The File builder creates an artifact from a file. Because it does not require
     5  any virtualization or network resources, it's very fast and useful for testing.
     6  */
     7  
     8  import (
     9  	"fmt"
    10  	"io"
    11  	"io/ioutil"
    12  	"os"
    13  
    14  	"github.com/hashicorp/packer/helper/multistep"
    15  	"github.com/hashicorp/packer/packer"
    16  )
    17  
    18  const BuilderId = "packer.file"
    19  
    20  type Builder struct {
    21  	config *Config
    22  	runner multistep.Runner
    23  }
    24  
    25  func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
    26  	c, warnings, errs := NewConfig(raws...)
    27  	if errs != nil {
    28  		return warnings, errs
    29  	}
    30  	b.config = c
    31  
    32  	return warnings, nil
    33  }
    34  
    35  // Run is where the actual build should take place. It takes a Build and a Ui.
    36  func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
    37  	artifact := new(FileArtifact)
    38  
    39  	if b.config.Source != "" {
    40  		source, err := os.Open(b.config.Source)
    41  		defer source.Close()
    42  		if err != nil {
    43  			return nil, err
    44  		}
    45  
    46  		// Create will truncate an existing file
    47  		target, err := os.Create(b.config.Target)
    48  		defer target.Close()
    49  		if err != nil {
    50  			return nil, err
    51  		}
    52  
    53  		ui.Say(fmt.Sprintf("Copying %s to %s", source.Name(), target.Name()))
    54  		bytes, err := io.Copy(target, source)
    55  		if err != nil {
    56  			return nil, err
    57  		}
    58  		ui.Say(fmt.Sprintf("Copied %d bytes", bytes))
    59  		artifact.filename = target.Name()
    60  	} else {
    61  		// We're going to write Contents; if it's empty we'll just create an
    62  		// empty file.
    63  		err := ioutil.WriteFile(b.config.Target, []byte(b.config.Content), 0600)
    64  		if err != nil {
    65  			return nil, err
    66  		}
    67  		artifact.filename = b.config.Target
    68  	}
    69  
    70  	return artifact, nil
    71  }
    72  
    73  // Cancel cancels a possibly running Builder. This should block until
    74  // the builder actually cancels and cleans up after itself.
    75  func (b *Builder) Cancel() {
    76  	b.runner.Cancel()
    77  }