Skip to content

Commit

Permalink
Now have some blue/green working. Doesn't play nice with registrator …
Browse files Browse the repository at this point in the history
…though
  • Loading branch information
byrnedo committed Mar 14, 2016
1 parent 7781b84 commit e30f43a
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 14 deletions.
2 changes: 2 additions & 0 deletions configparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ func (f *ConfigParser) parseSettings(lines [][]byte) (projSettings *ProjectConfi
projSettings.ProjectName = string(lineParts[2])
case "project_sep":
projSettings.ProjectSeparator = stripChars(string(lineParts[2]), " \t")
case "blue_green":
projSettings.BlueGreenMode, _ = strconv.ParseBool(string(lineParts[2]))
}
}
continue
Expand Down
32 changes: 32 additions & 0 deletions container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,38 @@ func (set *Container) launchInForeground(cmd []interface{}, wg *sync.WaitGroup)

}

func (set *Container) BlueGreenDeploy(attach bool, dryRun bool, wg *sync.WaitGroup) error {
// rename the current
Warning.Println("Temporarily renaming running container")
oldName := set.Name + "_old_" + helpers.RandStringBytesMaskImprSrc(5)
if err := helpers.RenameContainer(set.Name, oldName); err != nil {
return err
}

var oldC = new(Container)
*oldC = *set
oldC.Name = oldName

if err := set.Run(attach, dryRun, wg); err != nil {
// put back the old
set.Stop(nil)

Warning.Println("Error running new container, reverting container name")
if err := helpers.RenameContainer(oldName, set.Name); err != nil {
return err
}
return err
}

// shutdown the old
if err := oldC.Stop(nil); err != nil {
Error.Println("Error stopping old container")
return err
}

return nil
}

func (set *Container) RecreateAndRun(attach bool, dryRun bool, wg *sync.WaitGroup) error {
if !dryRun {
set.Rm([]string{"-f"})
Expand Down
7 changes: 7 additions & 0 deletions helpers/dockerhelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ func GetContainerServiceNameLabel(name string) string {
return getLabel(ServiceLabelName, name)
}

func RenameContainer(currentName string, newName string) error {
ses := sh.NewSession()
ses.Stderr = ioutil.Discard
_, err := ses.Command("docker", "rename", currentName, newName).Output()
return err
}

func getLabel(label string, container string) string {
ses := sh.NewSession()
ses.Stderr = ioutil.Discard
Expand Down
29 changes: 29 additions & 0 deletions helpers/stringhelp.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,39 @@
package helpers

import (
"math/rand"
"strconv"
"strings"
"time"
)

var src = rand.NewSource(time.Now().UnixNano())

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)

func RandStringBytesMaskImprSrc(n int) string {
b := make([]byte, n)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}

return string(b)
}

func GetNumericSuffix(name string, sep string) (int, error) {
namePts := strings.Split(name, sep)
instNumStr := namePts[len(namePts)-1]
Expand Down
8 changes: 6 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,16 @@ func main() {
Aliases: []string{},
Usage: "Create then run or update containers",
Action: func(c *cli.Context) {
//first get settings
settings := getSettings()
//then should peek state
//TODO

settings.LaunchSignalWatcher()
if err := settings.ContainerCleanupList.CapitanRm([]string{"-f"}, dryRun); err != nil {
Warning.Println("Failed to scale down containers:", err)
}
if err := settings.ContainerList.CapitanUp(attach, dryRun); err != nil {
if err := settings.ContainerList.CapitanUp(attach, dryRun, settings.BlueGreenMode); err != nil {
Error.Println("Up failed:", err)
os.Exit(1)
}
Expand Down Expand Up @@ -136,7 +140,7 @@ func main() {
}
if err := settings.ContainerList.Filter(func(i *container.Container) bool {
return i.ServiceType == c.Args().Get(0)
}).CapitanUp(false, dryRun); err != nil {
}).CapitanUp(false, dryRun, settings.BlueGreenMode); err != nil {
Error.Println("Scale failed:", err)
os.Exit(1)
}
Expand Down
41 changes: 29 additions & 12 deletions projectconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
type ProjectConfig struct {
ProjectName string
ProjectSeparator string
BlueGreenMode bool
IsInteractive bool
ContainerList SettingsList
ContainerCleanupList SettingsList
Expand Down Expand Up @@ -191,17 +192,21 @@ func (settings SettingsList) CapitanCreate(dryRun bool) error {

if set.Build != "" {
Info.Println("Building image")
if err := set.BuildImage(); err != nil {
return err
if ! dryRun {
if err := set.BuildImage(); err != nil {
return err
}
}
}

if helpers.GetImageId(set.Image) == "" {
Warning.Printf("Capitan was unable to find image %s locally\n", set.Image)

Info.Println("Pulling image")
if err := helpers.PullImage(set.Image); err != nil {
return err
if ! dryRun {
if err := helpers.PullImage(set.Image); err != nil {
return err
}
}
}

Expand All @@ -220,7 +225,7 @@ func (settings SettingsList) CapitanCreate(dryRun bool) error {
// Recreates a container if the container's image has a newer id locally
// OR if the command used to create the container is now changed (i.e.
// config has changed.
func (settings SettingsList) CapitanUp(attach bool, dryRun bool) error {
func (settings SettingsList) CapitanUp(attach bool, dryRun bool, blueGreenMode bool) error {
sort.Sort(settings)

wg := sync.WaitGroup{}
Expand All @@ -232,17 +237,22 @@ func (settings SettingsList) CapitanUp(attach bool, dryRun bool) error {

if set.Build != "" {
Info.Println("Building image")
if err := set.BuildImage(); err != nil {
return err
if ! dryRun {
if err := set.BuildImage(); err != nil {
return err
}
}
}

if helpers.GetImageId(set.Image) == "" {
Warning.Printf("Capitan was unable to find image %s locally\n", set.Image)

Info.Println("Pulling image")
if err := helpers.PullImage(set.Image); err != nil {
return err

if ! dryRun {
if err := helpers.PullImage(set.Image); err != nil {
return err
}
}
}

Expand All @@ -267,9 +277,16 @@ func (settings SettingsList) CapitanUp(attach bool, dryRun bool) error {

if haveArgsChanged(set.Name, set.RunArguments) {
// remove and restart
Info.Println("Removing (run arguments changed):", set.Name)
if err = set.RecreateAndRun(attach, dryRun, &wg); err != nil {
return err
if blueGreenMode {
Info.Println("Run arguments changed, doing blue-green redeploy:", set.Name)
if err = set.BlueGreenDeploy(attach, dryRun, &wg); err != nil {
return err
}
} else {
Info.Println("Removing (run arguments changed):", set.Name)
if err = set.RecreateAndRun(attach, dryRun, &wg); err != nil {
return err
}
}
continue
}
Expand Down

0 comments on commit e30f43a

Please sign in to comment.