ominfra 0.0.0.dev125__tar.gz → 0.0.0.dev126__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {ominfra-0.0.0.dev125/ominfra.egg-info → ominfra-0.0.0.dev126}/PKG-INFO +3 -3
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/scripts/supervisor.py +74 -44
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/dispatchers.py +12 -24
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/groups.py +3 -2
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/inject.py +7 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/process.py +25 -9
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/supervisor.py +3 -2
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/types.py +39 -12
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126/ominfra.egg-info}/PKG-INFO +3 -3
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra.egg-info/requires.txt +2 -2
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/pyproject.toml +3 -3
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/LICENSE +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/MANIFEST.in +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/README.rst +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/.manifests.json +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/__about__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/__main__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/auth.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/cli.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/dataclasses.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/journald2aws/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/journald2aws/__main__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/journald2aws/cursor.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/journald2aws/driver.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/journald2aws/main.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/journald2aws/poster.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/logs.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/aws/metadata.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/gcp/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/clouds/gcp/auth.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/cmds.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/configs.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/_executor.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/configs.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/base.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/concerns/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/concerns/dirs.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/concerns/nginx.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/concerns/repo.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/concerns/supervisor.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/concerns/systemd.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/concerns/user.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/concerns/venv.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/main.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/_main.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/base.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/configs.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/deploy.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/main.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/nginx.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/repo.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/runtime.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/site.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/supervisor.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/poly/venv.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/remote.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/journald/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/journald/fields.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/journald/genmessages.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/journald/messages.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/journald/tailer.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/manage/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/manage/manage.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/pyremote/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/pyremote/_runcommands.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/pyremote/bootstrap.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/pyremote/runcommands.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/scripts/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/scripts/journald2aws.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/ssh.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/LICENSE.txt +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/__main__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/configs.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/context.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/datatypes.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/events.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/exceptions.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/main.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/poller.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/signals.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/states.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/supervisor/utils.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/tailscale/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/tailscale/api.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/tailscale/cli.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/threadworkers.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/tools/__init__.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/tools/listresources.py +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra.egg-info/SOURCES.txt +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra.egg-info/dependency_links.txt +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra.egg-info/entry_points.txt +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra.egg-info/top_level.txt +0 -0
- {ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ominfra
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev126
|
4
4
|
Summary: ominfra
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -12,8 +12,8 @@ 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: omdev==0.0.0.
|
16
|
-
Requires-Dist: omlish==0.0.0.
|
15
|
+
Requires-Dist: omdev==0.0.0.dev126
|
16
|
+
Requires-Dist: omlish==0.0.0.dev126
|
17
17
|
Provides-Extra: all
|
18
18
|
Requires-Dist: paramiko~=3.5; extra == "all"
|
19
19
|
Requires-Dist: asyncssh~=2.18; extra == "all"
|
@@ -4898,16 +4898,43 @@ class ServerContext(abc.ABC):
|
|
4898
4898
|
raise NotImplementedError
|
4899
4899
|
|
4900
4900
|
|
4901
|
-
|
4902
|
-
|
4903
|
-
|
4904
|
-
|
4905
|
-
|
4906
|
-
|
4907
|
-
|
4908
|
-
|
4909
|
-
|
4910
|
-
|
4901
|
+
class Dispatcher(abc.ABC):
|
4902
|
+
@abc.abstractmethod
|
4903
|
+
def readable(self) -> bool:
|
4904
|
+
raise NotImplementedError
|
4905
|
+
|
4906
|
+
@abc.abstractmethod
|
4907
|
+
def writable(self) -> bool:
|
4908
|
+
raise NotImplementedError
|
4909
|
+
|
4910
|
+
def handle_read_event(self) -> None:
|
4911
|
+
raise TypeError
|
4912
|
+
|
4913
|
+
def handle_write_event(self) -> None:
|
4914
|
+
raise TypeError
|
4915
|
+
|
4916
|
+
@abc.abstractmethod
|
4917
|
+
def handle_error(self) -> None:
|
4918
|
+
raise NotImplementedError
|
4919
|
+
|
4920
|
+
@property
|
4921
|
+
@abc.abstractmethod
|
4922
|
+
def closed(self) -> bool:
|
4923
|
+
raise NotImplementedError
|
4924
|
+
|
4925
|
+
|
4926
|
+
class OutputDispatcher(Dispatcher, abc.ABC):
|
4927
|
+
pass
|
4928
|
+
|
4929
|
+
|
4930
|
+
class InputDispatcher(Dispatcher, abc.ABC):
|
4931
|
+
@abc.abstractmethod
|
4932
|
+
def write(self, chars: ta.Union[bytes, str]) -> None:
|
4933
|
+
raise NotImplementedError
|
4934
|
+
|
4935
|
+
@abc.abstractmethod
|
4936
|
+
def flush(self) -> None:
|
4937
|
+
raise NotImplementedError
|
4911
4938
|
|
4912
4939
|
|
4913
4940
|
@functools.total_ordering
|
@@ -4966,7 +4993,7 @@ class Process(abc.ABC):
|
|
4966
4993
|
raise NotImplementedError
|
4967
4994
|
|
4968
4995
|
@abc.abstractmethod
|
4969
|
-
def get_dispatchers(self) -> ta.Mapping[int,
|
4996
|
+
def get_dispatchers(self) -> ta.Mapping[int, Dispatcher]:
|
4970
4997
|
raise NotImplementedError
|
4971
4998
|
|
4972
4999
|
|
@@ -5001,7 +5028,7 @@ class ProcessGroup(abc.ABC):
|
|
5001
5028
|
raise NotImplementedError
|
5002
5029
|
|
5003
5030
|
@abc.abstractmethod
|
5004
|
-
def get_dispatchers(self) -> ta.Mapping[int,
|
5031
|
+
def get_dispatchers(self) -> ta.Mapping[int, Dispatcher]:
|
5005
5032
|
raise NotImplementedError
|
5006
5033
|
|
5007
5034
|
@abc.abstractmethod
|
@@ -5415,7 +5442,7 @@ def check_execv_args(filename, argv, st) -> None:
|
|
5415
5442
|
# ../dispatchers.py
|
5416
5443
|
|
5417
5444
|
|
5418
|
-
class Dispatcher
|
5445
|
+
class BaseDispatcherImpl(Dispatcher, abc.ABC):
|
5419
5446
|
def __init__(
|
5420
5447
|
self,
|
5421
5448
|
process: Process,
|
@@ -5452,20 +5479,6 @@ class Dispatcher(abc.ABC):
|
|
5452
5479
|
def closed(self) -> bool:
|
5453
5480
|
return self._closed
|
5454
5481
|
|
5455
|
-
@abc.abstractmethod
|
5456
|
-
def readable(self) -> bool:
|
5457
|
-
raise NotImplementedError
|
5458
|
-
|
5459
|
-
@abc.abstractmethod
|
5460
|
-
def writable(self) -> bool:
|
5461
|
-
raise NotImplementedError
|
5462
|
-
|
5463
|
-
def handle_read_event(self) -> None:
|
5464
|
-
raise TypeError
|
5465
|
-
|
5466
|
-
def handle_write_event(self) -> None:
|
5467
|
-
raise TypeError
|
5468
|
-
|
5469
5482
|
def handle_error(self) -> None:
|
5470
5483
|
nil, t, v, tbinfo = compact_traceback()
|
5471
5484
|
|
@@ -5477,11 +5490,8 @@ class Dispatcher(abc.ABC):
|
|
5477
5490
|
log.debug('fd %s closed, stopped monitoring %s', self._fd, self)
|
5478
5491
|
self._closed = True
|
5479
5492
|
|
5480
|
-
def flush(self) -> None: # noqa
|
5481
|
-
pass
|
5482
|
-
|
5483
5493
|
|
5484
|
-
class OutputDispatcher
|
5494
|
+
class OutputDispatcherImpl(BaseDispatcherImpl, OutputDispatcher):
|
5485
5495
|
"""
|
5486
5496
|
Dispatcher for one channel (stdout or stderr) of one process. Serves several purposes:
|
5487
5497
|
|
@@ -5495,13 +5505,14 @@ class OutputDispatcher(Dispatcher):
|
|
5495
5505
|
process: Process,
|
5496
5506
|
event_type: ta.Type[ProcessCommunicationEvent],
|
5497
5507
|
fd: int,
|
5498
|
-
|
5508
|
+
*,
|
5509
|
+
event_callbacks: EventCallbacks,
|
5499
5510
|
) -> None:
|
5500
5511
|
super().__init__(
|
5501
5512
|
process,
|
5502
5513
|
event_type.channel,
|
5503
5514
|
fd,
|
5504
|
-
|
5515
|
+
event_callbacks=event_callbacks,
|
5505
5516
|
)
|
5506
5517
|
|
5507
5518
|
self._event_type = event_type
|
@@ -5698,19 +5709,20 @@ class OutputDispatcher(Dispatcher):
|
|
5698
5709
|
self.close()
|
5699
5710
|
|
5700
5711
|
|
5701
|
-
class InputDispatcher
|
5712
|
+
class InputDispatcherImpl(BaseDispatcherImpl, InputDispatcher):
|
5702
5713
|
def __init__(
|
5703
5714
|
self,
|
5704
5715
|
process: Process,
|
5705
5716
|
channel: str,
|
5706
5717
|
fd: int,
|
5707
|
-
|
5718
|
+
*,
|
5719
|
+
event_callbacks: EventCallbacks,
|
5708
5720
|
) -> None:
|
5709
5721
|
super().__init__(
|
5710
5722
|
process,
|
5711
5723
|
channel,
|
5712
5724
|
fd,
|
5713
|
-
|
5725
|
+
event_callbacks=event_callbacks,
|
5714
5726
|
)
|
5715
5727
|
|
5716
5728
|
self._input_buffer = b''
|
@@ -5769,7 +5781,7 @@ class ProcessGroupImpl(ProcessGroup):
|
|
5769
5781
|
|
5770
5782
|
self._processes = {}
|
5771
5783
|
for pconfig in self._config.processes or []:
|
5772
|
-
process = self._process_factory(pconfig, self)
|
5784
|
+
process = check_isinstance(self._process_factory(pconfig, self), Process)
|
5773
5785
|
self._processes[pconfig.name] = process
|
5774
5786
|
|
5775
5787
|
@property
|
@@ -5893,6 +5905,12 @@ class ProcessGroups:
|
|
5893
5905
|
# ../process.py
|
5894
5906
|
|
5895
5907
|
|
5908
|
+
# (process: Process, event_type: ta.Type[ProcessCommunicationEvent], fd: int)
|
5909
|
+
OutputDispatcherFactory = ta.NewType('OutputDispatcherFactory', Func[OutputDispatcher])
|
5910
|
+
|
5911
|
+
# (process: Process, event_type: ta.Type[ProcessCommunicationEvent], fd: int)
|
5912
|
+
InputDispatcherFactory = ta.NewType('InputDispatcherFactory', Func[InputDispatcher])
|
5913
|
+
|
5896
5914
|
InheritedFds = ta.NewType('InheritedFds', ta.FrozenSet[int])
|
5897
5915
|
|
5898
5916
|
|
@@ -5910,14 +5928,23 @@ class ProcessImpl(Process):
|
|
5910
5928
|
context: ServerContext,
|
5911
5929
|
event_callbacks: EventCallbacks,
|
5912
5930
|
|
5931
|
+
output_dispatcher_factory: OutputDispatcherFactory,
|
5932
|
+
input_dispatcher_factory: InputDispatcherFactory,
|
5933
|
+
|
5913
5934
|
inherited_fds: ta.Optional[InheritedFds] = None,
|
5935
|
+
|
5914
5936
|
) -> None:
|
5915
5937
|
super().__init__()
|
5916
5938
|
|
5917
5939
|
self._config = config
|
5918
5940
|
self._group = group
|
5941
|
+
|
5919
5942
|
self._context = context
|
5920
5943
|
self._event_callbacks = event_callbacks
|
5944
|
+
|
5945
|
+
self._output_dispatcher_factory = output_dispatcher_factory
|
5946
|
+
self._input_dispatcher_factory = input_dispatcher_factory
|
5947
|
+
|
5921
5948
|
self._inherited_fds = InheritedFds(frozenset(inherited_fds or []))
|
5922
5949
|
|
5923
5950
|
self._dispatchers: ta.Dict[int, Dispatcher] = {}
|
@@ -6161,29 +6188,29 @@ class ProcessImpl(Process):
|
|
6161
6188
|
etype: ta.Type[ProcessCommunicationEvent]
|
6162
6189
|
if stdout_fd is not None:
|
6163
6190
|
etype = ProcessCommunicationStdoutEvent
|
6164
|
-
dispatchers[stdout_fd] =
|
6191
|
+
dispatchers[stdout_fd] = check_isinstance(self._output_dispatcher_factory(
|
6165
6192
|
self,
|
6166
6193
|
etype,
|
6167
6194
|
stdout_fd,
|
6168
6195
|
**dispatcher_kw,
|
6169
|
-
)
|
6196
|
+
), OutputDispatcher)
|
6170
6197
|
|
6171
6198
|
if stderr_fd is not None:
|
6172
6199
|
etype = ProcessCommunicationStderrEvent
|
6173
|
-
dispatchers[stderr_fd] =
|
6200
|
+
dispatchers[stderr_fd] = check_isinstance(self._output_dispatcher_factory(
|
6174
6201
|
self,
|
6175
6202
|
etype,
|
6176
6203
|
stderr_fd,
|
6177
6204
|
**dispatcher_kw,
|
6178
|
-
)
|
6205
|
+
), OutputDispatcher)
|
6179
6206
|
|
6180
6207
|
if stdin_fd is not None:
|
6181
|
-
dispatchers[stdin_fd] =
|
6208
|
+
dispatchers[stdin_fd] = check_isinstance(self._input_dispatcher_factory(
|
6182
6209
|
self,
|
6183
6210
|
'stdin',
|
6184
6211
|
stdin_fd,
|
6185
6212
|
**dispatcher_kw,
|
6186
|
-
)
|
6213
|
+
), InputDispatcher)
|
6187
6214
|
|
6188
6215
|
return dispatchers, p
|
6189
6216
|
|
@@ -6715,7 +6742,7 @@ class Supervisor:
|
|
6715
6742
|
if self._process_groups.get(config.name) is not None:
|
6716
6743
|
return False
|
6717
6744
|
|
6718
|
-
group = self._process_group_factory(config)
|
6745
|
+
group = check_isinstance(self._process_group_factory(config), ProcessGroup)
|
6719
6746
|
group.after_setuid()
|
6720
6747
|
|
6721
6748
|
self._process_groups.add(group)
|
@@ -6981,6 +7008,9 @@ def bind_server(
|
|
6981
7008
|
|
6982
7009
|
inj.bind_factory(ProcessGroupFactory, ProcessGroupImpl),
|
6983
7010
|
inj.bind_factory(ProcessFactory, ProcessImpl),
|
7011
|
+
|
7012
|
+
inj.bind_factory(OutputDispatcherFactory, OutputDispatcherImpl),
|
7013
|
+
inj.bind_factory(InputDispatcherFactory, InputDispatcherImpl),
|
6984
7014
|
]
|
6985
7015
|
|
6986
7016
|
#
|
@@ -12,6 +12,9 @@ from .events import EventCallbacks
|
|
12
12
|
from .events import ProcessCommunicationEvent
|
13
13
|
from .events import ProcessLogStderrEvent
|
14
14
|
from .events import ProcessLogStdoutEvent
|
15
|
+
from .types import Dispatcher
|
16
|
+
from .types import InputDispatcher
|
17
|
+
from .types import OutputDispatcher
|
15
18
|
from .types import Process
|
16
19
|
from .utils import as_bytes
|
17
20
|
from .utils import compact_traceback
|
@@ -20,7 +23,7 @@ from .utils import read_fd
|
|
20
23
|
from .utils import strip_escapes
|
21
24
|
|
22
25
|
|
23
|
-
class Dispatcher
|
26
|
+
class BaseDispatcherImpl(Dispatcher, abc.ABC):
|
24
27
|
def __init__(
|
25
28
|
self,
|
26
29
|
process: Process,
|
@@ -57,20 +60,6 @@ class Dispatcher(abc.ABC):
|
|
57
60
|
def closed(self) -> bool:
|
58
61
|
return self._closed
|
59
62
|
|
60
|
-
@abc.abstractmethod
|
61
|
-
def readable(self) -> bool:
|
62
|
-
raise NotImplementedError
|
63
|
-
|
64
|
-
@abc.abstractmethod
|
65
|
-
def writable(self) -> bool:
|
66
|
-
raise NotImplementedError
|
67
|
-
|
68
|
-
def handle_read_event(self) -> None:
|
69
|
-
raise TypeError
|
70
|
-
|
71
|
-
def handle_write_event(self) -> None:
|
72
|
-
raise TypeError
|
73
|
-
|
74
63
|
def handle_error(self) -> None:
|
75
64
|
nil, t, v, tbinfo = compact_traceback()
|
76
65
|
|
@@ -82,11 +71,8 @@ class Dispatcher(abc.ABC):
|
|
82
71
|
log.debug('fd %s closed, stopped monitoring %s', self._fd, self)
|
83
72
|
self._closed = True
|
84
73
|
|
85
|
-
def flush(self) -> None: # noqa
|
86
|
-
pass
|
87
|
-
|
88
74
|
|
89
|
-
class OutputDispatcher
|
75
|
+
class OutputDispatcherImpl(BaseDispatcherImpl, OutputDispatcher):
|
90
76
|
"""
|
91
77
|
Dispatcher for one channel (stdout or stderr) of one process. Serves several purposes:
|
92
78
|
|
@@ -100,13 +86,14 @@ class OutputDispatcher(Dispatcher):
|
|
100
86
|
process: Process,
|
101
87
|
event_type: ta.Type[ProcessCommunicationEvent],
|
102
88
|
fd: int,
|
103
|
-
|
89
|
+
*,
|
90
|
+
event_callbacks: EventCallbacks,
|
104
91
|
) -> None:
|
105
92
|
super().__init__(
|
106
93
|
process,
|
107
94
|
event_type.channel,
|
108
95
|
fd,
|
109
|
-
|
96
|
+
event_callbacks=event_callbacks,
|
110
97
|
)
|
111
98
|
|
112
99
|
self._event_type = event_type
|
@@ -303,19 +290,20 @@ class OutputDispatcher(Dispatcher):
|
|
303
290
|
self.close()
|
304
291
|
|
305
292
|
|
306
|
-
class InputDispatcher
|
293
|
+
class InputDispatcherImpl(BaseDispatcherImpl, InputDispatcher):
|
307
294
|
def __init__(
|
308
295
|
self,
|
309
296
|
process: Process,
|
310
297
|
channel: str,
|
311
298
|
fd: int,
|
312
|
-
|
299
|
+
*,
|
300
|
+
event_callbacks: EventCallbacks,
|
313
301
|
) -> None:
|
314
302
|
super().__init__(
|
315
303
|
process,
|
316
304
|
channel,
|
317
305
|
fd,
|
318
|
-
|
306
|
+
event_callbacks=event_callbacks,
|
319
307
|
)
|
320
308
|
|
321
309
|
self._input_buffer = b''
|
@@ -1,14 +1,15 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
2
|
import typing as ta
|
3
3
|
|
4
|
+
from omlish.lite.check import check_isinstance
|
4
5
|
from omlish.lite.typing import Func
|
5
6
|
|
6
7
|
from .configs import ProcessGroupConfig
|
7
|
-
from .dispatchers import Dispatcher
|
8
8
|
from .events import EventCallbacks
|
9
9
|
from .events import ProcessGroupAddedEvent
|
10
10
|
from .events import ProcessGroupRemovedEvent
|
11
11
|
from .states import ProcessState
|
12
|
+
from .types import Dispatcher
|
12
13
|
from .types import Process
|
13
14
|
from .types import ProcessGroup
|
14
15
|
from .types import ServerContext
|
@@ -36,7 +37,7 @@ class ProcessGroupImpl(ProcessGroup):
|
|
36
37
|
|
37
38
|
self._processes = {}
|
38
39
|
for pconfig in self._config.processes or []:
|
39
|
-
process = self._process_factory(pconfig, self)
|
40
|
+
process = check_isinstance(self._process_factory(pconfig, self), Process)
|
40
41
|
self._processes[pconfig.name] = process
|
41
42
|
|
42
43
|
@property
|
@@ -8,12 +8,16 @@ from omlish.lite.inject import inj
|
|
8
8
|
from .configs import ServerConfig
|
9
9
|
from .context import ServerContextImpl
|
10
10
|
from .context import ServerEpoch
|
11
|
+
from .dispatchers import InputDispatcherImpl
|
12
|
+
from .dispatchers import OutputDispatcherImpl
|
11
13
|
from .events import EventCallbacks
|
12
14
|
from .groups import ProcessFactory
|
13
15
|
from .groups import ProcessGroupImpl
|
14
16
|
from .poller import Poller
|
15
17
|
from .poller import get_poller_impl
|
16
18
|
from .process import InheritedFds
|
19
|
+
from .process import InputDispatcherFactory
|
20
|
+
from .process import OutputDispatcherFactory
|
17
21
|
from .process import ProcessImpl
|
18
22
|
from .signals import SignalReceiver
|
19
23
|
from .supervisor import ProcessGroupFactory
|
@@ -50,6 +54,9 @@ def bind_server(
|
|
50
54
|
|
51
55
|
inj.bind_factory(ProcessGroupFactory, ProcessGroupImpl),
|
52
56
|
inj.bind_factory(ProcessFactory, ProcessImpl),
|
57
|
+
|
58
|
+
inj.bind_factory(OutputDispatcherFactory, OutputDispatcherImpl),
|
59
|
+
inj.bind_factory(InputDispatcherFactory, InputDispatcherImpl),
|
53
60
|
]
|
54
61
|
|
55
62
|
#
|
@@ -9,6 +9,7 @@ import typing as ta
|
|
9
9
|
|
10
10
|
from omlish.lite.check import check_isinstance
|
11
11
|
from omlish.lite.logs import log
|
12
|
+
from omlish.lite.typing import Func
|
12
13
|
|
13
14
|
from .configs import ProcessConfig
|
14
15
|
from .context import check_execv_args
|
@@ -17,9 +18,6 @@ from .context import close_parent_pipes
|
|
17
18
|
from .context import drop_privileges
|
18
19
|
from .context import make_pipes
|
19
20
|
from .datatypes import RestartUnconditionally
|
20
|
-
from .dispatchers import Dispatcher
|
21
|
-
from .dispatchers import InputDispatcher
|
22
|
-
from .dispatchers import OutputDispatcher
|
23
21
|
from .events import PROCESS_STATE_EVENT_MAP
|
24
22
|
from .events import EventCallbacks
|
25
23
|
from .events import ProcessCommunicationEvent
|
@@ -30,6 +28,9 @@ from .exceptions import ProcessError
|
|
30
28
|
from .signals import sig_name
|
31
29
|
from .states import ProcessState
|
32
30
|
from .states import SupervisorState
|
31
|
+
from .types import Dispatcher
|
32
|
+
from .types import InputDispatcher
|
33
|
+
from .types import OutputDispatcher
|
33
34
|
from .types import Process
|
34
35
|
from .types import ProcessGroup
|
35
36
|
from .types import ServerContext
|
@@ -42,6 +43,12 @@ from .utils import get_path
|
|
42
43
|
from .utils import real_exit
|
43
44
|
|
44
45
|
|
46
|
+
# (process: Process, event_type: ta.Type[ProcessCommunicationEvent], fd: int)
|
47
|
+
OutputDispatcherFactory = ta.NewType('OutputDispatcherFactory', Func[OutputDispatcher])
|
48
|
+
|
49
|
+
# (process: Process, event_type: ta.Type[ProcessCommunicationEvent], fd: int)
|
50
|
+
InputDispatcherFactory = ta.NewType('InputDispatcherFactory', Func[InputDispatcher])
|
51
|
+
|
45
52
|
InheritedFds = ta.NewType('InheritedFds', ta.FrozenSet[int])
|
46
53
|
|
47
54
|
|
@@ -59,14 +66,23 @@ class ProcessImpl(Process):
|
|
59
66
|
context: ServerContext,
|
60
67
|
event_callbacks: EventCallbacks,
|
61
68
|
|
69
|
+
output_dispatcher_factory: OutputDispatcherFactory,
|
70
|
+
input_dispatcher_factory: InputDispatcherFactory,
|
71
|
+
|
62
72
|
inherited_fds: ta.Optional[InheritedFds] = None,
|
73
|
+
|
63
74
|
) -> None:
|
64
75
|
super().__init__()
|
65
76
|
|
66
77
|
self._config = config
|
67
78
|
self._group = group
|
79
|
+
|
68
80
|
self._context = context
|
69
81
|
self._event_callbacks = event_callbacks
|
82
|
+
|
83
|
+
self._output_dispatcher_factory = output_dispatcher_factory
|
84
|
+
self._input_dispatcher_factory = input_dispatcher_factory
|
85
|
+
|
70
86
|
self._inherited_fds = InheritedFds(frozenset(inherited_fds or []))
|
71
87
|
|
72
88
|
self._dispatchers: ta.Dict[int, Dispatcher] = {}
|
@@ -310,29 +326,29 @@ class ProcessImpl(Process):
|
|
310
326
|
etype: ta.Type[ProcessCommunicationEvent]
|
311
327
|
if stdout_fd is not None:
|
312
328
|
etype = ProcessCommunicationStdoutEvent
|
313
|
-
dispatchers[stdout_fd] =
|
329
|
+
dispatchers[stdout_fd] = check_isinstance(self._output_dispatcher_factory(
|
314
330
|
self,
|
315
331
|
etype,
|
316
332
|
stdout_fd,
|
317
333
|
**dispatcher_kw,
|
318
|
-
)
|
334
|
+
), OutputDispatcher)
|
319
335
|
|
320
336
|
if stderr_fd is not None:
|
321
337
|
etype = ProcessCommunicationStderrEvent
|
322
|
-
dispatchers[stderr_fd] =
|
338
|
+
dispatchers[stderr_fd] = check_isinstance(self._output_dispatcher_factory(
|
323
339
|
self,
|
324
340
|
etype,
|
325
341
|
stderr_fd,
|
326
342
|
**dispatcher_kw,
|
327
|
-
)
|
343
|
+
), OutputDispatcher)
|
328
344
|
|
329
345
|
if stdin_fd is not None:
|
330
|
-
dispatchers[stdin_fd] =
|
346
|
+
dispatchers[stdin_fd] = check_isinstance(self._input_dispatcher_factory(
|
331
347
|
self,
|
332
348
|
'stdin',
|
333
349
|
stdin_fd,
|
334
350
|
**dispatcher_kw,
|
335
|
-
)
|
351
|
+
), InputDispatcher)
|
336
352
|
|
337
353
|
return dispatchers, p
|
338
354
|
|
@@ -4,13 +4,13 @@ import time
|
|
4
4
|
import typing as ta
|
5
5
|
|
6
6
|
from omlish.lite.cached import cached_nullary
|
7
|
+
from omlish.lite.check import check_isinstance
|
7
8
|
from omlish.lite.check import check_not_none
|
8
9
|
from omlish.lite.logs import log
|
9
10
|
from omlish.lite.typing import Func
|
10
11
|
|
11
12
|
from .configs import ProcessGroupConfig
|
12
13
|
from .context import ServerContextImpl
|
13
|
-
from .dispatchers import Dispatcher
|
14
14
|
from .events import TICK_EVENTS
|
15
15
|
from .events import EventCallbacks
|
16
16
|
from .events import SupervisorRunningEvent
|
@@ -21,6 +21,7 @@ from .poller import Poller
|
|
21
21
|
from .signals import SignalReceiver
|
22
22
|
from .signals import sig_name
|
23
23
|
from .states import SupervisorState
|
24
|
+
from .types import Dispatcher
|
24
25
|
from .types import Process
|
25
26
|
from .utils import ExitNow
|
26
27
|
from .utils import as_string
|
@@ -149,7 +150,7 @@ class Supervisor:
|
|
149
150
|
if self._process_groups.get(config.name) is not None:
|
150
151
|
return False
|
151
152
|
|
152
|
-
group = self._process_group_factory(config)
|
153
|
+
group = check_isinstance(self._process_group_factory(config), ProcessGroup)
|
153
154
|
group.after_setuid()
|
154
155
|
|
155
156
|
self._process_groups.add(group)
|
@@ -31,16 +31,43 @@ class ServerContext(abc.ABC):
|
|
31
31
|
raise NotImplementedError
|
32
32
|
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
34
|
+
class Dispatcher(abc.ABC):
|
35
|
+
@abc.abstractmethod
|
36
|
+
def readable(self) -> bool:
|
37
|
+
raise NotImplementedError
|
38
|
+
|
39
|
+
@abc.abstractmethod
|
40
|
+
def writable(self) -> bool:
|
41
|
+
raise NotImplementedError
|
42
|
+
|
43
|
+
def handle_read_event(self) -> None:
|
44
|
+
raise TypeError
|
45
|
+
|
46
|
+
def handle_write_event(self) -> None:
|
47
|
+
raise TypeError
|
48
|
+
|
49
|
+
@abc.abstractmethod
|
50
|
+
def handle_error(self) -> None:
|
51
|
+
raise NotImplementedError
|
52
|
+
|
53
|
+
@property
|
54
|
+
@abc.abstractmethod
|
55
|
+
def closed(self) -> bool:
|
56
|
+
raise NotImplementedError
|
57
|
+
|
58
|
+
|
59
|
+
class OutputDispatcher(Dispatcher, abc.ABC):
|
60
|
+
pass
|
61
|
+
|
62
|
+
|
63
|
+
class InputDispatcher(Dispatcher, abc.ABC):
|
64
|
+
@abc.abstractmethod
|
65
|
+
def write(self, chars: ta.Union[bytes, str]) -> None:
|
66
|
+
raise NotImplementedError
|
67
|
+
|
68
|
+
@abc.abstractmethod
|
69
|
+
def flush(self) -> None:
|
70
|
+
raise NotImplementedError
|
44
71
|
|
45
72
|
|
46
73
|
@functools.total_ordering
|
@@ -99,7 +126,7 @@ class Process(abc.ABC):
|
|
99
126
|
raise NotImplementedError
|
100
127
|
|
101
128
|
@abc.abstractmethod
|
102
|
-
def get_dispatchers(self) -> ta.Mapping[int,
|
129
|
+
def get_dispatchers(self) -> ta.Mapping[int, Dispatcher]:
|
103
130
|
raise NotImplementedError
|
104
131
|
|
105
132
|
|
@@ -134,7 +161,7 @@ class ProcessGroup(abc.ABC):
|
|
134
161
|
raise NotImplementedError
|
135
162
|
|
136
163
|
@abc.abstractmethod
|
137
|
-
def get_dispatchers(self) -> ta.Mapping[int,
|
164
|
+
def get_dispatchers(self) -> ta.Mapping[int, Dispatcher]:
|
138
165
|
raise NotImplementedError
|
139
166
|
|
140
167
|
@abc.abstractmethod
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ominfra
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev126
|
4
4
|
Summary: ominfra
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -12,8 +12,8 @@ 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: omdev==0.0.0.
|
16
|
-
Requires-Dist: omlish==0.0.0.
|
15
|
+
Requires-Dist: omdev==0.0.0.dev126
|
16
|
+
Requires-Dist: omlish==0.0.0.dev126
|
17
17
|
Provides-Extra: all
|
18
18
|
Requires-Dist: paramiko~=3.5; extra == "all"
|
19
19
|
Requires-Dist: asyncssh~=2.18; extra == "all"
|
@@ -12,7 +12,7 @@ authors = [
|
|
12
12
|
urls = {source = 'https://github.com/wrmsr/omlish'}
|
13
13
|
license = {text = 'BSD-3-Clause'}
|
14
14
|
requires-python = '>=3.12'
|
15
|
-
version = '0.0.0.
|
15
|
+
version = '0.0.0.dev126'
|
16
16
|
classifiers = [
|
17
17
|
'License :: OSI Approved :: BSD License',
|
18
18
|
'Development Status :: 2 - Pre-Alpha',
|
@@ -22,8 +22,8 @@ classifiers = [
|
|
22
22
|
]
|
23
23
|
description = 'ominfra'
|
24
24
|
dependencies = [
|
25
|
-
'omdev == 0.0.0.
|
26
|
-
'omlish == 0.0.0.
|
25
|
+
'omdev == 0.0.0.dev126',
|
26
|
+
'omlish == 0.0.0.dev126',
|
27
27
|
]
|
28
28
|
|
29
29
|
[project.optional-dependencies]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{ominfra-0.0.0.dev125 → ominfra-0.0.0.dev126}/ominfra/deploy/executor/concerns/supervisor.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|