ominfra 0.0.0.dev138__py3-none-any.whl → 0.0.0.dev140__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/manage/__init__.py +13 -0
- ominfra/manage/{new/commands → commands}/base.py +9 -7
- ominfra/manage/{new/commands → commands}/subprocess.py +20 -15
- ominfra/manage/main.py +175 -0
- ominfra/manage/payload.py +35 -0
- ominfra/manage/spawning.py +100 -0
- ominfra/pyremote.py +18 -8
- ominfra/scripts/journald2aws.py +7 -0
- ominfra/{manage/new/_manage.py → scripts/manage.py} +248 -153
- ominfra/scripts/supervisor.py +7 -0
- {ominfra-0.0.0.dev138.dist-info → ominfra-0.0.0.dev140.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev138.dist-info → ominfra-0.0.0.dev140.dist-info}/RECORD +17 -44
- ominfra/manage/deploy/_executor.py +0 -1415
- ominfra/manage/deploy/configs.py +0 -19
- ominfra/manage/deploy/executor/__init__.py +0 -1
- ominfra/manage/deploy/executor/base.py +0 -115
- ominfra/manage/deploy/executor/concerns/__init__.py +0 -0
- ominfra/manage/deploy/executor/concerns/dirs.py +0 -28
- ominfra/manage/deploy/executor/concerns/nginx.py +0 -47
- ominfra/manage/deploy/executor/concerns/repo.py +0 -17
- ominfra/manage/deploy/executor/concerns/supervisor.py +0 -46
- ominfra/manage/deploy/executor/concerns/systemd.py +0 -88
- ominfra/manage/deploy/executor/concerns/user.py +0 -25
- ominfra/manage/deploy/executor/concerns/venv.py +0 -22
- ominfra/manage/deploy/executor/main.py +0 -119
- ominfra/manage/deploy/poly/__init__.py +0 -1
- ominfra/manage/deploy/poly/_main.py +0 -975
- ominfra/manage/deploy/poly/base.py +0 -178
- ominfra/manage/deploy/poly/configs.py +0 -38
- ominfra/manage/deploy/poly/deploy.py +0 -25
- ominfra/manage/deploy/poly/main.py +0 -18
- ominfra/manage/deploy/poly/nginx.py +0 -60
- ominfra/manage/deploy/poly/repo.py +0 -41
- ominfra/manage/deploy/poly/runtime.py +0 -39
- ominfra/manage/deploy/poly/site.py +0 -11
- ominfra/manage/deploy/poly/supervisor.py +0 -64
- ominfra/manage/deploy/poly/venv.py +0 -52
- ominfra/manage/deploy/remote.py +0 -91
- ominfra/manage/manage.py +0 -12
- ominfra/manage/new/__init__.py +0 -1
- ominfra/manage/new/commands/__init__.py +0 -0
- ominfra/manage/new/main.py +0 -234
- /ominfra/manage/{deploy → commands}/__init__.py +0 -0
- {ominfra-0.0.0.dev138.dist-info → ominfra-0.0.0.dev140.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev138.dist-info → ominfra-0.0.0.dev140.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev138.dist-info → ominfra-0.0.0.dev140.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev138.dist-info → ominfra-0.0.0.dev140.dist-info}/top_level.txt +0 -0
@@ -2,11 +2,11 @@
|
|
2
2
|
# noinspection DuplicatedCode
|
3
3
|
# @omlish-lite
|
4
4
|
# @omlish-script
|
5
|
-
# @omlish-amalg-output main.py
|
5
|
+
# @omlish-amalg-output ../manage/main.py
|
6
6
|
# ruff: noqa: N802 UP006 UP007 UP036
|
7
7
|
"""
|
8
8
|
manage.py -s 'docker run -i python:3.12'
|
9
|
-
manage.py -
|
9
|
+
manage.py -s 'ssh -i /foo/bar.pem foo@bar.baz' -q --python=python3.8
|
10
10
|
"""
|
11
11
|
import abc
|
12
12
|
import base64
|
@@ -49,13 +49,14 @@ if sys.version_info < (3, 8):
|
|
49
49
|
|
50
50
|
|
51
51
|
# commands/base.py
|
52
|
-
|
52
|
+
CommandT = ta.TypeVar('CommandT', bound='Command')
|
53
53
|
CommandOutputT = ta.TypeVar('CommandOutputT', bound='Command.Output')
|
54
54
|
|
55
|
-
#
|
55
|
+
# ../../omlish/lite/cached.py
|
56
56
|
T = ta.TypeVar('T')
|
57
|
+
CallableT = ta.TypeVar('CallableT', bound=ta.Callable)
|
57
58
|
|
58
|
-
#
|
59
|
+
# ../../omlish/lite/check.py
|
59
60
|
SizedT = ta.TypeVar('SizedT', bound=ta.Sized)
|
60
61
|
|
61
62
|
|
@@ -66,22 +67,24 @@ SizedT = ta.TypeVar('SizedT', bound=ta.Sized)
|
|
66
67
|
##
|
67
68
|
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
class Input(abc.ABC): # noqa
|
72
|
-
pass
|
73
|
-
|
70
|
+
@dc.dataclass(frozen=True)
|
71
|
+
class Command(abc.ABC, ta.Generic[CommandOutputT]):
|
74
72
|
@dc.dataclass(frozen=True)
|
75
73
|
class Output(abc.ABC): # noqa
|
76
74
|
pass
|
77
75
|
|
76
|
+
|
77
|
+
##
|
78
|
+
|
79
|
+
|
80
|
+
class CommandExecutor(abc.ABC, ta.Generic[CommandT, CommandOutputT]):
|
78
81
|
@abc.abstractmethod
|
79
|
-
def
|
82
|
+
def execute(self, i: CommandT) -> CommandOutputT:
|
80
83
|
raise NotImplementedError
|
81
84
|
|
82
85
|
|
83
86
|
########################################
|
84
|
-
#
|
87
|
+
# ../../pyremote.py
|
85
88
|
"""
|
86
89
|
Basically this: https://mitogen.networkgenomics.com/howitworks.html
|
87
90
|
"""
|
@@ -203,6 +206,8 @@ _PYREMOTE_BOOTSTRAP_SRC_FD = 101
|
|
203
206
|
|
204
207
|
_PYREMOTE_BOOTSTRAP_CHILD_PID_VAR = '_OPYR_CHILD_PID'
|
205
208
|
_PYREMOTE_BOOTSTRAP_ARGV0_VAR = '_OPYR_ARGV0'
|
209
|
+
_PYREMOTE_BOOTSTRAP_CONTEXT_NAME_VAR = '_OPYR_CONTEXT_NAME'
|
210
|
+
_PYREMOTE_BOOTSTRAP_SRC_FILE_VAR = '_OPYR_SRC_FILE'
|
206
211
|
_PYREMOTE_BOOTSTRAP_OPTIONS_JSON_VAR = '_OPYR_OPTIONS_JSON'
|
207
212
|
|
208
213
|
_PYREMOTE_BOOTSTRAP_ACK0 = b'OPYR000\n'
|
@@ -245,11 +250,10 @@ def _pyremote_bootstrap_main(context_name: str) -> None:
|
|
245
250
|
for f in [r0, w0, r1, w1]:
|
246
251
|
os.close(f)
|
247
252
|
|
248
|
-
# Save
|
253
|
+
# Save vars
|
249
254
|
os.environ[_PYREMOTE_BOOTSTRAP_CHILD_PID_VAR] = str(cp)
|
250
|
-
|
251
|
-
# Save original argv0
|
252
255
|
os.environ[_PYREMOTE_BOOTSTRAP_ARGV0_VAR] = sys.executable
|
256
|
+
os.environ[_PYREMOTE_BOOTSTRAP_CONTEXT_NAME_VAR] = context_name
|
253
257
|
|
254
258
|
# Start repl reading stdin from r0
|
255
259
|
os.execl(sys.executable, sys.executable + (_PYREMOTE_BOOTSTRAP_PROC_TITLE_FMT % (context_name,)))
|
@@ -300,6 +304,7 @@ def pyremote_build_bootstrap_cmd(context_name: str) -> str:
|
|
300
304
|
|
301
305
|
'_PYREMOTE_BOOTSTRAP_CHILD_PID_VAR',
|
302
306
|
'_PYREMOTE_BOOTSTRAP_ARGV0_VAR',
|
307
|
+
'_PYREMOTE_BOOTSTRAP_CONTEXT_NAME_VAR',
|
303
308
|
|
304
309
|
'_PYREMOTE_BOOTSTRAP_ACK0',
|
305
310
|
'_PYREMOTE_BOOTSTRAP_ACK1',
|
@@ -335,14 +340,15 @@ def pyremote_build_bootstrap_cmd(context_name: str) -> str:
|
|
335
340
|
class PyremotePayloadRuntime:
|
336
341
|
input: ta.BinaryIO
|
337
342
|
output: ta.BinaryIO
|
343
|
+
context_name: str
|
338
344
|
main_src: str
|
339
345
|
options: PyremoteBootstrapOptions
|
340
346
|
env_info: PyremoteEnvInfo
|
341
347
|
|
342
348
|
|
343
349
|
def pyremote_bootstrap_finalize() -> PyremotePayloadRuntime:
|
344
|
-
# If
|
345
|
-
if
|
350
|
+
# If src file var is not present we need to do initial finalization
|
351
|
+
if _PYREMOTE_BOOTSTRAP_SRC_FILE_VAR not in os.environ:
|
346
352
|
# Read second copy of main src
|
347
353
|
r1 = os.fdopen(_PYREMOTE_BOOTSTRAP_SRC_FD, 'rb', 0)
|
348
354
|
main_src = r1.read().decode('utf-8')
|
@@ -366,11 +372,14 @@ def pyremote_bootstrap_finalize() -> PyremotePayloadRuntime:
|
|
366
372
|
os.write(tfd, main_src.encode('utf-8'))
|
367
373
|
os.close(tfd)
|
368
374
|
|
369
|
-
# Set
|
375
|
+
# Set vars
|
376
|
+
os.environ[_PYREMOTE_BOOTSTRAP_SRC_FILE_VAR] = tfn
|
370
377
|
os.environ[_PYREMOTE_BOOTSTRAP_OPTIONS_JSON_VAR] = options_json.decode('utf-8')
|
371
378
|
|
372
379
|
# Re-exec temp file
|
373
|
-
os.
|
380
|
+
exe = os.environ[_PYREMOTE_BOOTSTRAP_ARGV0_VAR]
|
381
|
+
context_name = os.environ[_PYREMOTE_BOOTSTRAP_CONTEXT_NAME_VAR]
|
382
|
+
os.execl(exe, exe + (_PYREMOTE_BOOTSTRAP_PROC_TITLE_FMT % (context_name,)), tfn)
|
374
383
|
|
375
384
|
else:
|
376
385
|
# Load options json var
|
@@ -378,12 +387,15 @@ def pyremote_bootstrap_finalize() -> PyremotePayloadRuntime:
|
|
378
387
|
options = PyremoteBootstrapOptions(**json.loads(options_json_str))
|
379
388
|
|
380
389
|
# Read temp source file
|
381
|
-
with open(
|
390
|
+
with open(os.environ.pop(_PYREMOTE_BOOTSTRAP_SRC_FILE_VAR)) as sf:
|
382
391
|
main_src = sf.read()
|
383
392
|
|
384
393
|
# Restore original argv0
|
385
394
|
sys.executable = os.environ.pop(_PYREMOTE_BOOTSTRAP_ARGV0_VAR)
|
386
395
|
|
396
|
+
# Grab context name
|
397
|
+
context_name = os.environ.pop(_PYREMOTE_BOOTSTRAP_CONTEXT_NAME_VAR)
|
398
|
+
|
387
399
|
# Write third ack
|
388
400
|
os.write(1, _PYREMOTE_BOOTSTRAP_ACK2)
|
389
401
|
|
@@ -406,6 +418,7 @@ def pyremote_bootstrap_finalize() -> PyremotePayloadRuntime:
|
|
406
418
|
return PyremotePayloadRuntime(
|
407
419
|
input=input,
|
408
420
|
output=output,
|
421
|
+
context_name=context_name,
|
409
422
|
main_src=main_src,
|
410
423
|
options=options,
|
411
424
|
env_info=env_info,
|
@@ -526,7 +539,7 @@ class PyremoteBootstrapDriver:
|
|
526
539
|
|
527
540
|
|
528
541
|
########################################
|
529
|
-
#
|
542
|
+
# ../../../omlish/lite/cached.py
|
530
543
|
|
531
544
|
|
532
545
|
class _cached_nullary: # noqa
|
@@ -550,8 +563,14 @@ def cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
550
563
|
return _cached_nullary(fn)
|
551
564
|
|
552
565
|
|
566
|
+
def static_init(fn: CallableT) -> CallableT:
|
567
|
+
fn = cached_nullary(fn)
|
568
|
+
fn()
|
569
|
+
return fn
|
570
|
+
|
571
|
+
|
553
572
|
########################################
|
554
|
-
#
|
573
|
+
# ../../../omlish/lite/check.py
|
555
574
|
|
556
575
|
|
557
576
|
def check_isinstance(v: ta.Any, spec: ta.Union[ta.Type[T], tuple]) -> T:
|
@@ -648,7 +667,7 @@ def check_non_empty(v: SizedT) -> SizedT:
|
|
648
667
|
|
649
668
|
|
650
669
|
########################################
|
651
|
-
#
|
670
|
+
# ../../../omlish/lite/json.py
|
652
671
|
|
653
672
|
|
654
673
|
##
|
@@ -679,7 +698,7 @@ json_dumps_compact: ta.Callable[..., str] = functools.partial(json.dumps, **JSON
|
|
679
698
|
|
680
699
|
|
681
700
|
########################################
|
682
|
-
#
|
701
|
+
# ../../../omlish/lite/reflect.py
|
683
702
|
|
684
703
|
|
685
704
|
_GENERIC_ALIAS_TYPES = (
|
@@ -734,7 +753,40 @@ def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
|
|
734
753
|
|
735
754
|
|
736
755
|
########################################
|
737
|
-
#
|
756
|
+
# ../payload.py
|
757
|
+
|
758
|
+
|
759
|
+
@cached_nullary
|
760
|
+
def _get_self_src() -> str:
|
761
|
+
return inspect.getsource(sys.modules[__name__])
|
762
|
+
|
763
|
+
|
764
|
+
def _is_src_amalg(src: str) -> bool:
|
765
|
+
for l in src.splitlines(): # noqa
|
766
|
+
if l.startswith('# @omlish-amalg-output '):
|
767
|
+
return True
|
768
|
+
return False
|
769
|
+
|
770
|
+
|
771
|
+
@cached_nullary
|
772
|
+
def _is_self_amalg() -> bool:
|
773
|
+
return _is_src_amalg(_get_self_src())
|
774
|
+
|
775
|
+
|
776
|
+
def get_payload_src(*, file: ta.Optional[str]) -> str:
|
777
|
+
if file is not None:
|
778
|
+
with open(file) as f:
|
779
|
+
return f.read()
|
780
|
+
|
781
|
+
if _is_self_amalg():
|
782
|
+
return _get_self_src()
|
783
|
+
|
784
|
+
import importlib.resources
|
785
|
+
return importlib.resources.files(__package__.split('.')[0] + '.scripts').joinpath('manage.py').read_text()
|
786
|
+
|
787
|
+
|
788
|
+
########################################
|
789
|
+
# ../../../omlish/lite/logs.py
|
738
790
|
"""
|
739
791
|
TODO:
|
740
792
|
- translate json keys
|
@@ -1004,7 +1056,7 @@ def configure_standard_logging(
|
|
1004
1056
|
|
1005
1057
|
|
1006
1058
|
########################################
|
1007
|
-
#
|
1059
|
+
# ../../../omlish/lite/marshal.py
|
1008
1060
|
"""
|
1009
1061
|
TODO:
|
1010
1062
|
- pickle stdlib objs? have to pin to 3.8 pickle protocol, will be cross-version
|
@@ -1351,7 +1403,7 @@ def unmarshal_obj(o: ta.Any, ty: ta.Union[ta.Type[T], ta.Any]) -> T:
|
|
1351
1403
|
|
1352
1404
|
|
1353
1405
|
########################################
|
1354
|
-
#
|
1406
|
+
# ../../../omlish/lite/runtime.py
|
1355
1407
|
|
1356
1408
|
|
1357
1409
|
@cached_nullary
|
@@ -1368,7 +1420,7 @@ def check_runtime_version() -> None:
|
|
1368
1420
|
|
1369
1421
|
|
1370
1422
|
########################################
|
1371
|
-
#
|
1423
|
+
# ../../../omlish/lite/subprocesses.py
|
1372
1424
|
|
1373
1425
|
|
1374
1426
|
##
|
@@ -1498,24 +1550,23 @@ def subprocess_close(
|
|
1498
1550
|
##
|
1499
1551
|
|
1500
1552
|
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
args: ta.Sequence[str]
|
1553
|
+
@dc.dataclass(frozen=True)
|
1554
|
+
class SubprocessCommand(Command['SubprocessCommand.Output']):
|
1555
|
+
args: ta.Sequence[str]
|
1505
1556
|
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1557
|
+
shell: bool = False
|
1558
|
+
cwd: ta.Optional[str] = None
|
1559
|
+
env: ta.Optional[ta.Mapping[str, str]] = None
|
1509
1560
|
|
1510
|
-
|
1511
|
-
|
1561
|
+
capture_stdout: bool = False
|
1562
|
+
capture_stderr: bool = False
|
1512
1563
|
|
1513
|
-
|
1514
|
-
|
1564
|
+
input: ta.Optional[bytes] = None
|
1565
|
+
timeout: ta.Optional[float] = None
|
1515
1566
|
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1567
|
+
def __post_init__(self) -> None:
|
1568
|
+
if isinstance(self.args, str):
|
1569
|
+
raise TypeError(self.args)
|
1519
1570
|
|
1520
1571
|
@dc.dataclass(frozen=True)
|
1521
1572
|
class Output(Command.Output):
|
@@ -1527,7 +1578,12 @@ class SubprocessCommand(Command['SubprocessCommand.Input', 'SubprocessCommand.Ou
|
|
1527
1578
|
stdout: ta.Optional[bytes] = None
|
1528
1579
|
stderr: ta.Optional[bytes] = None
|
1529
1580
|
|
1530
|
-
|
1581
|
+
|
1582
|
+
##
|
1583
|
+
|
1584
|
+
|
1585
|
+
class SubprocessCommandExecutor(CommandExecutor[SubprocessCommand, SubprocessCommand.Output]):
|
1586
|
+
def execute(self, inp: SubprocessCommand) -> SubprocessCommand.Output:
|
1531
1587
|
proc = subprocess.Popen(
|
1532
1588
|
subprocess_maybe_shell_wrap_exec(*inp.args),
|
1533
1589
|
|
@@ -1558,6 +1614,101 @@ class SubprocessCommand(Command['SubprocessCommand.Input', 'SubprocessCommand.Ou
|
|
1558
1614
|
)
|
1559
1615
|
|
1560
1616
|
|
1617
|
+
########################################
|
1618
|
+
# ../spawning.py
|
1619
|
+
|
1620
|
+
|
1621
|
+
class PySpawner:
|
1622
|
+
DEFAULT_PYTHON = 'python3'
|
1623
|
+
|
1624
|
+
def __init__(
|
1625
|
+
self,
|
1626
|
+
src: str,
|
1627
|
+
*,
|
1628
|
+
shell: ta.Optional[str] = None,
|
1629
|
+
shell_quote: bool = False,
|
1630
|
+
python: str = DEFAULT_PYTHON,
|
1631
|
+
stderr: ta.Optional[ta.Literal['pipe', 'stdout', 'devnull']] = None,
|
1632
|
+
) -> None:
|
1633
|
+
super().__init__()
|
1634
|
+
|
1635
|
+
self._src = src
|
1636
|
+
self._shell = shell
|
1637
|
+
self._shell_quote = shell_quote
|
1638
|
+
self._python = python
|
1639
|
+
self._stderr = stderr
|
1640
|
+
|
1641
|
+
#
|
1642
|
+
|
1643
|
+
class _PreparedCmd(ta.NamedTuple):
|
1644
|
+
cmd: ta.Sequence[str]
|
1645
|
+
shell: bool
|
1646
|
+
|
1647
|
+
def _prepare_cmd(self) -> _PreparedCmd:
|
1648
|
+
if self._shell is not None:
|
1649
|
+
sh_src = f'{self._python} -c {shlex.quote(self._src)}'
|
1650
|
+
if self._shell_quote:
|
1651
|
+
sh_src = shlex.quote(sh_src)
|
1652
|
+
sh_cmd = f'{self._shell} {sh_src}'
|
1653
|
+
return PySpawner._PreparedCmd(
|
1654
|
+
cmd=[sh_cmd],
|
1655
|
+
shell=True,
|
1656
|
+
)
|
1657
|
+
|
1658
|
+
else:
|
1659
|
+
return PySpawner._PreparedCmd(
|
1660
|
+
cmd=[self._python, '-c', self._src],
|
1661
|
+
shell=False,
|
1662
|
+
)
|
1663
|
+
|
1664
|
+
#
|
1665
|
+
|
1666
|
+
_STDERR_KWARG_MAP: ta.Mapping[str, int] = {
|
1667
|
+
'pipe': subprocess.PIPE,
|
1668
|
+
'stdout': subprocess.STDOUT,
|
1669
|
+
'devnull': subprocess.DEVNULL,
|
1670
|
+
}
|
1671
|
+
|
1672
|
+
@dc.dataclass(frozen=True)
|
1673
|
+
class Spawned:
|
1674
|
+
stdin: ta.IO
|
1675
|
+
stdout: ta.IO
|
1676
|
+
stderr: ta.Optional[ta.IO]
|
1677
|
+
|
1678
|
+
@contextlib.contextmanager
|
1679
|
+
def spawn(
|
1680
|
+
self,
|
1681
|
+
*,
|
1682
|
+
timeout: ta.Optional[float] = None,
|
1683
|
+
) -> ta.Generator[Spawned, None, None]:
|
1684
|
+
pc = self._prepare_cmd()
|
1685
|
+
|
1686
|
+
with subprocess.Popen(
|
1687
|
+
subprocess_maybe_shell_wrap_exec(*pc.cmd),
|
1688
|
+
shell=pc.shell,
|
1689
|
+
stdin=subprocess.PIPE,
|
1690
|
+
stdout=subprocess.PIPE,
|
1691
|
+
stderr=self._STDERR_KWARG_MAP[self._stderr] if self._stderr is not None else None,
|
1692
|
+
) as proc:
|
1693
|
+
stdin = check_not_none(proc.stdin)
|
1694
|
+
stdout = check_not_none(proc.stdout)
|
1695
|
+
|
1696
|
+
try:
|
1697
|
+
yield PySpawner.Spawned(
|
1698
|
+
stdin=stdin,
|
1699
|
+
stdout=stdout,
|
1700
|
+
stderr=proc.stderr,
|
1701
|
+
)
|
1702
|
+
|
1703
|
+
finally:
|
1704
|
+
try:
|
1705
|
+
stdin.close()
|
1706
|
+
except BrokenPipeError:
|
1707
|
+
pass
|
1708
|
+
|
1709
|
+
proc.wait(timeout)
|
1710
|
+
|
1711
|
+
|
1561
1712
|
########################################
|
1562
1713
|
# main.py
|
1563
1714
|
|
@@ -1570,29 +1721,23 @@ _COMMAND_TYPES = {
|
|
1570
1721
|
}
|
1571
1722
|
|
1572
1723
|
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
)
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
cty.Output,
|
1590
|
-
k,
|
1591
|
-
get_obj_marshaler(cty.Output),
|
1724
|
+
@static_init
|
1725
|
+
def _register_command_marshaling() -> None:
|
1726
|
+
for fn in [
|
1727
|
+
lambda c: c,
|
1728
|
+
lambda c: c.Output,
|
1729
|
+
]:
|
1730
|
+
register_opj_marshaler(
|
1731
|
+
fn(Command),
|
1732
|
+
PolymorphicObjMarshaler.of([
|
1733
|
+
PolymorphicObjMarshaler.Impl(
|
1734
|
+
fn(cty),
|
1735
|
+
k,
|
1736
|
+
get_obj_marshaler(fn(cty)),
|
1737
|
+
)
|
1738
|
+
for k, cty in _COMMAND_TYPES.items()
|
1739
|
+
]),
|
1592
1740
|
)
|
1593
|
-
for k, cty in _COMMAND_TYPES.items()
|
1594
|
-
]),
|
1595
|
-
)
|
1596
1741
|
|
1597
1742
|
|
1598
1743
|
##
|
@@ -1630,12 +1775,12 @@ def _remote_main() -> None:
|
|
1630
1775
|
rt = pyremote_bootstrap_finalize() # noqa
|
1631
1776
|
|
1632
1777
|
while True:
|
1633
|
-
i = _recv_obj(rt.input, Command
|
1778
|
+
i = _recv_obj(rt.input, Command)
|
1634
1779
|
if i is None:
|
1635
1780
|
break
|
1636
1781
|
|
1637
|
-
if isinstance(i, SubprocessCommand
|
1638
|
-
o =
|
1782
|
+
if isinstance(i, SubprocessCommand):
|
1783
|
+
o = SubprocessCommandExecutor().execute(i) # noqa
|
1639
1784
|
else:
|
1640
1785
|
raise TypeError(i)
|
1641
1786
|
|
@@ -1645,38 +1790,6 @@ def _remote_main() -> None:
|
|
1645
1790
|
##
|
1646
1791
|
|
1647
1792
|
|
1648
|
-
@cached_nullary
|
1649
|
-
def _get_self_src() -> str:
|
1650
|
-
return inspect.getsource(sys.modules[__name__])
|
1651
|
-
|
1652
|
-
|
1653
|
-
def _is_src_amalg(src: str) -> bool:
|
1654
|
-
for l in src.splitlines(): # noqa
|
1655
|
-
if l.startswith('# @omlish-amalg-output '):
|
1656
|
-
return True
|
1657
|
-
return False
|
1658
|
-
|
1659
|
-
|
1660
|
-
@cached_nullary
|
1661
|
-
def _is_self_amalg() -> bool:
|
1662
|
-
return _is_src_amalg(_get_self_src())
|
1663
|
-
|
1664
|
-
|
1665
|
-
def _get_amalg_src(*, amalg_file: ta.Optional[str]) -> str:
|
1666
|
-
if amalg_file is not None:
|
1667
|
-
with open(amalg_file) as f:
|
1668
|
-
return f.read()
|
1669
|
-
|
1670
|
-
if _is_self_amalg():
|
1671
|
-
return _get_self_src()
|
1672
|
-
|
1673
|
-
import importlib.resources
|
1674
|
-
return importlib.resources.read_text(__package__, '_manage.py')
|
1675
|
-
|
1676
|
-
|
1677
|
-
##
|
1678
|
-
|
1679
|
-
|
1680
1793
|
def _main() -> None:
|
1681
1794
|
import argparse
|
1682
1795
|
|
@@ -1685,19 +1798,20 @@ def _main() -> None:
|
|
1685
1798
|
parser.add_argument('-s', '--shell')
|
1686
1799
|
parser.add_argument('-q', '--shell-quote', action='store_true')
|
1687
1800
|
parser.add_argument('--python', default='python3')
|
1688
|
-
parser.add_argument('--
|
1801
|
+
parser.add_argument('--debug', action='store_true')
|
1802
|
+
parser.add_argument('--_payload-file')
|
1689
1803
|
|
1690
1804
|
args = parser.parse_args()
|
1691
1805
|
|
1692
1806
|
#
|
1693
1807
|
|
1694
|
-
|
1808
|
+
payload_src = get_payload_src(file=args._payload_file) # noqa
|
1695
1809
|
|
1696
1810
|
#
|
1697
1811
|
|
1698
1812
|
remote_src = '\n\n'.join([
|
1699
1813
|
'__name__ = "__remote__"',
|
1700
|
-
|
1814
|
+
payload_src,
|
1701
1815
|
'_remote_main()',
|
1702
1816
|
])
|
1703
1817
|
|
@@ -1705,60 +1819,41 @@ def _main() -> None:
|
|
1705
1819
|
|
1706
1820
|
bs_src = pyremote_build_bootstrap_cmd(__package__ or 'manage')
|
1707
1821
|
|
1708
|
-
if args.shell is not None:
|
1709
|
-
sh_src = f'{args.python} -c {shlex.quote(bs_src)}'
|
1710
|
-
if args.shell_quote:
|
1711
|
-
sh_src = shlex.quote(sh_src)
|
1712
|
-
sh_cmd = f'{args.shell} {sh_src}'
|
1713
|
-
cmd = [sh_cmd]
|
1714
|
-
shell = True
|
1715
|
-
else:
|
1716
|
-
cmd = [args.python, '-c', bs_src]
|
1717
|
-
shell = False
|
1718
|
-
|
1719
|
-
proc = subprocess.Popen(
|
1720
|
-
subprocess_maybe_shell_wrap_exec(*cmd),
|
1721
|
-
shell=shell,
|
1722
|
-
stdin=subprocess.PIPE,
|
1723
|
-
stdout=subprocess.PIPE,
|
1724
|
-
)
|
1725
|
-
|
1726
|
-
stdin = check_not_none(proc.stdin)
|
1727
|
-
stdout = check_not_none(proc.stdout)
|
1728
|
-
|
1729
|
-
res = PyremoteBootstrapDriver( # noqa
|
1730
|
-
remote_src,
|
1731
|
-
PyremoteBootstrapOptions(
|
1732
|
-
# debug=True,
|
1733
|
-
),
|
1734
|
-
).run(stdin, stdout)
|
1735
|
-
# print(res)
|
1736
|
-
|
1737
1822
|
#
|
1738
1823
|
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
print(o)
|
1824
|
+
spawner = PySpawner(
|
1825
|
+
bs_src,
|
1826
|
+
shell=args.shell,
|
1827
|
+
shell_quote=args.shell_quote,
|
1828
|
+
python=args.python,
|
1829
|
+
)
|
1830
|
+
with spawner.spawn() as proc:
|
1831
|
+
res = PyremoteBootstrapDriver( # noqa
|
1832
|
+
remote_src,
|
1833
|
+
PyremoteBootstrapOptions(
|
1834
|
+
debug=args.debug,
|
1835
|
+
),
|
1836
|
+
).run(proc.stdin, proc.stdout)
|
1837
|
+
# print(res)
|
1755
1838
|
|
1756
|
-
|
1757
|
-
stdin.close()
|
1758
|
-
except BrokenPipeError:
|
1759
|
-
pass
|
1839
|
+
#
|
1760
1840
|
|
1761
|
-
|
1841
|
+
for ci in [
|
1842
|
+
SubprocessCommand(
|
1843
|
+
args=['python3', '-'],
|
1844
|
+
input=b'print(1)\n',
|
1845
|
+
capture_stdout=True,
|
1846
|
+
),
|
1847
|
+
SubprocessCommand(
|
1848
|
+
args=['uname'],
|
1849
|
+
capture_stdout=True,
|
1850
|
+
),
|
1851
|
+
]:
|
1852
|
+
_send_obj(proc.stdin, ci, Command)
|
1853
|
+
|
1854
|
+
o = _recv_obj(proc.stdout, Command.Output)
|
1855
|
+
|
1856
|
+
print(o)
|
1762
1857
|
|
1763
1858
|
|
1764
1859
|
if __name__ == '__main__':
|
ominfra/scripts/supervisor.py
CHANGED
@@ -101,6 +101,7 @@ V = ta.TypeVar('V')
|
|
101
101
|
|
102
102
|
# ../../omlish/lite/cached.py
|
103
103
|
T = ta.TypeVar('T')
|
104
|
+
CallableT = ta.TypeVar('CallableT', bound=ta.Callable)
|
104
105
|
|
105
106
|
# ../../omlish/lite/check.py
|
106
107
|
SizedT = ta.TypeVar('SizedT', bound=ta.Sized)
|
@@ -1454,6 +1455,12 @@ def cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
1454
1455
|
return _cached_nullary(fn)
|
1455
1456
|
|
1456
1457
|
|
1458
|
+
def static_init(fn: CallableT) -> CallableT:
|
1459
|
+
fn = cached_nullary(fn)
|
1460
|
+
fn()
|
1461
|
+
return fn
|
1462
|
+
|
1463
|
+
|
1457
1464
|
########################################
|
1458
1465
|
# ../../../omlish/lite/check.py
|
1459
1466
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ominfra
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev140
|
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.dev140
|
16
|
+
Requires-Dist: omlish==0.0.0.dev140
|
17
17
|
Provides-Extra: all
|
18
18
|
Requires-Dist: paramiko~=3.5; extra == "all"
|
19
19
|
Requires-Dist: asyncssh~=2.18; extra == "all"
|