pybiolib 1.2.1111__py3-none-any.whl → 1.2.1117__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,9 +4,7 @@ import tarfile
4
4
  import time
5
5
  from urllib.parse import urlparse
6
6
 
7
- from docker.errors import ImageNotFound
8
7
  from docker.models.containers import Container
9
- from docker.models.images import Image
10
8
  from docker.models.networks import Network
11
9
  from docker.types import EndpointConfig
12
10
 
@@ -17,7 +15,8 @@ from biolib.biolib_errors import BioLibError
17
15
  from biolib.biolib_logging import logger_no_user_data
18
16
  from biolib.compute_node.cloud_utils import CloudUtils
19
17
  from biolib.compute_node.utils import BIOLIB_PROXY_NETWORK_NAME
20
- from biolib.typing_utils import Dict, List, Optional, cast
18
+ from biolib.compute_node.webserver.proxy_utils import get_biolib_nginx_proxy_image
19
+ from biolib.typing_utils import Dict, List, Optional
21
20
 
22
21
 
23
22
  # Prepare for remote hosts with specified port
@@ -83,7 +82,7 @@ class RemoteHostProxy:
83
82
  try:
84
83
  self._container = docker.containers.create(
85
84
  detach=True,
86
- image=self._get_biolib_remote_host_proxy_image(),
85
+ image=get_biolib_nginx_proxy_image(),
87
86
  name=self._name,
88
87
  network=BIOLIB_PROXY_NETWORK_NAME,
89
88
  networking_config=networking_config,
@@ -130,23 +129,6 @@ class RemoteHostProxy:
130
129
  if self._container:
131
130
  self._container.remove(force=True)
132
131
 
133
- def _get_biolib_remote_host_proxy_image(self) -> Image:
134
- if utils.IS_RUNNING_IN_CLOUD:
135
- try:
136
- logger_no_user_data.debug('Getting local Docker image for remote host proxy')
137
- return cast(Image, self._docker.images.get('biolib-remote-host-proxy:latest'))
138
- except ImageNotFound:
139
- logger_no_user_data.debug(
140
- 'Local Docker image for remote host proxy not available. Falling back to public image...'
141
- )
142
-
143
- public_image_uri = 'public.ecr.aws/h5y4b3l1/biolib-remote-host-proxy:latest'
144
- try:
145
- logger_no_user_data.debug('Getting public Docker image for remote host proxy')
146
- return cast(Image, self._docker.images.get(public_image_uri))
147
- except ImageNotFound:
148
- logger_no_user_data.debug('Pulling public Docker image for remote host proxy')
149
- return cast(Image, self._docker.images.pull(public_image_uri))
150
132
 
151
133
  def _write_nginx_config_to_container(self, upstream_server_name: str, upstream_server_ports: List[int]) -> None:
152
134
  if not self._container:
@@ -0,0 +1,140 @@
1
+ import io
2
+ import tarfile
3
+ import time
4
+
5
+ from docker.models.containers import Container
6
+
7
+ from biolib.biolib_docker_client import BiolibDockerClient
8
+ from biolib.biolib_errors import BioLibError
9
+ from biolib.biolib_logging import logger_no_user_data
10
+ from biolib.compute_node.utils import BIOLIB_PROXY_NETWORK_NAME
11
+ from biolib.typing_utils import Optional
12
+ from biolib.compute_node.webserver.proxy_utils import get_biolib_nginx_proxy_image
13
+
14
+ class ComputeNodeResultsProxy:
15
+ _instance: Optional['ComputeNodeResultsProxy'] = None
16
+
17
+ def __init__(self, tls_pem_certificate_path: str, tls_pem_key_path: str):
18
+ assert tls_pem_certificate_path, "tls_pem_certificate_path is required"
19
+ assert tls_pem_key_path, "tls_pem_key_path is required"
20
+ self._name = 'biolib-compute-node-results-proxy'
21
+ self._container: Optional[Container] = None
22
+ self._docker = BiolibDockerClient().get_docker_client()
23
+ self._tls_pem_certificate_path = tls_pem_certificate_path
24
+ self._tls_pem_key_path = tls_pem_key_path
25
+
26
+ @staticmethod
27
+ def start_proxy(tls_pem_certificate_path: str, tls_pem_key_path: str) -> None:
28
+ if ComputeNodeResultsProxy._instance is None:
29
+ ComputeNodeResultsProxy._instance = ComputeNodeResultsProxy(tls_pem_certificate_path, tls_pem_key_path)
30
+ ComputeNodeResultsProxy._instance._start() # pylint: disable=protected-access
31
+
32
+ @staticmethod
33
+ def stop_proxy() -> None:
34
+ if ComputeNodeResultsProxy._instance is not None:
35
+ ComputeNodeResultsProxy._instance._terminate() # pylint: disable=protected-access
36
+ ComputeNodeResultsProxy._instance = None
37
+
38
+ def _start(self) -> None:
39
+ docker = BiolibDockerClient.get_docker_client()
40
+
41
+ for index in range(3):
42
+ logger_no_user_data.debug(
43
+ f'Attempt {index} at creating ComputeNodeResultsProxy container "{self._name}"...'
44
+ )
45
+ try:
46
+ self._container = docker.containers.create(
47
+ detach=True,
48
+ image=get_biolib_nginx_proxy_image(),
49
+ name=self._name,
50
+ network=BIOLIB_PROXY_NETWORK_NAME,
51
+ ports={'443/tcp': 20443},
52
+ volumes={
53
+ self._tls_pem_certificate_path: {'bind': '/etc/ssl/certs/certificate.pem', 'mode': 'ro'},
54
+ self._tls_pem_key_path: {'bind': '/etc/ssl/private/private_key.pem', 'mode': 'ro'},
55
+ },
56
+ )
57
+ break
58
+ except Exception as error:
59
+ logger_no_user_data.exception(f'Failed to create container "{self._name}" hit error: {error}')
60
+
61
+ logger_no_user_data.debug('Sleeping before re-trying container creation...')
62
+ time.sleep(3)
63
+
64
+ if not self._container or not self._container.id:
65
+ raise BioLibError(f'Exceeded re-try limit for creating container {self._name}')
66
+
67
+ self._write_nginx_config_to_container()
68
+ self._container.start()
69
+
70
+ proxy_is_ready = False
71
+ for retry_count in range(1, 5):
72
+ time.sleep(0.5 * retry_count)
73
+ container_logs = self._container.logs()
74
+ if b'ready for start up\n' in container_logs or b'start worker process ' in container_logs:
75
+ proxy_is_ready = True
76
+ break
77
+
78
+ if not proxy_is_ready:
79
+ self._terminate()
80
+ raise Exception('ComputeNodeResultsProxy did not start properly')
81
+
82
+ self._container.reload()
83
+
84
+ def _terminate(self):
85
+ if self._container:
86
+ self._container.remove(force=True)
87
+
88
+
89
+ def _write_nginx_config_to_container(self) -> None:
90
+ if not self._container:
91
+ raise Exception('ComputeNodeResultsProxy container not defined when attempting to write NGINX config')
92
+
93
+ docker = BiolibDockerClient.get_docker_client()
94
+
95
+ nginx_config = """
96
+ events {
97
+ worker_connections 1024;
98
+ }
99
+
100
+ http {
101
+ client_max_body_size 0;
102
+ resolver 127.0.0.11 ipv6=off valid=30s;
103
+
104
+ server {
105
+ listen 443 ssl;
106
+ ssl_certificate /etc/ssl/certs/certificate.pem;
107
+ ssl_certificate_key /etc/ssl/private/private_key.pem;
108
+ ssl_protocols TLSv1.2 TLSv1.3;
109
+ ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
110
+ ssl_prefer_server_ciphers on;
111
+
112
+ location / {
113
+ if ($http_biolib_result_uuid = "") {
114
+ return 400 "Missing biolib-result-uuid header";
115
+ }
116
+
117
+ if ($http_biolib_result_port = "") {
118
+ return 400 "Missing biolib-result-port header";
119
+ }
120
+
121
+ set $target_host "biolib-app-caller-proxy-$http_biolib_result_uuid";
122
+ proxy_pass http://$target_host:1080;
123
+ proxy_set_header biolib-result-uuid $http_biolib_result_uuid;
124
+ proxy_set_header biolib-result-port $http_biolib_result_port;
125
+ proxy_pass_request_headers on;
126
+ }
127
+ }
128
+ }
129
+ """
130
+
131
+ nginx_config_bytes = nginx_config.encode()
132
+ tarfile_in_memory = io.BytesIO()
133
+ with tarfile.open(fileobj=tarfile_in_memory, mode='w:gz') as tar:
134
+ info = tarfile.TarInfo('/nginx.conf')
135
+ info.size = len(nginx_config_bytes)
136
+ tar.addfile(info, io.BytesIO(nginx_config_bytes))
137
+
138
+ tarfile_bytes = tarfile_in_memory.getvalue()
139
+ tarfile_in_memory.close()
140
+ docker.api.put_archive(self._container.id, '/etc/nginx', tarfile_bytes)
@@ -0,0 +1,28 @@
1
+ from docker.errors import ImageNotFound
2
+ from docker.models.images import Image
3
+
4
+ from biolib import utils
5
+ from biolib.biolib_docker_client import BiolibDockerClient
6
+ from biolib.biolib_logging import logger_no_user_data
7
+ from biolib.typing_utils import cast
8
+
9
+
10
+ def get_biolib_nginx_proxy_image() -> Image:
11
+ docker = BiolibDockerClient().get_docker_client()
12
+
13
+ if utils.IS_RUNNING_IN_CLOUD:
14
+ try:
15
+ logger_no_user_data.debug('Getting local Docker image for nginx proxy')
16
+ return cast(Image, docker.images.get('biolib-remote-host-proxy:latest'))
17
+ except ImageNotFound:
18
+ logger_no_user_data.debug(
19
+ 'Local Docker image for nginx proxy not available. Falling back to public image...'
20
+ )
21
+
22
+ public_image_uri = 'public.ecr.aws/h5y4b3l1/biolib-remote-host-proxy:latest'
23
+ try:
24
+ logger_no_user_data.debug('Getting public Docker image for nginx proxy')
25
+ return cast(Image, docker.images.get(public_image_uri))
26
+ except ImageNotFound:
27
+ logger_no_user_data.debug('Pulling public Docker image for nginx proxy')
28
+ return cast(Image, docker.images.pull(public_image_uri))
@@ -17,6 +17,7 @@ from biolib.biolib_logging import TRACE, logger, logger_no_user_data
17
17
  from biolib.compute_node.cloud_utils.cloud_utils import CloudUtils
18
18
  from biolib.compute_node.utils import BIOLIB_PROXY_NETWORK_NAME
19
19
  from biolib.compute_node.webserver import webserver_utils
20
+ from biolib.compute_node.webserver.compute_node_results_proxy import ComputeNodeResultsProxy
20
21
  from biolib.compute_node.webserver.gunicorn_flask_application import GunicornFlaskApplication
21
22
  from biolib.compute_node.webserver.webserver_utils import get_job_compute_state_or_404
22
23
  from biolib.typing_utils import Optional
@@ -152,6 +153,12 @@ def start_webserver(
152
153
  time.sleep(2)
153
154
 
154
155
  if utils.IS_RUNNING_IN_CLOUD:
156
+ try:
157
+ logger_no_user_data.debug('Stopping ComputeNodeResultsProxy')
158
+ ComputeNodeResultsProxy.stop_proxy()
159
+ except BaseException:
160
+ logger_no_user_data.exception('Failed to stop ComputeNodeResultsProxy')
161
+
155
162
  try:
156
163
  logger_no_user_data.debug(f'Removing Docker network {BIOLIB_PROXY_NETWORK_NAME}')
157
164
  docker_client = BiolibDockerClient.get_docker_client()
@@ -184,6 +191,12 @@ def start_webserver(
184
191
  logger_no_user_data.exception(f'Failed to create Docker network {BIOLIB_PROXY_NETWORK_NAME}')
185
192
 
186
193
  if biolib_proxy_network:
194
+ try:
195
+ logger_no_user_data.debug('Starting ComputeNodeResultsProxy')
196
+ ComputeNodeResultsProxy.start_proxy(tls_pem_certificate_path, tls_pem_key_path)
197
+ except BaseException:
198
+ logger_no_user_data.exception('Failed to start ComputeNodeResultsProxy')
199
+
187
200
  CloudUtils.initialize()
188
201
  webserver_utils.start_auto_shutdown_timer()
189
202
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pybiolib
3
- Version: 1.2.1111
3
+ Version: 1.2.1117
4
4
  Summary: BioLib Python Client
5
5
  License: MIT
6
6
  Keywords: biolib
@@ -126,13 +126,15 @@ biolib/compute_node/job_worker/large_file_system.py,sha256=Xe_LILVfTD9LXb-0HwLqG
126
126
  biolib/compute_node/job_worker/mappings.py,sha256=Z48Kg4nbcOvsT2-9o3RRikBkqflgO4XeaWxTGz-CNvI,2499
127
127
  biolib/compute_node/job_worker/utilization_reporter_thread.py,sha256=7tm5Yk9coqJ9VbEdnO86tSXI0iM0omwIyKENxdxiVXk,8575
128
128
  biolib/compute_node/job_worker/utils.py,sha256=wgxcIA8yAhUPdCwyvuuJ0JmreyWmmUoBO33vWtG60xg,1282
129
- biolib/compute_node/remote_host_proxy.py,sha256=xyjq0zKSxbJGUA6a0q9JCnzquk7gIztbI1clLGnymQM,17278
129
+ biolib/compute_node/remote_host_proxy.py,sha256=W0zzPtiHAOofCslkn9cnjFY1VKEbMSdrer87j23Zv_8,16295
130
130
  biolib/compute_node/socker_listener_thread.py,sha256=T5_UikA3MB9bD5W_dckYLPTgixh72vKUlgbBvj9dbM0,1601
131
131
  biolib/compute_node/socket_sender_thread.py,sha256=YgamPHeUm2GjMFGx8qk-99WlZhEs-kAb3q_2O6qByig,971
132
132
  biolib/compute_node/utils.py,sha256=fvdbetPKMdfHkPqNZRw6eln_i13myu-n8tuceTUcfPU,4913
133
133
  biolib/compute_node/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
134
+ biolib/compute_node/webserver/compute_node_results_proxy.py,sha256=sP_ZzjJjAusrHzCQC3qu3ItGY3YZzPinaFOHbattDjs,5565
134
135
  biolib/compute_node/webserver/gunicorn_flask_application.py,sha256=jPfR_YvNBekLUXWo_vHFV-FIwlb8s8tacKmGHvh93qc,914
135
- biolib/compute_node/webserver/webserver.py,sha256=Ec5ZgOUBb_1pINjHrlENMUpLdAPiBiTyiaP51-FZ4gQ,8362
136
+ biolib/compute_node/webserver/proxy_utils.py,sha256=JNt1oqPuR5n63E5NC1l8AZN51NLuMw4lqVkocZnq72o,1164
137
+ biolib/compute_node/webserver/webserver.py,sha256=XOLYIJcrs_MU3uvct7SGPn8cYDi8ugA_wkDo6JeOQDU,9061
136
138
  biolib/compute_node/webserver/webserver_types.py,sha256=2t8EaFKESnves3BA_NBdnS2yAdo1qwamCFHiSt888nE,380
137
139
  biolib/compute_node/webserver/webserver_utils.py,sha256=XWvwYPbWNR3qS0FYbLLp-MDDfVk0QdaAmg3xPrT0H2s,4234
138
140
  biolib/compute_node/webserver/worker_thread.py,sha256=7uD9yQPhePYvP2HCJ27EeZ_h6psfIWFgqm1RHZxzobs,12483
@@ -155,8 +157,8 @@ biolib/utils/cache_state.py,sha256=u256F37QSRIVwqKlbnCyzAX4EMI-kl6Dwu6qwj-Qmag,3
155
157
  biolib/utils/multipart_uploader.py,sha256=XvGP1I8tQuKhAH-QugPRoEsCi9qvbRk-DVBs5PNwwJo,8452
156
158
  biolib/utils/seq_util.py,sha256=Ozk0blGtPur_D9MwShD02r_mphyQmgZkx-lOHOwnlIM,6730
157
159
  biolib/utils/zip/remote_zip.py,sha256=0wErYlxir5921agfFeV1xVjf29l9VNgGQvNlWOlj2Yc,23232
158
- pybiolib-1.2.1111.dist-info/LICENSE,sha256=F2h7gf8i0agDIeWoBPXDMYScvQOz02pAWkKhTGOHaaw,1067
159
- pybiolib-1.2.1111.dist-info/METADATA,sha256=FimvlfOuyzXFZZTJy_czDvIwLdbiL6cg0PATItgsgho,1571
160
- pybiolib-1.2.1111.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
161
- pybiolib-1.2.1111.dist-info/entry_points.txt,sha256=p6DyaP_2kctxegTX23WBznnrDi4mz6gx04O5uKtRDXg,42
162
- pybiolib-1.2.1111.dist-info/RECORD,,
160
+ pybiolib-1.2.1117.dist-info/LICENSE,sha256=F2h7gf8i0agDIeWoBPXDMYScvQOz02pAWkKhTGOHaaw,1067
161
+ pybiolib-1.2.1117.dist-info/METADATA,sha256=SfoHQrH4vo-GUXZYGyZdjFpwou9KjMBwUH7bIVwA7sM,1571
162
+ pybiolib-1.2.1117.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
163
+ pybiolib-1.2.1117.dist-info/entry_points.txt,sha256=p6DyaP_2kctxegTX23WBznnrDi4mz6gx04O5uKtRDXg,42
164
+ pybiolib-1.2.1117.dist-info/RECORD,,