Skip to content

Commit 2620dbc

Browse files
committed
Refactor UpdateService
1 parent 18afa25 commit 2620dbc

File tree

4 files changed

+315
-297
lines changed

4 files changed

+315
-297
lines changed

ecs-cli/modules/cli/compose/entity/service/service.go

Lines changed: 71 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,10 @@ func (s *Service) Start() error {
211211
}
212212

213213
// Up creates the task definition and service and starts the containers if necessary.
214-
// It does so by calling DescribeService to see if its present, else's calls Create() and Start()
215-
// If the compose file had changed, it would update the service with the new task definition
216-
// by calling UpdateService with the new task definition
214+
// It does so by calling DescribeService to see if it exists, then calls Create() and Start().
215+
// Otherwise, if the compose or ecs-params files have changed, it will update
216+
// the existing service with the new task definition by calling UpdateService
217+
// with the new task definition and service parameters.
217218
func (s *Service) Up() error {
218219
// describe service to get the task definition and count running
219220
ecsService, err := s.describeService()
@@ -252,8 +253,8 @@ func (s *Service) Up() error {
252253
return s.startService()
253254
}
254255

255-
// Update Service
256-
if err = s.updateExistingService(ecsService, newTaskDefinition); err != nil {
256+
// Update Existing Service
257+
if err = s.updateService(ecsService, newTaskDefinition); err != nil {
257258
return err
258259
}
259260

@@ -265,7 +266,39 @@ func (s *Service) Up() error {
265266
return nil
266267
}
267268

268-
func (s *Service) updateExistingService(ecsService *ecs.Service, newTaskDefinition *ecs.TaskDefinition) error {
269+
func (s *Service) buildUpdateServiceInput(count int64, serviceName, taskDefinition string) (*ecs.UpdateServiceInput, error) {
270+
cluster := s.Context().CommandConfig.Cluster
271+
deploymentConfig := s.DeploymentConfig()
272+
forceDeployment := s.Context().CLIContext.Bool(flags.ForceDeploymentFlag)
273+
networkConfig, err := composeutils.ConvertToECSNetworkConfiguration(s.ecsContext.ECSParams)
274+
if err != nil {
275+
return nil, err
276+
}
277+
278+
input := &ecs.UpdateServiceInput{
279+
DesiredCount: aws.Int64(count),
280+
Service: aws.String(serviceName),
281+
Cluster: aws.String(cluster),
282+
DeploymentConfiguration: deploymentConfig,
283+
ForceNewDeployment: &forceDeployment,
284+
}
285+
286+
if s.healthCheckGP != nil {
287+
input.HealthCheckGracePeriodSeconds = aws.Int64(*s.healthCheckGP)
288+
}
289+
290+
if networkConfig != nil {
291+
input.NetworkConfiguration = networkConfig
292+
}
293+
294+
if taskDefinition != "" {
295+
input.TaskDefinition = aws.String(taskDefinition)
296+
}
297+
298+
return input, nil
299+
}
300+
301+
func (s *Service) updateService(ecsService *ecs.Service, newTaskDefinition *ecs.TaskDefinition) error {
269302
if s.Context().CLIContext.Bool(flags.EnableServiceDiscoveryFlag) {
270303
return fmt.Errorf("Service Discovery can not be enabled on an existing ECS Service")
271304
}
@@ -288,41 +321,26 @@ func (s *Service) updateExistingService(ecsService *ecs.Service, newTaskDefiniti
288321
newTaskDefinitionId := entity.GetIdFromArn(newTaskDefinition.TaskDefinitionArn)
289322

290323
if oldTaskDefinitionId == newTaskDefinitionId {
291-
return s.updateService(newCount)
324+
return s.updateServiceCount(newCount)
292325
}
293326

294-
deploymentConfig := s.DeploymentConfig()
295327
// if the task definitions were different, updateService with new task definition
296328
// this creates a deployment in ECS and slowly takes down the containers with old ones and starts new ones
297329

298-
networkConfig, err := composeutils.ConvertToECSNetworkConfiguration(s.ecsContext.ECSParams)
330+
updateServiceInput, err := s.buildUpdateServiceInput(newCount, ecsServiceName, newTaskDefinitionId)
299331
if err != nil {
300332
return err
301333
}
302334

303-
forceDeployment := s.Context().CLIContext.Bool(flags.ForceDeploymentFlag)
304-
305-
err = s.Context().ECSClient.UpdateService(ecsServiceName, newTaskDefinitionId, newCount, deploymentConfig, networkConfig, s.healthCheckGP, forceDeployment)
335+
err = s.Context().ECSClient.UpdateService(updateServiceInput)
306336
if err != nil {
307337
return err
308338
}
309-
fields := log.Fields{
310-
"serviceName": ecsServiceName,
311-
"taskDefinition": newTaskDefinitionId,
312-
"desiredCount": newCount,
313-
}
314-
if deploymentConfig != nil && deploymentConfig.MaximumPercent != nil {
315-
fields["deployment-max-percent"] = aws.Int64Value(deploymentConfig.MaximumPercent)
316-
}
317-
if deploymentConfig != nil && deploymentConfig.MinimumHealthyPercent != nil {
318-
fields["deployment-min-healthy-percent"] = aws.Int64Value(deploymentConfig.MinimumHealthyPercent)
319-
}
320-
if s.healthCheckGP != nil {
321-
fields["health-check-grace-period"] = *s.healthCheckGP
322-
}
323339

324-
log.WithFields(fields).Info("Updated the ECS service with a new task definition. " +
325-
"Old containers will be stopped automatically, and replaced with new ones")
340+
message := "Updated the ECS service with a new task definition. " +
341+
"Old containers will be stopped automatically, and replaced with new ones"
342+
s.logUpdateService(updateServiceInput, message)
343+
326344
return waitForServiceTasks(s, ecsServiceName)
327345
}
328346

@@ -336,13 +354,13 @@ func (s *Service) Info(filterProjectTasks bool) (project.InfoSet, error) {
336354

337355
// Scale the service desired count to be the specified count
338356
func (s *Service) Scale(count int) error {
339-
return s.updateService(int64(count))
357+
return s.updateServiceCount(int64(count))
340358
}
341359

342360
// Stop stops all the containers in the service by calling ECS.UpdateService(count=0)
343361
// TODO, Store the current desiredCount in a cache, so that number of tasks(group of containers) can be started again
344362
func (s *Service) Stop() error {
345-
return s.updateService(int64(0))
363+
return s.updateServiceCount(int64(0))
346364
}
347365

348366
// Down stops any running containers(tasks) by calling Stop() and deletes an active ECS Service
@@ -527,7 +545,7 @@ func (s *Service) createService() error {
527545
defer s.logCreateService(serviceName, taskDefName)
528546

529547
// Call ECS Client
530-
err = s.Context().ECSClient.CreateService(serviceName, createServiceInput)
548+
err = s.Context().ECSClient.CreateService(createServiceInput)
531549
if err != nil {
532550
return err
533551
}
@@ -574,7 +592,7 @@ func (s *Service) startService() error {
574592
"desiredCount": desiredCount,
575593
"force-deployment": strconv.FormatBool(forceDeployment),
576594
}).Info("Forcing new deployment of running ECS Service")
577-
return s.updateService(desiredCount)
595+
return s.updateServiceCount(desiredCount)
578596
}
579597
//NoOp
580598
log.WithFields(log.Fields{
@@ -584,43 +602,47 @@ func (s *Service) startService() error {
584602

585603
return waitForServiceTasks(s, serviceName)
586604
}
587-
return s.updateService(int64(1))
605+
return s.updateServiceCount(int64(1))
588606
}
589607

590-
// updateService calls the underlying ECS.UpdateService with the specified count
591-
func (s *Service) updateService(count int64) error {
608+
// updateServiceCount calls the underlying ECS.UpdateService with the specified count
609+
// NOTE: If network configuration has changed in ECS Params, this will also be updated
610+
func (s *Service) updateServiceCount(count int64) error {
592611
serviceName := entity.GetServiceName(s)
593-
deploymentConfig := s.DeploymentConfig()
594-
networkConfig, err := composeutils.ConvertToECSNetworkConfiguration(s.ecsContext.ECSParams)
595-
forceDeployment := s.Context().CLIContext.Bool(flags.ForceDeploymentFlag)
596612

613+
updateServiceInput, err := s.buildUpdateServiceInput(count, serviceName, "")
597614
if err != nil {
598615
return err
599616
}
600617

601-
if err = s.Context().ECSClient.UpdateService(serviceName, "", count, deploymentConfig, networkConfig, s.healthCheckGP, forceDeployment); err != nil {
618+
if err = s.Context().ECSClient.UpdateService(updateServiceInput); err != nil {
602619
return err
603620
}
604621

622+
s.logUpdateService(updateServiceInput, "Updated ECS service successfully")
623+
624+
return waitForServiceTasks(s, serviceName)
625+
}
626+
627+
func (s *Service) logUpdateService(input *ecs.UpdateServiceInput, message string) {
605628
fields := log.Fields{
606-
"serviceName": serviceName,
607-
"desiredCount": count,
629+
"service": aws.StringValue(input.Service),
630+
"desiredCount": aws.Int64Value(input.DesiredCount),
608631
}
609-
if deploymentConfig != nil && deploymentConfig.MaximumPercent != nil {
610-
fields["deployment-max-percent"] = aws.Int64Value(deploymentConfig.MaximumPercent)
632+
if s.deploymentConfig != nil && s.deploymentConfig.MaximumPercent != nil {
633+
fields["deployment-max-percent"] = aws.Int64Value(s.deploymentConfig.MaximumPercent)
611634
}
612-
if deploymentConfig != nil && deploymentConfig.MinimumHealthyPercent != nil {
613-
fields["deployment-min-healthy-percent"] = aws.Int64Value(deploymentConfig.MinimumHealthyPercent)
635+
if s.deploymentConfig != nil && s.deploymentConfig.MinimumHealthyPercent != nil {
636+
fields["deployment-min-healthy-percent"] = aws.Int64Value(s.deploymentConfig.MinimumHealthyPercent)
614637
}
615638
if s.healthCheckGP != nil {
616639
fields["health-check-grace-period"] = *s.healthCheckGP
617640
}
618-
if forceDeployment {
619-
fields["force-deployment"] = forceDeployment
641+
if input.ForceNewDeployment != nil {
642+
fields["force-deployment"] = aws.BoolValue(input.ForceNewDeployment)
620643
}
621644

622-
log.WithFields(fields).Info("Updated ECS service successfully")
623-
return waitForServiceTasks(s, serviceName)
645+
log.WithFields(fields).Info(message)
624646
}
625647

626648
func getSDSIDFromArn(sdsARN string) string {

0 commit comments

Comments
 (0)