This repository has been archived by the owner on Mar 28, 2022. It is now read-only.
forked from cloudfoundry-community/cf-resource
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request cloudfoundry-community#72 from platform-accelerati…
…on-lab/master Replace autopilot zero down time deploys with own implementation.
- Loading branch information
Showing
9 changed files
with
425 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/bash | ||
|
||
./$(dirname $0)/cf $* | ||
|
||
exit 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package zdt | ||
|
||
import ( | ||
"fmt" | ||
"os/exec" | ||
) | ||
|
||
func CanPush( | ||
cf func(args ...string) *exec.Cmd, | ||
currentAppName string, | ||
) bool { | ||
|
||
if currentAppName == "" { | ||
return false | ||
} | ||
|
||
findErr := cf("app", currentAppName).Run() | ||
appExists := findErr == nil | ||
|
||
return appExists | ||
} | ||
|
||
func Push( | ||
cf func(args ...string) *exec.Cmd, | ||
currentAppName string, | ||
pushFunction func() error, | ||
showLogs bool, | ||
) error { | ||
|
||
venerableAppName := fmt.Sprintf("%s-venerable", currentAppName) | ||
|
||
actions := []Action{ | ||
{ | ||
Forward: cf("rename", currentAppName, venerableAppName).Run, | ||
}, | ||
{ | ||
Forward: pushFunction, | ||
ReversePrevious: func() error { | ||
if showLogs { | ||
_ = cf("logs", currentAppName, "--recent").Run() | ||
} | ||
_ = cf("delete", "-f", currentAppName).Run() | ||
return cf("rename", venerableAppName, currentAppName).Run() | ||
}, | ||
}, | ||
{ | ||
Forward: cf("delete", "-f", venerableAppName).Run, | ||
}, | ||
} | ||
|
||
return Actions{ | ||
Actions: actions, | ||
RewindFailureMessage: "Oh no. Something's gone wrong. I've tried to roll back but you should check to see if everything is OK.", | ||
}.Execute() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package zdt_test | ||
|
||
import ( | ||
"errors" | ||
"os/exec" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
"github.com/onsi/gomega/gbytes" | ||
|
||
"github.com/concourse/cf-resource/out/zdt" | ||
) | ||
|
||
var stdout *gbytes.Buffer | ||
|
||
func cli(path string) func(args ...string) *exec.Cmd { | ||
return func(args ...string) *exec.Cmd { | ||
cmd := exec.Command(path, args...) | ||
cmd.Stdout = stdout | ||
return cmd | ||
} | ||
} | ||
|
||
var _ = Describe("CanPush", func() { | ||
cf := cli("assets/cf") | ||
errCf := cli("assets/erroringCf") | ||
|
||
BeforeEach(func() { | ||
stdout = gbytes.NewBuffer() | ||
}) | ||
|
||
It("needs a currentAppName", func() { | ||
Expect(zdt.CanPush(cf, "")).To(BeFalse()) | ||
Expect(stdout.Contents()).To(BeEmpty()) | ||
}) | ||
|
||
It("needs the app to exist", func() { | ||
Expect(zdt.CanPush(errCf, "my-app")).To(BeFalse()) | ||
Expect(stdout).To(gbytes.Say("cf app my-app")) | ||
}) | ||
|
||
It("is ok when app exists", func() { | ||
Expect(zdt.CanPush(cf, "my-app")).To(BeTrue()) | ||
Expect(stdout).To(gbytes.Say("cf app my-app")) | ||
}) | ||
}) | ||
|
||
var _ = Describe("Push", func() { | ||
cf := cli("assets/cf") | ||
|
||
BeforeEach(func() { | ||
stdout = gbytes.NewBuffer() | ||
}) | ||
|
||
It("pushes an app with zero downtime", func() { | ||
pushFunction := func() error { return cf("push", "my-app").Run() } | ||
err := zdt.Push(cf, "my-app", pushFunction, false) | ||
|
||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(stdout).To(gbytes.Say("cf rename my-app my-app-venerable")) | ||
Expect(stdout).To(gbytes.Say("cf push my-app")) | ||
Expect(stdout).To(gbytes.Say("cf delete -f my-app-venerable")) | ||
}) | ||
|
||
It("rolls back on failed push", func() { | ||
pushErr := errors.New("push failed") | ||
pushFunction := func() error { | ||
_ = cf("push", "my-app").Run() | ||
return pushErr | ||
} | ||
err := zdt.Push(cf, "my-app", pushFunction, false) | ||
|
||
Expect(err).To(Equal(pushErr)) | ||
Expect(stdout).To(gbytes.Say("cf rename my-app my-app-venerable")) | ||
Expect(stdout).To(gbytes.Say("cf push my-app")) | ||
Expect(stdout).ToNot(gbytes.Say("cf logs")) | ||
Expect(stdout).To(gbytes.Say("cf delete -f my-app")) | ||
Expect(stdout).To(gbytes.Say("cf rename my-app-venerable my-app")) | ||
}) | ||
|
||
It("shows logs on failure when flag is set", func() { | ||
pushFunction := func() error { | ||
_ = cf("push", "my-app").Run() | ||
return errors.New("push failed") | ||
} | ||
err := zdt.Push(cf, "my-app", pushFunction, true) | ||
|
||
Expect(err).To(HaveOccurred()) | ||
Expect(stdout).To(gbytes.Say("cf rename my-app my-app-venerable")) | ||
Expect(stdout).To(gbytes.Say("cf push my-app")) | ||
Expect(stdout).To(gbytes.Say("cf logs my-app --recent")) | ||
Expect(stdout).To(gbytes.Say("cf delete -f my-app")) | ||
Expect(stdout).To(gbytes.Say("cf rename my-app-venerable my-app")) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package zdt | ||
|
||
import "fmt" | ||
|
||
type Actions struct { | ||
Actions []Action | ||
|
||
RewindFailureMessage string | ||
} | ||
|
||
func (actions Actions) Execute() error { | ||
for _, action := range actions.Actions { | ||
err := action.Forward() | ||
if err != nil { | ||
if action.ReversePrevious == nil { | ||
return err | ||
} | ||
|
||
reverseError := action.ReversePrevious() | ||
if reverseError != nil { | ||
if actions.RewindFailureMessage != "" { | ||
return fmt.Errorf("%s: %s", actions.RewindFailureMessage, reverseError) | ||
} else { | ||
return reverseError | ||
} | ||
} | ||
|
||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
type Action struct { | ||
Forward func() error | ||
ReversePrevious func() error | ||
} |
Oops, something went wrong.