Skip to content

Commit

Permalink
Wait for deployment to finish by default
Browse files Browse the repository at this point in the history
  • Loading branch information
qbart committed Dec 13, 2022
1 parent a18d2e4 commit 2fa0141
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 3 deletions.
91 changes: 89 additions & 2 deletions awscmd/ecs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,25 @@ package awscmd
import (
"context"
"fmt"
"io"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/wzshiming/ctc"
)

type InputEcsDeploy struct {
Region string
Cluster string
Service string
DockerImage string
OneOffs []string
}

type OuputEcsDeploy struct {
Service string
Service string
PrimaryDeploymentID string
}

func EcsDeploy(ctx context.Context, input *InputEcsDeploy) (*OuputEcsDeploy, error) {
Expand Down Expand Up @@ -79,8 +84,90 @@ func EcsDeploy(ctx context.Context, input *InputEcsDeploy) (*OuputEcsDeploy, err
if err != nil {
return nil, fmt.Errorf("Failed to update service with new task revision: %w", err)
}
var primaryDeployment *ecs.Deployment = nil
for _, deployment := range updateOut.Service.Deployments {
if *deployment.Status == "PRIMARY" {
primaryDeployment = deployment
break
}
}

if primaryDeployment == nil {
return &OuputEcsDeploy{
Service: *updateOut.Service.ServiceName,
}, fmt.Errorf("Service %s deployed but couldn't fetch primary deployment status", *updateOut.Service.ServiceName)
}

return &OuputEcsDeploy{
Service: *updateOut.Service.ServiceName,
Service: *updateOut.Service.ServiceName,
PrimaryDeploymentID: *primaryDeployment.Id,
}, nil
}

type InputEcsDeployWait struct {
Region string
Cluster string
Service string
DeploymentID string
}

type OuputEcsDeployWait struct {
}

func EcsDeployWait(ctx context.Context, input *InputEcsDeployWait, w io.Writer) (*OuputEcsDeployWait, error) {
sess, err := NewSession(input.Region)
if err != nil {
return nil, err
}
svc := ecs.New(sess)

attempt := 1

for {
serviceOut, err := svc.DescribeServicesWithContext(ctx, &ecs.DescribeServicesInput{
Cluster: aws.String(input.Cluster),
Services: []*string{aws.String(input.Service)},
})
if err != nil {
return nil, fmt.Errorf("Failed to fetch service: %w", err)
}
if len(serviceOut.Services) == 0 {
return nil, fmt.Errorf("No service definition found")
}
if len(serviceOut.Services) != 1 {
// this should not happen because we defined only 1 service in input but stays for sanity check
return nil, fmt.Errorf("Ambigious match, found more than 1 service")
}

var primaryDeployment *ecs.Deployment = nil
for _, deployment := range serviceOut.Services[0].Deployments {
if *deployment.Id == input.DeploymentID {
primaryDeployment = deployment
break
}
}

if primaryDeployment == nil {
return nil, fmt.Errorf("Failed to monitor service deployment")
}

fmt.Fprintf(w, "%s%d%s Running | %s%d%s Pending | %s%d%s Desired (Attempt %d, retrying in 10s)\n",
ctc.ForegroundGreen, *primaryDeployment.RunningCount, ctc.Reset,
ctc.ForegroundYellow, *primaryDeployment.PendingCount, ctc.Reset,
ctc.ForegroundRed, *primaryDeployment.DesiredCount, ctc.Reset,
attempt,
)

if *primaryDeployment.RolloutState != "IN_PROGRESS" {
completed := (*primaryDeployment.RolloutState == "COMPLETED")
if completed {
return &OuputEcsDeployWait{}, nil
} else {
return nil, fmt.Errorf("Deployment failed")
}
}

time.Sleep(10 * time.Second)
attempt++
}
}
22 changes: 21 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,33 @@ func main() {
DockerImage: c.String("docker-image"),
}
out, err := awscmd.EcsDeploy(context.TODO(), input)
if out != nil {
fmt.Fprintf(
c.App.Writer,
"%sNew deployment for service `%s` created%s\n",
ctc.ForegroundYellow,
out.Service,
ctc.Reset,
)
}
if err != nil {
return err
}

waitInput := &awscmd.InputEcsDeployWait{
Region: c.String("region"),
Cluster: c.String("cluster"),
Service: c.String("service"),
DeploymentID: out.PrimaryDeploymentID,
}
_, err = awscmd.EcsDeployWait(context.TODO(), waitInput, c.App.Writer)
if err != nil {
return err
}

fmt.Fprintf(
c.App.Writer,
"%sNew deployment for service `%s` created%s\n",
"%sDeployment for service `%s` finished%s\n",
ctc.ForegroundGreen,
out.Service,
ctc.Reset,
Expand Down

0 comments on commit 2fa0141

Please sign in to comment.