From f73fe211b4006d00259ca8b183980aff4942443a Mon Sep 17 00:00:00 2001 From: Casey Lee Date: Wed, 8 Mar 2017 08:48:12 -0800 Subject: [PATCH] * Default buildspecs * Environment term also does service term * Quickstart demo --- Makefile | 10 +++++++-- README.md | 8 +++++-- cli/pipelines.go | 1 + common/context.go | 35 +++++++++++++++++++----------- common/stack.go | 10 +++++++++ templates/assets.go | 8 +++---- templates/assets/bucket.yml | 2 +- templates/assets/pipeline.yml | 10 +++++++-- wiki | 2 +- workflows/environment_terminate.go | 28 ++++++++++++++++++++++++ workflows/pipeline_upsert.go | 7 ++++-- workflows/pipeline_upsert_test.go | 2 +- 12 files changed, 95 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index 455a4e5b..10ee794c 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ IS_MASTER := $(filter master, $(BRANCH)) VERSION := $(shell cat VERSION)$(if $(IS_MASTER),,-$(BRANCH)) SRC_FILES = $(shell glide nv) ARCH := $(shell go env GOARCH) +OS := $(shell go env GOOS) BUILD_DIR = $(if $(CIRCLE_ARTIFACTS),$(CIRCLE_ARTIFACTS),.release) BUILD_FILES = $(foreach os, $(TARGET_OS), $(BUILD_DIR)/$(PACKAGE)-$(os)-$(ARCH)) UPLOAD_FILES = $(foreach os, $(TARGET_OS), $(PACKAGE)-$(os)-$(ARCH)) @@ -43,13 +44,18 @@ else endif -build: $(BUILD_FILES) gen +build: gen $(BUILD_FILES) $(BUILD_FILES): @echo "=== building $(VERSION) - $@ ===" mkdir -p $(BUILD_DIR) GOOS=$(word 2,$(subst -, ,$(notdir $@))) GOARCH=$(word 3,$(subst -, ,$(notdir $@))) go build -ldflags=$(GOLDFLAGS) -o '$@' +install: build + @echo "=== building $(VERSION) - $(PACKAGE)-$(OS)-$(ARCH) ===" + cp $(BUILD_DIR)/$(PACKAGE)-$(OS)-$(ARCH) /usr/local/bin/mu + chmod 755 /usr/local/bin/mu + release-clean: ifeq ($(IS_MASTER),) @echo "=== clearing old release $(VERSION) ===" @@ -91,4 +97,4 @@ fmt: go fmt $(SRC_FILES) -.PHONY: default all lint test build deps gen clean release-clean release-create dev-release release $(UPLOAD_FILES) $(TARGET_OS) +.PHONY: default all lint test build deps gen clean release-clean release-create dev-release release install $(UPLOAD_FILES) $(TARGET_OS) diff --git a/README.md b/README.md index 838c6ee7..e40d398d 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,11 @@ The `mu` tool uses CloudFormation stacks to manage all resources it creates. Ad ![Architecture Diagram](https://github.com/stelligent/mu/wiki/img/ms-architecture-3.png) +# Demo +Watch the 90 second demo below to see mu in action! + +![Demo](https://github.com/stelligent/mu/wiki/quickstart/mu-quickstart.gif) + # Get Started! Install latest version to /usr/local/bin (or for additional options, see [wiki](https://github.com/stelligent/mu/wiki/Installation)): @@ -19,7 +24,6 @@ curl -s https://raw.githubusercontent.com/stelligent/mu/master/install.sh | sh Assuming your project already has a Dockerfile, you can initialize your mu.yml file with: `mu init`. More details available in the [quickstart](https://github.com/stelligent/mu/wiki/Quickstart). - # What's next? Check out the [examples](examples) to see common `mu.yml` configuration use cases: @@ -36,7 +40,7 @@ Refer to the wiki for complete details on the configuration of `mu.yml` and the * **[Environments](https://github.com/stelligent/mu/wiki/Environments)** - managing VPCs, ECS clusters, container instances and ALBs * **[Services](https://github.com/stelligent/mu/wiki/Services)** - managing ECS service configuration * **[Pipelines](https://github.com/stelligent/mu/wiki/Pipelines)** - managing continuous delivery pipelines -* **[CLI](https://github.com/stelligent/mu/wiki/CLI)** - details about using the CLI +* **[CLI](https://github.com/stelligent/mu/wiki/CLI-Usage)** - details about using the CLI * **[Custom CloudFormation](https://github.com/stelligent/mu/wiki/Custom-CloudFormation)** - details about customizing the CloudFormation that is generated by mu. # Contributing diff --git a/cli/pipelines.go b/cli/pipelines.go index a46fecde..4702ccf2 100644 --- a/cli/pipelines.go +++ b/cli/pipelines.go @@ -74,6 +74,7 @@ func newPipelinesUpsertCommand(ctx *common.Context) *cli.Command { byteToken, err := terminal.ReadPassword(int(syscall.Stdin)) if err == nil { token = strings.TrimSpace(string(byteToken)) + fmt.Println("") } } diff --git a/common/context.go b/common/context.go index 0a14e870..517fe967 100644 --- a/common/context.go +++ b/common/context.go @@ -37,31 +37,40 @@ func NewContext() *Context { // InitializeConfigFromFile loads config from file func (ctx *Context) InitializeConfigFromFile(muFile string) error { absMuFile, err := filepath.Abs(muFile) - if err != nil { - return err - } - - // load yaml config - yamlFile, err := os.Open(absMuFile) - if err != nil { - return err - } - defer func() { - yamlFile.Close() - }() // set the basedir ctx.Config.Basedir = path.Dir(absMuFile) + log.Debugf("Setting basedir=%s", ctx.Config.Basedir) + ctx.Config.Repo.Name = path.Base(ctx.Config.Basedir) + log.Debugf("Setting repo name=%s", ctx.Config.Repo.Name) + ctx.Config.Repo.Revision = time.Now().Format("20060102150405") - gitRevision, err := findGitRevision(absMuFile) + + gitRevision, err := findGitRevision(ctx.Config.Basedir) if err == nil { ctx.Config.Repo.Revision = gitRevision + } else { + log.Warningf("Unable to determine git revision: %s", err.Error()) } + log.Debugf("Setting repo revision=%s", ctx.Config.Repo.Revision) + gitSlug, err := findGitSlug() if err == nil { ctx.Config.Repo.Slug = gitSlug + } else { + log.Warningf("Unable to determine git slug: %s", err.Error()) + } + log.Debugf("Setting repo slug=%s", ctx.Config.Repo.Slug) + + // load yaml config + yamlFile, err := os.Open(absMuFile) + if err != nil { + return err } + defer func() { + yamlFile.Close() + }() return ctx.InitializeConfig(bufio.NewReader(yamlFile)) } diff --git a/common/stack.go b/common/stack.go index 6fc7e702..a49ec0a2 100644 --- a/common/stack.go +++ b/common/stack.go @@ -137,6 +137,16 @@ func buildStackTags(tags map[string]string) []*cloudformation.Tag { func (cfnMgr *cloudformationStackManager) UpsertStack(stackName string, templateBodyReader io.Reader, parameters map[string]string, tags map[string]string) error { stack := cfnMgr.AwaitFinalStatus(stackName) + // delete stack if in rollback status + if stack != nil && stack.Status == cloudformation.StackStatusRollbackComplete { + log.Warningf(" Stack '%s' was in '%s' status, deleting...", stackName, stack.Status) + err := cfnMgr.DeleteStack(stackName) + if err != nil { + return err + } + stack = cfnMgr.AwaitFinalStatus(stackName) + } + // load the template templateBodyBytes := new(bytes.Buffer) templateBodyBytes.ReadFrom(templateBodyReader) diff --git a/templates/assets.go b/templates/assets.go index 3543bedc..bf3b54be 100644 --- a/templates/assets.go +++ b/templates/assets.go @@ -75,7 +75,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _assetsBucketYml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x64\x8f\x4d\x4b\xc3\x40\x10\x86\xef\xfb\x2b\x46\x28\xf4\xb4\x10\xed\xa9\x7b\xab\xa8\xe0\x41\x0d\xd9\xda\x9e\xb7\x71\x52\x17\xb3\x1f\x4c\x66\xa1\x52\xfa\xdf\x25\x1b\x22\x5b\xcd\x6d\xf2\xce\x3c\xfb\xbc\x52\x4a\xb1\xd9\xeb\x2d\xba\xd8\x1b\xc6\xa7\x40\xce\xf0\x0e\x69\xb0\xc1\x2b\x58\xde\x55\xb7\x95\xac\xd6\xb2\x5a\x2f\xc5\x03\x0e\x2d\xd9\xc8\x39\x79\x79\x87\x43\x6a\xbf\x90\xc1\x7a\xd0\x2b\x51\x1b\x32\x0e\x19\x69\x50\x02\xe0\x3e\x47\x35\x61\x67\x4f\xe3\x0c\xb0\xfd\x8e\xa8\x40\x33\x59\x7f\xcc\x3f\xae\x68\xd3\x26\x70\x80\x34\x20\x74\x81\x80\x3f\x71\x7e\xc0\x1b\x87\xa2\xc1\x21\x24\x6a\xb1\xc0\x97\xe0\xcd\x5e\x2b\xa5\x57\x4a\x4d\x51\x4e\x6a\x0a\x11\x89\xed\x74\x33\x7e\x53\xf8\x6a\x1c\x2a\xb8\xd1\xe9\x00\x8b\x73\x69\x7a\x91\x8b\x73\x06\x35\x78\xb4\xc1\xff\x8e\x9b\xb6\x0d\xc9\xf3\xf3\xc7\x45\xbc\x25\x8e\x89\xff\x49\x5c\x95\x19\xf9\x10\xba\x5c\x21\xda\x88\xbd\xf5\x73\x97\xbc\xbc\x33\x7d\x1a\x05\x1a\xec\xa0\xd0\x7d\x3c\xc5\x40\x3c\xab\x16\x92\x2e\xc9\xe9\x5a\xfe\xd1\x15\x3f\x01\x00\x00\xff\xff\x25\xb1\xdb\xa7\xbd\x01\x00\x00") +var _assetsBucketYml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x64\x8f\xcf\x4e\xc3\x30\x0c\x87\xef\x79\x0a\x23\x4d\xda\x29\x52\x61\xa7\xe5\x56\x04\x48\x1c\x80\xaa\x19\xdb\x39\x2b\xee\x88\x68\xfe\xc8\x75\xa4\xa1\x69\xef\x8e\x9a\xaa\xa8\x85\xdc\x9c\xcf\xfe\xf9\xb3\x94\x52\x94\x07\xbd\x43\x17\x3b\xc3\xf8\x14\xc8\x19\xde\x23\xf5\x36\x78\x05\xeb\xbb\xe2\xb6\x90\xc5\x56\x16\xdb\xb5\x78\xc0\xbe\x21\x1b\x39\x93\x97\x77\x38\xa6\xe6\x0b\x19\xac\x07\xbd\x11\x95\x21\xe3\x90\x91\x7a\x25\x00\xee\x33\xaa\x08\x5b\x7b\x1e\x6a\x80\xdd\x77\x44\x05\x9a\xc9\xfa\x53\xfe\x58\xa4\x8d\x9d\xc0\x01\x52\x8f\xd0\x06\x02\xfe\xc4\x69\x81\x37\x0e\x45\x8d\x7d\x48\xd4\xe0\x2c\x7e\x1e\x5c\x1e\xb4\x52\x7a\xa3\xd4\x88\x32\xa9\x28\x44\x24\xb6\xe3\xcc\xf0\x46\xf8\x6a\x1c\x2a\xb8\xd1\xe9\x08\x2e\xc9\xd5\x65\x2e\x7b\x95\xab\x4b\xce\xaa\xf1\x64\x83\xff\x2d\xcb\xa6\x09\xc9\xf3\xf3\xc7\x55\xbc\x25\x8e\x89\xff\x79\x2c\xee\x19\x56\x40\x68\xf3\x15\xd1\x46\xec\xac\x9f\xce\xc9\xcd\x7b\xd3\xa5\xc1\xa1\xc6\x16\x66\xc6\x8f\xe7\x18\x88\x27\xdb\xa5\xe7\x38\xfd\x57\x57\xfc\x04\x00\x00\xff\xff\x36\x33\x97\x82\xc0\x01\x00\x00") func assetsBucketYmlBytes() ([]byte, error) { return bindataRead( @@ -90,7 +90,7 @@ func assetsBucketYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "assets/bucket.yml", size: 445, mode: os.FileMode(420), modTime: time.Unix(1485929866, 0)} + info := bindataFileInfo{name: "assets/bucket.yml", size: 448, mode: os.FileMode(420), modTime: time.Unix(1488950882, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -135,7 +135,7 @@ func assetsClusterYml() (*asset, error) { return a, nil } -var _assetsPipelineYml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xec\x5a\x6d\x6f\x1b\x39\xee\x7f\x9f\x4f\xc1\xfa\x5f\x20\x40\xfe\x37\x76\x9c\xa4\xed\x76\x80\xdb\x83\x9b\x78\x7b\xc6\x25\xb1\x61\x27\xed\x01\x87\x43\x21\xcf\xd0\xb6\x36\x33\xd2\x40\x0f\xf6\xfa\xda\x7c\xf7\x83\x34\x4f\x9a\xf1\x63\xda\x6c\x93\xee\x6d\x5e\xc5\x22\x45\x52\xfc\x51\x94\xc8\x91\xe7\x79\x07\x9d\x8f\xa3\x1b\x8c\x93\x88\x28\xfc\x85\x8b\x98\xa8\x0f\x28\x24\xe5\xcc\x87\xc3\x93\xe3\xf6\xb1\x77\xfc\xd6\x3b\x7e\x7b\x78\x70\x81\x32\x10\x34\x51\x96\x72\x75\x0b\x09\x4d\x30\xa2\x0c\x41\x4b\xca\xa6\x70\xce\x43\x1c\xe4\x43\x84\x85\x76\xe0\x9d\xa6\x51\x08\x13\x2e\x20\xe0\x4c\x51\xa6\xb9\x96\x10\x62\x44\xe7\x28\x96\x07\x03\x22\x48\x8c\x0a\x85\xf4\x0f\x00\xde\x53\xf5\x77\x3d\xbe\x95\x28\xcc\x2f\x80\x9b\x65\x82\x3e\x8c\x94\xa0\x6c\x6a\x07\x2a\x06\xa4\xdc\x60\xd8\x8b\xb9\x43\x4c\xf8\x03\xe6\x1a\x76\x50\x1c\x12\x1d\x45\x30\x11\x3c\x6e\x42\x9f\x45\x4b\x50\x33\x84\x6b\x12\x63\x13\x18\x57\xf6\xd7\xed\xf0\xb2\x50\xf2\x4e\x10\x16\xcc\x1e\xa0\x26\x9d\x90\x91\x27\x44\x47\xca\x87\x46\x4c\xa4\x42\xd1\x28\xa4\xde\xf0\x3b\x64\xa9\xd0\x6b\xde\x0d\x66\xdc\x07\x25\x34\xee\xa1\x65\x84\x81\x40\xd5\x84\x9e\x82\x98\x4e\x67\x0a\x22\xce\xef\x40\xf2\x18\xd5\xcc\xe0\x12\xd1\x3b\x84\xb7\xe3\xf6\x4f\x6f\x49\xfb\xf5\xab\xb3\xd7\x67\xa7\xaf\x4e\x4e\x5e\xbd\x6e\x4f\xde\x8c\x4f\x71\x1c\x9e\x9d\x91\xf6\xab\xd3\x36\x39\x3b\xf9\xe9\x0d\x99\x40\xbf\xa3\xd5\xcc\x1a\x03\x0b\xaa\x66\x40\x82\x00\xa5\x34\x5e\x32\xde\x6a\xc2\x7b\xeb\xb1\x99\x52\x89\xf4\x5b\xad\x29\x55\x33\x3d\x6e\x06\x3c\x6e\x49\x54\x8a\xb2\xa9\x6c\x29\x33\x59\x1e\x00\x58\xec\xad\xed\x9b\x56\x91\x3b\xe3\xb2\x77\x7d\xfb\xcf\x4f\xe7\xfd\xeb\x9b\x4e\xef\xba\x3b\x6c\xac\x2e\xf2\x66\x86\x30\xb6\xb1\x64\xe2\x88\x50\x86\x02\xd4\x32\x41\x63\x8c\x96\x68\x23\xcc\xd2\xcd\x8a\x0d\x62\x24\x49\x72\x13\xce\x79\x9c\x68\x85\x7b\x59\xf2\xee\xb6\x77\x79\xf1\xe9\x7d\xf7\xba\x3b\xec\x5c\xb6\x3f\x8d\xae\x3a\x97\x97\x3b\xcc\xb1\xc2\xf7\x36\xa6\x17\x93\xe9\x6e\x33\xc8\x42\xb6\x02\x1e\xa2\x95\xd2\xd2\x63\xcd\x94\xf6\xc6\x44\xa2\xdf\x3e\x6b\x1e\x9f\x6d\xb5\x88\x1a\x0d\x3b\x4c\xb9\x41\xa9\xbe\x23\x32\x0a\xa5\x5a\x35\xe0\x49\x70\x59\x6f\xca\x13\xa0\xb2\x6a\xc8\x95\xfe\x8e\x90\xc4\xda\xb8\x28\x26\x2c\x94\x56\xf5\x93\x80\x51\x37\xe2\x6b\x60\x08\x79\x70\x87\xc2\x6f\x37\xdb\x27\xcd\xf6\xc3\x20\xa8\xab\xbf\xe0\x0b\x16\x71\x12\xbe\x23\x12\xb5\x88\x76\x1a\xb2\x2e\x0b\x2a\x8c\x22\x3a\x45\xa6\x5a\xb1\x6e\x09\x8c\x90\x48\x94\xad\x30\x93\xbc\xc9\x3e\x22\x11\xb4\x88\x8c\x71\x94\x49\x45\xa2\xc8\x18\x67\x8e\xa4\x8a\x61\xf9\xb9\xbc\xc7\xa9\x60\xc4\xce\x53\x76\xe0\x13\x23\xcd\x91\x4d\x59\x79\x38\x57\x14\xfc\x42\xa3\xdd\xfe\x8f\xb5\x17\x51\xa6\x7f\xf3\x48\x1c\xbe\xde\x14\xf5\x8c\xc4\x68\x14\x9b\xf0\x36\x4b\xa1\x91\x75\x7d\xee\x08\xc7\x9a\x83\x42\xb6\xb5\x47\x26\x18\xec\xbb\xc0\x30\x9d\x97\xe2\x6b\x26\x66\xe8\xda\x35\x6d\x5d\x8b\x23\x68\x40\xd4\xcc\xcc\x8b\x75\x73\x19\x47\x7f\x01\x81\x11\x51\x74\x6e\xcd\x2d\xaf\x15\x2b\x3e\x30\xcc\x8d\x2c\x7d\x74\xd9\x7c\x1f\x4d\xd7\x99\x4f\x62\x0d\xc8\xe6\x54\x70\x16\x23\x53\xd6\x2d\x98\x44\x7c\x69\xfe\x73\x52\x43\x4d\x65\x88\x73\xa3\x6f\x20\x78\xf8\xc8\xfa\x12\xc1\x43\x1d\x98\x39\x35\x95\x25\xa1\x71\x30\x44\xc9\xb5\x08\xd0\x5e\xd5\x8a\xe8\x19\xf2\xaa\x93\x3b\x1f\x47\xbe\xdf\xeb\x5c\xf9\xbe\xa1\x58\xc2\x40\xf0\x04\x85\xa2\xe9\x4c\xf3\xd7\x91\x52\xc7\x68\x18\x06\x3c\xa2\xc1\xf2\x82\x07\xda\x58\x96\xd3\x01\x46\x8a\x28\xac\x0e\x79\xd0\x9d\x4c\x30\x50\x3e\x74\xa2\x88\x2f\x8a\x71\xa3\x80\xb2\x80\x26\x24\xf2\x9d\x41\x80\x11\x8a\x39\x0d\xb0\x3a\xe8\x41\x91\x39\x9a\x24\x26\xff\xe1\x8c\x2c\xa4\xd9\xb9\x0e\x57\xc7\xae\xd8\x9d\xe7\x81\x54\xd2\x2f\xcd\xce\x48\x26\x72\x7c\x68\xb4\x1a\xf9\x6f\xb3\x1a\x67\x9d\x5e\x3a\xb2\x34\x38\xf8\xa5\x62\x4f\xa6\x96\x15\x0a\x36\x79\x61\xad\x1f\xb6\x79\xa2\xb0\x1d\x1a\x47\x8d\xca\x78\x8e\x5e\x9d\x52\xb9\xe9\x9f\x78\xed\x63\xaf\xfd\xe6\x30\x03\x38\xbf\xcc\xff\x98\x18\xe7\xd5\xc9\x53\xc0\x9c\xeb\xfe\x76\xa4\x57\x8d\xac\xc4\xb0\x7f\xb4\x17\xca\xb0\xd1\xaf\x9b\x34\xc8\x53\xff\x3d\xaa\xfe\xf8\x57\x0c\xd4\x16\x52\x16\x3e\x6b\x39\xde\xe9\xe0\x0e\x73\x8e\x3c\x3f\xfd\x2e\x96\x0e\xf4\x3a\x4b\x0b\x15\xb5\x09\x44\x30\x9f\x2c\xa4\x2f\x4f\x7d\xdf\x77\xd1\x3a\xfa\x56\x3b\x8e\xea\x30\x45\x5c\x87\x13\x5b\x51\x9b\x09\x75\x32\x06\x72\x65\x8c\x92\xd8\x1f\x10\x29\x9d\xf0\xfb\x5a\x87\x6d\xdb\xda\x36\x77\x77\x84\xa2\x13\x12\xa8\x95\xbd\x5d\x70\xf8\xfe\x40\xf0\xc2\xb1\x17\x98\x20\x0b\x65\x9f\xf9\xd5\xfc\xbf\x21\x03\xa4\xdb\xe1\xc5\x48\x8f\xe1\xe5\x67\x2b\x77\xa4\x48\x70\x67\x86\xef\x3d\x92\xe9\xce\x78\x2b\xc7\x56\xda\x33\xc8\x39\xec\x2d\x08\xd2\xc5\x67\xdc\xd9\xae\xb7\x79\x09\x5e\xbc\x47\xd5\x51\xaa\x6a\x52\xb3\x23\xf2\xa0\xcc\x57\x29\x4b\xc0\xd2\xa5\x9e\xf7\x2f\xba\x83\xde\xa0\x7b\xd9\xbb\xee\x66\xa4\x6e\x79\x4a\xd6\xb9\x5f\x0c\x71\x52\x56\xb4\x05\xd1\xbd\x36\x3b\x3c\xce\x70\xc1\x9a\x5e\x6e\x73\x87\x94\xc5\xe0\x7d\xbe\xaa\x5a\xb4\x6e\xb4\xf2\x86\xc6\xc8\xb5\xea\xb1\x2b\xca\xb4\x42\xe9\xc3\xe9\xb1\x8b\xeb\xca\x2d\xfa\x7b\x81\x6a\x2f\xd8\x9b\x11\x4d\xef\xdf\x16\xce\x1a\xfc\x4f\x06\x68\x5a\x72\x6d\x41\xb3\x52\x18\x6d\x80\x32\xab\x5b\xee\x0b\xb2\xa3\xf5\x03\x11\x94\x8c\x23\x74\x8c\x05\x2f\xf3\xe2\x45\xff\xfc\x1f\xdd\xe1\xa7\xce\xa0\xf7\xe9\x43\x77\x38\xea\xf5\xaf\xdd\x7d\xfd\x81\x44\x1a\x7d\x68\x37\x4f\xce\x1e\x1a\x20\x59\xab\x61\x64\x6e\xd2\xa9\x91\x5f\x1c\xc9\xf3\x3c\x2f\x1c\x37\xdb\xce\x70\x32\x33\x95\x4a\x35\xab\xa5\x67\x4c\x65\x08\x8a\x92\xa9\x3e\x6e\x33\x9e\x29\x62\x3c\x79\x69\xbd\x52\x2b\xa7\xee\x5b\x73\x77\x34\x4b\x4f\xf7\x2d\x77\xd0\xdc\xd9\xef\xc1\xe3\xd0\xd2\x52\xb4\xc6\x94\xb5\x62\xbd\x4e\xcd\x2c\xe6\x21\xfc\xbf\xf8\x6d\x07\x5f\xac\xc1\x0b\xac\x2d\xa9\x60\x39\x0f\x20\xd1\x72\x06\x9e\x82\x88\x98\x6b\xb6\x33\x89\xac\xc6\x95\xf9\x33\x95\xcb\xca\x5a\xbd\x52\xe8\xf6\x4d\x79\x61\x2f\xda\x9d\x20\xc0\x44\x11\x16\x3c\xc9\xb6\x4c\x2f\xfb\x1e\x29\x8c\x58\xb7\x45\x53\x43\xcb\x1a\xd9\x38\xc7\xad\x1a\xfe\x88\x3b\xf5\xcf\x0d\x55\xa8\xf9\xca\x0d\x85\x6c\x0e\x3a\x81\x97\x9f\xb3\x2a\xf8\x1e\xbe\x7c\x01\x0c\x66\x1c\x1a\xa3\x3b\x9a\x24\x94\x4d\x41\x27\x21\x51\xb6\x0e\x75\xc2\xa9\xb1\xe7\x6e\xcd\x0a\x55\x47\xc1\xba\xad\xeb\x48\x30\x16\xc9\x19\x5f\x54\xa6\x4c\xe0\x57\xc9\x19\xfc\x6c\xa8\x4d\xf3\xef\xba\xb9\xf3\xb2\x8d\xe0\x19\xf9\xa6\xc0\x2f\x87\xec\xaf\x62\x71\x2f\x3f\xd7\x5b\x16\xf7\x0d\xf8\xb9\xca\xfd\xd5\xa9\xe5\xf0\xe8\xa8\x75\x74\xb8\x3d\xaf\x98\xb5\x3d\x6d\x56\x31\x2e\xda\x91\x53\x8c\x91\x40\x59\xda\xe2\x2c\x38\x9f\x53\x56\xc9\xfb\xe0\x5b\xf2\x4a\xad\x53\xbd\x21\xb3\x14\x4d\xe4\xc7\xba\xcd\xa5\xf9\x78\x50\x34\x60\x9e\xf0\xe0\xa8\xb5\x87\x76\x1c\x1c\x86\xfb\x39\x41\xfc\xe7\xc1\xf1\xac\x0f\x8e\xac\x9d\xf9\xfb\x1d\x1c\x85\x82\xfd\x0f\x8e\x72\xca\x83\x0f\x0e\x13\xfd\xcf\xfe\xe0\x78\xda\xac\x62\x0f\x8e\xed\x39\xc5\x3d\x38\x4a\xce\xe7\x94\x55\x9e\xef\xc1\x91\x77\x6d\xd7\x42\x5b\x10\xfd\xfc\xbf\x0d\x08\x1a\xd7\x75\x04\xab\x3a\xd5\x6d\x08\x3b\x7e\x1d\x29\x32\x75\xbb\xa1\x29\xfa\x23\xb7\x63\x93\x77\x5b\xa5\xdb\xeb\xed\xb1\x44\xab\x12\x14\xf8\xd7\xbf\x9d\x88\x5e\x2b\x24\x17\x63\x56\xd5\xab\xa5\xc3\x73\xa2\x70\xca\xc5\x72\xcd\x24\x80\xfe\x82\xa1\xf0\xe1\x66\x46\x45\x38\x20\x42\x2d\x2b\xd4\xb2\x53\xd6\x3e\xac\x10\x06\x82\xcf\x69\x68\x66\xa6\x1f\x82\x1c\x62\x5f\xab\x8a\xf5\x0e\xa9\xea\x81\x94\xd1\x21\x9f\x73\x36\xa1\x53\x2d\xc8\x6a\x17\x31\x33\xd3\x86\x4f\xf9\x1a\xa6\xc2\x62\x9f\xb8\xb8\x1c\xc5\xc7\xa9\xfc\x2f\x7b\x9f\xe2\xf2\x38\x2f\x50\x0a\x55\xc5\x3b\x8f\x0a\xa7\x1d\x71\x18\x87\x9a\xf5\x85\xf5\x40\xbb\x86\x6f\xfe\xf1\x70\x23\xbc\x29\x5b\xa7\xda\xe9\xd9\x17\xc3\xaa\x74\xc7\x37\x9d\x8f\xa3\x87\x62\xe7\x7e\xea\xcc\xff\x6a\xb1\xb7\x3f\x7a\x7b\xe0\x9e\x13\x1f\x82\x7c\x96\x6c\xb3\xc4\x69\xf0\x58\x69\xd3\x6e\x45\xa5\xd4\xde\x73\x9a\x70\x3f\x8e\xb7\x37\xfa\x6c\x0f\x7f\xdb\x15\x3f\x92\xb3\xeb\xde\x2b\x3d\x7d\x52\x8b\xff\x4e\xbd\xf4\xd9\xb2\x09\xd2\x3b\xf2\x0f\x07\xca\xd7\x6f\x81\x7a\xdb\xeb\xdb\xd0\xa9\x4b\xdb\x73\x27\xdc\x54\xef\x7a\x3f\x86\xcf\x77\x7a\x6e\x0f\xef\x57\x9b\x03\xdf\xe6\xfb\xaa\xac\xbd\x76\xc6\xa0\x7e\xb7\xdb\x76\x3c\x24\x89\xe0\xf3\x87\xe6\xab\x74\x16\x89\x1e\x09\xa9\x2b\xc2\x74\x45\xd8\x16\x0f\x9d\x6b\xa9\x78\x7c\x41\x14\x29\x8c\xcf\x6a\x8d\xfc\x6d\xc5\xca\xd5\x16\x76\xc4\xe9\xff\x68\x76\x28\xc3\xe4\x31\xb2\xc3\x9a\xa0\x5b\x17\xa3\x7f\x88\xec\xb0\xc5\x73\x7b\x66\x87\xc7\xf2\x7d\x55\xd6\x5a\xcf\x9f\xd6\xaa\xaf\x91\xe2\x62\xa5\xbc\x19\x9d\x16\x03\x97\x3c\x48\x55\xc3\x8b\x5e\x9c\x70\xa1\xec\x87\x30\x88\xb5\x37\xb6\x0f\x0a\x3c\xf7\x93\xfd\x41\x6a\x7e\xf1\x26\x29\xaf\x50\x6e\xf3\xd7\x7b\xd9\x57\x34\x5b\x6c\xe5\xcf\xf5\x02\xce\xa4\xa9\x60\xc8\x42\x66\x8f\x43\xec\xd3\x3d\x57\x6e\x6b\xc6\x63\xfc\x9b\xc0\x29\xe5\xec\xaf\x59\x09\x3b\xb4\xbf\xee\xff\xaf\x35\xa7\xb8\x68\xbd\xfc\x9c\xeb\x4a\x0b\xb7\x4a\xfd\x5a\x79\x0a\x9f\xbe\x1d\xcf\x7f\x5a\xe7\xad\x98\xb6\x55\x5a\x21\xc9\xcc\x3d\x38\xf8\x6f\x00\x00\x00\xff\xff\x3a\x38\x89\xd7\xb2\x2f\x00\x00") +var _assetsPipelineYml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xec\x5a\xff\x6f\x1a\x3b\x12\xff\x9d\xbf\x62\xca\x55\x8a\x94\xbb\x85\x90\xa4\xed\xeb\x4a\xf7\x4e\xdb\x40\x73\xe8\x48\x40\x40\xda\x93\x4e\xa7\xc8\xec\x1a\xf0\xcb\xae\xbd\xf2\x17\x28\xd7\xe6\x7f\x3f\xd9\xfb\xcd\xbb\x7c\x4d\x9b\x36\xe9\x7b\x8f\x9f\xc0\x33\x9e\x19\xcf\x67\x3c\xf6\x0c\x76\x1c\xa7\xe6\x7d\x1c\x8d\x71\x14\x87\x48\xe2\xf7\x8c\x47\x48\x7e\xc0\x5c\x10\x46\x5d\x38\x3a\x3d\x69\x9d\x38\x27\x6f\x9d\x93\xb7\x47\xb5\x36\x16\x3e\x27\xb1\x34\x94\xab\x1b\x88\x49\x8c\x43\x42\x31\x28\x41\xe8\x0c\x2e\x58\x80\x07\xd9\x10\xa2\x81\x19\x78\xa7\x48\x18\xc0\x94\x71\xf0\x19\x95\x84\x2a\xa6\x04\x04\x38\x24\x0b\xcc\x57\xb5\x01\xe2\x28\xc2\x12\x73\xe1\xd6\x00\x2e\x89\xfc\xa7\x9a\xdc\x08\xcc\xf5\x2f\x80\xf1\x2a\xc6\x2e\x8c\x24\x27\x74\x66\x06\x4a\x06\x24\xdc\xa0\xd9\xf3\xb9\x43\x1c\xb3\x07\xcc\xd5\xec\x20\x19\xc4\x2a\x0c\x61\xca\x59\xd4\x80\x3e\x0d\x57\x20\xe7\x18\xae\x51\x84\x1b\x40\x99\x34\xbf\x6e\x86\xbd\x5c\xc9\x3b\x8e\xa8\x3f\x7f\x80\x9a\x64\x42\x4a\x9e\x22\x15\x4a\x17\xea\x11\x12\x12\xf3\x7a\x2e\x75\xcc\xee\x30\x4d\x84\x5e\xb3\x8e\x3f\x67\x2e\x48\xae\xf0\x01\x5a\x46\xd8\xe7\x58\x36\xa0\x2b\x21\x22\xb3\xb9\x84\x90\xb1\x3b\x10\x2c\xc2\x72\xae\x71\x09\xc9\x1d\x86\xb7\x93\xd6\x2f\x6f\x51\xeb\xf5\xab\xf3\xd7\xe7\x67\xaf\x4e\x4f\x5f\xbd\x6e\x4d\xdf\x4c\xce\xf0\x24\x38\x3f\x47\xad\x57\x67\x2d\x74\x7e\xfa\xcb\x1b\x34\x85\xbe\xa7\xe4\xdc\x18\x03\x4b\x22\xe7\x80\x7c\x1f\x0b\xa1\xbd\xa4\xbd\xd5\x80\x4b\xe3\xb1\xb9\x94\xb1\x70\x9b\xcd\x19\x91\x73\x35\x69\xf8\x2c\x6a\x0a\x2c\x25\xa1\x33\xd1\x94\x7a\xb2\xa8\x01\x18\xec\x8d\xed\xdb\x56\x91\x39\xa3\xd7\xbd\xbe\xf9\xf7\xed\x45\xff\x7a\xec\x75\xaf\x3b\xc3\xfa\xfa\x22\xc7\x73\x0c\x13\x13\x4b\x3a\x8e\x10\xa1\x98\x83\x5c\xc5\x58\x1b\xa3\x04\x36\x11\x66\xe8\x7a\xc5\x1a\x31\x14\xc7\x99\x09\x17\x2c\x8a\x95\xc4\x07\x59\xf2\xee\xa6\xdb\x6b\xdf\x5e\x76\xae\x3b\x43\xaf\xd7\xba\x1d\x5d\x79\xbd\xde\x1e\x73\x8c\xf0\x83\x8d\xe9\x46\x68\xb6\xdf\x0c\xb4\x14\x4d\x9f\x05\xd8\x48\x69\xaa\x89\xa2\x52\x39\x13\x24\xb0\xdb\x3a\x6f\x9c\x9c\xef\xb4\x88\x68\x0d\x7b\x4c\x19\x63\x21\x7f\x20\x32\x12\x0b\xb9\x6e\xc0\x93\xe0\xb2\xd9\x94\x27\x40\x65\xdd\x90\x2b\xf5\x03\x21\x89\x94\x76\x51\x84\x68\x20\x8c\xea\x27\x01\xa3\x6a\xc4\xd7\xc0\x10\x30\xff\x0e\x73\xb7\xd5\x68\x9d\x36\x5a\x0f\x83\xa0\xaa\xbe\xcd\x96\x34\x64\x28\x78\x87\x04\x56\x3c\xdc\x6b\xc8\xa6\x2c\x28\x71\x18\x92\x19\xa6\xb2\x19\xa9\x26\xc7\x21\x46\x02\x8b\x66\x90\x4a\xde\x66\x1f\x12\x18\x14\x0f\xb5\x71\x84\x0a\x89\xc2\x50\x1b\xa7\x8f\xa4\x92\x61\xd9\xb9\x7c\xc0\xa9\xa0\xc5\x2e\x12\x76\x60\x53\x2d\xcd\x92\x4d\x68\x71\x38\x97\x14\xbc\x27\xe1\x7e\xff\x47\xca\x09\x09\x55\x9f\x1c\x14\x05\xaf\xb7\x45\x3d\x45\x11\xd6\x8a\x75\x78\xeb\xa5\x90\xd0\xb8\x3e\x73\x84\x65\x4d\x2d\x97\x6d\xec\x11\x31\xf6\x0f\x5d\x60\x90\xcc\x4b\xf0\xd5\x13\x53\x74\xcd\x9a\x76\xae\xc5\x12\x34\x40\x72\xae\xe7\x45\xaa\xb1\x8a\xc2\xbf\x01\xc7\x21\x92\x64\x61\xcc\x2d\xae\x15\x6b\x3e\xd0\xcc\xf5\x34\x7d\x74\xe8\xe2\x10\x4d\xd7\xa9\x4f\x22\x05\x98\x2e\x08\x67\x34\xc2\x54\x1a\xb7\xe0\x38\x64\x2b\xfd\xcd\x4a\x0d\x15\x95\x01\x5e\x68\x7d\x03\xce\x82\x47\xd6\x17\x73\x16\x28\x5f\xcf\xa9\xa8\x2c\x08\xf5\xda\x10\x0b\xa6\xb8\x8f\xcd\x55\x2d\x8f\x9e\x21\x2b\x3b\xd9\xfb\x38\x72\xdd\xae\x77\xe5\xba\x9a\x62\x08\x03\xce\x62\xcc\x25\x49\x66\xea\x8f\x27\x84\x8a\xb0\x66\x18\xb0\x90\xf8\xab\x36\xf3\x95\xb6\x2c\xa3\x03\x8c\x24\x92\xb8\x3c\xe4\x40\x67\x3a\xc5\xbe\x74\xc1\x0b\x43\xb6\xcc\xc7\xb5\x02\x42\x7d\x12\xa3\xd0\xb5\x06\x01\x46\x98\x2f\x88\x8f\xcb\x83\x0e\xe4\x99\xa3\x81\x22\xf4\x3f\x46\xd1\x52\xe8\x9d\x6b\x71\x79\x66\xc5\xf6\x3c\x07\x84\x14\x6e\x61\x76\x4a\xd2\x91\xe3\x42\xbd\x59\xcf\x7e\xeb\xd5\x58\xeb\x74\x92\x91\x95\xc6\xc1\x2d\x14\x3b\x22\xb1\x2c\x57\xb0\xcd\x0b\x1b\xfd\xb0\xcb\x13\xb9\xed\x50\x3f\xae\x97\xc6\x33\xf4\xaa\x94\xd2\x4d\xff\xd4\x69\x9d\x38\xad\x37\x47\x29\xc0\xd9\x65\xfe\xe7\xc4\x38\xab\x4e\x9e\x02\xe6\x4c\xf7\xb7\x23\xbd\x6e\x64\x29\x86\xdd\xe3\x83\x50\x86\xad\x7e\xdd\xa6\x41\x9c\xb9\x97\x58\xf6\x27\xbf\x61\x5f\xee\x20\xa5\xe1\xb3\x91\xe3\x9d\xf2\xef\x70\xc6\x91\xe5\xa7\xef\x62\xe9\x40\x6d\xb2\x34\x57\x51\x99\x80\x38\x75\xd1\x52\xb8\xe2\xcc\x75\x5d\x1b\xad\xe3\x6f\xb5\xe3\xb8\x0a\x53\xc8\x54\x30\x35\x15\xb5\x9e\x50\x25\x63\x5f\xac\x8d\x11\x14\xb9\x03\x24\x84\x15\x7e\x5f\xeb\xb0\x5d\x5b\xdb\xe4\x6e\x8f\x4b\x32\x45\xbe\x5c\xdb\xdb\x39\x87\xeb\x0e\x38\xcb\x1d\xdb\xc6\x31\xa6\x81\xe8\x53\xb7\x9c\xff\xb7\x64\x80\x64\x3b\xbc\x18\xa9\x09\xbc\xfc\x6c\xe4\x8e\x24\xf2\xef\xf4\xf0\xbd\x83\x52\xdd\x29\x6f\xe9\xd8\x4a\x7a\x06\x19\x87\xb9\x05\x41\xb2\xf8\x94\x3b\xdd\xf5\x26\x2f\xc1\x8b\x4b\x2c\x3d\x29\xcb\x26\x35\x3c\x9e\x05\x65\xb6\x4a\x51\x00\x96\x2c\xf5\xa2\xdf\xee\x0c\xba\x83\x4e\xaf\x7b\xdd\x49\x49\x9d\xe2\x94\xac\x72\xbf\x18\xe2\x69\x51\xd1\xe6\x44\xfb\xda\x6c\xf1\x58\xc3\x39\x6b\x72\xb9\xcd\x1c\x52\x14\x83\xf7\xd9\xaa\x2a\xd1\xba\xd5\xca\x31\x89\x30\x53\xb2\x4b\xaf\x08\x55\x12\x0b\x17\xce\x4e\x6c\x5c\xd7\x6e\xd1\x3f\x0a\x54\x73\xc1\xde\x8e\x68\x72\xff\x36\x70\x56\xe0\x7f\x32\x40\x93\x92\x6b\x07\x9a\xa5\xc2\x68\x0b\x94\x69\xdd\x72\x9f\x93\x2d\xad\x1f\x10\x27\x68\x12\x62\xcb\x58\x70\x52\x2f\xb6\xfb\x17\xff\xea\x0c\x6f\xbd\x41\xf7\xf6\x43\x67\x38\xea\xf6\xaf\xed\x7d\xfd\x01\x85\x0a\xbb\xd0\x6a\x9c\x9e\x3f\x34\x40\xd2\x56\xc3\x48\xdf\xa4\x13\x23\xbf\x58\x92\x17\x59\x5e\x38\x69\xb4\xac\xe1\x78\xae\x2b\x95\x72\x56\x4b\xce\x98\xd2\x10\xe4\x25\x53\x75\xdc\x64\x3c\x5d\xc4\x38\xa2\x67\xbc\x52\x29\xa7\xee\x9b\x0b\x7b\x34\x4d\x4f\xf7\x4d\x7b\x50\xdf\xd9\xef\xc1\x61\xd0\x54\x82\x37\x27\x84\x36\x23\xb5\x49\xcd\x3c\x62\x01\xfc\x95\x7f\xda\xc3\x17\x29\x70\x7c\x63\x4b\x22\x58\x2c\x7c\x88\x95\x98\x83\x23\x21\x44\xfa\x9a\x6d\x4d\x42\xeb\x71\xa5\x3f\xba\x72\x59\x5b\xab\x53\x08\xdd\xbd\x29\xdb\xe6\xa2\xed\xf9\x3e\x8e\x25\xa2\xfe\x93\x6c\xcb\xe4\xb2\xef\xa0\xdc\x88\x4d\x5b\x34\x31\xb4\xa8\x91\xb5\x73\xec\xaa\xe1\xf7\xb8\x53\xbf\xef\x86\xb2\x9c\x77\xbb\xd8\x90\x06\xf4\x9e\x0b\x11\xa1\x12\x7f\x92\xd5\xf8\x6a\x77\xde\x7b\x37\xbd\xf1\xad\xe9\xb4\x8c\x06\x9d\x0b\x17\xea\x2f\x3f\x57\xcb\xe4\xfb\xfa\x1f\x6c\xff\x62\xba\x00\x15\xc3\xcb\xcf\x69\xd1\x7d\x0f\x5f\xbe\x00\xf6\xe7\x0c\xea\xa3\x3b\x12\xc7\x84\xce\x40\xc5\x01\x92\xa6\xec\xb5\x00\xa8\x1f\x98\x1c\xd2\xba\xd8\x52\xb0\x29\x53\x58\x12\xb4\x45\x62\xce\x96\xa5\x29\x53\xf8\x4d\x30\x0a\xbf\x6a\x6a\x43\x7f\xdd\x34\x77\x51\x74\x2d\x1c\x2d\xbf\xb1\x8a\xc2\x62\xc8\xfc\xca\x17\xf7\x72\x2d\x1e\xea\xf0\x6b\x99\xf9\xab\x13\xd9\xd1\xf1\x71\xf3\xf8\x68\x77\x16\xd3\x4b\x7b\xda\x1c\xa6\x3d\xb4\x27\x83\x69\x23\x81\xd0\xa4\xa1\x9a\x73\x3e\xa7\x1c\x96\x75\xdd\x77\x64\xb1\x4a\x5f\x7c\x4b\x1e\xcb\x5b\xd6\x8f\x75\x77\x4c\xb2\xff\x20\x6f\xf7\x3c\xe1\x31\x55\x69\x46\xed\x39\xa6\x34\xf7\x73\x82\xf8\xcf\x63\xea\xcf\x63\xaa\x38\xa6\xd2\x5e\xed\xf7\x3b\xa6\x72\x05\x87\x1f\x53\xc5\x94\x07\x1f\x53\x7a\xb3\x3d\xf7\x63\xea\x69\x73\x98\x39\xa6\x76\x67\x30\xfb\x98\x2a\x38\x9f\x53\x0e\x7b\xbe\xc7\x54\xd6\x91\xde\x08\x6d\x4e\x74\xb3\x6f\x5b\x10\xd4\xae\xf3\x38\x2d\x3b\xd5\x6e\x76\x5b\x7e\x1d\x49\x34\xb3\x3b\xbd\x09\xfa\x23\xbb\x1b\x95\x75\x92\x85\xdd\xc7\xee\xd2\x58\xc9\x02\x14\xf8\xcf\x7f\xad\x88\xde\x28\x24\x13\xa3\x57\xd5\xad\x64\xc3\x0b\x24\xf1\x8c\xf1\xd5\x86\x49\x00\xfd\x25\xc5\xdc\x85\xf1\x9c\xf0\x60\x80\xb8\x5c\x95\xa8\x45\x17\xb0\x75\x54\x22\x0c\x38\x5b\x90\x40\xcf\x4c\xfe\xe4\xb2\x88\x7d\x25\x4b\xd6\x5b\xa4\xb2\x07\x12\x46\x8b\x7c\xc1\xe8\x94\xcc\x14\x47\xeb\x1d\xd2\xd4\x4c\x13\x3e\xc5\x4b\x9f\x12\x8b\x79\xbe\x63\x73\xe4\x7f\xbc\x65\x9f\xf4\xed\x8d\xcd\x63\xbd\xae\xc9\x55\xe5\x6f\x58\x4a\x9c\x66\xc4\x62\x1c\x2a\xda\xe7\xc6\x03\xad\x0a\xbe\xd9\x1f\xa3\x5b\xe1\x4d\xd8\xbc\x72\x17\xeb\x50\x0c\xcb\xd2\x2d\xdf\x78\x1f\x47\x0f\xc5\xce\xfe\x1b\x37\xfb\x54\x62\xef\x70\xf4\x0e\xc0\x3d\x23\x3e\x04\xf9\x34\xd9\xa6\x89\x53\xe3\xb1\xd6\x82\xde\x89\x4a\xa1\xbd\x6b\x35\x18\x7f\x1e\x6f\x6f\xf5\xd9\x01\xfe\x36\x2b\x7e\x24\x67\x57\xbd\x57\x78\xfa\xb4\x12\xff\x5e\xb5\xd0\xda\xb1\x09\x92\x1b\xf9\x4f\x07\xca\xd7\x6f\x81\x6a\x4b\xef\xdb\xd0\xa9\x4a\x3b\x70\x27\x8c\xcb\x57\xbd\x9f\xc3\xe7\x7b\x3d\x77\x80\xf7\xcb\xad\x88\x6f\xf3\x7d\x59\xd6\x41\x3b\x63\x50\xbd\xdb\xed\x3a\x1e\xe2\x98\xb3\xc5\x43\xf3\x55\x32\x0b\x85\x8f\x84\xd4\x15\xa2\xaa\x24\x6c\x87\x87\x2e\x94\x90\x2c\x6a\x23\x89\x72\xe3\xd3\x52\x23\x7b\x37\xb2\x76\xb5\x85\x3d\x71\xfa\x07\xcd\x0e\x45\x98\x3c\x46\x76\xd8\x10\x74\x9b\x62\xf4\x77\x91\x1d\x76\x78\xee\xc0\xec\xf0\x58\xbe\x2f\xcb\xda\xe8\xf9\xb3\x4a\xf5\x35\x92\x8c\xaf\x95\x37\xa3\xb3\x7c\xa0\xc7\xfc\x44\x35\xbc\xe8\x46\x31\xe3\xd2\xfc\xc9\x07\x91\x72\x26\xe6\xb1\x84\x63\x3f\x47\xa8\x25\xe6\xe7\xef\xad\xb2\x0a\xe5\x26\x7b\x99\x98\xfe\x43\x68\x8a\xad\xec\x29\xa2\xcf\xa8\xd0\x15\x0c\x5a\x8a\xf4\xe1\x8b\x79\x96\x68\xcb\x6d\xce\x59\x84\xff\xc1\xf1\x8c\x30\xfa\xf7\xb4\x84\x1d\x9a\x5f\xf7\x7f\x69\x2e\x08\x5e\x36\x5f\x7e\xce\x74\x25\x85\x5b\xa9\x7e\x2d\x3d\xf3\x4f\xde\xc5\x67\x3f\x8d\xf3\xd6\x4c\xdb\x29\x2d\x97\xa4\xe7\xd6\x6a\xff\x0f\x00\x00\xff\xff\x3d\xba\x2c\x4f\x8e\x30\x00\x00") func assetsPipelineYmlBytes() ([]byte, error) { return bindataRead( @@ -150,7 +150,7 @@ func assetsPipelineYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "assets/pipeline.yml", size: 12210, mode: os.FileMode(420), modTime: time.Unix(1488948221, 0)} + info := bindataFileInfo{name: "assets/pipeline.yml", size: 12430, mode: os.FileMode(420), modTime: time.Unix(1488953817, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/templates/assets/bucket.yml b/templates/assets/bucket.yml index f2baf542..7aa92f21 100644 --- a/templates/assets/bucket.yml +++ b/templates/assets/bucket.yml @@ -9,7 +9,7 @@ Resources: Bucket: Type: AWS::S3::Bucket Properties: - BucketName: !Sub ${BucketPrefix}-${AWS::Region}-${AWS::AccountId} + BucketName: !Sub mu-${BucketPrefix}-${AWS::Region}-${AWS::AccountId} Outputs: Bucket: Description: Name of the pipeline bucket diff --git a/templates/assets/pipeline.yml b/templates/assets/pipeline.yml index de00c0a5..13f1f0bb 100644 --- a/templates/assets/pipeline.yml +++ b/templates/assets/pipeline.yml @@ -201,6 +201,9 @@ Resources: Type: CODEPIPELINE BuildSpec: !Sub | version: 0.1 + environment_variables: + plaintext: + DEFAULT_BUILDSPEC: "${DefaultBuildspec}" phases: build: commands: @@ -209,7 +212,7 @@ Resources: - mu -c ${MuFile} env up ${TestEnv} || echo "Skipping update of environment" - mu -c ${MuFile} svc deploy ${TestEnv} -t latest - mu env show ${TestEnv} -f json > env.json - - mv buildspec-test.yml buildspec.yml || echo "${DefaultBuildspec}" > buildspec.yml + - mv buildspec-test.yml buildspec.yml || echo "$DEFAULT_BUILDSPEC" > buildspec.yml artifacts: files: - '**/*' @@ -247,6 +250,9 @@ Resources: Type: CODEPIPELINE BuildSpec: !Sub | version: 0.1 + environment_variables: + plaintext: + DEFAULT_BUILDSPEC: "${DefaultBuildspec}" phases: build: commands: @@ -255,7 +261,7 @@ Resources: - mu -c ${MuFile} env up ${ProdEnv} || echo "Skipping update of environment" - mu -c ${MuFile} svc deploy ${ProdEnv} -t latest - mu env show ${ProdEnv} -f json > env.json - - mv buildspec-prod.yml buildspec.yml || echo "${DefaultBuildspec}" > buildspec.yml + - mv buildspec-prod.yml buildspec.yml || echo "$DEFAULT_BUILDSPEC" > buildspec.yml artifacts: files: - '**/*' diff --git a/wiki b/wiki index 488fcffe..f615a3f4 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 488fcffe9aaff4da82bc92239c3ca0b4b99e1222 +Subproject commit f615a3f4ca6af1f3a9988d519aad0759ed5fc13a diff --git a/workflows/environment_terminate.go b/workflows/environment_terminate.go index 64308e14..d82d5fbf 100644 --- a/workflows/environment_terminate.go +++ b/workflows/environment_terminate.go @@ -10,11 +10,39 @@ func NewEnvironmentTerminator(ctx *common.Context, environmentName string) Execu workflow := new(environmentWorkflow) return newWorkflow( + workflow.environmentServiceTerminator(environmentName, ctx.StackManager, ctx.StackManager, ctx.StackManager), workflow.environmentEcsTerminator(environmentName, ctx.StackManager, ctx.StackManager), workflow.environmentVpcTerminator(environmentName, ctx.StackManager, ctx.StackManager), ) } +func (workflow *environmentWorkflow) environmentServiceTerminator(environmentName string, stackLister common.StackLister, stackDeleter common.StackDeleter, stackWaiter common.StackWaiter) Executor { + return func() error { + log.Noticef("Terminating Services for environment '%s' ...", environmentName) + stacks, err := stackLister.ListStacks(common.StackTypeService) + if err != nil { + return err + } + for _, stack := range stacks { + if stack.Tags["environment"] != environmentName { + continue + } + err := stackDeleter.DeleteStack(stack.Name) + if err != nil { + return err + } + } + for _, stack := range stacks { + if stack.Tags["environment"] != environmentName { + continue + } + log.Infof(" Undeploying service '%s' from environment '%s'", stack.Tags["service"], environmentName ) + stackWaiter.AwaitFinalStatus(stack.Name) + } + + return nil + } +} func (workflow *environmentWorkflow) environmentEcsTerminator(environmentName string, stackDeleter common.StackDeleter, stackWaiter common.StackWaiter) Executor { return func() error { log.Noticef("Terminating ECS environment '%s' ...", environmentName) diff --git a/workflows/pipeline_upsert.go b/workflows/pipeline_upsert.go index 725bc1b7..7abd0680 100644 --- a/workflows/pipeline_upsert.go +++ b/workflows/pipeline_upsert.go @@ -6,6 +6,7 @@ import ( "github.com/stelligent/mu/common" "github.com/stelligent/mu/templates" "strings" + "regexp" ) // NewPipelineUpserter create a new workflow for upserting a pipeline @@ -32,7 +33,7 @@ func (workflow *pipelineWorkflow) pipelineBucket(stackUpserter common.StackUpser } log.Noticef("Upserting Bucket for CodePipeline") bucketParams := make(map[string]string) - bucketParams["BucketPrefix"] = "mu-codepipeline" + bucketParams["BucketPrefix"] = "codepipeline" err = stackUpserter.UpsertStack(bucketStackName, template, bucketParams, buildPipelineTags(workflow.serviceName, common.StackTypeBucket)) if err != nil { return err @@ -111,7 +112,9 @@ func (workflow *pipelineWorkflow) pipelineUpserter(tokenProvider func(bool) stri } buildspecBytes := new(bytes.Buffer) buildspecBytes.ReadFrom(buildspec) - pipelineParams["DefaultBuildspec"] = buildspecBytes.String() + newlineRegexp := regexp.MustCompile(`\r?\n`) + buildspecString := newlineRegexp.ReplaceAllString(buildspecBytes.String(), "\\n") + pipelineParams["DefaultBuildspec"] = buildspecString version := workflow.pipelineConfig.MuVersion if version == "" { diff --git a/workflows/pipeline_upsert_test.go b/workflows/pipeline_upsert_test.go index 1ef0265e..82064011 100644 --- a/workflows/pipeline_upsert_test.go +++ b/workflows/pipeline_upsert_test.go @@ -34,7 +34,7 @@ func TestPipelineBucket(t *testing.T) { stackParams := stackManager.Calls[0].Arguments.Get(1).(map[string]string) assert.NotNil(stackParams) - assert.Equal("mu-codepipeline", stackParams["BucketPrefix"]) + assert.Equal("codepipeline", stackParams["BucketPrefix"]) } func TestPipelineUpserter(t *testing.T) {