ominfra 0.0.0.dev181__py3-none-any.whl → 0.0.0.dev183__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.
- ominfra/configs.py +33 -0
- ominfra/manage/deploy/apps.py +1 -1
- ominfra/manage/deploy/conf/__init__.py +0 -0
- ominfra/manage/deploy/conf/inject.py +17 -0
- ominfra/manage/deploy/{conf.py → conf/manager.py} +28 -6
- ominfra/manage/deploy/conf/specs.py +95 -0
- ominfra/manage/deploy/inject.py +9 -18
- ominfra/manage/deploy/inject_.py +13 -0
- ominfra/manage/deploy/paths/specs.py +10 -0
- ominfra/manage/deploy/specs.py +1 -59
- ominfra/manage/deploy/tags.py +2 -3
- ominfra/scripts/journald2aws.py +42 -0
- ominfra/scripts/manage.py +664 -548
- ominfra/scripts/supervisor.py +42 -0
- {ominfra-0.0.0.dev181.dist-info → ominfra-0.0.0.dev183.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev181.dist-info → ominfra-0.0.0.dev183.dist-info}/RECORD +20 -16
- ominfra/systemd.py +0 -18
- {ominfra-0.0.0.dev181.dist-info → ominfra-0.0.0.dev183.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev181.dist-info → ominfra-0.0.0.dev183.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev181.dist-info → ominfra-0.0.0.dev183.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev181.dist-info → ominfra-0.0.0.dev183.dist-info}/top_level.txt +0 -0
ominfra/configs.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
2
|
# @omlish-lite
|
3
|
+
import io
|
3
4
|
import json
|
4
5
|
import os.path
|
5
6
|
import typing as ta
|
@@ -14,6 +15,11 @@ T = ta.TypeVar('T')
|
|
14
15
|
|
15
16
|
ConfigMapping = ta.Mapping[str, ta.Any]
|
16
17
|
|
18
|
+
IniConfigSectionSettingsMap = ta.Mapping[str, ta.Mapping[str, ta.Union[str, ta.Sequence[str]]]] # ta.TypeAlias
|
19
|
+
|
20
|
+
|
21
|
+
##
|
22
|
+
|
17
23
|
|
18
24
|
def parse_config_file(
|
19
25
|
name: str,
|
@@ -58,6 +64,9 @@ def read_config_file(
|
|
58
64
|
return msh.unmarshal_obj(config_dct, cls)
|
59
65
|
|
60
66
|
|
67
|
+
##
|
68
|
+
|
69
|
+
|
61
70
|
def build_config_named_children(
|
62
71
|
o: ta.Union[
|
63
72
|
ta.Sequence[ConfigMapping],
|
@@ -94,3 +103,27 @@ def build_config_named_children(
|
|
94
103
|
seen.add(n)
|
95
104
|
|
96
105
|
return lst
|
106
|
+
|
107
|
+
|
108
|
+
##
|
109
|
+
|
110
|
+
|
111
|
+
def render_ini_config(
|
112
|
+
settings_by_section: IniConfigSectionSettingsMap,
|
113
|
+
) -> str:
|
114
|
+
out = io.StringIO()
|
115
|
+
|
116
|
+
for i, (section, settings) in enumerate(settings_by_section.items()):
|
117
|
+
if i:
|
118
|
+
out.write('\n')
|
119
|
+
|
120
|
+
out.write(f'[{section}]\n')
|
121
|
+
|
122
|
+
for k, v in settings.items():
|
123
|
+
if isinstance(v, str):
|
124
|
+
out.write(f'{k}={v}\n')
|
125
|
+
else:
|
126
|
+
for vv in v:
|
127
|
+
out.write(f'{k}={vv}\n')
|
128
|
+
|
129
|
+
return out.getvalue()
|
ominfra/manage/deploy/apps.py
CHANGED
@@ -6,7 +6,7 @@ from omlish.lite.cached import cached_nullary
|
|
6
6
|
from omlish.lite.check import check
|
7
7
|
from omlish.os.paths import relative_symlink
|
8
8
|
|
9
|
-
from .conf import DeployConfManager
|
9
|
+
from .conf.manager import DeployConfManager
|
10
10
|
from .git import DeployGitManager
|
11
11
|
from .paths.owners import DeployPathOwner
|
12
12
|
from .paths.paths import DeployPath
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from omlish.lite.inject import InjectorBindingOrBindings
|
5
|
+
from omlish.lite.inject import InjectorBindings
|
6
|
+
from omlish.lite.inject import inj
|
7
|
+
|
8
|
+
from ..inject_ import bind_deploy_manager
|
9
|
+
from .manager import DeployConfManager
|
10
|
+
|
11
|
+
|
12
|
+
def bind_deploy_conf() -> InjectorBindings:
|
13
|
+
lst: ta.List[InjectorBindingOrBindings] = [
|
14
|
+
bind_deploy_manager(DeployConfManager),
|
15
|
+
]
|
16
|
+
|
17
|
+
return inj.as_bindings(*lst)
|
@@ -20,20 +20,40 @@ import os.path
|
|
20
20
|
import typing as ta
|
21
21
|
|
22
22
|
from omlish.lite.check import check
|
23
|
+
from omlish.lite.json import json_dumps_pretty
|
24
|
+
from omlish.lite.strings import strip_with_newline
|
23
25
|
from omlish.os.paths import is_path_in_dir
|
24
26
|
from omlish.os.paths import relative_symlink
|
25
27
|
|
26
|
-
from
|
28
|
+
from ....configs import render_ini_config
|
29
|
+
from ..paths.paths import DeployPath
|
30
|
+
from ..tags import DEPLOY_TAG_SEPARATOR
|
31
|
+
from ..tags import DeployApp
|
32
|
+
from ..tags import DeployConf
|
33
|
+
from ..tags import DeployTagMap
|
34
|
+
from .specs import DeployAppConfContent
|
27
35
|
from .specs import DeployAppConfFile
|
28
36
|
from .specs import DeployAppConfLink
|
29
37
|
from .specs import DeployAppConfSpec
|
30
|
-
from .
|
31
|
-
from .
|
32
|
-
from .
|
33
|
-
from .tags import DeployTagMap
|
38
|
+
from .specs import IniDeployAppConfContent
|
39
|
+
from .specs import JsonDeployAppConfContent
|
40
|
+
from .specs import RawDeployAppConfContent
|
34
41
|
|
35
42
|
|
36
43
|
class DeployConfManager:
|
44
|
+
def _render_app_conf_content(self, ac: DeployAppConfContent) -> str:
|
45
|
+
if isinstance(ac, RawDeployAppConfContent):
|
46
|
+
return ac.body
|
47
|
+
|
48
|
+
elif isinstance(ac, JsonDeployAppConfContent):
|
49
|
+
return strip_with_newline(json_dumps_pretty(ac.obj))
|
50
|
+
|
51
|
+
elif isinstance(ac, IniDeployAppConfContent):
|
52
|
+
return strip_with_newline(render_ini_config(ac.sections))
|
53
|
+
|
54
|
+
else:
|
55
|
+
raise TypeError(ac)
|
56
|
+
|
37
57
|
async def _write_app_conf_file(
|
38
58
|
self,
|
39
59
|
acf: DeployAppConfFile,
|
@@ -42,10 +62,12 @@ class DeployConfManager:
|
|
42
62
|
conf_file = os.path.join(app_conf_dir, acf.path)
|
43
63
|
check.arg(is_path_in_dir(app_conf_dir, conf_file))
|
44
64
|
|
65
|
+
body = self._render_app_conf_content(acf.content)
|
66
|
+
|
45
67
|
os.makedirs(os.path.dirname(conf_file), exist_ok=True)
|
46
68
|
|
47
69
|
with open(conf_file, 'w') as f: # noqa
|
48
|
-
f.write(
|
70
|
+
f.write(body)
|
49
71
|
|
50
72
|
#
|
51
73
|
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import abc
|
3
|
+
import dataclasses as dc
|
4
|
+
import typing as ta
|
5
|
+
|
6
|
+
from omlish.lite.check import check
|
7
|
+
from omlish.lite.marshal import register_single_field_type_obj_marshaler
|
8
|
+
|
9
|
+
from ....configs import IniConfigSectionSettingsMap
|
10
|
+
from ..paths.specs import check_valid_deploy_spec_path
|
11
|
+
|
12
|
+
|
13
|
+
##
|
14
|
+
|
15
|
+
|
16
|
+
class DeployAppConfContent(abc.ABC): # noqa
|
17
|
+
pass
|
18
|
+
|
19
|
+
|
20
|
+
#
|
21
|
+
|
22
|
+
|
23
|
+
@register_single_field_type_obj_marshaler('body')
|
24
|
+
@dc.dataclass(frozen=True)
|
25
|
+
class RawDeployAppConfContent(DeployAppConfContent):
|
26
|
+
body: str
|
27
|
+
|
28
|
+
|
29
|
+
#
|
30
|
+
|
31
|
+
|
32
|
+
@register_single_field_type_obj_marshaler('obj')
|
33
|
+
@dc.dataclass(frozen=True)
|
34
|
+
class JsonDeployAppConfContent(DeployAppConfContent):
|
35
|
+
obj: ta.Any
|
36
|
+
|
37
|
+
|
38
|
+
#
|
39
|
+
|
40
|
+
|
41
|
+
@register_single_field_type_obj_marshaler('sections')
|
42
|
+
@dc.dataclass(frozen=True)
|
43
|
+
class IniDeployAppConfContent(DeployAppConfContent):
|
44
|
+
sections: IniConfigSectionSettingsMap
|
45
|
+
|
46
|
+
|
47
|
+
##
|
48
|
+
|
49
|
+
|
50
|
+
@dc.dataclass(frozen=True)
|
51
|
+
class DeployAppConfFile:
|
52
|
+
path: str
|
53
|
+
content: DeployAppConfContent
|
54
|
+
|
55
|
+
def __post_init__(self) -> None:
|
56
|
+
check_valid_deploy_spec_path(self.path)
|
57
|
+
|
58
|
+
|
59
|
+
##
|
60
|
+
|
61
|
+
|
62
|
+
@dc.dataclass(frozen=True)
|
63
|
+
class DeployAppConfLink: # noqa
|
64
|
+
"""
|
65
|
+
May be either:
|
66
|
+
- @conf(.ext)* - links a single file in root of app conf dir to conf/@conf/@dst(.ext)*
|
67
|
+
- @conf/file - links a single file in a single subdir to conf/@conf/@dst--file
|
68
|
+
- @conf/ - links a directory in root of app conf dir to conf/@conf/@dst/
|
69
|
+
"""
|
70
|
+
|
71
|
+
src: str
|
72
|
+
|
73
|
+
kind: ta.Literal['current_only', 'all_active'] = 'current_only'
|
74
|
+
|
75
|
+
def __post_init__(self) -> None:
|
76
|
+
check_valid_deploy_spec_path(self.src)
|
77
|
+
if '/' in self.src:
|
78
|
+
check.equal(self.src.count('/'), 1)
|
79
|
+
|
80
|
+
|
81
|
+
##
|
82
|
+
|
83
|
+
|
84
|
+
@dc.dataclass(frozen=True)
|
85
|
+
class DeployAppConfSpec:
|
86
|
+
files: ta.Optional[ta.Sequence[DeployAppConfFile]] = None
|
87
|
+
|
88
|
+
links: ta.Optional[ta.Sequence[DeployAppConfLink]] = None
|
89
|
+
|
90
|
+
def __post_init__(self) -> None:
|
91
|
+
if self.files:
|
92
|
+
seen: ta.Set[str] = set()
|
93
|
+
for f in self.files:
|
94
|
+
check.not_in(f.path, seen)
|
95
|
+
seen.add(f.path)
|
ominfra/manage/deploy/inject.py
CHANGED
@@ -14,16 +14,16 @@ from ..commands.inject import bind_command
|
|
14
14
|
from .apps import DeployAppManager
|
15
15
|
from .commands import DeployCommand
|
16
16
|
from .commands import DeployCommandExecutor
|
17
|
-
from .conf import
|
17
|
+
from .conf.inject import bind_deploy_conf
|
18
18
|
from .config import DeployConfig
|
19
19
|
from .deploy import DeployManager
|
20
20
|
from .driver import DeployDriver
|
21
21
|
from .driver import DeployDriverFactory
|
22
22
|
from .git import DeployGitManager
|
23
|
+
from .inject_ import bind_deploy_manager
|
23
24
|
from .interp import InterpCommand
|
24
25
|
from .interp import InterpCommandExecutor
|
25
26
|
from .paths.inject import bind_deploy_paths
|
26
|
-
from .paths.owners import DeployPathOwner
|
27
27
|
from .specs import DeploySpec
|
28
28
|
from .tags import DeployTime
|
29
29
|
from .tmp import DeployHomeAtomics
|
@@ -90,6 +90,8 @@ def bind_deploy(
|
|
90
90
|
lst: ta.List[InjectorBindingOrBindings] = [
|
91
91
|
inj.bind(deploy_config),
|
92
92
|
|
93
|
+
bind_deploy_conf(),
|
94
|
+
|
93
95
|
bind_deploy_paths(),
|
94
96
|
|
95
97
|
bind_deploy_scope(),
|
@@ -97,27 +99,16 @@ def bind_deploy(
|
|
97
99
|
|
98
100
|
#
|
99
101
|
|
100
|
-
def bind_manager(cls: type) -> InjectorBindings:
|
101
|
-
return inj.as_bindings(
|
102
|
-
inj.bind(cls, singleton=True),
|
103
|
-
|
104
|
-
*([inj.bind(DeployPathOwner, to_key=cls, array=True)] if issubclass(cls, DeployPathOwner) else []),
|
105
|
-
)
|
106
|
-
|
107
|
-
#
|
108
|
-
|
109
102
|
lst.extend([
|
110
|
-
|
111
|
-
|
112
|
-
bind_manager(DeployConfManager),
|
103
|
+
bind_deploy_manager(DeployAppManager),
|
113
104
|
|
114
|
-
|
105
|
+
bind_deploy_manager(DeployGitManager),
|
115
106
|
|
116
|
-
|
107
|
+
bind_deploy_manager(DeployManager),
|
117
108
|
|
118
|
-
|
109
|
+
bind_deploy_manager(DeployTmpManager),
|
119
110
|
|
120
|
-
|
111
|
+
bind_deploy_manager(DeployVenvManager),
|
121
112
|
])
|
122
113
|
|
123
114
|
#
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
from omlish.lite.inject import InjectorBindings
|
3
|
+
from omlish.lite.inject import inj
|
4
|
+
|
5
|
+
from .paths.owners import DeployPathOwner
|
6
|
+
|
7
|
+
|
8
|
+
def bind_deploy_manager(cls: type) -> InjectorBindings:
|
9
|
+
return inj.as_bindings(
|
10
|
+
inj.bind(cls, singleton=True),
|
11
|
+
|
12
|
+
*([inj.bind(DeployPathOwner, to_key=cls, array=True)] if issubclass(cls, DeployPathOwner) else []),
|
13
|
+
)
|
ominfra/manage/deploy/specs.py
CHANGED
@@ -7,6 +7,7 @@ import typing as ta
|
|
7
7
|
from omlish.lite.cached import cached_nullary
|
8
8
|
from omlish.lite.check import check
|
9
9
|
|
10
|
+
from .conf.specs import DeployAppConfSpec
|
10
11
|
from .tags import DeployApp
|
11
12
|
from .tags import DeployAppKey
|
12
13
|
from .tags import DeployKey
|
@@ -21,14 +22,6 @@ KeyDeployTagT = ta.TypeVar('KeyDeployTagT', bound='KeyDeployTag')
|
|
21
22
|
##
|
22
23
|
|
23
24
|
|
24
|
-
def check_valid_deploy_spec_path(s: str) -> str:
|
25
|
-
check.non_empty_str(s)
|
26
|
-
for c in ['..', '//']:
|
27
|
-
check.not_in(c, s)
|
28
|
-
check.arg(not s.startswith('/'))
|
29
|
-
return s
|
30
|
-
|
31
|
-
|
32
25
|
class DeploySpecKeyed(ta.Generic[KeyDeployTagT]):
|
33
26
|
@cached_nullary
|
34
27
|
def _key_str(self) -> str:
|
@@ -83,57 +76,6 @@ class DeployVenvSpec:
|
|
83
76
|
##
|
84
77
|
|
85
78
|
|
86
|
-
@dc.dataclass(frozen=True)
|
87
|
-
class DeployAppConfFile:
|
88
|
-
path: str
|
89
|
-
body: str
|
90
|
-
|
91
|
-
def __post_init__(self) -> None:
|
92
|
-
check_valid_deploy_spec_path(self.path)
|
93
|
-
|
94
|
-
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
@dc.dataclass(frozen=True)
|
99
|
-
class DeployAppConfLink: # noqa
|
100
|
-
"""
|
101
|
-
May be either:
|
102
|
-
- @conf(.ext)* - links a single file in root of app conf dir to conf/@conf/@dst(.ext)*
|
103
|
-
- @conf/file - links a single file in a single subdir to conf/@conf/@dst--file
|
104
|
-
- @conf/ - links a directory in root of app conf dir to conf/@conf/@dst/
|
105
|
-
"""
|
106
|
-
|
107
|
-
src: str
|
108
|
-
|
109
|
-
kind: ta.Literal['current_only', 'all_active'] = 'current_only'
|
110
|
-
|
111
|
-
def __post_init__(self) -> None:
|
112
|
-
check_valid_deploy_spec_path(self.src)
|
113
|
-
if '/' in self.src:
|
114
|
-
check.equal(self.src.count('/'), 1)
|
115
|
-
|
116
|
-
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
@dc.dataclass(frozen=True)
|
121
|
-
class DeployAppConfSpec:
|
122
|
-
files: ta.Optional[ta.Sequence[DeployAppConfFile]] = None
|
123
|
-
|
124
|
-
links: ta.Optional[ta.Sequence[DeployAppConfLink]] = None
|
125
|
-
|
126
|
-
def __post_init__(self) -> None:
|
127
|
-
if self.files:
|
128
|
-
seen: ta.Set[str] = set()
|
129
|
-
for f in self.files:
|
130
|
-
check.not_in(f.path, seen)
|
131
|
-
seen.add(f.path)
|
132
|
-
|
133
|
-
|
134
|
-
##
|
135
|
-
|
136
|
-
|
137
79
|
@dc.dataclass(frozen=True)
|
138
80
|
class DeployAppSpec(DeploySpecKeyed[DeployAppKey]):
|
139
81
|
app: DeployApp
|
ominfra/manage/deploy/tags.py
CHANGED
@@ -4,8 +4,7 @@ import dataclasses as dc
|
|
4
4
|
import typing as ta
|
5
5
|
|
6
6
|
from omlish.lite.check import check
|
7
|
-
from omlish.lite.marshal import
|
8
|
-
from omlish.lite.marshal import register_type_obj_marshaler
|
7
|
+
from omlish.lite.marshal import register_single_field_type_obj_marshaler
|
9
8
|
|
10
9
|
|
11
10
|
##
|
@@ -84,7 +83,7 @@ def _register_deploy_tag(cls):
|
|
84
83
|
_DEPLOY_TAGS_BY_NAME[cls.tag_name] = cls
|
85
84
|
_DEPLOY_TAGS_BY_KWARG[cls.tag_kwarg] = cls
|
86
85
|
|
87
|
-
|
86
|
+
register_single_field_type_obj_marshaler('s', cls)
|
88
87
|
|
89
88
|
return cls
|
90
89
|
|
ominfra/scripts/journald2aws.py
CHANGED
@@ -74,6 +74,7 @@ ExitStackedT = ta.TypeVar('ExitStackedT', bound='ExitStacked')
|
|
74
74
|
|
75
75
|
# ../../../configs.py
|
76
76
|
ConfigMapping = ta.Mapping[str, ta.Any]
|
77
|
+
IniConfigSectionSettingsMap = ta.Mapping[str, ta.Mapping[str, ta.Union[str, ta.Sequence[str]]]] # ta.TypeAlias
|
77
78
|
|
78
79
|
# ../../../threadworkers.py
|
79
80
|
ThreadWorkerT = ta.TypeVar('ThreadWorkerT', bound='ThreadWorker')
|
@@ -2804,6 +2805,17 @@ def register_type_obj_marshaler(ty: type, om: ObjMarshaler) -> None:
|
|
2804
2805
|
_REGISTERED_OBJ_MARSHALERS_BY_TYPE[ty] = om
|
2805
2806
|
|
2806
2807
|
|
2808
|
+
def register_single_field_type_obj_marshaler(fld, ty=None):
|
2809
|
+
def inner(ty): # noqa
|
2810
|
+
register_type_obj_marshaler(ty, SingleFieldObjMarshaler(ty, fld))
|
2811
|
+
return ty
|
2812
|
+
|
2813
|
+
if ty is not None:
|
2814
|
+
return inner(ty)
|
2815
|
+
else:
|
2816
|
+
return inner
|
2817
|
+
|
2818
|
+
|
2807
2819
|
##
|
2808
2820
|
|
2809
2821
|
|
@@ -3261,6 +3273,9 @@ class AwsLogMessageBuilder:
|
|
3261
3273
|
# ../../../../configs.py
|
3262
3274
|
|
3263
3275
|
|
3276
|
+
##
|
3277
|
+
|
3278
|
+
|
3264
3279
|
def parse_config_file(
|
3265
3280
|
name: str,
|
3266
3281
|
f: ta.TextIO,
|
@@ -3304,6 +3319,9 @@ def read_config_file(
|
|
3304
3319
|
return msh.unmarshal_obj(config_dct, cls)
|
3305
3320
|
|
3306
3321
|
|
3322
|
+
##
|
3323
|
+
|
3324
|
+
|
3307
3325
|
def build_config_named_children(
|
3308
3326
|
o: ta.Union[
|
3309
3327
|
ta.Sequence[ConfigMapping],
|
@@ -3342,6 +3360,30 @@ def build_config_named_children(
|
|
3342
3360
|
return lst
|
3343
3361
|
|
3344
3362
|
|
3363
|
+
##
|
3364
|
+
|
3365
|
+
|
3366
|
+
def render_ini_config(
|
3367
|
+
settings_by_section: IniConfigSectionSettingsMap,
|
3368
|
+
) -> str:
|
3369
|
+
out = io.StringIO()
|
3370
|
+
|
3371
|
+
for i, (section, settings) in enumerate(settings_by_section.items()):
|
3372
|
+
if i:
|
3373
|
+
out.write('\n')
|
3374
|
+
|
3375
|
+
out.write(f'[{section}]\n')
|
3376
|
+
|
3377
|
+
for k, v in settings.items():
|
3378
|
+
if isinstance(v, str):
|
3379
|
+
out.write(f'{k}={v}\n')
|
3380
|
+
else:
|
3381
|
+
for vv in v:
|
3382
|
+
out.write(f'{k}={vv}\n')
|
3383
|
+
|
3384
|
+
return out.getvalue()
|
3385
|
+
|
3386
|
+
|
3345
3387
|
########################################
|
3346
3388
|
# ../../../../journald/messages.py
|
3347
3389
|
|