ominfra 0.0.0.dev175__py3-none-any.whl → 0.0.0.dev177__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 +9 -8
- ominfra/manage/deploy/conf.py +0 -12
- ominfra/manage/deploy/config.py +1 -2
- ominfra/manage/deploy/deploy.py +13 -0
- ominfra/manage/deploy/git.py +24 -9
- ominfra/manage/deploy/inject.py +7 -8
- ominfra/manage/deploy/paths/manager.py +0 -3
- ominfra/manage/deploy/paths/owners.py +4 -10
- ominfra/manage/deploy/specs.py +5 -0
- ominfra/manage/deploy/tags.py +4 -0
- ominfra/manage/deploy/tmp.py +9 -28
- ominfra/manage/deploy/venvs.py +13 -11
- ominfra/manage/main.py +10 -7
- ominfra/scripts/journald2aws.py +40 -5
- ominfra/scripts/manage.py +1418 -1381
- ominfra/scripts/supervisor.py +40 -5
- {ominfra-0.0.0.dev175.dist-info → ominfra-0.0.0.dev177.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev175.dist-info → ominfra-0.0.0.dev177.dist-info}/RECORD +24 -24
- {ominfra-0.0.0.dev175.dist-info → ominfra-0.0.0.dev177.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev175.dist-info → ominfra-0.0.0.dev177.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev175.dist-info → ominfra-0.0.0.dev177.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev175.dist-info → ominfra-0.0.0.dev177.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
@@ -20,16 +20,12 @@ class DeployAppManager(DeployPathOwner):
|
|
20
20
|
def __init__(
|
21
21
|
self,
|
22
22
|
*,
|
23
|
-
deploy_home: ta.Optional[DeployHome] = None,
|
24
|
-
|
25
23
|
conf: DeployConfManager,
|
26
24
|
git: DeployGitManager,
|
27
25
|
venvs: DeployVenvManager,
|
28
26
|
) -> None:
|
29
27
|
super().__init__()
|
30
28
|
|
31
|
-
self._deploy_home = deploy_home
|
32
|
-
|
33
29
|
self._conf = conf
|
34
30
|
self._git = git
|
35
31
|
self._venvs = venvs
|
@@ -70,12 +66,13 @@ class DeployAppManager(DeployPathOwner):
|
|
70
66
|
async def prepare_app(
|
71
67
|
self,
|
72
68
|
spec: DeployAppSpec,
|
69
|
+
home: DeployHome,
|
73
70
|
tags: DeployTagMap,
|
74
71
|
) -> None:
|
75
|
-
|
72
|
+
check.non_empty_str(home)
|
76
73
|
|
77
74
|
def build_path(pth: DeployPath) -> str:
|
78
|
-
return os.path.join(
|
75
|
+
return os.path.join(home, pth.render(tags))
|
79
76
|
|
80
77
|
app_dir = build_path(self._APP_DIR)
|
81
78
|
deploy_dir = build_path(self._DEPLOY_DIR)
|
@@ -85,7 +82,9 @@ class DeployAppManager(DeployPathOwner):
|
|
85
82
|
|
86
83
|
os.makedirs(deploy_dir, exist_ok=True)
|
87
84
|
|
88
|
-
deploying_link = os.path.join(
|
85
|
+
deploying_link = os.path.join(home, 'deploys/deploying')
|
86
|
+
if os.path.exists(deploying_link):
|
87
|
+
os.unlink(deploying_link)
|
89
88
|
relative_symlink(
|
90
89
|
deploy_dir,
|
91
90
|
deploying_link,
|
@@ -130,7 +129,7 @@ class DeployAppManager(DeployPathOwner):
|
|
130
129
|
# else:
|
131
130
|
# os.makedirs(os.path.join(dst, os.path.relpath(dp2, src)))
|
132
131
|
|
133
|
-
current_link = os.path.join(
|
132
|
+
current_link = os.path.join(home, 'deploys/current')
|
134
133
|
|
135
134
|
# if os.path.exists(current_link):
|
136
135
|
# mirror_symlinks(
|
@@ -147,6 +146,7 @@ class DeployAppManager(DeployPathOwner):
|
|
147
146
|
app_git_dir = os.path.join(app_dir, 'git')
|
148
147
|
await self._git.checkout(
|
149
148
|
spec.git,
|
149
|
+
home,
|
150
150
|
app_git_dir,
|
151
151
|
)
|
152
152
|
|
@@ -156,6 +156,7 @@ class DeployAppManager(DeployPathOwner):
|
|
156
156
|
app_venv_dir = os.path.join(app_dir, 'venv')
|
157
157
|
await self._venvs.setup_venv(
|
158
158
|
spec.venv,
|
159
|
+
home,
|
159
160
|
app_git_dir,
|
160
161
|
app_venv_dir,
|
161
162
|
)
|
ominfra/manage/deploy/conf.py
CHANGED
@@ -31,21 +31,9 @@ from .tags import DEPLOY_TAG_SEPARATOR
|
|
31
31
|
from .tags import DeployApp
|
32
32
|
from .tags import DeployConf
|
33
33
|
from .tags import DeployTagMap
|
34
|
-
from .types import DeployHome
|
35
34
|
|
36
35
|
|
37
36
|
class DeployConfManager:
|
38
|
-
def __init__(
|
39
|
-
self,
|
40
|
-
*,
|
41
|
-
deploy_home: ta.Optional[DeployHome] = None,
|
42
|
-
) -> None:
|
43
|
-
super().__init__()
|
44
|
-
|
45
|
-
self._deploy_home = deploy_home
|
46
|
-
|
47
|
-
#
|
48
|
-
|
49
37
|
async def _write_app_conf_file(
|
50
38
|
self,
|
51
39
|
acf: DeployAppConfFile,
|
ominfra/manage/deploy/config.py
CHANGED
ominfra/manage/deploy/deploy.py
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
2
|
import datetime
|
3
|
+
import os.path
|
3
4
|
import typing as ta
|
4
5
|
|
6
|
+
from omlish.lite.check import check
|
5
7
|
from omlish.lite.typing import Func0
|
6
8
|
|
7
9
|
from .apps import DeployAppManager
|
@@ -10,6 +12,7 @@ from .specs import DeploySpec
|
|
10
12
|
from .tags import DeployAppRev
|
11
13
|
from .tags import DeployTagMap
|
12
14
|
from .tags import DeployTime
|
15
|
+
from .types import DeployHome
|
13
16
|
|
14
17
|
|
15
18
|
DEPLOY_TAG_DATETIME_FMT = '%Y%m%dT%H%M%SZ'
|
@@ -51,6 +54,15 @@ class DeployManager:
|
|
51
54
|
|
52
55
|
#
|
53
56
|
|
57
|
+
hs = check.non_empty_str(spec.home)
|
58
|
+
hs = os.path.expanduser(hs)
|
59
|
+
hs = os.path.realpath(hs)
|
60
|
+
hs = os.path.abspath(hs)
|
61
|
+
|
62
|
+
home = DeployHome(hs)
|
63
|
+
|
64
|
+
#
|
65
|
+
|
54
66
|
deploy_tags = DeployTagMap(
|
55
67
|
self._make_deploy_time(),
|
56
68
|
spec.key(),
|
@@ -67,5 +79,6 @@ class DeployManager:
|
|
67
79
|
|
68
80
|
await self._apps.prepare_app(
|
69
81
|
app,
|
82
|
+
home,
|
70
83
|
app_tags,
|
71
84
|
)
|
ominfra/manage/deploy/git.py
CHANGED
@@ -15,11 +15,11 @@ import typing as ta
|
|
15
15
|
from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
|
16
16
|
from omlish.lite.cached import async_cached_nullary
|
17
17
|
from omlish.lite.check import check
|
18
|
-
from omlish.os.atomics import AtomicPathSwapping
|
19
18
|
|
20
19
|
from .paths.owners import SingleDirDeployPathOwner
|
21
20
|
from .specs import DeployGitRepo
|
22
21
|
from .specs import DeployGitSpec
|
22
|
+
from .tmp import DeployHomeAtomics
|
23
23
|
from .types import DeployHome
|
24
24
|
from .types import DeployRev
|
25
25
|
|
@@ -31,12 +31,10 @@ class DeployGitManager(SingleDirDeployPathOwner):
|
|
31
31
|
def __init__(
|
32
32
|
self,
|
33
33
|
*,
|
34
|
-
|
35
|
-
atomics: AtomicPathSwapping,
|
34
|
+
atomics: DeployHomeAtomics,
|
36
35
|
) -> None:
|
37
36
|
super().__init__(
|
38
37
|
owned_dir='git',
|
39
|
-
deploy_home=deploy_home,
|
40
38
|
)
|
41
39
|
|
42
40
|
self._atomics = atomics
|
@@ -48,13 +46,15 @@ class DeployGitManager(SingleDirDeployPathOwner):
|
|
48
46
|
self,
|
49
47
|
git: 'DeployGitManager',
|
50
48
|
repo: DeployGitRepo,
|
49
|
+
home: DeployHome,
|
51
50
|
) -> None:
|
52
51
|
super().__init__()
|
53
52
|
|
54
53
|
self._git = git
|
55
54
|
self._repo = repo
|
55
|
+
self._home = home
|
56
56
|
self._dir = os.path.join(
|
57
|
-
self._git._make_dir(), # noqa
|
57
|
+
self._git._make_dir(home), # noqa
|
58
58
|
check.non_empty_str(repo.host),
|
59
59
|
check.non_empty_str(repo.path),
|
60
60
|
)
|
@@ -97,7 +97,7 @@ class DeployGitManager(SingleDirDeployPathOwner):
|
|
97
97
|
|
98
98
|
async def checkout(self, spec: DeployGitSpec, dst_dir: str) -> None:
|
99
99
|
check.state(not os.path.exists(dst_dir))
|
100
|
-
with self._git._atomics.begin_atomic_path_swap( # noqa
|
100
|
+
with self._git._atomics(self._home).begin_atomic_path_swap( # noqa
|
101
101
|
'dir',
|
102
102
|
dst_dir,
|
103
103
|
auto_commit=True,
|
@@ -112,16 +112,31 @@ class DeployGitManager(SingleDirDeployPathOwner):
|
|
112
112
|
await dst_call('git', 'fetch', '--depth=1', 'local', spec.rev)
|
113
113
|
await dst_call('git', 'checkout', spec.rev, *(spec.subtrees or []))
|
114
114
|
|
115
|
-
def get_repo_dir(
|
115
|
+
def get_repo_dir(
|
116
|
+
self,
|
117
|
+
repo: DeployGitRepo,
|
118
|
+
home: DeployHome,
|
119
|
+
) -> RepoDir:
|
116
120
|
try:
|
117
121
|
return self._repo_dirs[repo]
|
118
122
|
except KeyError:
|
119
|
-
repo_dir = self._repo_dirs[repo] = DeployGitManager.RepoDir(
|
123
|
+
repo_dir = self._repo_dirs[repo] = DeployGitManager.RepoDir(
|
124
|
+
self,
|
125
|
+
repo,
|
126
|
+
home,
|
127
|
+
)
|
120
128
|
return repo_dir
|
121
129
|
|
122
130
|
async def checkout(
|
123
131
|
self,
|
124
132
|
spec: DeployGitSpec,
|
133
|
+
home: DeployHome,
|
125
134
|
dst_dir: str,
|
126
135
|
) -> None:
|
127
|
-
await self.get_repo_dir(
|
136
|
+
await self.get_repo_dir(
|
137
|
+
spec.repo,
|
138
|
+
home,
|
139
|
+
).checkout(
|
140
|
+
spec,
|
141
|
+
dst_dir,
|
142
|
+
)
|
ominfra/manage/deploy/inject.py
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
import os.path
|
3
2
|
import typing as ta
|
4
3
|
|
5
4
|
from omlish.lite.inject import InjectorBindingOrBindings
|
6
5
|
from omlish.lite.inject import InjectorBindings
|
7
6
|
from omlish.lite.inject import inj
|
8
|
-
from omlish.os.atomics import AtomicPathSwapping
|
9
7
|
|
10
8
|
from ..commands.inject import bind_command
|
11
9
|
from .apps import DeployAppManager
|
@@ -19,8 +17,8 @@ from .interp import InterpCommand
|
|
19
17
|
from .interp import InterpCommandExecutor
|
20
18
|
from .paths.inject import bind_deploy_paths
|
21
19
|
from .paths.owners import DeployPathOwner
|
20
|
+
from .tmp import DeployHomeAtomics
|
22
21
|
from .tmp import DeployTmpManager
|
23
|
-
from .types import DeployHome
|
24
22
|
from .venvs import DeployVenvManager
|
25
23
|
|
26
24
|
|
@@ -55,13 +53,18 @@ def bind_deploy(
|
|
55
53
|
bind_manager(DeployManager),
|
56
54
|
|
57
55
|
bind_manager(DeployTmpManager),
|
58
|
-
inj.bind(AtomicPathSwapping, to_key=DeployTmpManager),
|
59
56
|
|
60
57
|
bind_manager(DeployVenvManager),
|
61
58
|
])
|
62
59
|
|
63
60
|
#
|
64
61
|
|
62
|
+
def provide_deploy_home_atomics(tmp: DeployTmpManager) -> DeployHomeAtomics:
|
63
|
+
return DeployHomeAtomics(tmp.get_swapping)
|
64
|
+
lst.append(inj.bind(provide_deploy_home_atomics, singleton=True))
|
65
|
+
|
66
|
+
#
|
67
|
+
|
65
68
|
lst.extend([
|
66
69
|
bind_command(DeployCommand, DeployCommandExecutor),
|
67
70
|
bind_command(InterpCommand, InterpCommandExecutor),
|
@@ -69,8 +72,4 @@ def bind_deploy(
|
|
69
72
|
|
70
73
|
#
|
71
74
|
|
72
|
-
if (dh := deploy_config.deploy_home) is not None:
|
73
|
-
dh = os.path.abspath(os.path.expanduser(dh))
|
74
|
-
lst.append(inj.bind(dh, key=DeployHome))
|
75
|
-
|
76
75
|
return inj.as_bindings(*lst)
|
@@ -3,7 +3,6 @@ import typing as ta
|
|
3
3
|
|
4
4
|
from omlish.lite.cached import cached_nullary
|
5
5
|
|
6
|
-
from ..types import DeployHome
|
7
6
|
from .owners import DeployPathOwner
|
8
7
|
from .owners import DeployPathOwners
|
9
8
|
from .paths import DeployPath
|
@@ -14,12 +13,10 @@ class DeployPathsManager:
|
|
14
13
|
def __init__(
|
15
14
|
self,
|
16
15
|
*,
|
17
|
-
deploy_home: ta.Optional[DeployHome],
|
18
16
|
deploy_path_owners: DeployPathOwners,
|
19
17
|
) -> None:
|
20
18
|
super().__init__()
|
21
19
|
|
22
|
-
self._deploy_home = deploy_home
|
23
20
|
self._deploy_path_owners = deploy_path_owners
|
24
21
|
|
25
22
|
@cached_nullary
|
@@ -3,7 +3,6 @@ import abc
|
|
3
3
|
import os.path
|
4
4
|
import typing as ta
|
5
5
|
|
6
|
-
from omlish.lite.cached import cached_nullary
|
7
6
|
from omlish.lite.check import check
|
8
7
|
|
9
8
|
from ..types import DeployHome
|
@@ -24,7 +23,6 @@ class SingleDirDeployPathOwner(DeployPathOwner, abc.ABC):
|
|
24
23
|
self,
|
25
24
|
*args: ta.Any,
|
26
25
|
owned_dir: str,
|
27
|
-
deploy_home: ta.Optional[DeployHome],
|
28
26
|
**kwargs: ta.Any,
|
29
27
|
) -> None:
|
30
28
|
super().__init__(*args, **kwargs)
|
@@ -32,17 +30,13 @@ class SingleDirDeployPathOwner(DeployPathOwner, abc.ABC):
|
|
32
30
|
check.not_in('/', owned_dir)
|
33
31
|
self._owned_dir: str = check.non_empty_str(owned_dir)
|
34
32
|
|
35
|
-
self._deploy_home = deploy_home
|
36
|
-
|
37
33
|
self._owned_deploy_paths = frozenset([DeployPath.parse(self._owned_dir + '/')])
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
return os.path.join(check.non_empty_str(self._deploy_home), self._owned_dir)
|
35
|
+
def _dir(self, home: DeployHome) -> str:
|
36
|
+
return os.path.join(check.non_empty_str(home), self._owned_dir)
|
42
37
|
|
43
|
-
|
44
|
-
|
45
|
-
if not os.path.isdir(d := self._dir()):
|
38
|
+
def _make_dir(self, home: DeployHome) -> str:
|
39
|
+
if not os.path.isdir(d := self._dir(home)):
|
46
40
|
os.makedirs(d, exist_ok=True)
|
47
41
|
return d
|
48
42
|
|
ominfra/manage/deploy/specs.py
CHANGED
@@ -11,6 +11,7 @@ from .tags import DeployApp
|
|
11
11
|
from .tags import DeployAppKey
|
12
12
|
from .tags import DeployKey
|
13
13
|
from .tags import KeyDeployTag # noqa
|
14
|
+
from .types import DeployHome
|
14
15
|
from .types import DeployRev
|
15
16
|
|
16
17
|
|
@@ -153,9 +154,13 @@ class DeployAppSpec(DeploySpecKeyed[DeployAppKey]):
|
|
153
154
|
|
154
155
|
@dc.dataclass(frozen=True)
|
155
156
|
class DeploySpec(DeploySpecKeyed[DeployKey]):
|
157
|
+
home: DeployHome
|
158
|
+
|
156
159
|
apps: ta.Sequence[DeployAppSpec]
|
157
160
|
|
158
161
|
def __post_init__(self) -> None:
|
162
|
+
check.non_empty_str(self.home)
|
163
|
+
|
159
164
|
seen: ta.Set[DeployApp] = set()
|
160
165
|
for a in self.apps:
|
161
166
|
if a.app in seen:
|
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/tmp.py
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
import typing as ta
|
3
|
-
|
4
|
-
from omlish.lite.cached import cached_nullary
|
5
2
|
from omlish.lite.check import check
|
6
|
-
from omlish.
|
7
|
-
from omlish.os.atomics import AtomicPathSwapKind
|
3
|
+
from omlish.lite.typing import Func1
|
8
4
|
from omlish.os.atomics import AtomicPathSwapping
|
9
5
|
from omlish.os.atomics import TempDirAtomicPathSwapping
|
10
6
|
|
@@ -12,35 +8,20 @@ from .paths.owners import SingleDirDeployPathOwner
|
|
12
8
|
from .types import DeployHome
|
13
9
|
|
14
10
|
|
11
|
+
class DeployHomeAtomics(Func1[DeployHome, AtomicPathSwapping]):
|
12
|
+
pass
|
13
|
+
|
14
|
+
|
15
15
|
class DeployTmpManager(
|
16
16
|
SingleDirDeployPathOwner,
|
17
|
-
AtomicPathSwapping,
|
18
17
|
):
|
19
|
-
def __init__(
|
20
|
-
self,
|
21
|
-
*,
|
22
|
-
deploy_home: ta.Optional[DeployHome] = None,
|
23
|
-
) -> None:
|
18
|
+
def __init__(self) -> None:
|
24
19
|
super().__init__(
|
25
20
|
owned_dir='tmp',
|
26
|
-
deploy_home=deploy_home,
|
27
21
|
)
|
28
22
|
|
29
|
-
|
30
|
-
def _swapping(self) -> AtomicPathSwapping:
|
23
|
+
def get_swapping(self, home: DeployHome) -> AtomicPathSwapping:
|
31
24
|
return TempDirAtomicPathSwapping(
|
32
|
-
temp_dir=self._make_dir(),
|
33
|
-
root_dir=check.non_empty_str(
|
34
|
-
)
|
35
|
-
|
36
|
-
def begin_atomic_path_swap(
|
37
|
-
self,
|
38
|
-
kind: AtomicPathSwapKind,
|
39
|
-
dst_path: str,
|
40
|
-
**kwargs: ta.Any,
|
41
|
-
) -> AtomicPathSwap:
|
42
|
-
return self._swapping().begin_atomic_path_swap(
|
43
|
-
kind,
|
44
|
-
dst_path,
|
45
|
-
**kwargs,
|
25
|
+
temp_dir=self._make_dir(home),
|
26
|
+
root_dir=check.non_empty_str(home),
|
46
27
|
)
|
ominfra/manage/deploy/venvs.py
CHANGED
@@ -6,29 +6,31 @@ 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
|
10
|
-
from omlish.
|
12
|
+
from omlish.lite.check import check
|
11
13
|
|
12
14
|
from .specs import DeployVenvSpec
|
15
|
+
from .types import DeployHome
|
13
16
|
|
14
17
|
|
15
18
|
class DeployVenvManager:
|
16
|
-
def __init__(
|
17
|
-
self,
|
18
|
-
*,
|
19
|
-
atomics: AtomicPathSwapping,
|
20
|
-
) -> None:
|
21
|
-
super().__init__()
|
22
|
-
|
23
|
-
self._atomics = atomics
|
24
|
-
|
25
19
|
async def setup_venv(
|
26
20
|
self,
|
27
21
|
spec: DeployVenvSpec,
|
22
|
+
home: DeployHome,
|
28
23
|
git_dir: str,
|
29
24
|
venv_dir: str,
|
30
25
|
) -> None:
|
31
|
-
|
26
|
+
if spec.interp is not None:
|
27
|
+
i = InterpSpecifier.parse(check.not_none(spec.interp))
|
28
|
+
o = check.not_none(await DEFAULT_INTERP_RESOLVER.resolve(i))
|
29
|
+
sys_exe = o.exe
|
30
|
+
else:
|
31
|
+
sys_exe = 'python3'
|
32
|
+
|
33
|
+
#
|
32
34
|
|
33
35
|
# !! NOTE: (most) venvs cannot be relocated, so an atomic swap can't be used. it's up to the path manager to
|
34
36
|
# garbage collect orphaned dirs.
|
ominfra/manage/main.py
CHANGED
@@ -66,10 +66,9 @@ class MainCli(ArgparseCli):
|
|
66
66
|
|
67
67
|
argparse_arg('--debug', action='store_true'),
|
68
68
|
|
69
|
-
argparse_arg('--deploy-home'),
|
70
|
-
|
71
69
|
argparse_arg('target'),
|
72
|
-
argparse_arg('command',
|
70
|
+
argparse_arg('-f', '--command-file', action='append'),
|
71
|
+
argparse_arg('command', nargs='*'),
|
73
72
|
)
|
74
73
|
async def run(self) -> None:
|
75
74
|
bs = MainBootstrap(
|
@@ -79,9 +78,7 @@ class MainCli(ArgparseCli):
|
|
79
78
|
debug=bool(self.args.debug),
|
80
79
|
),
|
81
80
|
|
82
|
-
deploy_config=DeployConfig(
|
83
|
-
deploy_home=self.args.deploy_home,
|
84
|
-
),
|
81
|
+
deploy_config=DeployConfig(),
|
85
82
|
|
86
83
|
remote_config=RemoteConfig(
|
87
84
|
payload_file=self.args._payload_file, # noqa
|
@@ -115,13 +112,19 @@ class MainCli(ArgparseCli):
|
|
115
112
|
#
|
116
113
|
|
117
114
|
cmds: ta.List[Command] = []
|
115
|
+
|
118
116
|
cmd: Command
|
119
|
-
|
117
|
+
|
118
|
+
for c in self.args.command or []:
|
120
119
|
if not c.startswith('{'):
|
121
120
|
c = json.dumps({c: {}})
|
122
121
|
cmd = msh.unmarshal_obj(json.loads(c), Command)
|
123
122
|
cmds.append(cmd)
|
124
123
|
|
124
|
+
for cf in self.args.command_file or []:
|
125
|
+
cmd = read_config_file(cf, Command, msh=msh)
|
126
|
+
cmds.append(cmd)
|
127
|
+
|
125
128
|
#
|
126
129
|
|
127
130
|
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(
|