github.com/technosophos/deis@v1.7.1-0.20150915173815-f9005256004b/deisctl/cmd/upgrade.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	"github.com/deis/deis/deisctl/backend"
     8  	"github.com/deis/deis/deisctl/config"
     9  	"github.com/deis/deis/deisctl/config/model"
    10  )
    11  
    12  // UpgradePrep stops and uninstalls all components except router and publisher
    13  func UpgradePrep(b backend.Backend) error {
    14  	var wg sync.WaitGroup
    15  
    16  	b.Stop([]string{"database", "registry@*", "controller", "builder", "logger", "logspout"}, &wg, Stdout, Stderr)
    17  	wg.Wait()
    18  	b.Destroy([]string{"database", "registry@*", "controller", "builder", "logger", "logspout"}, &wg, Stdout, Stderr)
    19  	wg.Wait()
    20  
    21  	b.Stop([]string{"store-volume", "store-gateway@*"}, &wg, Stdout, Stderr)
    22  	wg.Wait()
    23  	b.Destroy([]string{"store-volume", "store-gateway@*"}, &wg, Stdout, Stderr)
    24  	wg.Wait()
    25  
    26  	b.Stop([]string{"store-metadata"}, &wg, Stdout, Stderr)
    27  	wg.Wait()
    28  	b.Destroy([]string{"store-metadata"}, &wg, Stdout, Stderr)
    29  	wg.Wait()
    30  
    31  	b.Stop([]string{"store-daemon"}, &wg, Stdout, Stderr)
    32  	wg.Wait()
    33  	b.Destroy([]string{"store-daemon"}, &wg, Stdout, Stderr)
    34  	wg.Wait()
    35  
    36  	b.Stop([]string{"store-monitor"}, &wg, Stdout, Stderr)
    37  	wg.Wait()
    38  	b.Destroy([]string{"store-monitor"}, &wg, Stdout, Stderr)
    39  	wg.Wait()
    40  
    41  	fmt.Fprintln(Stdout, "The platform has been stopped, but applications are still serving traffic as normal.")
    42  	fmt.Fprintln(Stdout, "Your cluster is now ready for upgrade. Install a new deisctl version and run `deisctl upgrade-takeover`.")
    43  	fmt.Fprintln(Stdout, "For more details, see: http://docs.deis.io/en/latest/managing_deis/upgrading-deis/#graceful-upgrade")
    44  	return nil
    45  }
    46  
    47  func listPublishedServices(cb config.Backend) ([]*model.ConfigNode, error) {
    48  	nodes, err := cb.GetRecursive("deis/services")
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	return nodes, nil
    54  }
    55  
    56  func republishServices(ttl uint64, nodes []*model.ConfigNode, cb config.Backend) error {
    57  	for _, node := range nodes {
    58  		_, err := cb.SetWithTTL(node.Key, node.Value, ttl)
    59  		if err != nil {
    60  			return err
    61  		}
    62  	}
    63  
    64  	return nil
    65  }
    66  
    67  // UpgradeTakeover gracefully starts a platform stopped with UpgradePrep
    68  func UpgradeTakeover(b backend.Backend, cb config.Backend) error {
    69  
    70  	if err := doUpgradeTakeOver(b, cb); err != nil {
    71  		return err
    72  	}
    73  
    74  	return nil
    75  }
    76  
    77  func doUpgradeTakeOver(b backend.Backend, cb config.Backend) error {
    78  	var wg sync.WaitGroup
    79  
    80  	nodes, err := listPublishedServices(cb)
    81  	if err != nil {
    82  		return err
    83  	}
    84  
    85  	b.Stop([]string{"publisher"}, &wg, Stdout, Stderr)
    86  	wg.Wait()
    87  	b.Destroy([]string{"publisher"}, &wg, Stdout, Stderr)
    88  	wg.Wait()
    89  
    90  	if err := republishServices(1800, nodes, cb); err != nil {
    91  		return err
    92  	}
    93  
    94  	b.RollingRestart("router", &wg, Stdout, Stderr)
    95  	wg.Wait()
    96  	b.Create([]string{"publisher"}, &wg, Stdout, Stderr)
    97  	wg.Wait()
    98  	b.Start([]string{"publisher"}, &wg, Stdout, Stderr)
    99  	wg.Wait()
   100  
   101  	installDefaultServices(b, false, &wg, Stdout, Stderr) // @fixme: hax?
   102  	wg.Wait()
   103  
   104  	startDefaultServices(b, false, &wg, Stdout, Stderr) // @fixme: hax?
   105  	wg.Wait()
   106  	return nil
   107  }