// Run executes the deployment command func (c *Command) Run(args []string) int { c.args = args err := c.setupConfig() if err != nil { c.UI.Error(err.Error()) return 1 } go func() { select { case <-util.MakeShutdownCh(): c.UI.Info("Shutting down agents, waiting for inflight requests and running tasks to complete.") } select { case <-util.MakeShutdownCh(): c.UI.Info("Forcing inflight requests to complete and exiting running tasks.") os.Exit(1) } }() agent := NewOperation(c.UI, c.config) err = agent.Run() if err != nil { c.UI.Error(fmt.Sprintf("Failed to run agent: %s", err.Error())) return 2 } return 0 }
// register publishes an entry in the correct version node on the server // to inform watchers of the state of the local copy of this version. func (v *Version) register() error { v.log.Printf("registering\n") v.registered = true defer func() { v.registered = false }() doneCh := make(chan struct{}) // Function to shutdown this version's goroutines when the application // requests an exit. go func() { shutdownCh := util.MakeShutdownCh() select { case <-shutdownCh: v.shutdown() case <-doneCh: v.shutdown() } }() err := v.customer.Run(v.deployment.session) if err != nil { v.log.Printf("registration failed: %s", err) } else { v.log.Printf("deregistered") } close(doneCh) return err }
func (d *Deployment) Run() error { session, err := waiter.NewSession(d.client, d.Config.ID) if err != nil { return err } defer session.Close() d.session = session go func() { for version := range d.registerVersion { go func() { err := version.register() if err != nil { d.err.Printf("could not register {%s}: %s\n", version.ID, err) d.ui.Error(fmt.Sprintf("[%s] version '%s' not registered: %s", d.Config.ID, version.ID, err)) } }() } }() go func() { for version := range d.deployVersion { if !version.exists() { output, err := version.deploy() if err != nil { d.ui.Error(fmt.Sprintf("[%s] version '%s' deployment failed: %s", d.Config.ID, version.ID, err)) } else { d.ui.Output(fmt.Sprintf("[%s] version '%s' deployed", d.Config.ID, version.ID)) } d.ui.Info(output) } // Rollout this version since it has only been deployed now if version.ID == d.currentVersion() { d.rolloutVersion <- version } } }() go func() { for version := range d.rolloutVersion { output, err := version.rollout() if err != nil { d.ui.Error(fmt.Sprintf("[%s] version '%s' rollout failed: %s", d.Config.ID, version.ID, err)) } d.ui.Info(output) for _, otherVersion := range d.versions { if otherVersion != version && otherVersion.exists() { otherVersion.setState("available", true) } } } }() go func() { for version := range d.cleanVersion { output, err := version.clean() if err != nil { d.ui.Error(fmt.Sprintf("[%s] version '%s' cleanup failed: %s", d.Config.ID, version.ID, err)) } else { d.ui.Output(fmt.Sprintf("[%s] version '%s' removed", d.Config.ID, version.ID)) } d.ui.Info(output) } }() doneCh := make(chan struct{}, 2) go func() { err := d.watchCurrentVersion() if err != nil { d.ui.Error(fmt.Sprintf("[%s] crashed: %s", d.Config.ID, err)) } doneCh <- struct{}{} }() go func() { err := d.watchVersions() if err != nil { d.ui.Error(fmt.Sprintf("[%s] crashed: %s", d.Config.ID, err)) } doneCh <- struct{}{} }() go func() { select { case <-util.MakeShutdownCh(): close(d.deployVersion) close(d.rolloutVersion) close(d.cleanVersion) close(d.registerVersion) } }() <-doneCh <-doneCh return nil }