Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
package main
import (
"errors"
"fmt"
"os"
"regexp"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ecs"
flag "github.com/ogier/pflag"
)
func failOnError(err error) {
if err != nil {
fmt.Printf("%v\n", err)
os.Exit(1)
}
}
// findClusterArn finds a cluster's arn from a more human
// readable name
func findClusterArn(svc *ecs.ECS, clusterName string) (string, error) {
params := &ecs.ListClustersInput{}
clusters, err := svc.ListClusters(params)
if err != nil {
return "", err
}
for _, ClusterID := range clusters.ClusterArns {
var pattern = `/` + clusterName + `$`
matched, _ := regexp.MatchString(pattern, *ClusterID)
if matched {
return *ClusterID, nil
}
}
return "", errors.New("Could not find cluster with name: " + clusterName)
}
// findServiceArn finds a service arn from a more human
// readable name
func findServiceArn(svc *ecs.ECS, clusterArn string, serviceName string) (string, error) {
params := &ecs.ListServicesInput{
Cluster: aws.String(clusterArn),
}
params.SetMaxResults(100)
services, err := svc.ListServices(params)
if err != nil {
return "", err
}
for _, ServiceID := range services.ServiceArns {
var pattern = `/` + serviceName + `$`
matched, _ := regexp.MatchString(pattern, *ServiceID)
if matched {
return *ServiceID, nil
}
}
return "", errors.New("Could not find service with name: " + serviceName)
}
// findTaskArn
// finds the first task definition in a cluster and service.
//
// Returns task ARN
//
// TODO:
// filter the resulting tasks by essential: true
// and only return the essential?
// either that or assume that the new image will
// somewhat match the old image, and use that to pick
// one of the tasks.
func findTaskArn(svc *ecs.ECS, clusterArn string, serviceArn string) (string, error) {
params := &ecs.DescribeServicesInput{
Services: []*string{
aws.String(serviceArn),
},
Cluster: aws.String(clusterArn),
}
resp, err := svc.DescribeServices(params)
return *resp.Services[0].TaskDefinition, err
}
// setImage
// Create a new Task Definition based on an existing
// ARN, and a new image.
//
// Returns new task's ARN
//
func setImage(svc *ecs.ECS, taskArn string, image string) (string, error) {
params := &ecs.DescribeTaskDefinitionInput{TaskDefinition: aws.String(taskArn)}
resp, err := svc.DescribeTaskDefinition(params)
if err != nil {
return "", err
}
task := resp.TaskDefinition
var out = taskArn
if *task.ContainerDefinitions[0].Image != image {
task.ContainerDefinitions[0].Image = &image
regResp, err := svc.RegisterTaskDefinition(&ecs.RegisterTaskDefinitionInput{
Family: task.Family,
ContainerDefinitions: task.ContainerDefinitions,
Volumes: task.Volumes,
})
if err != nil {
return "", err
}
out = *regResp.TaskDefinition.TaskDefinitionArn
}
return out, nil
}
func main() {
var cluster = flag.String("cluster", "default", "Name of cluster")
flag.Parse()
if flag.NArg() < 2 {
fmt.Println("Usage:\n\taws-rollout [service] [image]")
return
}
var service = flag.Arg(0)
var image = flag.Arg(1)
fmt.Printf("Cluster: %s\n", *cluster)
fmt.Printf("Service: %s\n", service)
fmt.Printf("Image: %s\n", image)
svc := ecs.New(session.New())
clusterArn, err := findClusterArn(svc, *cluster)
failOnError(err)
serviceArn, err := findServiceArn(svc, clusterArn, service)
failOnError(err)
taskArn, err := findTaskArn(svc, clusterArn, serviceArn)
failOnError(err)
newTaskArn, err := setImage(svc, taskArn, image)
failOnError(err)
params := &ecs.UpdateServiceInput{
Service: aws.String(serviceArn),
Cluster: aws.String(clusterArn),
TaskDefinition: aws.String(newTaskArn),
}
serv, err := svc.UpdateService(params)
failOnError(err)
fmt.Printf("Deployed Task: %s\n", newTaskArn)
fmt.Printf("Pending Count: %d\n", *serv.Service.PendingCount)
fmt.Println("Deployment Success!")
}