ominfra 0.0.0.dev174__py3-none-any.whl → 0.0.0.dev176__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 +4 -2
- ominfra/manage/commands/marshal.py +1 -1
- ominfra/manage/deploy/apps.py +2 -0
- ominfra/manage/deploy/conf.py +12 -6
- ominfra/manage/deploy/paths/paths.py +2 -2
- ominfra/manage/deploy/specs.py +3 -9
- ominfra/manage/deploy/tags.py +4 -0
- ominfra/manage/deploy/venvs.py +11 -1
- ominfra/manage/main.py +12 -3
- ominfra/scripts/journald2aws.py +40 -5
- ominfra/scripts/manage.py +1429 -1373
- ominfra/scripts/supervisor.py +40 -5
- {ominfra-0.0.0.dev174.dist-info → ominfra-0.0.0.dev176.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev174.dist-info → ominfra-0.0.0.dev176.dist-info}/RECORD +18 -18
- {ominfra-0.0.0.dev174.dist-info → ominfra-0.0.0.dev176.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev174.dist-info → ominfra-0.0.0.dev176.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev174.dist-info → ominfra-0.0.0.dev176.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev174.dist-info → ominfra-0.0.0.dev176.dist-info}/top_level.txt +0 -0
ominfra/configs.py
CHANGED
@@ -6,7 +6,8 @@ import typing as ta
|
|
6
6
|
|
7
7
|
from omdev.toml.parser import toml_loads
|
8
8
|
from omlish.lite.check import check
|
9
|
-
from omlish.lite.marshal import
|
9
|
+
from omlish.lite.marshal import OBJ_MARSHALER_MANAGER
|
10
|
+
from omlish.lite.marshal import ObjMarshalerManager
|
10
11
|
|
11
12
|
|
12
13
|
T = ta.TypeVar('T')
|
@@ -46,6 +47,7 @@ def read_config_file(
|
|
46
47
|
cls: ta.Type[T],
|
47
48
|
*,
|
48
49
|
prepare: ta.Optional[ta.Callable[[ConfigMapping], ConfigMapping]] = None,
|
50
|
+
msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
|
49
51
|
) -> T:
|
50
52
|
with open(path) as cf:
|
51
53
|
config_dct = parse_config_file(os.path.basename(path), cf)
|
@@ -53,7 +55,7 @@ def read_config_file(
|
|
53
55
|
if prepare is not None:
|
54
56
|
config_dct = prepare(config_dct)
|
55
57
|
|
56
|
-
return unmarshal_obj(config_dct, cls)
|
58
|
+
return msh.unmarshal_obj(config_dct, cls)
|
57
59
|
|
58
60
|
|
59
61
|
def build_config_named_children(
|
ominfra/manage/deploy/apps.py
CHANGED
@@ -86,6 +86,8 @@ class DeployAppManager(DeployPathOwner):
|
|
86
86
|
os.makedirs(deploy_dir, exist_ok=True)
|
87
87
|
|
88
88
|
deploying_link = os.path.join(deploy_home, 'deploys/deploying')
|
89
|
+
if os.path.exists(deploying_link):
|
90
|
+
os.unlink(deploying_link)
|
89
91
|
relative_symlink(
|
90
92
|
deploy_dir,
|
91
93
|
deploying_link,
|
ominfra/manage/deploy/conf.py
CHANGED
@@ -24,13 +24,12 @@ from omlish.os.paths import is_path_in_dir
|
|
24
24
|
from omlish.os.paths import relative_symlink
|
25
25
|
|
26
26
|
from .paths.paths import DeployPath
|
27
|
-
from .specs import AllActiveDeployAppConfLink
|
28
|
-
from .specs import CurrentOnlyDeployAppConfLink
|
29
27
|
from .specs import DeployAppConfFile
|
30
28
|
from .specs import DeployAppConfLink
|
31
29
|
from .specs import DeployAppConfSpec
|
32
30
|
from .tags import DEPLOY_TAG_SEPARATOR
|
33
31
|
from .tags import DeployApp
|
32
|
+
from .tags import DeployConf
|
34
33
|
from .tags import DeployTagMap
|
35
34
|
from .types import DeployHome
|
36
35
|
|
@@ -63,6 +62,7 @@ class DeployConfManager:
|
|
63
62
|
#
|
64
63
|
|
65
64
|
class _ComputedConfLink(ta.NamedTuple):
|
65
|
+
conf: DeployConf
|
66
66
|
is_dir: bool
|
67
67
|
link_src: str
|
68
68
|
link_dst: str
|
@@ -70,8 +70,9 @@ class DeployConfManager:
|
|
70
70
|
_UNIQUE_LINK_NAME_STR = '@app--@time--@app-key'
|
71
71
|
_UNIQUE_LINK_NAME = DeployPath.parse(_UNIQUE_LINK_NAME_STR)
|
72
72
|
|
73
|
+
@classmethod
|
73
74
|
def _compute_app_conf_link_dst(
|
74
|
-
|
75
|
+
cls,
|
75
76
|
link: DeployAppConfLink,
|
76
77
|
tags: DeployTagMap,
|
77
78
|
app_conf_dir: str,
|
@@ -85,6 +86,7 @@ class DeployConfManager:
|
|
85
86
|
if (is_dir := link.src.endswith('/')):
|
86
87
|
# @conf/ - links a directory in root of app conf dir to conf/@conf/@dst/
|
87
88
|
check.arg(link.src.count('/') == 1)
|
89
|
+
conf = DeployConf(link.src.split('/')[0])
|
88
90
|
link_dst_pfx = link.src
|
89
91
|
link_dst_sfx = ''
|
90
92
|
|
@@ -92,6 +94,7 @@ class DeployConfManager:
|
|
92
94
|
# @conf/file - links a single file in a single subdir to conf/@conf/@dst--file
|
93
95
|
d, f = os.path.split(link.src)
|
94
96
|
# TODO: check filename :|
|
97
|
+
conf = DeployConf(d)
|
95
98
|
link_dst_pfx = d + '/'
|
96
99
|
link_dst_sfx = DEPLOY_TAG_SEPARATOR + f
|
97
100
|
|
@@ -99,18 +102,20 @@ class DeployConfManager:
|
|
99
102
|
# @conf(.ext)* - links a single file in root of app conf dir to conf/@conf/@dst(.ext)*
|
100
103
|
if '.' in link.src:
|
101
104
|
l, _, r = link.src.partition('.')
|
105
|
+
conf = DeployConf(l)
|
102
106
|
link_dst_pfx = l + '/'
|
103
107
|
link_dst_sfx = '.' + r
|
104
108
|
else:
|
109
|
+
conf = DeployConf(link.src)
|
105
110
|
link_dst_pfx = link.src + '/'
|
106
111
|
link_dst_sfx = ''
|
107
112
|
|
108
113
|
#
|
109
114
|
|
110
|
-
if
|
115
|
+
if link.kind == 'current_only':
|
111
116
|
link_dst_mid = str(tags[DeployApp].s)
|
112
|
-
elif
|
113
|
-
link_dst_mid =
|
117
|
+
elif link.kind == 'all_active':
|
118
|
+
link_dst_mid = cls._UNIQUE_LINK_NAME.render(tags)
|
114
119
|
else:
|
115
120
|
raise TypeError(link)
|
116
121
|
|
@@ -124,6 +129,7 @@ class DeployConfManager:
|
|
124
129
|
link_dst = os.path.join(conf_link_dir, link_dst_name)
|
125
130
|
|
126
131
|
return DeployConfManager._ComputedConfLink(
|
132
|
+
conf=conf,
|
127
133
|
is_dir=is_dir,
|
128
134
|
link_src=link_src,
|
129
135
|
link_dst=link_dst,
|
@@ -170,7 +170,7 @@ class FileDeployPathPart(DeployPathPart):
|
|
170
170
|
return 'file'
|
171
171
|
|
172
172
|
|
173
|
-
|
173
|
+
##
|
174
174
|
|
175
175
|
|
176
176
|
@dc.dataclass(frozen=True)
|
@@ -197,7 +197,7 @@ class DeployPath:
|
|
197
197
|
return pd
|
198
198
|
|
199
199
|
@property
|
200
|
-
def kind(self) ->
|
200
|
+
def kind(self) -> DeployPathKind:
|
201
201
|
return self.parts[-1].kind
|
202
202
|
|
203
203
|
def render(self, tags: ta.Optional[DeployTagMap] = None) -> str:
|
ominfra/manage/deploy/specs.py
CHANGED
@@ -95,7 +95,7 @@ class DeployAppConfFile:
|
|
95
95
|
|
96
96
|
|
97
97
|
@dc.dataclass(frozen=True)
|
98
|
-
class DeployAppConfLink
|
98
|
+
class DeployAppConfLink: # noqa
|
99
99
|
"""
|
100
100
|
May be either:
|
101
101
|
- @conf(.ext)* - links a single file in root of app conf dir to conf/@conf/@dst(.ext)*
|
@@ -105,20 +105,14 @@ class DeployAppConfLink(abc.ABC): # noqa
|
|
105
105
|
|
106
106
|
src: str
|
107
107
|
|
108
|
+
kind: ta.Literal['current_only', 'all_active'] = 'current_only'
|
109
|
+
|
108
110
|
def __post_init__(self) -> None:
|
109
111
|
check_valid_deploy_spec_path(self.src)
|
110
112
|
if '/' in self.src:
|
111
113
|
check.equal(self.src.count('/'), 1)
|
112
114
|
|
113
115
|
|
114
|
-
class CurrentOnlyDeployAppConfLink(DeployAppConfLink):
|
115
|
-
pass
|
116
|
-
|
117
|
-
|
118
|
-
class AllActiveDeployAppConfLink(DeployAppConfLink):
|
119
|
-
pass
|
120
|
-
|
121
|
-
|
122
116
|
#
|
123
117
|
|
124
118
|
|
ominfra/manage/deploy/tags.py
CHANGED
@@ -4,6 +4,8 @@ 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 SingleFieldObjMarshaler
|
8
|
+
from omlish.lite.marshal import register_type_obj_marshaler
|
7
9
|
|
8
10
|
|
9
11
|
##
|
@@ -82,6 +84,8 @@ def _register_deploy_tag(cls):
|
|
82
84
|
_DEPLOY_TAGS_BY_NAME[cls.tag_name] = cls
|
83
85
|
_DEPLOY_TAGS_BY_KWARG[cls.tag_kwarg] = cls
|
84
86
|
|
87
|
+
register_type_obj_marshaler(cls, SingleFieldObjMarshaler(cls, 's'))
|
88
|
+
|
85
89
|
return cls
|
86
90
|
|
87
91
|
|
ominfra/manage/deploy/venvs.py
CHANGED
@@ -6,7 +6,10 @@ TODO:
|
|
6
6
|
"""
|
7
7
|
import os.path
|
8
8
|
|
9
|
+
from omdev.interp.resolvers import DEFAULT_INTERP_RESOLVER
|
10
|
+
from omdev.interp.types import InterpSpecifier
|
9
11
|
from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
|
12
|
+
from omlish.lite.check import check
|
10
13
|
from omlish.os.atomics import AtomicPathSwapping
|
11
14
|
|
12
15
|
from .specs import DeployVenvSpec
|
@@ -28,7 +31,14 @@ class DeployVenvManager:
|
|
28
31
|
git_dir: str,
|
29
32
|
venv_dir: str,
|
30
33
|
) -> None:
|
31
|
-
|
34
|
+
if spec.interp is not None:
|
35
|
+
i = InterpSpecifier.parse(check.not_none(spec.interp))
|
36
|
+
o = check.not_none(await DEFAULT_INTERP_RESOLVER.resolve(i))
|
37
|
+
sys_exe = o.exe
|
38
|
+
else:
|
39
|
+
sys_exe = 'python3'
|
40
|
+
|
41
|
+
#
|
32
42
|
|
33
43
|
# !! NOTE: (most) venvs cannot be relocated, so an atomic swap can't be used. it's up to the path manager to
|
34
44
|
# garbage collect orphaned dirs.
|
ominfra/manage/main.py
CHANGED
@@ -35,6 +35,8 @@ from .targets.targets import ManageTarget
|
|
35
35
|
|
36
36
|
@dc.dataclass(frozen=True)
|
37
37
|
class ManageConfig:
|
38
|
+
deploy_home: ta.Optional[str] = None
|
39
|
+
|
38
40
|
targets: ta.Optional[ta.Mapping[str, ManageTarget]] = None
|
39
41
|
|
40
42
|
|
@@ -69,7 +71,8 @@ class MainCli(ArgparseCli):
|
|
69
71
|
argparse_arg('--deploy-home'),
|
70
72
|
|
71
73
|
argparse_arg('target'),
|
72
|
-
argparse_arg('command',
|
74
|
+
argparse_arg('-f', '--command-file', action='append'),
|
75
|
+
argparse_arg('command', nargs='*'),
|
73
76
|
)
|
74
77
|
async def run(self) -> None:
|
75
78
|
bs = MainBootstrap(
|
@@ -80,7 +83,7 @@ class MainCli(ArgparseCli):
|
|
80
83
|
),
|
81
84
|
|
82
85
|
deploy_config=DeployConfig(
|
83
|
-
deploy_home=self.args.deploy_home,
|
86
|
+
deploy_home=self.args.deploy_home or self.config().deploy_home,
|
84
87
|
),
|
85
88
|
|
86
89
|
remote_config=RemoteConfig(
|
@@ -115,13 +118,19 @@ class MainCli(ArgparseCli):
|
|
115
118
|
#
|
116
119
|
|
117
120
|
cmds: ta.List[Command] = []
|
121
|
+
|
118
122
|
cmd: Command
|
119
|
-
|
123
|
+
|
124
|
+
for c in self.args.command or []:
|
120
125
|
if not c.startswith('{'):
|
121
126
|
c = json.dumps({c: {}})
|
122
127
|
cmd = msh.unmarshal_obj(json.loads(c), Command)
|
123
128
|
cmds.append(cmd)
|
124
129
|
|
130
|
+
for cf in self.args.command_file or []:
|
131
|
+
cmd = read_config_file(cf, Command, msh=msh)
|
132
|
+
cmds.append(cmd)
|
133
|
+
|
125
134
|
#
|
126
135
|
|
127
136
|
async with injector[ManageTargetConnector].connect(tgt) as ce:
|
ominfra/scripts/journald2aws.py
CHANGED
@@ -2686,6 +2686,18 @@ class FieldsObjMarshaler(ObjMarshaler):
|
|
2686
2686
|
})
|
2687
2687
|
|
2688
2688
|
|
2689
|
+
@dc.dataclass(frozen=True)
|
2690
|
+
class SingleFieldObjMarshaler(ObjMarshaler):
|
2691
|
+
ty: type
|
2692
|
+
fld: str
|
2693
|
+
|
2694
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
2695
|
+
return getattr(o, self.fld)
|
2696
|
+
|
2697
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
2698
|
+
return self.ty(**{self.fld: o})
|
2699
|
+
|
2700
|
+
|
2689
2701
|
@dc.dataclass(frozen=True)
|
2690
2702
|
class PolymorphicObjMarshaler(ObjMarshaler):
|
2691
2703
|
class Impl(ta.NamedTuple):
|
@@ -2760,7 +2772,7 @@ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
|
|
2760
2772
|
**{t: IterableObjMarshaler(t, DynamicObjMarshaler()) for t in (list, tuple, set, frozenset)},
|
2761
2773
|
**{t: MappingObjMarshaler(t, DynamicObjMarshaler(), DynamicObjMarshaler()) for t in (dict,)},
|
2762
2774
|
|
2763
|
-
|
2775
|
+
**{t: DynamicObjMarshaler() for t in (ta.Any, object)},
|
2764
2776
|
|
2765
2777
|
**{t: DatetimeObjMarshaler(t) for t in (datetime.date, datetime.time, datetime.datetime)},
|
2766
2778
|
decimal.Decimal: DecimalObjMarshaler(),
|
@@ -2785,6 +2797,16 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
|
|
2785
2797
|
##
|
2786
2798
|
|
2787
2799
|
|
2800
|
+
_REGISTERED_OBJ_MARSHALERS_BY_TYPE: ta.MutableMapping[type, ObjMarshaler] = weakref.WeakKeyDictionary()
|
2801
|
+
|
2802
|
+
|
2803
|
+
def register_type_obj_marshaler(ty: type, om: ObjMarshaler) -> None:
|
2804
|
+
_REGISTERED_OBJ_MARSHALERS_BY_TYPE[ty] = om
|
2805
|
+
|
2806
|
+
|
2807
|
+
##
|
2808
|
+
|
2809
|
+
|
2788
2810
|
class ObjMarshalerManager:
|
2789
2811
|
def __init__(
|
2790
2812
|
self,
|
@@ -2794,6 +2816,8 @@ class ObjMarshalerManager:
|
|
2794
2816
|
default_obj_marshalers: ta.Dict[ta.Any, ObjMarshaler] = _DEFAULT_OBJ_MARSHALERS, # noqa
|
2795
2817
|
generic_mapping_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_MAPPING_TYPES, # noqa
|
2796
2818
|
generic_iterable_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES, # noqa
|
2819
|
+
|
2820
|
+
registered_obj_marshalers: ta.Mapping[type, ObjMarshaler] = _REGISTERED_OBJ_MARSHALERS_BY_TYPE,
|
2797
2821
|
) -> None:
|
2798
2822
|
super().__init__()
|
2799
2823
|
|
@@ -2802,6 +2826,7 @@ class ObjMarshalerManager:
|
|
2802
2826
|
self._obj_marshalers = dict(default_obj_marshalers)
|
2803
2827
|
self._generic_mapping_types = generic_mapping_types
|
2804
2828
|
self._generic_iterable_types = generic_iterable_types
|
2829
|
+
self._registered_obj_marshalers = registered_obj_marshalers
|
2805
2830
|
|
2806
2831
|
self._lock = threading.RLock()
|
2807
2832
|
self._marshalers: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
|
@@ -2817,6 +2842,9 @@ class ObjMarshalerManager:
|
|
2817
2842
|
non_strict_fields: bool = False,
|
2818
2843
|
) -> ObjMarshaler:
|
2819
2844
|
if isinstance(ty, type):
|
2845
|
+
if (reg := self._registered_obj_marshalers.get(ty)) is not None:
|
2846
|
+
return reg
|
2847
|
+
|
2820
2848
|
if abc.ABC in ty.__bases__:
|
2821
2849
|
impls = [ity for ity in deep_subclasses(ty) if abc.ABC not in ity.__bases__] # type: ignore
|
2822
2850
|
if all(ity.__qualname__.endswith(ty.__name__) for ity in impls):
|
@@ -2881,9 +2909,15 @@ class ObjMarshalerManager:
|
|
2881
2909
|
|
2882
2910
|
#
|
2883
2911
|
|
2884
|
-
def
|
2912
|
+
def set_obj_marshaler(
|
2913
|
+
self,
|
2914
|
+
ty: ta.Any,
|
2915
|
+
m: ObjMarshaler,
|
2916
|
+
*,
|
2917
|
+
override: bool = False,
|
2918
|
+
) -> None:
|
2885
2919
|
with self._lock:
|
2886
|
-
if ty in self._obj_marshalers:
|
2920
|
+
if not override and ty in self._obj_marshalers:
|
2887
2921
|
raise KeyError(ty)
|
2888
2922
|
self._obj_marshalers[ty] = m
|
2889
2923
|
|
@@ -2974,7 +3008,7 @@ class ObjMarshalContext:
|
|
2974
3008
|
|
2975
3009
|
OBJ_MARSHALER_MANAGER = ObjMarshalerManager()
|
2976
3010
|
|
2977
|
-
|
3011
|
+
set_obj_marshaler = OBJ_MARSHALER_MANAGER.set_obj_marshaler
|
2978
3012
|
get_obj_marshaler = OBJ_MARSHALER_MANAGER.get_obj_marshaler
|
2979
3013
|
|
2980
3014
|
marshal_obj = OBJ_MARSHALER_MANAGER.marshal_obj
|
@@ -3259,6 +3293,7 @@ def read_config_file(
|
|
3259
3293
|
cls: ta.Type[T],
|
3260
3294
|
*,
|
3261
3295
|
prepare: ta.Optional[ta.Callable[[ConfigMapping], ConfigMapping]] = None,
|
3296
|
+
msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
|
3262
3297
|
) -> T:
|
3263
3298
|
with open(path) as cf:
|
3264
3299
|
config_dct = parse_config_file(os.path.basename(path), cf)
|
@@ -3266,7 +3301,7 @@ def read_config_file(
|
|
3266
3301
|
if prepare is not None:
|
3267
3302
|
config_dct = prepare(config_dct)
|
3268
3303
|
|
3269
|
-
return unmarshal_obj(config_dct, cls)
|
3304
|
+
return msh.unmarshal_obj(config_dct, cls)
|
3270
3305
|
|
3271
3306
|
|
3272
3307
|
def build_config_named_children(
|