iker-python-common 1.0.62__py3-none-any.whl → 1.0.63__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.
- {iker_python_common-1.0.62.dist-info → iker_python_common-1.0.63.dist-info}/METADATA +1 -2
- {iker_python_common-1.0.62.dist-info → iker_python_common-1.0.63.dist-info}/RECORD +4 -5
- {iker_python_common-1.0.62.dist-info → iker_python_common-1.0.63.dist-info}/WHEEL +1 -1
- iker/common/utils/dockerutils.py +0 -236
- {iker_python_common-1.0.62.dist-info → iker_python_common-1.0.63.dist-info}/top_level.txt +0 -0
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iker-python-common
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.63
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.12
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.13
|
|
7
7
|
Classifier: Programming Language :: Python :: 3.14
|
|
8
8
|
Requires-Python: <3.15,>=3.12
|
|
9
9
|
Requires-Dist: asyncpg>=0.30
|
|
10
|
-
Requires-Dist: docker>=7.1
|
|
11
10
|
Requires-Dist: numpy>=2.3
|
|
12
11
|
Requires-Dist: psycopg>=3.2
|
|
13
12
|
Requires-Dist: pymysql>=1.1
|
|
@@ -4,7 +4,6 @@ iker/common/utils/argutils.py,sha256=hMLNqdZs_Kjc2hw4Npm6N47RivP6JRNzCKIbJr1jYy8
|
|
|
4
4
|
iker/common/utils/config.py,sha256=z8rLqli961A-qAV9EaELp-pKuhNUNaq1Btdv-uwG7_I,4690
|
|
5
5
|
iker/common/utils/csv.py,sha256=_V9OUrKcojec2L-hWagEIVnL2uvGjyJAFTrD7tHNr48,7573
|
|
6
6
|
iker/common/utils/dbutils.py,sha256=09DgvfPVDCPXwOAO_FTynLXhSq--ZzRz2fCQ6vJ5qqk,16151
|
|
7
|
-
iker/common/utils/dockerutils.py,sha256=n2WuzXaZB6_WocSljvPOnfExSIjIHRUbuWp2oBbaPKQ,8004
|
|
8
7
|
iker/common/utils/dtutils.py,sha256=86vbaa4pgcBWERZvTfJ92PKB3IimxP6tf0O11ho2Ffk,12554
|
|
9
8
|
iker/common/utils/funcutils.py,sha256=4AkkvK9_Z2tgk1-Sp6-vLLVhI15cIgN9xW58QqL5QL4,7780
|
|
10
9
|
iker/common/utils/jsonutils.py,sha256=AkziMAYVQDODHRqZC-c1x7VqI2hHY3Kxrw7gmoss8mU,18527
|
|
@@ -18,7 +17,7 @@ iker/common/utils/span.py,sha256=u_KuWi2U7QDMUotl4AeW2_57ItL3YhVDSeCwaOiFDvs,596
|
|
|
18
17
|
iker/common/utils/strutils.py,sha256=Tu_qFeH3K-SfwvMxdrZAc9iLPV8ZmtX4ntyyFGNslf8,5094
|
|
19
18
|
iker/common/utils/testutils.py,sha256=2VieV5yeCDntSKQSpIeyqRT8BZmZYE_ArMeQz3g7fXY,5568
|
|
20
19
|
iker/common/utils/typeutils.py,sha256=RVkYkFRgDrx77OHFH7PavMV0AIB0S8ly40rs4g7JWE4,8220
|
|
21
|
-
iker_python_common-1.0.
|
|
22
|
-
iker_python_common-1.0.
|
|
23
|
-
iker_python_common-1.0.
|
|
24
|
-
iker_python_common-1.0.
|
|
20
|
+
iker_python_common-1.0.63.dist-info/METADATA,sha256=QUw6lKzGDZRY3Aul1qTE4B_dxtO96Tw0Mvo_acp9Ilw,867
|
|
21
|
+
iker_python_common-1.0.63.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
22
|
+
iker_python_common-1.0.63.dist-info/top_level.txt,sha256=4_B8Prfc_lxFafFYTQThIU1ZqOYQ4pHHHnJ_fQ_oHs8,5
|
|
23
|
+
iker_python_common-1.0.63.dist-info/RECORD,,
|
iker/common/utils/dockerutils.py
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import contextlib
|
|
2
|
-
import dataclasses
|
|
3
|
-
import re
|
|
4
|
-
from collections.abc import Generator, Iterator
|
|
5
|
-
from typing import Any
|
|
6
|
-
|
|
7
|
-
import docker
|
|
8
|
-
import docker.errors
|
|
9
|
-
import docker.models.containers
|
|
10
|
-
import docker.models.images
|
|
11
|
-
import requests.exceptions
|
|
12
|
-
|
|
13
|
-
from iker.common.utils import logger
|
|
14
|
-
from iker.common.utils.strutils import parse_int_or, trim_to_empty
|
|
15
|
-
|
|
16
|
-
__all__ = [
|
|
17
|
-
"ImageName",
|
|
18
|
-
"docker_create_client",
|
|
19
|
-
"docker_build_image",
|
|
20
|
-
"docker_get_image",
|
|
21
|
-
"docker_pull_image",
|
|
22
|
-
"docker_fetch_image",
|
|
23
|
-
"docker_run_detached",
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@dataclasses.dataclass
|
|
28
|
-
class ImageName(object):
|
|
29
|
-
registry_host: str | None
|
|
30
|
-
registry_port: int | None
|
|
31
|
-
components: list[str]
|
|
32
|
-
tag: str | None
|
|
33
|
-
|
|
34
|
-
@property
|
|
35
|
-
def registry(self) -> str:
|
|
36
|
-
if self.registry_host is None and self.registry_port is None:
|
|
37
|
-
return ""
|
|
38
|
-
if self.registry_port is None:
|
|
39
|
-
return self.registry_host
|
|
40
|
-
return f"{self.registry_host}:{self.registry_port}"
|
|
41
|
-
|
|
42
|
-
@property
|
|
43
|
-
def repository(self) -> str:
|
|
44
|
-
return "/".join(self.components)
|
|
45
|
-
|
|
46
|
-
@staticmethod
|
|
47
|
-
def parse(s: str):
|
|
48
|
-
|
|
49
|
-
# Registry absent version
|
|
50
|
-
matcher = re.compile(
|
|
51
|
-
r"^(?P<components>[a-z0-9]+((__?|-+)[a-z0-9]+)*(/[a-z0-9]+((__?|-+)[a-z0-9]+)*)*)(:(?P<tag>\w[\w.-]{0,127}))?$")
|
|
52
|
-
match = matcher.match(s)
|
|
53
|
-
if match:
|
|
54
|
-
return ImageName(registry_host=None,
|
|
55
|
-
registry_port=None,
|
|
56
|
-
components=trim_to_empty(match.group("components")).split("/"),
|
|
57
|
-
tag=match.group("tag"))
|
|
58
|
-
|
|
59
|
-
# Registry present version
|
|
60
|
-
matcher = re.compile(
|
|
61
|
-
r"^((?P<host>[a-zA-Z0-9.-]+)(:(?P<port>\d+))?/)?(?P<components>[a-z0-9]+((__?|-+)[a-z0-9]+)*(/[a-z0-9]+((__?|-+)[a-z0-9]+)*)*)(:(?P<tag>\w[\w.-]{0,127}))?$")
|
|
62
|
-
match = matcher.match(s)
|
|
63
|
-
if match:
|
|
64
|
-
return ImageName(registry_host=match.group("host"),
|
|
65
|
-
registry_port=parse_int_or(match.group("port"), None),
|
|
66
|
-
components=trim_to_empty(match.group("components")).split("/"),
|
|
67
|
-
tag=match.group("tag"))
|
|
68
|
-
|
|
69
|
-
return None
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def docker_create_client(
|
|
73
|
-
registry: str,
|
|
74
|
-
username: str,
|
|
75
|
-
password: str,
|
|
76
|
-
) -> contextlib.AbstractContextManager[docker.DockerClient]:
|
|
77
|
-
try:
|
|
78
|
-
client = docker.DockerClient()
|
|
79
|
-
client.login(registry=registry, username=username, password=password, reauth=True)
|
|
80
|
-
return contextlib.closing(client)
|
|
81
|
-
except docker.errors.APIError:
|
|
82
|
-
logger.exception("Failed to login Docker server <%s>", registry)
|
|
83
|
-
raise
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def docker_build_image(
|
|
87
|
-
client: docker.DockerClient,
|
|
88
|
-
tag: str,
|
|
89
|
-
path: str,
|
|
90
|
-
dockerfile: str,
|
|
91
|
-
build_args: dict[str, str],
|
|
92
|
-
) -> tuple[docker.models.images.Image, Iterator[dict[str, str]]]:
|
|
93
|
-
try:
|
|
94
|
-
return client.images.build(tag=tag,
|
|
95
|
-
path=path,
|
|
96
|
-
dockerfile=dockerfile,
|
|
97
|
-
buildargs=build_args,
|
|
98
|
-
rm=True,
|
|
99
|
-
forcerm=True,
|
|
100
|
-
nocache=True)
|
|
101
|
-
|
|
102
|
-
except docker.errors.BuildError:
|
|
103
|
-
logger.exception("Failed to build image <%s>", tag)
|
|
104
|
-
raise
|
|
105
|
-
except docker.errors.APIError:
|
|
106
|
-
logger.exception("Docker server returns an error while building image <%s>", tag)
|
|
107
|
-
raise
|
|
108
|
-
except Exception:
|
|
109
|
-
logger.exception("Unexpected error occurred while building image <%s>", tag)
|
|
110
|
-
raise
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def docker_get_image(
|
|
114
|
-
client: docker.DockerClient,
|
|
115
|
-
image: str,
|
|
116
|
-
) -> docker.models.images.Image:
|
|
117
|
-
try:
|
|
118
|
-
return client.images.get(image)
|
|
119
|
-
except docker.errors.ImageNotFound:
|
|
120
|
-
logger.exception("Image <%s> is not found from local repository", image)
|
|
121
|
-
raise
|
|
122
|
-
except docker.errors.APIError:
|
|
123
|
-
logger.exception("Docker server returns an error while getting image <%s>", image)
|
|
124
|
-
raise
|
|
125
|
-
except Exception:
|
|
126
|
-
logger.exception("Unexpected error occurred while getting image <%s>", image)
|
|
127
|
-
raise
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def docker_pull_image(
|
|
131
|
-
client: docker.DockerClient,
|
|
132
|
-
image: str,
|
|
133
|
-
fallback_local: bool = False,
|
|
134
|
-
) -> docker.models.images.Image:
|
|
135
|
-
try:
|
|
136
|
-
return client.images.pull(image)
|
|
137
|
-
except docker.errors.ImageNotFound:
|
|
138
|
-
if not fallback_local:
|
|
139
|
-
logger.exception("Image <%s> is not found from remote repository", image)
|
|
140
|
-
raise
|
|
141
|
-
logger.warning("Image <%s> is not found from remote repository, try local repository instead", image)
|
|
142
|
-
except docker.errors.APIError:
|
|
143
|
-
if not fallback_local:
|
|
144
|
-
logger.exception("Docker server returns an error while pulling image <%s>", image)
|
|
145
|
-
raise
|
|
146
|
-
logger.warning("Docker server returns an error while pulling image <%s>, try local repository instead", image)
|
|
147
|
-
except Exception:
|
|
148
|
-
logger.exception("Unexpected error occurred while pulling image <%s>", image)
|
|
149
|
-
raise
|
|
150
|
-
|
|
151
|
-
return docker_get_image(client, image)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def docker_fetch_image(
|
|
155
|
-
client: docker.DockerClient,
|
|
156
|
-
image: str,
|
|
157
|
-
force_pull: bool = False,
|
|
158
|
-
) -> docker.models.images.Image:
|
|
159
|
-
if force_pull:
|
|
160
|
-
return docker_pull_image(client, image, fallback_local=True)
|
|
161
|
-
else:
|
|
162
|
-
try:
|
|
163
|
-
return docker_get_image(client, image)
|
|
164
|
-
except Exception:
|
|
165
|
-
return docker_pull_image(client, image, fallback_local=False)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
def docker_run_detached(
|
|
169
|
-
client: docker.DockerClient,
|
|
170
|
-
image: str,
|
|
171
|
-
name: str,
|
|
172
|
-
command: str | list[str],
|
|
173
|
-
volumes: dict[str, dict[str, str]],
|
|
174
|
-
environment: dict[str, str],
|
|
175
|
-
extra_hosts: dict[str, str],
|
|
176
|
-
timeout: int,
|
|
177
|
-
**kwargs,
|
|
178
|
-
) -> tuple[dict[str, Any], Any]:
|
|
179
|
-
@contextlib.contextmanager
|
|
180
|
-
def managed_docker_run(
|
|
181
|
-
client: docker.DockerClient,
|
|
182
|
-
**kwargs,
|
|
183
|
-
) -> Generator[docker.models.containers.Container, None, None]:
|
|
184
|
-
container_model = None
|
|
185
|
-
try:
|
|
186
|
-
container_model = client.containers.run(**kwargs)
|
|
187
|
-
yield container_model
|
|
188
|
-
except docker.errors.DockerException:
|
|
189
|
-
raise
|
|
190
|
-
finally:
|
|
191
|
-
if container_model is not None:
|
|
192
|
-
try:
|
|
193
|
-
if container_model.status != "exited":
|
|
194
|
-
try:
|
|
195
|
-
container_model.stop()
|
|
196
|
-
except docker.errors.DockerException:
|
|
197
|
-
pass
|
|
198
|
-
container_model.wait()
|
|
199
|
-
try:
|
|
200
|
-
container_model.remove()
|
|
201
|
-
except docker.errors.DockerException:
|
|
202
|
-
pass
|
|
203
|
-
except Exception:
|
|
204
|
-
raise
|
|
205
|
-
|
|
206
|
-
try:
|
|
207
|
-
run_args = kwargs.copy()
|
|
208
|
-
run_args.update(dict(image=image,
|
|
209
|
-
name=name,
|
|
210
|
-
command=command,
|
|
211
|
-
volumes=volumes,
|
|
212
|
-
environment=environment,
|
|
213
|
-
extra_hosts=extra_hosts,
|
|
214
|
-
detach=True))
|
|
215
|
-
|
|
216
|
-
with managed_docker_run(client, **run_args) as container_model:
|
|
217
|
-
result = container_model.wait(timeout=timeout)
|
|
218
|
-
logs = container_model.logs()
|
|
219
|
-
|
|
220
|
-
return result, logs
|
|
221
|
-
|
|
222
|
-
except requests.exceptions.ReadTimeout:
|
|
223
|
-
logger.exception("Running container <%s> of image <%s> exceed the timeout", name, image)
|
|
224
|
-
raise
|
|
225
|
-
except docker.errors.ImageNotFound:
|
|
226
|
-
logger.exception("Image <%s> is not found", image)
|
|
227
|
-
raise
|
|
228
|
-
except docker.errors.ContainerError:
|
|
229
|
-
logger.exception("Failed to run container <%s> of image <%s>", name, image)
|
|
230
|
-
raise
|
|
231
|
-
except docker.errors.APIError:
|
|
232
|
-
logger.exception("Docker server returns an error while running container <%s> of image <%s>", name, image)
|
|
233
|
-
raise
|
|
234
|
-
except Exception:
|
|
235
|
-
logger.exception("Unexpected error occurred while running container <%s> of image <%s>", image)
|
|
236
|
-
raise
|
|
File without changes
|