@@ -49,37 +49,6 @@ const (
4949// re-creating container, adding or removing replicas, or starting stopped containers.
5050// Cross services dependencies are managed by creating services in expected order and updating `service:xx` reference
5151// when a service has converged, so dependent ones can be managed with resolved containers references.
52- type convergence struct {
53- compose * composeService
54- services map [string ]Containers
55- networks map [string ]string
56- volumes map [string ]string
57- stateMutex sync.Mutex
58- }
59-
60- func (c * convergence ) getObservedState (serviceName string ) Containers {
61- c .stateMutex .Lock ()
62- defer c .stateMutex .Unlock ()
63- return c .services [serviceName ]
64- }
65-
66- func newConvergence (services []string , state Containers , networks map [string ]string , volumes map [string ]string , s * composeService ) * convergence {
67- observedState := map [string ]Containers {}
68- for _ , s := range services {
69- observedState [s ] = Containers {}
70- }
71- for _ , c := range state .filter (isNotOneOff ) {
72- service := c .Labels [api .ServiceLabel ]
73- observedState [service ] = append (observedState [service ], c )
74- }
75- return & convergence {
76- compose : s ,
77- services : observedState ,
78- networks : networks ,
79- volumes : volumes ,
80- }
81- }
82-
8352func getScale (config types.ServiceConfig ) (int , error ) {
8453 scale := config .GetScale ()
8554 if scale > 1 && config .ContainerName != "" {
@@ -90,21 +59,18 @@ func getScale(config types.ServiceConfig) (int, error) {
9059 return scale , nil
9160}
9261
93- // resolveServiceReferences replaces reference to another service with reference to an actual container
94- func (c * convergence ) resolveServiceReferences (service * types.ServiceConfig ) error {
95- err := c .resolveVolumeFrom (service )
96- if err != nil {
62+ // resolveServiceReferences replaces references to other services with references
63+ // to actual container IDs. It resolves VolumesFrom, NetworkMode, IPC and PID
64+ // shared namespaces. The containersByService map provides the observed containers
65+ // grouped by service name.
66+ func resolveServiceReferences (service * types.ServiceConfig , containersByService map [string ]Containers ) error {
67+ if err := resolveVolumeFrom (service , containersByService ); err != nil {
9768 return err
9869 }
99-
100- err = c .resolveSharedNamespaces (service )
101- if err != nil {
102- return err
103- }
104- return nil
70+ return resolveSharedNamespaces (service , containersByService )
10571}
10672
107- func ( c * convergence ) resolveVolumeFrom (service * types.ServiceConfig ) error {
73+ func resolveVolumeFrom (service * types.ServiceConfig , containersByService map [ string ] Containers ) error {
10874 for i , vol := range service .VolumesFrom {
10975 spec := strings .Split (vol , ":" )
11076 if len (spec ) == 0 {
@@ -115,7 +81,7 @@ func (c *convergence) resolveVolumeFrom(service *types.ServiceConfig) error {
11581 continue
11682 }
11783 name := spec [0 ]
118- dependencies := c . getObservedState ( name )
84+ dependencies := containersByService [ name ]
11985 if len (dependencies ) == 0 {
12086 return fmt .Errorf ("cannot share volume with service %s: container missing" , name )
12187 }
@@ -124,28 +90,25 @@ func (c *convergence) resolveVolumeFrom(service *types.ServiceConfig) error {
12490 return nil
12591}
12692
127- func (c * convergence ) resolveSharedNamespaces (service * types.ServiceConfig ) error {
128- str := service .NetworkMode
129- if name := getDependentServiceFromMode (str ); name != "" {
130- dependencies := c .getObservedState (name )
93+ func resolveSharedNamespaces (service * types.ServiceConfig , containersByService map [string ]Containers ) error {
94+ if name := getDependentServiceFromMode (service .NetworkMode ); name != "" {
95+ dependencies := containersByService [name ]
13196 if len (dependencies ) == 0 {
13297 return fmt .Errorf ("cannot share network namespace with service %s: container missing" , name )
13398 }
13499 service .NetworkMode = types .ContainerPrefix + dependencies .sorted ()[0 ].ID
135100 }
136101
137- str = service .Ipc
138- if name := getDependentServiceFromMode (str ); name != "" {
139- dependencies := c .getObservedState (name )
102+ if name := getDependentServiceFromMode (service .Ipc ); name != "" {
103+ dependencies := containersByService [name ]
140104 if len (dependencies ) == 0 {
141105 return fmt .Errorf ("cannot share IPC namespace with service %s: container missing" , name )
142106 }
143107 service .Ipc = types .ContainerPrefix + dependencies .sorted ()[0 ].ID
144108 }
145109
146- str = service .Pid
147- if name := getDependentServiceFromMode (str ); name != "" {
148- dependencies := c .getObservedState (name )
110+ if name := getDependentServiceFromMode (service .Pid ); name != "" {
111+ dependencies := containersByService [name ]
149112 if len (dependencies ) == 0 {
150113 return fmt .Errorf ("cannot share PID namespace with service %s: container missing" , name )
151114 }
0 commit comments