omserv 0.0.0.dev22__py3-none-any.whl → 0.0.0.dev24__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.
- omserv/nginx/__init__.py +0 -0
- omserv/nginx/build.py +122 -0
- omserv/nginx/configs.py +86 -0
- omserv/nginx/patches/__init__.py +0 -0
- omserv/nginx/stubstatus.py +73 -0
- {omserv-0.0.0.dev22.dist-info → omserv-0.0.0.dev24.dist-info}/METADATA +2 -2
- {omserv-0.0.0.dev22.dist-info → omserv-0.0.0.dev24.dist-info}/RECORD +10 -5
- {omserv-0.0.0.dev22.dist-info → omserv-0.0.0.dev24.dist-info}/LICENSE +0 -0
- {omserv-0.0.0.dev22.dist-info → omserv-0.0.0.dev24.dist-info}/WHEEL +0 -0
- {omserv-0.0.0.dev22.dist-info → omserv-0.0.0.dev24.dist-info}/top_level.txt +0 -0
omserv/nginx/__init__.py
ADDED
File without changes
|
omserv/nginx/build.py
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
import multiprocessing
|
2
|
+
import os.path
|
3
|
+
import shutil
|
4
|
+
import subprocess
|
5
|
+
import sys
|
6
|
+
import tempfile
|
7
|
+
import urllib.request
|
8
|
+
|
9
|
+
from omlish import check
|
10
|
+
from omlish import lang
|
11
|
+
|
12
|
+
|
13
|
+
NGINX_VERSION = '1.27.0'
|
14
|
+
NGINX_SRC_URL = f'https://nginx.org/download/nginx-{NGINX_VERSION}.tar.gz'
|
15
|
+
|
16
|
+
NGINX_VTS_VERSION = '0.2.2'
|
17
|
+
NGINX_VTS_SRC_URL = f'https://github.com/vozlt/nginx-module-vts/archive/refs/tags/v{NGINX_VTS_VERSION}.tar.gz'
|
18
|
+
|
19
|
+
|
20
|
+
def build_nginx() -> None:
|
21
|
+
build_dir = tempfile.mkdtemp('-omlish-nginx-build')
|
22
|
+
print(f'{build_dir=}')
|
23
|
+
|
24
|
+
#
|
25
|
+
|
26
|
+
nginx_src_file = urllib.request.urlretrieve(NGINX_SRC_URL)[0] # noqa
|
27
|
+
print(f'{nginx_src_file=}')
|
28
|
+
|
29
|
+
nginx_vts_src_file = urllib.request.urlretrieve(NGINX_VTS_SRC_URL)[0] # noqa
|
30
|
+
print(f'{nginx_vts_src_file=}')
|
31
|
+
|
32
|
+
subprocess.check_call(['tar', 'xvzf', nginx_src_file, '-C', build_dir])
|
33
|
+
nginx_dir = os.path.join(build_dir, f'nginx-{NGINX_VERSION}')
|
34
|
+
|
35
|
+
subprocess.check_call(['tar', 'xvzf', nginx_vts_src_file, '-C', build_dir])
|
36
|
+
nginx_vts_dir = os.path.join(build_dir, f'nginx-module-vts-{NGINX_VTS_VERSION}')
|
37
|
+
|
38
|
+
#
|
39
|
+
|
40
|
+
patch_prefix = f'nginx-{NGINX_VERSION}_'
|
41
|
+
for r in lang.get_relative_resources('patches', globals=globals()).values():
|
42
|
+
if r.is_file and r.name.startswith(patch_prefix) and r.name.endswith('.patch'):
|
43
|
+
print(r.name)
|
44
|
+
|
45
|
+
patch_src = r.read_bytes()
|
46
|
+
subprocess.run(
|
47
|
+
['git', 'apply'],
|
48
|
+
cwd=nginx_dir,
|
49
|
+
input=patch_src,
|
50
|
+
check=True,
|
51
|
+
)
|
52
|
+
|
53
|
+
#
|
54
|
+
|
55
|
+
cflags = [
|
56
|
+
'-g',
|
57
|
+
'-O2',
|
58
|
+
'-fstack-protector',
|
59
|
+
]
|
60
|
+
ldflags = []
|
61
|
+
|
62
|
+
if sys.platform == 'darwin':
|
63
|
+
openssl_prefix = subprocess.check_output(['brew', '--prefix', 'openssl']).decode().strip()
|
64
|
+
pcre_prefix = subprocess.check_output(['brew', '--prefix', 'pcre']).decode().strip()
|
65
|
+
cflags.extend([
|
66
|
+
f'-I{openssl_prefix}/include',
|
67
|
+
f'-I{pcre_prefix}/include',
|
68
|
+
])
|
69
|
+
ldflags.extend([
|
70
|
+
f'-L{openssl_prefix}/lib',
|
71
|
+
f'-L{pcre_prefix}/lib',
|
72
|
+
])
|
73
|
+
|
74
|
+
subprocess.check_call([
|
75
|
+
check.not_none(shutil.which('sh')),
|
76
|
+
|
77
|
+
'configure',
|
78
|
+
|
79
|
+
f'--with-cc-opt={" ".join(cflags)}',
|
80
|
+
f'--with-ld-opt={" ".join(ldflags)}',
|
81
|
+
|
82
|
+
'--with-compat',
|
83
|
+
'--with-threads',
|
84
|
+
'--with-debug',
|
85
|
+
'--with-ipv6',
|
86
|
+
'--with-pcre',
|
87
|
+
'--with-pcre-jit',
|
88
|
+
|
89
|
+
'--with-http_auth_request_module',
|
90
|
+
'--with-http_gunzip_module',
|
91
|
+
'--with-http_gzip_static_module',
|
92
|
+
'--with-http_ssl_module',
|
93
|
+
'--with-http_stub_status_module',
|
94
|
+
'--with-http_v2_module',
|
95
|
+
|
96
|
+
'--with-stream',
|
97
|
+
'--with-stream_ssl_module',
|
98
|
+
'--with-stream_ssl_preread_module',
|
99
|
+
|
100
|
+
f'--add-module={nginx_vts_dir}',
|
101
|
+
], cwd=nginx_dir)
|
102
|
+
|
103
|
+
#
|
104
|
+
|
105
|
+
make_jobs = max(multiprocessing.cpu_count() // 2, 1)
|
106
|
+
subprocess.check_call([
|
107
|
+
'make',
|
108
|
+
f'-j{make_jobs}',
|
109
|
+
], cwd=nginx_dir)
|
110
|
+
|
111
|
+
#
|
112
|
+
|
113
|
+
exe_file = os.path.join(nginx_dir, 'objs', 'nginx')
|
114
|
+
print(exe_file)
|
115
|
+
|
116
|
+
|
117
|
+
def _main() -> None:
|
118
|
+
build_nginx()
|
119
|
+
|
120
|
+
|
121
|
+
if __name__ == '__main__':
|
122
|
+
_main()
|
omserv/nginx/configs.py
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
- omnibus/jmespath
|
4
|
+
|
5
|
+
https://nginx.org/en/docs/dev/development_guide.html
|
6
|
+
https://nginx.org/en/docs/dev/development_guide.html#config_directives
|
7
|
+
https://nginx.org/en/docs/example.html
|
8
|
+
|
9
|
+
https://github.com/yandex/gixy
|
10
|
+
"""
|
11
|
+
import dataclasses as dc
|
12
|
+
import typing as ta
|
13
|
+
|
14
|
+
from omlish import check
|
15
|
+
from omlish import lang
|
16
|
+
from omlish.text.indent import IndentWriter
|
17
|
+
|
18
|
+
|
19
|
+
@dc.dataclass()
|
20
|
+
class Items(lang.Final):
|
21
|
+
lst: list['Item']
|
22
|
+
|
23
|
+
@classmethod
|
24
|
+
def of(cls, obj: ta.Any) -> 'Items':
|
25
|
+
if isinstance(obj, Items):
|
26
|
+
return obj
|
27
|
+
return cls([Item.of(e) for e in check.isinstance(obj, list)])
|
28
|
+
|
29
|
+
|
30
|
+
@dc.dataclass()
|
31
|
+
class Item(lang.Final):
|
32
|
+
name: str
|
33
|
+
args: list[str] | None = None
|
34
|
+
block: Items | None = None
|
35
|
+
|
36
|
+
@classmethod
|
37
|
+
def of(cls, obj: ta.Any) -> 'Item':
|
38
|
+
if isinstance(obj, Item):
|
39
|
+
return obj
|
40
|
+
args = check.isinstance(obj, tuple)
|
41
|
+
name, args = check.isinstance(args[0], str), args[1:]
|
42
|
+
if args and not isinstance(args[-1], str):
|
43
|
+
block, args = Items.of(args[-1]), args[:-1]
|
44
|
+
else:
|
45
|
+
block = None
|
46
|
+
return Item(name, [check.isinstance(e, str) for e in args], block=block)
|
47
|
+
|
48
|
+
|
49
|
+
def render(wr: IndentWriter, obj: ta.Any) -> None:
|
50
|
+
if isinstance(obj, Item):
|
51
|
+
wr.write(obj.name)
|
52
|
+
for e in obj.args or ():
|
53
|
+
wr.write(' ')
|
54
|
+
wr.write(e)
|
55
|
+
if obj.block:
|
56
|
+
wr.write(' {\n')
|
57
|
+
with wr.indent():
|
58
|
+
render(wr, obj.block)
|
59
|
+
wr.write('}\n')
|
60
|
+
else:
|
61
|
+
wr.write(';\n')
|
62
|
+
|
63
|
+
elif isinstance(obj, Items):
|
64
|
+
for e2 in obj.lst:
|
65
|
+
render(wr, e2)
|
66
|
+
|
67
|
+
else:
|
68
|
+
raise TypeError(obj)
|
69
|
+
|
70
|
+
|
71
|
+
def _main() -> None:
|
72
|
+
conf = Items.of([
|
73
|
+
('user', 'www', 'www'),
|
74
|
+
('worker_processes', '2'),
|
75
|
+
('events', [
|
76
|
+
('worker_connections', '2000'),
|
77
|
+
]),
|
78
|
+
])
|
79
|
+
|
80
|
+
wr = IndentWriter()
|
81
|
+
render(wr, conf)
|
82
|
+
print(wr.getvalue())
|
83
|
+
|
84
|
+
|
85
|
+
if __name__ == '__main__':
|
86
|
+
_main()
|
File without changes
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import dataclasses as dc
|
2
|
+
import re
|
3
|
+
import textwrap
|
4
|
+
import typing as ta
|
5
|
+
|
6
|
+
|
7
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
8
|
+
class StubStatus:
|
9
|
+
active: int
|
10
|
+
|
11
|
+
# std: accepts handled requests
|
12
|
+
# ext: 2xx 4xx 5xx
|
13
|
+
counts: ta.Mapping[str, int]
|
14
|
+
|
15
|
+
reading: int
|
16
|
+
writing: int
|
17
|
+
waiting: int
|
18
|
+
|
19
|
+
|
20
|
+
_ACTIVE_PAT = re.compile(r'^Active connections: (?P<active>\d+)')
|
21
|
+
_RWW_PAT = re.compile(r'^Reading: (?P<reading>\d+) Writing: (?P<writing>\d+) Waiting: (?P<waiting>\d+)')
|
22
|
+
|
23
|
+
|
24
|
+
def parse_stub_status(s: str) -> StubStatus:
|
25
|
+
# Active connections: 1
|
26
|
+
# server accepts handled requests 2xx 4xx 5xx
|
27
|
+
# 20 20 20 18 1 0
|
28
|
+
# Reading: 0 Writing: 1 Waiting: 0
|
29
|
+
|
30
|
+
lines = [l for l in s.splitlines() for l in [l.strip()] if l]
|
31
|
+
if len(lines) < 4:
|
32
|
+
raise Exception('Not enough lines')
|
33
|
+
|
34
|
+
if (active_m := _ACTIVE_PAT.match(lines[0])) is None:
|
35
|
+
raise Exception('Failed to match active line')
|
36
|
+
active = int(active_m.groupdict()['active'])
|
37
|
+
|
38
|
+
if (rww_m := _RWW_PAT.match(lines[3])) is None:
|
39
|
+
raise Exception('Failed to match rww line')
|
40
|
+
reading = int(rww_m.groupdict()['reading'])
|
41
|
+
writing = int(rww_m.groupdict()['writing'])
|
42
|
+
waiting = int(rww_m.groupdict()['waiting'])
|
43
|
+
|
44
|
+
ct_lbl = lines[1].split()[1:]
|
45
|
+
ct_val = lines[2].split()
|
46
|
+
if len(ct_lbl) != len(ct_val):
|
47
|
+
raise Exception('Counts label/value mismatch')
|
48
|
+
counts = {l: int(v) for l, v in zip(ct_lbl, ct_val)}
|
49
|
+
|
50
|
+
return StubStatus(
|
51
|
+
active=active,
|
52
|
+
|
53
|
+
counts=counts,
|
54
|
+
|
55
|
+
reading=reading,
|
56
|
+
writing=writing,
|
57
|
+
waiting=waiting,
|
58
|
+
)
|
59
|
+
|
60
|
+
|
61
|
+
def _main() -> None:
|
62
|
+
s = textwrap.dedent("""
|
63
|
+
Active connections: 1
|
64
|
+
server accepts handled requests 2xx 4xx 5xx
|
65
|
+
20 20 20 18 1 0
|
66
|
+
Reading: 0 Writing: 1 Waiting: 0
|
67
|
+
""")
|
68
|
+
ss = parse_stub_status(s)
|
69
|
+
print(ss)
|
70
|
+
|
71
|
+
|
72
|
+
if __name__ == '__main__':
|
73
|
+
_main()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: omserv
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev24
|
4
4
|
Summary: omserv
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Operating System :: POSIX
|
13
13
|
Requires-Python: ~=3.12
|
14
14
|
License-File: LICENSE
|
15
|
-
Requires-Dist: omlish ==0.0.0.
|
15
|
+
Requires-Dist: omlish ==0.0.0.dev24
|
16
16
|
Provides-Extra: all
|
17
17
|
Requires-Dist: h11 ~=0.14 ; extra == 'all'
|
18
18
|
Requires-Dist: h2 ~=4.1 ; extra == 'all'
|
@@ -9,6 +9,11 @@ omserv/apps/markers.py,sha256=aj39pNZYlTSjUQT02wOftzrkTq1TTMIfE0aMoV_XxVk,882
|
|
9
9
|
omserv/apps/routes.py,sha256=shcN8qCSF2YoKal7nk-lemCAK3RX8MuHgNHhq_CTnh0,3762
|
10
10
|
omserv/apps/sessions.py,sha256=glruQSbOSbCYLPp6nDRNSHCyp5hj4oiOPhh3R0F9BTM,1537
|
11
11
|
omserv/apps/templates.py,sha256=PBRZHIF9UbnFnq-4EC6RmPeRkeH8lCBbpJkSdseHs6A,2125
|
12
|
+
omserv/nginx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
+
omserv/nginx/build.py,sha256=mCvX7f1LGguLNPVQEwxlWO6OQpad43JbLu96gbIlNy4,3141
|
14
|
+
omserv/nginx/configs.py,sha256=4oQDcKJKIatRG621qiZCYTayJI3-vv63TtRCiUxEVWI,2008
|
15
|
+
omserv/nginx/stubstatus.py,sha256=_VnXZdXxSA7jIelYSwJLf9mOnt_UOvpWghAPWtlWSLw,1857
|
16
|
+
omserv/nginx/patches/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
17
|
omserv/node/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
18
|
omserv/node/models.py,sha256=XsfAI-LjlRkRfK0_ofh-gai5IUq_g357UfThK9dZ0UM,1258
|
14
19
|
omserv/node/registry.py,sha256=0hodmyQn3POOZJBG8zTr9ojR80-ZNmIwJpQbchJg8EM,3459
|
@@ -37,8 +42,8 @@ omserv/server/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
37
42
|
omserv/server/streams/httpstream.py,sha256=0DeiAPLGbEGNa0fHTs8lUpi_CFZs4M5_QB-TiS8mobQ,8015
|
38
43
|
omserv/server/streams/utils.py,sha256=aMOrqWIg_Hht5W4kLg3y7oR5AEkVvMrZhyjzo6U5owE,1527
|
39
44
|
omserv/server/streams/wsstream.py,sha256=3Vyzox7dCE1tDSXjb6xBubWo41ZF9d38Hrsrlj6h1J8,15482
|
40
|
-
omserv-0.0.0.
|
41
|
-
omserv-0.0.0.
|
42
|
-
omserv-0.0.0.
|
43
|
-
omserv-0.0.0.
|
44
|
-
omserv-0.0.0.
|
45
|
+
omserv-0.0.0.dev24.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
46
|
+
omserv-0.0.0.dev24.dist-info/METADATA,sha256=1LoV9C_TsRisl-F-w3OQ66tquPXZz-yIKpdLBhskYLk,881
|
47
|
+
omserv-0.0.0.dev24.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
48
|
+
omserv-0.0.0.dev24.dist-info/top_level.txt,sha256=HXehpnxeKscKNULzKNzZ27oNawBrsh1PaNAirbX-XNA,7
|
49
|
+
omserv-0.0.0.dev24.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|