github.com/daniellockard/packer@v0.7.6-0.20141210173435-5a9390934716/post-processor/docker-push/post-processor.go (about)

     1  package dockerpush
     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  	"github.com/mitchellh/packer/post-processor/docker-tag"
    10  	"strings"
    11  )
    12  
    13  type Config struct {
    14  	common.PackerConfig `mapstructure:",squash"`
    15  
    16  	Login         bool
    17  	LoginEmail    string `mapstructure:"login_email"`
    18  	LoginUsername string `mapstructure:"login_username"`
    19  	LoginPassword string `mapstructure:"login_password"`
    20  	LoginServer   string `mapstructure:"login_server"`
    21  
    22  	tpl *packer.ConfigTemplate
    23  }
    24  
    25  type PostProcessor struct {
    26  	Driver docker.Driver
    27  
    28  	config Config
    29  }
    30  
    31  func (p *PostProcessor) Configure(raws ...interface{}) error {
    32  	_, err := common.DecodeConfig(&p.config, raws...)
    33  	if err != nil {
    34  		return err
    35  	}
    36  
    37  	p.config.tpl, err = packer.NewConfigTemplate()
    38  	if err != nil {
    39  		return err
    40  	}
    41  	p.config.tpl.UserVars = p.config.PackerUserVars
    42  
    43  	// Accumulate any errors
    44  	errs := new(packer.MultiError)
    45  
    46  	// Process templates
    47  	templates := map[string]*string{
    48  		"login_email":    &p.config.LoginEmail,
    49  		"login_username": &p.config.LoginUsername,
    50  		"login_password": &p.config.LoginPassword,
    51  		"login_server":   &p.config.LoginServer,
    52  	}
    53  
    54  	for n, ptr := range templates {
    55  		var err error
    56  		*ptr, err = p.config.tpl.Process(*ptr, nil)
    57  		if err != nil {
    58  			errs = packer.MultiErrorAppend(
    59  				errs, fmt.Errorf("Error processing %s: %s", n, err))
    60  		}
    61  	}
    62  
    63  	if len(errs.Errors) > 0 {
    64  		return errs
    65  	}
    66  
    67  	return nil
    68  }
    69  
    70  func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
    71  	if artifact.BuilderId() != dockerimport.BuilderId &&
    72  		artifact.BuilderId() != dockertag.BuilderId {
    73  		err := fmt.Errorf(
    74  			"Unknown artifact type: %s\nCan only import from docker-import and docker-tag artifacts.",
    75  			artifact.BuilderId())
    76  		return nil, false, err
    77  	}
    78  
    79  	driver := p.Driver
    80  	if driver == nil {
    81  		// If no driver is set, then we use the real driver
    82  		driver = &docker.DockerDriver{Tpl: p.config.tpl, Ui: ui}
    83  	}
    84  
    85  	if p.config.Login {
    86  		ui.Message("Logging in...")
    87  		err := driver.Login(
    88  			p.config.LoginServer,
    89  			p.config.LoginEmail,
    90  			p.config.LoginUsername,
    91  			p.config.LoginPassword)
    92  		if err != nil {
    93  			return nil, false, fmt.Errorf(
    94  				"Error logging in to Docker: %s", err)
    95  		}
    96  
    97  		defer func() {
    98  			ui.Message("Logging out...")
    99  			if err := driver.Logout(p.config.LoginServer); err != nil {
   100  				ui.Error(fmt.Sprintf("Error logging out: %s", err))
   101  			}
   102  		}()
   103  	}
   104  
   105  	// Get the name. We strip off any tags from the name because the
   106  	// push doesn't use those.
   107  	name := artifact.Id()
   108  
   109  	if i := strings.Index(name, "/"); i >= 0 {
   110  		// This should always be true because the / is required. But we have
   111  		// to get the index to this so we don't accidentally strip off the port
   112  		if j := strings.Index(name[i:], ":"); j >= 0 {
   113  			name = name[:i+j]
   114  		}
   115  	}
   116  
   117  	ui.Message("Pushing: " + name)
   118  	if err := driver.Push(name); err != nil {
   119  		return nil, false, err
   120  	}
   121  
   122  	return nil, false, nil
   123  }