ominfra 0.0.0.dev154__py3-none-any.whl → 0.0.0.dev155__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. ominfra/manage/bootstrap.py +4 -0
  2. ominfra/manage/bootstrap_.py +5 -0
  3. ominfra/manage/commands/inject.py +8 -11
  4. ominfra/manage/commands/{execution.py → local.py} +1 -5
  5. ominfra/manage/commands/ping.py +23 -0
  6. ominfra/manage/commands/types.py +8 -0
  7. ominfra/manage/deploy/apps.py +72 -0
  8. ominfra/manage/deploy/config.py +8 -0
  9. ominfra/manage/deploy/git.py +136 -0
  10. ominfra/manage/deploy/inject.py +21 -0
  11. ominfra/manage/deploy/paths.py +81 -28
  12. ominfra/manage/deploy/types.py +13 -0
  13. ominfra/manage/deploy/venvs.py +66 -0
  14. ominfra/manage/inject.py +20 -4
  15. ominfra/manage/main.py +15 -27
  16. ominfra/manage/remote/_main.py +1 -1
  17. ominfra/manage/remote/config.py +0 -2
  18. ominfra/manage/remote/connection.py +7 -24
  19. ominfra/manage/remote/execution.py +1 -1
  20. ominfra/manage/remote/inject.py +3 -14
  21. ominfra/manage/system/commands.py +22 -2
  22. ominfra/manage/system/config.py +3 -1
  23. ominfra/manage/system/inject.py +16 -6
  24. ominfra/manage/system/packages.py +33 -7
  25. ominfra/manage/system/platforms.py +72 -0
  26. ominfra/manage/targets/__init__.py +0 -0
  27. ominfra/manage/targets/connection.py +150 -0
  28. ominfra/manage/targets/inject.py +42 -0
  29. ominfra/manage/targets/targets.py +87 -0
  30. ominfra/scripts/journald2aws.py +24 -7
  31. ominfra/scripts/manage.py +1880 -438
  32. ominfra/scripts/supervisor.py +187 -25
  33. ominfra/supervisor/configs.py +163 -18
  34. {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/METADATA +3 -3
  35. {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/RECORD +40 -29
  36. ominfra/manage/system/types.py +0 -5
  37. /ominfra/manage/{commands → deploy}/interp.py +0 -0
  38. {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/LICENSE +0 -0
  39. {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/WHEEL +0 -0
  40. {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/entry_points.txt +0 -0
  41. {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,150 @@
1
+ # ruff: noqa: UP006 UP007
2
+ import abc
3
+ import contextlib
4
+ import dataclasses as dc
5
+ import typing as ta
6
+
7
+ from omlish.lite.check import check
8
+
9
+ from ..bootstrap import MainBootstrap
10
+ from ..commands.base import CommandExecutor
11
+ from ..commands.local import LocalCommandExecutor
12
+ from ..remote.connection import InProcessRemoteExecutionConnector
13
+ from ..remote.connection import PyremoteRemoteExecutionConnector
14
+ from ..remote.spawning import RemoteSpawning
15
+ from .targets import DockerManageTarget
16
+ from .targets import InProcessManageTarget
17
+ from .targets import LocalManageTarget
18
+ from .targets import ManageTarget
19
+ from .targets import SshManageTarget
20
+ from .targets import SubprocessManageTarget
21
+
22
+
23
+ ##
24
+
25
+
26
+ class ManageTargetConnector(abc.ABC):
27
+ @abc.abstractmethod
28
+ def connect(self, tgt: ManageTarget) -> ta.AsyncContextManager[CommandExecutor]:
29
+ raise NotImplementedError
30
+
31
+
32
+ ##
33
+
34
+
35
+ ManageTargetConnectorMap = ta.NewType('ManageTargetConnectorMap', ta.Mapping[ta.Type[ManageTarget], ManageTargetConnector]) # noqa
36
+
37
+
38
+ @dc.dataclass(frozen=True)
39
+ class TypeSwitchedManageTargetConnector(ManageTargetConnector):
40
+ connectors: ManageTargetConnectorMap
41
+
42
+ def get_connector(self, ty: ta.Type[ManageTarget]) -> ManageTargetConnector:
43
+ for k, v in self.connectors.items():
44
+ if issubclass(ty, k):
45
+ return v
46
+ raise KeyError(ty)
47
+
48
+ def connect(self, tgt: ManageTarget) -> ta.AsyncContextManager[CommandExecutor]:
49
+ return self.get_connector(type(tgt)).connect(tgt)
50
+
51
+
52
+ ##
53
+
54
+
55
+ @dc.dataclass(frozen=True)
56
+ class LocalManageTargetConnector(ManageTargetConnector):
57
+ _local_executor: LocalCommandExecutor
58
+ _in_process_connector: InProcessRemoteExecutionConnector
59
+ _pyremote_connector: PyremoteRemoteExecutionConnector
60
+ _bootstrap: MainBootstrap
61
+
62
+ @contextlib.asynccontextmanager
63
+ async def connect(self, tgt: ManageTarget) -> ta.AsyncGenerator[CommandExecutor, None]:
64
+ lmt = check.isinstance(tgt, LocalManageTarget)
65
+
66
+ if isinstance(lmt, InProcessManageTarget):
67
+ imt = check.isinstance(lmt, InProcessManageTarget)
68
+
69
+ if imt.mode == InProcessManageTarget.Mode.DIRECT:
70
+ yield self._local_executor
71
+
72
+ elif imt.mode == InProcessManageTarget.Mode.FAKE_REMOTE:
73
+ async with self._in_process_connector.connect() as rce:
74
+ yield rce
75
+
76
+ else:
77
+ raise TypeError(imt.mode)
78
+
79
+ elif isinstance(lmt, SubprocessManageTarget):
80
+ async with self._pyremote_connector.connect(
81
+ RemoteSpawning.Target(
82
+ python=lmt.python,
83
+ ),
84
+ self._bootstrap,
85
+ ) as rce:
86
+ yield rce
87
+
88
+ else:
89
+ raise TypeError(lmt)
90
+
91
+
92
+ ##
93
+
94
+
95
+ @dc.dataclass(frozen=True)
96
+ class DockerManageTargetConnector(ManageTargetConnector):
97
+ _pyremote_connector: PyremoteRemoteExecutionConnector
98
+ _bootstrap: MainBootstrap
99
+
100
+ @contextlib.asynccontextmanager
101
+ async def connect(self, tgt: ManageTarget) -> ta.AsyncGenerator[CommandExecutor, None]:
102
+ dmt = check.isinstance(tgt, DockerManageTarget)
103
+
104
+ sh_parts: ta.List[str] = ['docker']
105
+ if dmt.image is not None:
106
+ sh_parts.extend(['run', '-i', dmt.image])
107
+ elif dmt.container_id is not None:
108
+ sh_parts.extend(['exec', dmt.container_id])
109
+ else:
110
+ raise ValueError(dmt)
111
+
112
+ async with self._pyremote_connector.connect(
113
+ RemoteSpawning.Target(
114
+ shell=' '.join(sh_parts),
115
+ python=dmt.python,
116
+ ),
117
+ self._bootstrap,
118
+ ) as rce:
119
+ yield rce
120
+
121
+
122
+ ##
123
+
124
+
125
+ @dc.dataclass(frozen=True)
126
+ class SshManageTargetConnector(ManageTargetConnector):
127
+ _pyremote_connector: PyremoteRemoteExecutionConnector
128
+ _bootstrap: MainBootstrap
129
+
130
+ @contextlib.asynccontextmanager
131
+ async def connect(self, tgt: ManageTarget) -> ta.AsyncGenerator[CommandExecutor, None]:
132
+ smt = check.isinstance(tgt, SshManageTarget)
133
+
134
+ sh_parts: ta.List[str] = ['ssh']
135
+ if smt.key_file is not None:
136
+ sh_parts.extend(['-i', smt.key_file])
137
+ addr = check.not_none(smt.host)
138
+ if smt.username is not None:
139
+ addr = f'{smt.username}@{addr}'
140
+ sh_parts.append(addr)
141
+
142
+ async with self._pyremote_connector.connect(
143
+ RemoteSpawning.Target(
144
+ shell=' '.join(sh_parts),
145
+ shell_quote=True,
146
+ python=smt.python,
147
+ ),
148
+ self._bootstrap,
149
+ ) as rce:
150
+ yield rce
@@ -0,0 +1,42 @@
1
+ # ruff: noqa: UP006 UP007
2
+ import typing as ta
3
+
4
+ from omlish.lite.inject import Injector
5
+ from omlish.lite.inject import InjectorBindingOrBindings
6
+ from omlish.lite.inject import InjectorBindings
7
+ from omlish.lite.inject import inj
8
+
9
+ from .connection import DockerManageTargetConnector
10
+ from .connection import LocalManageTargetConnector
11
+ from .connection import ManageTargetConnector
12
+ from .connection import ManageTargetConnectorMap
13
+ from .connection import SshManageTargetConnector
14
+ from .connection import TypeSwitchedManageTargetConnector
15
+ from .targets import DockerManageTarget
16
+ from .targets import LocalManageTarget
17
+ from .targets import SshManageTarget
18
+
19
+
20
+ def bind_targets() -> InjectorBindings:
21
+ lst: ta.List[InjectorBindingOrBindings] = [
22
+ inj.bind(LocalManageTargetConnector, singleton=True),
23
+ inj.bind(DockerManageTargetConnector, singleton=True),
24
+ inj.bind(SshManageTargetConnector, singleton=True),
25
+
26
+ inj.bind(TypeSwitchedManageTargetConnector, singleton=True),
27
+ inj.bind(ManageTargetConnector, to_key=TypeSwitchedManageTargetConnector),
28
+ ]
29
+
30
+ #
31
+
32
+ def provide_manage_target_connector_map(injector: Injector) -> ManageTargetConnectorMap:
33
+ return ManageTargetConnectorMap({
34
+ LocalManageTarget: injector[LocalManageTargetConnector],
35
+ DockerManageTarget: injector[DockerManageTargetConnector],
36
+ SshManageTarget: injector[SshManageTargetConnector],
37
+ })
38
+ lst.append(inj.bind(provide_manage_target_connector_map, singleton=True))
39
+
40
+ #
41
+
42
+ return inj.as_bindings(*lst)
@@ -0,0 +1,87 @@
1
+ # ruff: noqa: UP006 UP007
2
+ """
3
+ It's desugaring. Subprocess and locals are only leafs. Retain an origin?
4
+ ** TWO LAYERS ** - ManageTarget is user-facing, ConnectorTarget is bound, internal
5
+ """
6
+ import abc
7
+ import dataclasses as dc
8
+ import enum
9
+ import typing as ta
10
+
11
+ from omlish.lite.check import check
12
+
13
+
14
+ ##
15
+
16
+
17
+ class ManageTarget(abc.ABC): # noqa
18
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
19
+ super().__init_subclass__(**kwargs)
20
+
21
+ check.state(cls.__name__.endswith('ManageTarget'))
22
+
23
+
24
+ #
25
+
26
+
27
+ @dc.dataclass(frozen=True)
28
+ class PythonRemoteManageTarget:
29
+ DEFAULT_PYTHON: ta.ClassVar[str] = 'python3'
30
+ python: str = DEFAULT_PYTHON
31
+
32
+
33
+ #
34
+
35
+
36
+ class RemoteManageTarget(ManageTarget, abc.ABC):
37
+ pass
38
+
39
+
40
+ class PhysicallyRemoteManageTarget(RemoteManageTarget, abc.ABC):
41
+ pass
42
+
43
+
44
+ class LocalManageTarget(ManageTarget, abc.ABC):
45
+ pass
46
+
47
+
48
+ ##
49
+
50
+
51
+ @dc.dataclass(frozen=True)
52
+ class SshManageTarget(PhysicallyRemoteManageTarget, PythonRemoteManageTarget):
53
+ host: ta.Optional[str] = None
54
+ username: ta.Optional[str] = None
55
+ key_file: ta.Optional[str] = None
56
+
57
+ def __post_init__(self) -> None:
58
+ check.non_empty_str(self.host)
59
+
60
+
61
+ ##
62
+
63
+
64
+ @dc.dataclass(frozen=True)
65
+ class DockerManageTarget(RemoteManageTarget, PythonRemoteManageTarget): # noqa
66
+ image: ta.Optional[str] = None
67
+ container_id: ta.Optional[str] = None
68
+
69
+ def __post_init__(self) -> None:
70
+ check.arg(bool(self.image) ^ bool(self.container_id))
71
+
72
+
73
+ ##
74
+
75
+
76
+ @dc.dataclass(frozen=True)
77
+ class InProcessManageTarget(LocalManageTarget):
78
+ class Mode(enum.Enum):
79
+ DIRECT = enum.auto()
80
+ FAKE_REMOTE = enum.auto()
81
+
82
+ mode: Mode = Mode.DIRECT
83
+
84
+
85
+ @dc.dataclass(frozen=True)
86
+ class SubprocessManageTarget(LocalManageTarget, PythonRemoteManageTarget):
87
+ pass
@@ -961,8 +961,6 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
961
961
  """
962
962
  TODO:
963
963
  - def maybe(v: lang.Maybe[T])
964
- - patch / override lite.check ?
965
- - checker interface?
966
964
  """
967
965
 
968
966
 
@@ -2270,6 +2268,20 @@ def attr_setting(obj, attr, val, *, default=None): # noqa
2270
2268
  setattr(obj, attr, orig)
2271
2269
 
2272
2270
 
2271
+ ##
2272
+
2273
+
2274
+ class aclosing(contextlib.AbstractAsyncContextManager): # noqa
2275
+ def __init__(self, thing):
2276
+ self.thing = thing
2277
+
2278
+ async def __aenter__(self):
2279
+ return self.thing
2280
+
2281
+ async def __aexit__(self, *exc_info):
2282
+ await self.thing.aclose()
2283
+
2284
+
2273
2285
  ########################################
2274
2286
  # ../../../../../omlish/lite/logs.py
2275
2287
  """
@@ -2545,7 +2557,8 @@ def configure_standard_logging(
2545
2557
  """
2546
2558
  TODO:
2547
2559
  - pickle stdlib objs? have to pin to 3.8 pickle protocol, will be cross-version
2548
- - nonstrict toggle
2560
+ - namedtuple
2561
+ - literals
2549
2562
  """
2550
2563
 
2551
2564
 
@@ -2835,14 +2848,18 @@ class ObjMarshalerManager:
2835
2848
  ) -> ObjMarshaler:
2836
2849
  if isinstance(ty, type):
2837
2850
  if abc.ABC in ty.__bases__:
2838
- return PolymorphicObjMarshaler.of([ # type: ignore
2851
+ impls = [ity for ity in deep_subclasses(ty) if abc.ABC not in ity.__bases__] # type: ignore
2852
+ if all(ity.__qualname__.endswith(ty.__name__) for ity in impls):
2853
+ ins = {ity: snake_case(ity.__qualname__[:-len(ty.__name__)]) for ity in impls}
2854
+ else:
2855
+ ins = {ity: ity.__qualname__ for ity in impls}
2856
+ return PolymorphicObjMarshaler.of([
2839
2857
  PolymorphicObjMarshaler.Impl(
2840
2858
  ity,
2841
- ity.__qualname__,
2859
+ itn,
2842
2860
  rec(ity),
2843
2861
  )
2844
- for ity in deep_subclasses(ty)
2845
- if abc.ABC not in ity.__bases__
2862
+ for ity, itn in ins.items()
2846
2863
  ])
2847
2864
 
2848
2865
  if issubclass(ty, enum.Enum):