@@ -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 {
97- return err
98- }
99-
100- err = c .resolveSharedNamespaces (service )
101- 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 {
10268 return err
10369 }
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,25 +90,32 @@ func (c *convergence) resolveVolumeFrom(service *types.ServiceConfig) error {
12490 return nil
12591}
12692
127- func (c * convergence ) resolveSharedNamespaces (service * types.ServiceConfig ) error {
128- resolve := func (field * string , noun string ) error {
129- if name := getDependentServiceFromMode (* field ); name != "" {
130- dependencies := c .getObservedState (name )
131- if len (dependencies ) == 0 {
132- return fmt .Errorf ("cannot share %s namespace with service %s: container missing" , noun , name )
133- }
134- * field = types .ContainerPrefix + dependencies .sorted ()[0 ].ID
93+ func resolveSharedNamespaces (service * types.ServiceConfig , containersByService map [string ]Containers ) error {
94+ if name := getDependentServiceFromMode (service .NetworkMode ); name != "" {
95+ dependencies := containersByService [name ]
96+ if len (dependencies ) == 0 {
97+ return fmt .Errorf ("cannot share network namespace with service %s: container missing" , name )
13598 }
136- return nil
99+ service . NetworkMode = types . ContainerPrefix + dependencies . sorted ()[ 0 ]. ID
137100 }
138101
139- if err := resolve (& service .NetworkMode , "network" ); err != nil {
140- return err
102+ if name := getDependentServiceFromMode (service .Ipc ); name != "" {
103+ dependencies := containersByService [name ]
104+ if len (dependencies ) == 0 {
105+ return fmt .Errorf ("cannot share IPC namespace with service %s: container missing" , name )
106+ }
107+ service .Ipc = types .ContainerPrefix + dependencies .sorted ()[0 ].ID
141108 }
142- if err := resolve (& service .Ipc , "IPC" ); err != nil {
143- return err
109+
110+ if name := getDependentServiceFromMode (service .Pid ); name != "" {
111+ dependencies := containersByService [name ]
112+ if len (dependencies ) == 0 {
113+ return fmt .Errorf ("cannot share PID namespace with service %s: container missing" , name )
114+ }
115+ service .Pid = types .ContainerPrefix + dependencies .sorted ()[0 ].ID
144116 }
145- return resolve (& service .Pid , "PID" )
117+
118+ return nil
146119}
147120
148121func getContainerName (projectName string , service types.ServiceConfig , number int ) string {
0 commit comments