ominfra 0.0.0.dev141__py3-none-any.whl → 0.0.0.dev142__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/commands/subprocess.py +18 -17
- ominfra/manage/main.py +25 -63
- ominfra/manage/protocol.py +45 -0
- ominfra/manage/spawning.py +4 -8
- ominfra/pyremote.py +13 -11
- ominfra/scripts/journald2aws.py +123 -86
- ominfra/scripts/manage.py +219 -176
- ominfra/scripts/supervisor.py +110 -86
- {ominfra-0.0.0.dev141.dist-info → ominfra-0.0.0.dev142.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev141.dist-info → ominfra-0.0.0.dev142.dist-info}/RECORD +14 -13
- {ominfra-0.0.0.dev141.dist-info → ominfra-0.0.0.dev142.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev141.dist-info → ominfra-0.0.0.dev142.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev141.dist-info → ominfra-0.0.0.dev142.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev141.dist-info → ominfra-0.0.0.dev142.dist-info}/top_level.txt +0 -0
ominfra/scripts/manage.py
CHANGED
@@ -59,6 +59,9 @@ CallableT = ta.TypeVar('CallableT', bound=ta.Callable)
|
|
59
59
|
# ../../omlish/lite/check.py
|
60
60
|
SizedT = ta.TypeVar('SizedT', bound=ta.Sized)
|
61
61
|
|
62
|
+
# ../../omlish/lite/subprocesses.py
|
63
|
+
SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull']
|
64
|
+
|
62
65
|
|
63
66
|
########################################
|
64
67
|
# ../commands/base.py
|
@@ -251,12 +254,14 @@ def _pyremote_bootstrap_main(context_name: str) -> None:
|
|
251
254
|
os.close(f)
|
252
255
|
|
253
256
|
# Save vars
|
254
|
-
os.environ
|
255
|
-
|
256
|
-
|
257
|
+
env = os.environ
|
258
|
+
exe = sys.executable
|
259
|
+
env[_PYREMOTE_BOOTSTRAP_CHILD_PID_VAR] = str(cp)
|
260
|
+
env[_PYREMOTE_BOOTSTRAP_ARGV0_VAR] = exe
|
261
|
+
env[_PYREMOTE_BOOTSTRAP_CONTEXT_NAME_VAR] = context_name
|
257
262
|
|
258
263
|
# Start repl reading stdin from r0
|
259
|
-
os.execl(
|
264
|
+
os.execl(exe, exe + (_PYREMOTE_BOOTSTRAP_PROC_TITLE_FMT % (context_name,)))
|
260
265
|
|
261
266
|
else:
|
262
267
|
# Child process
|
@@ -320,12 +325,12 @@ def pyremote_build_bootstrap_cmd(context_name: str) -> str:
|
|
320
325
|
if cl.strip()
|
321
326
|
)
|
322
327
|
|
323
|
-
bs_z = zlib.compress(bs_src.encode('utf-8'))
|
324
|
-
|
328
|
+
bs_z = zlib.compress(bs_src.encode('utf-8'), 9)
|
329
|
+
bs_z85 = base64.b85encode(bs_z).replace(b'\n', b'')
|
325
330
|
|
326
331
|
stmts = [
|
327
332
|
f'import {", ".join(_PYREMOTE_BOOTSTRAP_IMPORTS)}',
|
328
|
-
f'exec(zlib.decompress(base64.
|
333
|
+
f'exec(zlib.decompress(base64.b85decode({bs_z85!r})))',
|
329
334
|
f'_pyremote_bootstrap_main({context_name!r})',
|
330
335
|
]
|
331
336
|
|
@@ -514,7 +519,7 @@ class PyremoteBootstrapDriver:
|
|
514
519
|
|
515
520
|
#
|
516
521
|
|
517
|
-
def run(self,
|
522
|
+
def run(self, input: ta.IO, output: ta.IO) -> Result: # noqa
|
518
523
|
gen = self.gen()
|
519
524
|
|
520
525
|
gi: ta.Optional[bytes] = None
|
@@ -528,12 +533,12 @@ class PyremoteBootstrapDriver:
|
|
528
533
|
return e.value
|
529
534
|
|
530
535
|
if isinstance(go, self.Read):
|
531
|
-
if len(gi :=
|
536
|
+
if len(gi := input.read(go.sz)) != go.sz:
|
532
537
|
raise EOFError
|
533
538
|
elif isinstance(go, self.Write):
|
534
539
|
gi = None
|
535
|
-
|
536
|
-
|
540
|
+
output.write(go.d)
|
541
|
+
output.flush()
|
537
542
|
else:
|
538
543
|
raise TypeError(go)
|
539
544
|
|
@@ -1286,120 +1291,144 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
|
|
1286
1291
|
}
|
1287
1292
|
|
1288
1293
|
|
1289
|
-
|
1290
|
-
ty: ta.Any,
|
1291
|
-
rec: ta.Callable[[ta.Any], ObjMarshaler],
|
1292
|
-
*,
|
1293
|
-
nonstrict_dataclasses: bool = False,
|
1294
|
-
) -> ObjMarshaler:
|
1295
|
-
if isinstance(ty, type):
|
1296
|
-
if abc.ABC in ty.__bases__:
|
1297
|
-
return PolymorphicObjMarshaler.of([ # type: ignore
|
1298
|
-
PolymorphicObjMarshaler.Impl(
|
1299
|
-
ity,
|
1300
|
-
ity.__qualname__,
|
1301
|
-
rec(ity),
|
1302
|
-
)
|
1303
|
-
for ity in deep_subclasses(ty)
|
1304
|
-
if abc.ABC not in ity.__bases__
|
1305
|
-
])
|
1306
|
-
|
1307
|
-
if issubclass(ty, enum.Enum):
|
1308
|
-
return EnumObjMarshaler(ty)
|
1309
|
-
|
1310
|
-
if dc.is_dataclass(ty):
|
1311
|
-
return DataclassObjMarshaler(
|
1312
|
-
ty,
|
1313
|
-
{f.name: rec(f.type) for f in dc.fields(ty)},
|
1314
|
-
nonstrict=nonstrict_dataclasses,
|
1315
|
-
)
|
1294
|
+
##
|
1316
1295
|
|
1317
|
-
if is_generic_alias(ty):
|
1318
|
-
try:
|
1319
|
-
mt = _OBJ_MARSHALER_GENERIC_MAPPING_TYPES[ta.get_origin(ty)]
|
1320
|
-
except KeyError:
|
1321
|
-
pass
|
1322
|
-
else:
|
1323
|
-
k, v = ta.get_args(ty)
|
1324
|
-
return MappingObjMarshaler(mt, rec(k), rec(v))
|
1325
1296
|
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
[
|
1332
|
-
|
1297
|
+
class ObjMarshalerManager:
|
1298
|
+
def __init__(
|
1299
|
+
self,
|
1300
|
+
*,
|
1301
|
+
default_obj_marshalers: ta.Dict[ta.Any, ObjMarshaler] = _DEFAULT_OBJ_MARSHALERS, # noqa
|
1302
|
+
generic_mapping_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_MAPPING_TYPES, # noqa
|
1303
|
+
generic_iterable_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES, # noqa
|
1304
|
+
) -> None:
|
1305
|
+
super().__init__()
|
1333
1306
|
|
1334
|
-
|
1335
|
-
|
1307
|
+
self._obj_marshalers = dict(default_obj_marshalers)
|
1308
|
+
self._generic_mapping_types = generic_mapping_types
|
1309
|
+
self._generic_iterable_types = generic_iterable_types
|
1336
1310
|
|
1337
|
-
|
1311
|
+
self._lock = threading.RLock()
|
1312
|
+
self._marshalers: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
|
1313
|
+
self._proxies: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
|
1338
1314
|
|
1315
|
+
#
|
1339
1316
|
|
1340
|
-
|
1317
|
+
def make_obj_marshaler(
|
1318
|
+
self,
|
1319
|
+
ty: ta.Any,
|
1320
|
+
rec: ta.Callable[[ta.Any], ObjMarshaler],
|
1321
|
+
*,
|
1322
|
+
nonstrict_dataclasses: bool = False,
|
1323
|
+
) -> ObjMarshaler:
|
1324
|
+
if isinstance(ty, type):
|
1325
|
+
if abc.ABC in ty.__bases__:
|
1326
|
+
return PolymorphicObjMarshaler.of([ # type: ignore
|
1327
|
+
PolymorphicObjMarshaler.Impl(
|
1328
|
+
ity,
|
1329
|
+
ity.__qualname__,
|
1330
|
+
rec(ity),
|
1331
|
+
)
|
1332
|
+
for ity in deep_subclasses(ty)
|
1333
|
+
if abc.ABC not in ity.__bases__
|
1334
|
+
])
|
1335
|
+
|
1336
|
+
if issubclass(ty, enum.Enum):
|
1337
|
+
return EnumObjMarshaler(ty)
|
1338
|
+
|
1339
|
+
if dc.is_dataclass(ty):
|
1340
|
+
return DataclassObjMarshaler(
|
1341
|
+
ty,
|
1342
|
+
{f.name: rec(f.type) for f in dc.fields(ty)},
|
1343
|
+
nonstrict=nonstrict_dataclasses,
|
1344
|
+
)
|
1341
1345
|
|
1346
|
+
if is_generic_alias(ty):
|
1347
|
+
try:
|
1348
|
+
mt = self._generic_mapping_types[ta.get_origin(ty)]
|
1349
|
+
except KeyError:
|
1350
|
+
pass
|
1351
|
+
else:
|
1352
|
+
k, v = ta.get_args(ty)
|
1353
|
+
return MappingObjMarshaler(mt, rec(k), rec(v))
|
1342
1354
|
|
1343
|
-
|
1355
|
+
try:
|
1356
|
+
st = self._generic_iterable_types[ta.get_origin(ty)]
|
1357
|
+
except KeyError:
|
1358
|
+
pass
|
1359
|
+
else:
|
1360
|
+
[e] = ta.get_args(ty)
|
1361
|
+
return IterableObjMarshaler(st, rec(e))
|
1344
1362
|
|
1345
|
-
|
1363
|
+
if is_union_alias(ty):
|
1364
|
+
return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
|
1346
1365
|
|
1347
|
-
|
1366
|
+
raise TypeError(ty)
|
1348
1367
|
|
1368
|
+
#
|
1349
1369
|
|
1350
|
-
def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1370
|
+
def register_opj_marshaler(self, ty: ta.Any, m: ObjMarshaler) -> None:
|
1371
|
+
with self._lock:
|
1372
|
+
if ty in self._obj_marshalers:
|
1373
|
+
raise KeyError(ty)
|
1374
|
+
self._obj_marshalers[ty] = m
|
1355
1375
|
|
1376
|
+
def get_obj_marshaler(
|
1377
|
+
self,
|
1378
|
+
ty: ta.Any,
|
1379
|
+
*,
|
1380
|
+
no_cache: bool = False,
|
1381
|
+
**kwargs: ta.Any,
|
1382
|
+
) -> ObjMarshaler:
|
1383
|
+
with self._lock:
|
1384
|
+
if not no_cache:
|
1385
|
+
try:
|
1386
|
+
return self._obj_marshalers[ty]
|
1387
|
+
except KeyError:
|
1388
|
+
pass
|
1356
1389
|
|
1357
|
-
def get_obj_marshaler(
|
1358
|
-
ty: ta.Any,
|
1359
|
-
*,
|
1360
|
-
no_cache: bool = False,
|
1361
|
-
**kwargs: ta.Any,
|
1362
|
-
) -> ObjMarshaler:
|
1363
|
-
with _OBJ_MARSHALERS_LOCK:
|
1364
|
-
if not no_cache:
|
1365
1390
|
try:
|
1366
|
-
return
|
1391
|
+
return self._proxies[ty]
|
1367
1392
|
except KeyError:
|
1368
1393
|
pass
|
1369
1394
|
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
rec = functools.partial(
|
1376
|
-
get_obj_marshaler,
|
1377
|
-
no_cache=no_cache,
|
1378
|
-
**kwargs,
|
1379
|
-
)
|
1395
|
+
rec = functools.partial(
|
1396
|
+
self.get_obj_marshaler,
|
1397
|
+
no_cache=no_cache,
|
1398
|
+
**kwargs,
|
1399
|
+
)
|
1380
1400
|
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1401
|
+
p = ProxyObjMarshaler()
|
1402
|
+
self._proxies[ty] = p
|
1403
|
+
try:
|
1404
|
+
m = self.make_obj_marshaler(ty, rec, **kwargs)
|
1405
|
+
finally:
|
1406
|
+
del self._proxies[ty]
|
1407
|
+
p.m = m
|
1388
1408
|
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1409
|
+
if not no_cache:
|
1410
|
+
self._obj_marshalers[ty] = m
|
1411
|
+
return m
|
1412
|
+
|
1413
|
+
#
|
1414
|
+
|
1415
|
+
def marshal_obj(self, o: ta.Any, ty: ta.Any = None) -> ta.Any:
|
1416
|
+
return self.get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
|
1417
|
+
|
1418
|
+
def unmarshal_obj(self, o: ta.Any, ty: ta.Union[ta.Type[T], ta.Any]) -> T:
|
1419
|
+
return self.get_obj_marshaler(ty).unmarshal(o)
|
1392
1420
|
|
1393
1421
|
|
1394
1422
|
##
|
1395
1423
|
|
1396
1424
|
|
1397
|
-
|
1398
|
-
return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
|
1425
|
+
OBJ_MARSHALER_MANAGER = ObjMarshalerManager()
|
1399
1426
|
|
1427
|
+
register_opj_marshaler = OBJ_MARSHALER_MANAGER.register_opj_marshaler
|
1428
|
+
get_obj_marshaler = OBJ_MARSHALER_MANAGER.get_obj_marshaler
|
1400
1429
|
|
1401
|
-
|
1402
|
-
|
1430
|
+
marshal_obj = OBJ_MARSHALER_MANAGER.marshal_obj
|
1431
|
+
unmarshal_obj = OBJ_MARSHALER_MANAGER.unmarshal_obj
|
1403
1432
|
|
1404
1433
|
|
1405
1434
|
########################################
|
@@ -1419,6 +1448,48 @@ def check_runtime_version() -> None:
|
|
1419
1448
|
raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
|
1420
1449
|
|
1421
1450
|
|
1451
|
+
########################################
|
1452
|
+
# ../protocol.py
|
1453
|
+
|
1454
|
+
|
1455
|
+
class Channel:
|
1456
|
+
def __init__(
|
1457
|
+
self,
|
1458
|
+
input: ta.IO, # noqa
|
1459
|
+
output: ta.IO,
|
1460
|
+
*,
|
1461
|
+
msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
|
1462
|
+
) -> None:
|
1463
|
+
super().__init__()
|
1464
|
+
|
1465
|
+
self._input = input
|
1466
|
+
self._output = output
|
1467
|
+
self._msh = msh
|
1468
|
+
|
1469
|
+
def send_obj(self, o: ta.Any, ty: ta.Any = None) -> None:
|
1470
|
+
j = json_dumps_compact(self._msh.marshal_obj(o, ty))
|
1471
|
+
d = j.encode('utf-8')
|
1472
|
+
|
1473
|
+
self._output.write(struct.pack('<I', len(d)))
|
1474
|
+
self._output.write(d)
|
1475
|
+
self._output.flush()
|
1476
|
+
|
1477
|
+
def recv_obj(self, ty: ta.Any) -> ta.Any:
|
1478
|
+
d = self._input.read(4)
|
1479
|
+
if not d:
|
1480
|
+
return None
|
1481
|
+
if len(d) != 4:
|
1482
|
+
raise EOFError
|
1483
|
+
|
1484
|
+
sz = struct.unpack('<I', d)[0]
|
1485
|
+
d = self._input.read(sz)
|
1486
|
+
if len(d) != sz:
|
1487
|
+
raise EOFError
|
1488
|
+
|
1489
|
+
j = json.loads(d.decode('utf-8'))
|
1490
|
+
return self._msh.unmarshal_obj(j, ty)
|
1491
|
+
|
1492
|
+
|
1422
1493
|
########################################
|
1423
1494
|
# ../../../omlish/lite/subprocesses.py
|
1424
1495
|
|
@@ -1426,6 +1497,16 @@ def check_runtime_version() -> None:
|
|
1426
1497
|
##
|
1427
1498
|
|
1428
1499
|
|
1500
|
+
SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
|
1501
|
+
'pipe': subprocess.PIPE,
|
1502
|
+
'stdout': subprocess.STDOUT,
|
1503
|
+
'devnull': subprocess.DEVNULL,
|
1504
|
+
}
|
1505
|
+
|
1506
|
+
|
1507
|
+
##
|
1508
|
+
|
1509
|
+
|
1429
1510
|
_SUBPROCESS_SHELL_WRAP_EXECS = False
|
1430
1511
|
|
1431
1512
|
|
@@ -1552,21 +1633,21 @@ def subprocess_close(
|
|
1552
1633
|
|
1553
1634
|
@dc.dataclass(frozen=True)
|
1554
1635
|
class SubprocessCommand(Command['SubprocessCommand.Output']):
|
1555
|
-
|
1636
|
+
cmd: ta.Sequence[str]
|
1556
1637
|
|
1557
1638
|
shell: bool = False
|
1558
1639
|
cwd: ta.Optional[str] = None
|
1559
1640
|
env: ta.Optional[ta.Mapping[str, str]] = None
|
1560
1641
|
|
1561
|
-
|
1562
|
-
|
1642
|
+
stdout: str = 'pipe' # SubprocessChannelOption
|
1643
|
+
stderr: str = 'pipe' # SubprocessChannelOption
|
1563
1644
|
|
1564
1645
|
input: ta.Optional[bytes] = None
|
1565
1646
|
timeout: ta.Optional[float] = None
|
1566
1647
|
|
1567
1648
|
def __post_init__(self) -> None:
|
1568
|
-
if isinstance(self.
|
1569
|
-
raise TypeError(self.
|
1649
|
+
if isinstance(self.cmd, str):
|
1650
|
+
raise TypeError(self.cmd)
|
1570
1651
|
|
1571
1652
|
@dc.dataclass(frozen=True)
|
1572
1653
|
class Output(Command.Output):
|
@@ -1584,24 +1665,23 @@ class SubprocessCommand(Command['SubprocessCommand.Output']):
|
|
1584
1665
|
|
1585
1666
|
class SubprocessCommandExecutor(CommandExecutor[SubprocessCommand, SubprocessCommand.Output]):
|
1586
1667
|
def execute(self, inp: SubprocessCommand) -> SubprocessCommand.Output:
|
1587
|
-
|
1588
|
-
subprocess_maybe_shell_wrap_exec(*inp.
|
1668
|
+
with subprocess.Popen(
|
1669
|
+
subprocess_maybe_shell_wrap_exec(*inp.cmd),
|
1589
1670
|
|
1590
1671
|
shell=inp.shell,
|
1591
1672
|
cwd=inp.cwd,
|
1592
1673
|
env={**os.environ, **(inp.env or {})},
|
1593
1674
|
|
1594
1675
|
stdin=subprocess.PIPE if inp.input is not None else None,
|
1595
|
-
stdout=
|
1596
|
-
stderr=
|
1597
|
-
)
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
end_time = time.time()
|
1676
|
+
stdout=SUBPROCESS_CHANNEL_OPTION_VALUES[ta.cast(SubprocessChannelOption, inp.stdout)],
|
1677
|
+
stderr=SUBPROCESS_CHANNEL_OPTION_VALUES[ta.cast(SubprocessChannelOption, inp.stderr)],
|
1678
|
+
) as proc:
|
1679
|
+
start_time = time.time()
|
1680
|
+
stdout, stderr = proc.communicate(
|
1681
|
+
input=inp.input,
|
1682
|
+
timeout=inp.timeout,
|
1683
|
+
)
|
1684
|
+
end_time = time.time()
|
1605
1685
|
|
1606
1686
|
return SubprocessCommand.Output(
|
1607
1687
|
rc=proc.returncode,
|
@@ -1628,7 +1708,7 @@ class PySpawner:
|
|
1628
1708
|
shell: ta.Optional[str] = None,
|
1629
1709
|
shell_quote: bool = False,
|
1630
1710
|
python: str = DEFAULT_PYTHON,
|
1631
|
-
stderr: ta.Optional[
|
1711
|
+
stderr: ta.Optional[SubprocessChannelOption] = None,
|
1632
1712
|
) -> None:
|
1633
1713
|
super().__init__()
|
1634
1714
|
|
@@ -1663,12 +1743,6 @@ class PySpawner:
|
|
1663
1743
|
|
1664
1744
|
#
|
1665
1745
|
|
1666
|
-
_STDERR_KWARG_MAP: ta.Mapping[str, int] = {
|
1667
|
-
'pipe': subprocess.PIPE,
|
1668
|
-
'stdout': subprocess.STDOUT,
|
1669
|
-
'devnull': subprocess.DEVNULL,
|
1670
|
-
}
|
1671
|
-
|
1672
1746
|
@dc.dataclass(frozen=True)
|
1673
1747
|
class Spawned:
|
1674
1748
|
stdin: ta.IO
|
@@ -1688,7 +1762,7 @@ class PySpawner:
|
|
1688
1762
|
shell=pc.shell,
|
1689
1763
|
stdin=subprocess.PIPE,
|
1690
1764
|
stdout=subprocess.PIPE,
|
1691
|
-
stderr=
|
1765
|
+
stderr=SUBPROCESS_CHANNEL_OPTION_VALUES[self._stderr] if self._stderr is not None else None,
|
1692
1766
|
) as proc:
|
1693
1767
|
stdin = check_not_none(proc.stdin)
|
1694
1768
|
stdout = check_not_none(proc.stdout)
|
@@ -1721,51 +1795,28 @@ _COMMAND_TYPES = {
|
|
1721
1795
|
}
|
1722
1796
|
|
1723
1797
|
|
1724
|
-
|
1725
|
-
|
1798
|
+
##
|
1799
|
+
|
1800
|
+
|
1801
|
+
def register_command_marshaling(msh: ObjMarshalerManager) -> None:
|
1726
1802
|
for fn in [
|
1727
1803
|
lambda c: c,
|
1728
1804
|
lambda c: c.Output,
|
1729
1805
|
]:
|
1730
|
-
register_opj_marshaler(
|
1806
|
+
msh.register_opj_marshaler(
|
1731
1807
|
fn(Command),
|
1732
1808
|
PolymorphicObjMarshaler.of([
|
1733
1809
|
PolymorphicObjMarshaler.Impl(
|
1734
1810
|
fn(cty),
|
1735
1811
|
k,
|
1736
|
-
get_obj_marshaler(fn(cty)),
|
1812
|
+
msh.get_obj_marshaler(fn(cty)),
|
1737
1813
|
)
|
1738
1814
|
for k, cty in _COMMAND_TYPES.items()
|
1739
1815
|
]),
|
1740
1816
|
)
|
1741
1817
|
|
1742
1818
|
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
def _send_obj(f: ta.IO, o: ta.Any, ty: ta.Any = None) -> None:
|
1747
|
-
j = json_dumps_compact(marshal_obj(o, ty))
|
1748
|
-
d = j.encode('utf-8')
|
1749
|
-
|
1750
|
-
f.write(struct.pack('<I', len(d)))
|
1751
|
-
f.write(d)
|
1752
|
-
f.flush()
|
1753
|
-
|
1754
|
-
|
1755
|
-
def _recv_obj(f: ta.IO, ty: ta.Any) -> ta.Any:
|
1756
|
-
d = f.read(4)
|
1757
|
-
if not d:
|
1758
|
-
return None
|
1759
|
-
if len(d) != 4:
|
1760
|
-
raise EOFError
|
1761
|
-
|
1762
|
-
sz = struct.unpack('<I', d)[0]
|
1763
|
-
d = f.read(sz)
|
1764
|
-
if len(d) != sz:
|
1765
|
-
raise EOFError
|
1766
|
-
|
1767
|
-
j = json.loads(d.decode('utf-8'))
|
1768
|
-
return unmarshal_obj(j, ty)
|
1819
|
+
register_command_marshaling(OBJ_MARSHALER_MANAGER)
|
1769
1820
|
|
1770
1821
|
|
1771
1822
|
##
|
@@ -1773,9 +1824,10 @@ def _recv_obj(f: ta.IO, ty: ta.Any) -> ta.Any:
|
|
1773
1824
|
|
1774
1825
|
def _remote_main() -> None:
|
1775
1826
|
rt = pyremote_bootstrap_finalize() # noqa
|
1827
|
+
chan = Channel(rt.input, rt.output)
|
1776
1828
|
|
1777
1829
|
while True:
|
1778
|
-
i =
|
1830
|
+
i = chan.recv_obj(Command)
|
1779
1831
|
if i is None:
|
1780
1832
|
break
|
1781
1833
|
|
@@ -1784,7 +1836,7 @@ def _remote_main() -> None:
|
|
1784
1836
|
else:
|
1785
1837
|
raise TypeError(i)
|
1786
1838
|
|
1787
|
-
|
1839
|
+
chan.send_obj(o, Command.Output)
|
1788
1840
|
|
1789
1841
|
|
1790
1842
|
##
|
@@ -1795,11 +1847,13 @@ def _main() -> None:
|
|
1795
1847
|
|
1796
1848
|
parser = argparse.ArgumentParser()
|
1797
1849
|
|
1850
|
+
parser.add_argument('--_payload-file')
|
1851
|
+
|
1798
1852
|
parser.add_argument('-s', '--shell')
|
1799
1853
|
parser.add_argument('-q', '--shell-quote', action='store_true')
|
1800
1854
|
parser.add_argument('--python', default='python3')
|
1855
|
+
|
1801
1856
|
parser.add_argument('--debug', action='store_true')
|
1802
|
-
parser.add_argument('--_payload-file')
|
1803
1857
|
|
1804
1858
|
args = parser.parse_args()
|
1805
1859
|
|
@@ -1807,8 +1861,6 @@ def _main() -> None:
|
|
1807
1861
|
|
1808
1862
|
payload_src = get_payload_src(file=args._payload_file) # noqa
|
1809
1863
|
|
1810
|
-
#
|
1811
|
-
|
1812
1864
|
remote_src = '\n\n'.join([
|
1813
1865
|
'__name__ = "__remote__"',
|
1814
1866
|
payload_src,
|
@@ -1817,41 +1869,32 @@ def _main() -> None:
|
|
1817
1869
|
|
1818
1870
|
#
|
1819
1871
|
|
1820
|
-
bs_src = pyremote_build_bootstrap_cmd(__package__ or 'manage')
|
1821
|
-
|
1822
|
-
#
|
1823
|
-
|
1824
1872
|
spawner = PySpawner(
|
1825
|
-
|
1873
|
+
pyremote_build_bootstrap_cmd(__package__ or 'manage'),
|
1826
1874
|
shell=args.shell,
|
1827
1875
|
shell_quote=args.shell_quote,
|
1828
1876
|
python=args.python,
|
1829
1877
|
)
|
1878
|
+
|
1830
1879
|
with spawner.spawn() as proc:
|
1831
1880
|
res = PyremoteBootstrapDriver( # noqa
|
1832
1881
|
remote_src,
|
1833
1882
|
PyremoteBootstrapOptions(
|
1834
1883
|
debug=args.debug,
|
1835
1884
|
),
|
1836
|
-
).run(proc.
|
1837
|
-
|
1885
|
+
).run(proc.stdout, proc.stdin)
|
1886
|
+
|
1887
|
+
chan = Channel(proc.stdout, proc.stdin)
|
1838
1888
|
|
1839
1889
|
#
|
1840
1890
|
|
1841
1891
|
for ci in [
|
1842
|
-
SubprocessCommand(
|
1843
|
-
|
1844
|
-
input=b'print(1)\n',
|
1845
|
-
capture_stdout=True,
|
1846
|
-
),
|
1847
|
-
SubprocessCommand(
|
1848
|
-
args=['uname'],
|
1849
|
-
capture_stdout=True,
|
1850
|
-
),
|
1892
|
+
SubprocessCommand(['python3', '-'], input=b'print(1)\n'),
|
1893
|
+
SubprocessCommand(['uname']),
|
1851
1894
|
]:
|
1852
|
-
|
1895
|
+
chan.send_obj(ci, Command)
|
1853
1896
|
|
1854
|
-
o =
|
1897
|
+
o = chan.recv_obj(Command.Output)
|
1855
1898
|
|
1856
1899
|
print(o)
|
1857
1900
|
|