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 }