github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/orchestrator/service.go (about) 1 package orchestrator 2 3 import ( 4 "context" 5 6 "github.com/docker/swarmkit/api" 7 "github.com/docker/swarmkit/log" 8 "github.com/docker/swarmkit/manager/state/store" 9 ) 10 11 // IsReplicatedService checks if a service is a replicated service. 12 func IsReplicatedService(service *api.Service) bool { 13 // service nil validation is required as there are scenarios 14 // where service is removed from store 15 if service == nil { 16 return false 17 } 18 _, ok := service.Spec.GetMode().(*api.ServiceSpec_Replicated) 19 return ok 20 } 21 22 // IsGlobalService checks if the service is a global service. 23 func IsGlobalService(service *api.Service) bool { 24 if service == nil { 25 return false 26 } 27 _, ok := service.Spec.GetMode().(*api.ServiceSpec_Global) 28 return ok 29 } 30 31 // IsReplicatedJob returns true if the service is a replicated job. 32 func IsReplicatedJob(service *api.Service) bool { 33 if service == nil { 34 return false 35 } 36 37 _, ok := service.Spec.GetMode().(*api.ServiceSpec_ReplicatedJob) 38 return ok 39 } 40 41 // IsGlobalJob returns true if the service is a global job. 42 func IsGlobalJob(service *api.Service) bool { 43 if service == nil { 44 return false 45 } 46 47 _, ok := service.Spec.GetMode().(*api.ServiceSpec_GlobalJob) 48 return ok 49 } 50 51 // SetServiceTasksRemove sets the desired state of tasks associated with a service 52 // to REMOVE, so that they can be properly shut down by the agent and later removed 53 // by the task reaper. 54 func SetServiceTasksRemove(ctx context.Context, s *store.MemoryStore, service *api.Service) { 55 var ( 56 tasks []*api.Task 57 err error 58 ) 59 s.View(func(tx store.ReadTx) { 60 tasks, err = store.FindTasks(tx, store.ByServiceID(service.ID)) 61 }) 62 if err != nil { 63 log.G(ctx).WithError(err).Errorf("failed to list tasks") 64 return 65 } 66 67 err = s.Batch(func(batch *store.Batch) error { 68 for _, t := range tasks { 69 err := batch.Update(func(tx store.Tx) error { 70 // the task may have changed for some reason in the meantime 71 // since we read it out, so we need to get from the store again 72 // within the boundaries of a transaction 73 latestTask := store.GetTask(tx, t.ID) 74 75 // time travel is not allowed. if the current desired state is 76 // above the one we're trying to go to we can't go backwards. 77 // we have nothing to do and we should skip to the next task 78 if latestTask.DesiredState > api.TaskStateRemove { 79 // log a warning, though. we shouln't be trying to rewrite 80 // a state to an earlier state 81 log.G(ctx).Warnf( 82 "cannot update task %v in desired state %v to an earlier desired state %v", 83 latestTask.ID, latestTask.DesiredState, api.TaskStateRemove, 84 ) 85 return nil 86 } 87 // update desired state to REMOVE 88 latestTask.DesiredState = api.TaskStateRemove 89 90 if err := store.UpdateTask(tx, latestTask); err != nil { 91 log.G(ctx).WithError(err).Errorf("failed transaction: update task desired state to REMOVE") 92 } 93 return nil 94 }) 95 if err != nil { 96 return err 97 } 98 } 99 return nil 100 }) 101 if err != nil { 102 log.G(ctx).WithError(err).Errorf("task search transaction failed") 103 } 104 }