From 28d9ee7d457c938fc94f88462a61c390273b139f Mon Sep 17 00:00:00 2001 From: Theodor-Alexandru Irimia Date: Mon, 1 Jul 2019 13:08:45 +0200 Subject: [PATCH] Added functionality for blue-green releases --- command/deploy.go | 29 +++++++++++++++++++++++++++++ docs/commands.md | 2 ++ levant/structs/config.go | 4 ++++ 3 files changed, 35 insertions(+) diff --git a/command/deploy.go b/command/deploy.go index 06db75058..6f6d08926 100644 --- a/command/deploy.go +++ b/command/deploy.go @@ -59,6 +59,10 @@ General Options: Use the taskgroup count from the Nomad jobfile instead of the count that is currently set in a running job. + -blue-green + Set the max-parallel and the canary count of each task group to the current + count for a blue-green type release + -ignore-no-changes By default if no changes are detected when running a deployment Levant will exit with a status 1 to indicate a deployment didn't happen. This behaviour @@ -116,6 +120,7 @@ func (c *DeployCommand) Run(args []string) int { flags.StringVar(&config.Client.ConsulAddr, "consul-address", "", "") flags.BoolVar(&config.Deploy.ForceBatch, "force-batch", false, "") flags.BoolVar(&config.Deploy.ForceCount, "force-count", false, "") + flags.BoolVar(&config.Deploy.BlueGreen, "blue-green", false, "") flags.BoolVar(&config.Plan.IgnoreNoChanges, "ignore-no-changes", false, "") flags.StringVar(&level, "log-level", "INFO", "") flags.StringVar(&format, "log-format", "HUMAN", "") @@ -175,6 +180,18 @@ func (c *DeployCommand) Run(args []string) int { } } + if config.Deploy.BlueGreen { + if err = c.checkBlueGreen(config.Template.Job); err != nil { + c.UI.Error(fmt.Sprintf("[ERROR] levant/command: %v", err)) + return 1 + } + for _, taskGroup := range config.Template.Job.TaskGroups { + blueGreenCount := taskGroup.Count + taskGroup.Update.MaxParallel = blueGreenCount + taskGroup.Update.Canary = blueGreenCount + } + } + p := levant.PlanConfig{ Client: config.Client, Plan: config.Plan, @@ -224,3 +241,15 @@ func (c *DeployCommand) checkForceBatch(job *nomad.Job, forceBatch bool) error { return fmt.Errorf("force-batch passed but job is not periodic") } + +func (c *DeployCommand) checkBlueGreen(job *nomad.Job) error { + + if job.IsPeriodic() { + return fmt.Errorf("blue-green passed but job is periodic") + } + if *job.Type == "system" { + return fmt.Errorf(`blue-green passed but job type is "system"`) + } + + return nil +} diff --git a/docs/commands.md b/docs/commands.md index 184a8d0f6..01c3e7314 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -18,6 +18,8 @@ Levant supports a number of command line arguments which provide control over th * **-force-count** (bool: false) Use the taskgroup count from the Nomad job file instead of the count that is obtained from the running job count. +* **-blue-green** (bool: false) Set the max-parallel and the canary count of each task group to the current count for a blue-green type release + * **-ignore-no-changes** (bool: false) By default if no changes are detected when running a deployment Levant will exit with a status 1 to indicate a deployment didn't happen. This behaviour can be changed using this flag so that Levant will exit cleanly ensuring CD pipelines don't fail when no changes are detected * **-log-level** (string: "INFO") The level at which Levant will log to. Valid values are DEBUG, INFO, WARN, ERROR and FATAL. diff --git a/levant/structs/config.go b/levant/structs/config.go index 4839c25c9..36064a44b 100644 --- a/levant/structs/config.go +++ b/levant/structs/config.go @@ -35,6 +35,10 @@ type DeployConfig struct { // and force the count based on the rendered job file. ForceCount bool + // BlueGreen is a boolean flag that can be used to run a blue-green release, + // overwriting the max-parallel and the canary count variables + BlueGreen bool + // VaultToken is a string with the vault token. VaultToken string