2
2
import registry_proxy
3
3
import json
4
4
import docker
5
+ import time
5
6
6
7
SERVICE_RUNTIME_SETTINGS = 'simcore.service.settings'
7
8
8
- def IsServiceAWebServer (dockerImagePath ):
9
+ def IsServiceAWebServer (dockerImagePath ):
9
10
return str (dockerImagePath ).find ('webserver' ) != - 1
10
11
11
12
def login_docker_registry (dockerClient ):
@@ -14,7 +15,7 @@ def login_docker_registry(dockerClient):
14
15
registry_url = os .environ .get ('REGISTRY_URL' )
15
16
username = os .environ .get ('REGISTRY_USER' )
16
17
password = os .environ .get ('REGISTRY_PW' )
17
- dockerClient .login (registry = registry_url + '/v2' , username = username , password = password )
18
+ dockerClient .login (registry = registry_url + '/v2' , username = username , password = password )
18
19
except docker .errors .APIError as e :
19
20
raise Exception ('Error while loging to registry: ' + str (e ))
20
21
@@ -25,7 +26,7 @@ def check_service_uuid_available(dockerClient, service_uuid):
25
26
raise Exception ('A service with the same uuid is already running: ' + service_uuid )
26
27
27
28
def get_service_runtime_parameters_labels (image , tag ):
28
- image_labels = registry_proxy .retrieve_labels_of_image (image , tag )
29
+ image_labels = registry_proxy .retrieve_labels_of_image (image , tag )
29
30
runtime_parameters = dict ()
30
31
if SERVICE_RUNTIME_SETTINGS in image_labels :
31
32
runtime_parameters = json .loads (image_labels [SERVICE_RUNTIME_SETTINGS ])
@@ -101,19 +102,37 @@ def remove_overlay_network_of_swarm(docker_client, service_uuid):
101
102
except docker .errors .APIError as e :
102
103
raise Exception ("docker server error while removing networks for service with uuid " + service_uuid )
103
104
105
+ def wait_until_service_running_or_failed (service_id ):
106
+ client = docker .APIClient ()
107
+
108
+ # some times one has to wait until the task info is filled
109
+ while True :
110
+ task_infos_json = client .tasks (filters = {'service' :service_id })
111
+ if len (task_infos_json ) > 0 :
112
+ # check the status
113
+ status_json = task_infos_json [0 ]["Status" ]
114
+ task_state = status_json ["State" ]
115
+ if task_state == "running" :
116
+ # great it is running
117
+ break
118
+ elif task_state == 'failed' or task_state == "rejected" :
119
+ # error
120
+ raise Exception ("the service could not be started" )
121
+ time .sleep (0.005 ) # 5ms
122
+
104
123
def start_service (service_name , service_tag , service_uuid ):
105
124
# find the ones containing the service name
106
125
listOfReposForService = registry_proxy .retrieve_list_of_interactive_services_with_name (service_name )
107
126
# get the available image for each service (syntax is image:tag)
108
127
listOfImages = {}
109
128
for repo in listOfReposForService :
110
129
listOfImages [repo ] = registry_proxy .retrieve_list_of_images_in_repo (repo )
111
-
130
+
112
131
# initialise docker client and check the uuid is available
113
132
dockerClient = docker .from_env ()
114
133
check_service_uuid_available (dockerClient , service_uuid )
115
134
login_docker_registry (dockerClient )
116
-
135
+
117
136
# create a new network to connect the differnt containers
118
137
docker_network = create_overlay_network_in_swarm (dockerClient , service_name , service_uuid )
119
138
# create services
@@ -126,28 +145,29 @@ def start_service(service_name, service_tag, service_uuid):
126
145
tag = availableTagsList [len (availableTagsList )- 1 ]
127
146
if not service_tag == 'latest' and availableTagsList .count (service_tag ) == 1 :
128
147
tag = service_tag
129
-
148
+
130
149
dockerImageFullPath = os .environ .get ('REGISTRY_URL' ) + '/' + dockerImagePath + ':' + tag
131
-
150
+
132
151
# prepare runtime parameters
133
152
service_runtime_parameters_labels = get_service_runtime_parameters_labels (dockerImagePath , tag )
134
153
docker_service_runtime_parameters = convert_labels_to_docker_runtime_parameters (service_runtime_parameters_labels , service_uuid )
135
- add_uuid_label_to_service_runtime_params (docker_service_runtime_parameters , service_uuid )
154
+ add_uuid_label_to_service_runtime_params (docker_service_runtime_parameters , service_uuid )
136
155
add_network_to_service_runtime_params (docker_service_runtime_parameters , docker_network )
137
156
set_service_name (docker_service_runtime_parameters , registry_proxy .get_service_sub_name (dockerImagePath ), service_uuid )
138
157
# let-s start the service
139
- try :
158
+ try :
140
159
service = dockerClient .services .create (dockerImageFullPath , ** docker_service_runtime_parameters )
160
+ wait_until_service_running_or_failed (service .id )
141
161
published_ports = get_docker_image_published_ports (service .id )
142
162
container_meta_data = {"container_id" :service .id , "published_ports" :published_ports }
143
- containers_meta_data .append (container_meta_data )
163
+ containers_meta_data .append (container_meta_data )
144
164
except docker .errors .ImageNotFound as e :
145
165
# first cleanup
146
166
stop_service (service_uuid )
147
167
raise Exception ('Error service not found: ' + str (e ))
148
168
except docker .errors .APIError as e :
149
169
# first cleanup
150
- stop_service (service_uuid )
170
+ stop_service (service_uuid )
151
171
raise Exception ('Error while accessing docker server: ' + str (e ))
152
172
service_meta_data = {"service_name" :service_name , "service_uuid" :service_uuid , "containers" :containers_meta_data }
153
173
return json .dumps (service_meta_data )
@@ -156,11 +176,10 @@ def stop_service(service_uuid):
156
176
# get the docker client
157
177
dockerClient = docker .from_env ()
158
178
login_docker_registry (dockerClient )
159
-
160
- try :
179
+
180
+ try :
161
181
listOfRunningServicesWithUUID = dockerClient .services .list (filters = {'label' :'uuid=' + service_uuid })
162
182
[service .remove () for service in listOfRunningServicesWithUUID ]
163
183
remove_overlay_network_of_swarm (dockerClient , service_uuid )
164
184
except docker .errors .APIError as e :
165
185
raise Exception ('Error while stopping container' + str (e ))
166
-
0 commit comments