github.com/askholme/packer@v0.7.2-0.20140924152349-70d9566a6852/post-processor/docker-save/post-processor.go (about)

     1  package dockersave
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/mitchellh/packer/builder/docker"
     6  	"github.com/mitchellh/packer/common"
     7  	"github.com/mitchellh/packer/packer"
     8  	"github.com/mitchellh/packer/post-processor/docker-import"
     9  	"os"
    10  )
    11  
    12  const BuilderId = "packer.post-processor.docker-save"
    13  
    14  type Config struct {
    15  	common.PackerConfig `mapstructure:",squash"`
    16  
    17  	Path string `mapstructure:"path"`
    18  
    19  	tpl *packer.ConfigTemplate
    20  }
    21  
    22  type PostProcessor struct {
    23  	Driver docker.Driver
    24  
    25  	config Config
    26  }
    27  
    28  func (p *PostProcessor) Configure(raws ...interface{}) error {
    29  	_, err := common.DecodeConfig(&p.config, raws...)
    30  	if err != nil {
    31  		return err
    32  	}
    33  
    34  	p.config.tpl, err = packer.NewConfigTemplate()
    35  	if err != nil {
    36  		return err
    37  	}
    38  	p.config.tpl.UserVars = p.config.PackerUserVars
    39  
    40  	// Accumulate any errors
    41  	errs := new(packer.MultiError)
    42  
    43  	templates := map[string]*string{
    44  		"path": &p.config.Path,
    45  	}
    46  
    47  	for key, ptr := range templates {
    48  		if *ptr == "" {
    49  			errs = packer.MultiErrorAppend(
    50  				errs, fmt.Errorf("%s must be set", key))
    51  		}
    52  
    53  		*ptr, err = p.config.tpl.Process(*ptr, nil)
    54  		if err != nil {
    55  			errs = packer.MultiErrorAppend(
    56  				errs, fmt.Errorf("Error processing %s: %s", key, err))
    57  		}
    58  	}
    59  
    60  	if len(errs.Errors) > 0 {
    61  		return errs
    62  	}
    63  
    64  	return nil
    65  
    66  }
    67  
    68  func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
    69  	if artifact.BuilderId() != dockerimport.BuilderId {
    70  		err := fmt.Errorf(
    71  			"Unknown artifact type: %s\nCan only save Docker builder artifacts.",
    72  			artifact.BuilderId())
    73  		return nil, false, err
    74  	}
    75  
    76  	path := p.config.Path
    77  
    78  	// Open the file that we're going to write to
    79  	f, err := os.Create(path)
    80  	if err != nil {
    81  		err := fmt.Errorf("Error creating output file: %s", err)
    82  		return nil, false, err
    83  	}
    84  
    85  	driver := p.Driver
    86  	if driver == nil {
    87  		// If no driver is set, then we use the real driver
    88  		driver = &docker.DockerDriver{Tpl: p.config.tpl, Ui: ui}
    89  	}
    90  
    91  	ui.Message("Saving image: " + artifact.Id())
    92  
    93  	if err := driver.SaveImage(artifact.Id(), f); err != nil {
    94  		f.Close()
    95  		os.Remove(f.Name())
    96  
    97  		return nil, false, err
    98  	}
    99  
   100  	f.Close()
   101  	ui.Message("Saved to: " + path)
   102  
   103  	return artifact, true, nil
   104  }