ominfra 0.0.0.dev141__py3-none-any.whl → 0.0.0.dev142__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|