ominfra 0.0.0.dev154__py3-none-any.whl → 0.0.0.dev155__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/bootstrap.py +4 -0
- ominfra/manage/bootstrap_.py +5 -0
- ominfra/manage/commands/inject.py +8 -11
- ominfra/manage/commands/{execution.py → local.py} +1 -5
- ominfra/manage/commands/ping.py +23 -0
- ominfra/manage/commands/types.py +8 -0
- ominfra/manage/deploy/apps.py +72 -0
- ominfra/manage/deploy/config.py +8 -0
- ominfra/manage/deploy/git.py +136 -0
- ominfra/manage/deploy/inject.py +21 -0
- ominfra/manage/deploy/paths.py +81 -28
- ominfra/manage/deploy/types.py +13 -0
- ominfra/manage/deploy/venvs.py +66 -0
- ominfra/manage/inject.py +20 -4
- ominfra/manage/main.py +15 -27
- ominfra/manage/remote/_main.py +1 -1
- ominfra/manage/remote/config.py +0 -2
- ominfra/manage/remote/connection.py +7 -24
- ominfra/manage/remote/execution.py +1 -1
- ominfra/manage/remote/inject.py +3 -14
- ominfra/manage/system/commands.py +22 -2
- ominfra/manage/system/config.py +3 -1
- ominfra/manage/system/inject.py +16 -6
- ominfra/manage/system/packages.py +33 -7
- ominfra/manage/system/platforms.py +72 -0
- ominfra/manage/targets/__init__.py +0 -0
- ominfra/manage/targets/connection.py +150 -0
- ominfra/manage/targets/inject.py +42 -0
- ominfra/manage/targets/targets.py +87 -0
- ominfra/scripts/journald2aws.py +24 -7
- ominfra/scripts/manage.py +1880 -438
- ominfra/scripts/supervisor.py +187 -25
- ominfra/supervisor/configs.py +163 -18
- {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/RECORD +40 -29
- ominfra/manage/system/types.py +0 -5
- /ominfra/manage/{commands → deploy}/interp.py +0 -0
- {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev154.dist-info → ominfra-0.0.0.dev155.dist-info}/top_level.txt +0 -0
ominfra/manage/inject.py
CHANGED
@@ -6,8 +6,10 @@ from omlish.lite.inject import InjectorBindings
|
|
6
6
|
from omlish.lite.inject import inj
|
7
7
|
from omlish.lite.marshal import ObjMarshalerManager
|
8
8
|
|
9
|
+
from .bootstrap import MainBootstrap
|
9
10
|
from .commands.inject import bind_commands
|
10
11
|
from .config import MainConfig
|
12
|
+
from .deploy.config import DeployConfig
|
11
13
|
from .deploy.inject import bind_deploy
|
12
14
|
from .marshal import ObjMarshalerInstaller
|
13
15
|
from .marshal import ObjMarshalerInstallers
|
@@ -15,6 +17,7 @@ from .remote.config import RemoteConfig
|
|
15
17
|
from .remote.inject import bind_remote
|
16
18
|
from .system.config import SystemConfig
|
17
19
|
from .system.inject import bind_system
|
20
|
+
from .targets.inject import bind_targets
|
18
21
|
|
19
22
|
|
20
23
|
##
|
@@ -22,9 +25,13 @@ from .system.inject import bind_system
|
|
22
25
|
|
23
26
|
def bind_main(
|
24
27
|
*,
|
25
|
-
main_config: MainConfig,
|
26
|
-
|
27
|
-
|
28
|
+
main_config: MainConfig = MainConfig(),
|
29
|
+
|
30
|
+
deploy_config: DeployConfig = DeployConfig(),
|
31
|
+
remote_config: RemoteConfig = RemoteConfig(),
|
32
|
+
system_config: SystemConfig = SystemConfig(),
|
33
|
+
|
34
|
+
main_bootstrap: ta.Optional[MainBootstrap] = None,
|
28
35
|
) -> InjectorBindings:
|
29
36
|
lst: ta.List[InjectorBindingOrBindings] = [
|
30
37
|
inj.bind(main_config),
|
@@ -33,7 +40,9 @@ def bind_main(
|
|
33
40
|
main_config=main_config,
|
34
41
|
),
|
35
42
|
|
36
|
-
bind_deploy(
|
43
|
+
bind_deploy(
|
44
|
+
deploy_config=deploy_config,
|
45
|
+
),
|
37
46
|
|
38
47
|
bind_remote(
|
39
48
|
remote_config=remote_config,
|
@@ -42,10 +51,17 @@ def bind_main(
|
|
42
51
|
bind_system(
|
43
52
|
system_config=system_config,
|
44
53
|
),
|
54
|
+
|
55
|
+
bind_targets(),
|
45
56
|
]
|
46
57
|
|
47
58
|
#
|
48
59
|
|
60
|
+
if main_bootstrap is not None:
|
61
|
+
lst.append(inj.bind(main_bootstrap))
|
62
|
+
|
63
|
+
#
|
64
|
+
|
49
65
|
def build_obj_marshaler_manager(insts: ObjMarshalerInstallers) -> ObjMarshalerManager:
|
50
66
|
msh = ObjMarshalerManager()
|
51
67
|
inst: ObjMarshalerInstaller
|
ominfra/manage/main.py
CHANGED
@@ -6,7 +6,6 @@ manage.py -s 'docker run -i python:3.12'
|
|
6
6
|
manage.py -s 'ssh -i /foo/bar.pem foo@bar.baz' -q --python=python3.8
|
7
7
|
"""
|
8
8
|
import asyncio
|
9
|
-
import contextlib
|
10
9
|
import json
|
11
10
|
import sys
|
12
11
|
import typing as ta
|
@@ -22,22 +21,17 @@ from omlish.lite.pycharm import PycharmRemoteDebug
|
|
22
21
|
from .bootstrap import MainBootstrap
|
23
22
|
from .bootstrap_ import main_bootstrap
|
24
23
|
from .commands.base import Command
|
25
|
-
from .commands.base import CommandExecutor
|
26
|
-
from .commands.execution import LocalCommandExecutor
|
27
24
|
from .config import MainConfig
|
25
|
+
from .deploy.config import DeployConfig
|
28
26
|
from .remote.config import RemoteConfig
|
29
|
-
from .
|
30
|
-
from .
|
27
|
+
from .targets.connection import ManageTargetConnector
|
28
|
+
from .targets.targets import ManageTarget
|
31
29
|
|
32
30
|
|
33
31
|
class MainCli(ArgparseCli):
|
34
32
|
@argparse_command(
|
35
33
|
argparse_arg('--_payload-file'),
|
36
34
|
|
37
|
-
argparse_arg('-s', '--shell'),
|
38
|
-
argparse_arg('-q', '--shell-quote', action='store_true'),
|
39
|
-
argparse_arg('--python', default='python3'),
|
40
|
-
|
41
35
|
argparse_arg('--pycharm-debug-port', type=int),
|
42
36
|
argparse_arg('--pycharm-debug-host'),
|
43
37
|
argparse_arg('--pycharm-debug-version'),
|
@@ -46,8 +40,9 @@ class MainCli(ArgparseCli):
|
|
46
40
|
|
47
41
|
argparse_arg('--debug', action='store_true'),
|
48
42
|
|
49
|
-
argparse_arg('--
|
43
|
+
argparse_arg('--deploy-home'),
|
50
44
|
|
45
|
+
argparse_arg('target'),
|
51
46
|
argparse_arg('command', nargs='+'),
|
52
47
|
)
|
53
48
|
async def run(self) -> None:
|
@@ -58,6 +53,10 @@ class MainCli(ArgparseCli):
|
|
58
53
|
debug=bool(self.args.debug),
|
59
54
|
),
|
60
55
|
|
56
|
+
deploy_config=DeployConfig(
|
57
|
+
deploy_home=self.args.deploy_home,
|
58
|
+
),
|
59
|
+
|
61
60
|
remote_config=RemoteConfig(
|
62
61
|
payload_file=self.args._payload_file, # noqa
|
63
62
|
|
@@ -68,8 +67,6 @@ class MainCli(ArgparseCli):
|
|
68
67
|
) if self.args.pycharm_debug_port is not None else None,
|
69
68
|
|
70
69
|
timebomb_delay_s=self.args.remote_timebomb_delay_s,
|
71
|
-
|
72
|
-
use_in_process_remote_executor=True,
|
73
70
|
),
|
74
71
|
)
|
75
72
|
|
@@ -83,6 +80,11 @@ class MainCli(ArgparseCli):
|
|
83
80
|
|
84
81
|
msh = injector[ObjMarshalerManager]
|
85
82
|
|
83
|
+
ts = self.args.target
|
84
|
+
if not ts.startswith('{'):
|
85
|
+
ts = json.dumps({ts: {}})
|
86
|
+
tgt: ManageTarget = msh.unmarshal_obj(json.loads(ts), ManageTarget)
|
87
|
+
|
86
88
|
cmds: ta.List[Command] = []
|
87
89
|
cmd: Command
|
88
90
|
for c in self.args.command:
|
@@ -93,21 +95,7 @@ class MainCli(ArgparseCli):
|
|
93
95
|
|
94
96
|
#
|
95
97
|
|
96
|
-
async with
|
97
|
-
ce: CommandExecutor
|
98
|
-
|
99
|
-
if self.args.local:
|
100
|
-
ce = injector[LocalCommandExecutor]
|
101
|
-
|
102
|
-
else:
|
103
|
-
tgt = RemoteSpawning.Target(
|
104
|
-
shell=self.args.shell,
|
105
|
-
shell_quote=self.args.shell_quote,
|
106
|
-
python=self.args.python,
|
107
|
-
)
|
108
|
-
|
109
|
-
ce = await es.enter_async_context(injector[RemoteExecutionConnector].connect(tgt, bs)) # noqa
|
110
|
-
|
98
|
+
async with injector[ManageTargetConnector].connect(tgt) as ce:
|
111
99
|
async def run_command(cmd: Command) -> None:
|
112
100
|
res = await ce.try_execute(
|
113
101
|
cmd,
|
ominfra/manage/remote/_main.py
CHANGED
@@ -20,7 +20,7 @@ from omlish.os.deathsig import set_process_deathsig
|
|
20
20
|
|
21
21
|
from ...pyremote import pyremote_bootstrap_finalize
|
22
22
|
from ..bootstrap import MainBootstrap
|
23
|
-
from ..commands.
|
23
|
+
from ..commands.local import LocalCommandExecutor
|
24
24
|
from .channel import RemoteChannel
|
25
25
|
from .channel import RemoteChannelImpl
|
26
26
|
from .execution import _RemoteCommandHandler
|
ominfra/manage/remote/config.py
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
import abc
|
3
2
|
import asyncio
|
4
3
|
import contextlib
|
5
4
|
import typing as ta
|
6
5
|
|
7
6
|
from omlish.asyncs.asyncio.channels import asyncio_create_bytes_channel
|
8
7
|
from omlish.lite.cached import cached_nullary
|
8
|
+
from omlish.lite.contextmanagers import aclosing
|
9
9
|
from omlish.lite.marshal import ObjMarshalerManager
|
10
10
|
|
11
11
|
from ...pyremote import PyremoteBootstrapDriver
|
12
12
|
from ...pyremote import PyremoteBootstrapOptions
|
13
13
|
from ...pyremote import pyremote_build_bootstrap_cmd
|
14
14
|
from ..bootstrap import MainBootstrap
|
15
|
-
from ..commands.
|
15
|
+
from ..commands.local import LocalCommandExecutor
|
16
16
|
from ._main import _remote_execution_main # noqa
|
17
17
|
from .channel import RemoteChannelImpl
|
18
18
|
from .execution import RemoteCommandExecutor
|
@@ -25,20 +25,7 @@ from .spawning import RemoteSpawning
|
|
25
25
|
##
|
26
26
|
|
27
27
|
|
28
|
-
class
|
29
|
-
@abc.abstractmethod
|
30
|
-
def connect(
|
31
|
-
self,
|
32
|
-
tgt: RemoteSpawning.Target,
|
33
|
-
bs: MainBootstrap,
|
34
|
-
) -> ta.AsyncContextManager[RemoteCommandExecutor]:
|
35
|
-
raise NotImplementedError
|
36
|
-
|
37
|
-
|
38
|
-
##
|
39
|
-
|
40
|
-
|
41
|
-
class PyremoteRemoteExecutionConnector(RemoteExecutionConnector):
|
28
|
+
class PyremoteRemoteExecutionConnector:
|
42
29
|
def __init__(
|
43
30
|
self,
|
44
31
|
*,
|
@@ -104,7 +91,7 @@ class PyremoteRemoteExecutionConnector(RemoteExecutionConnector):
|
|
104
91
|
await chan.send_obj(bs)
|
105
92
|
|
106
93
|
rce: RemoteCommandExecutor
|
107
|
-
async with
|
94
|
+
async with aclosing(RemoteCommandExecutor(chan)) as rce:
|
108
95
|
await rce.start()
|
109
96
|
|
110
97
|
yield rce
|
@@ -113,7 +100,7 @@ class PyremoteRemoteExecutionConnector(RemoteExecutionConnector):
|
|
113
100
|
##
|
114
101
|
|
115
102
|
|
116
|
-
class InProcessRemoteExecutionConnector
|
103
|
+
class InProcessRemoteExecutionConnector:
|
117
104
|
def __init__(
|
118
105
|
self,
|
119
106
|
*,
|
@@ -126,11 +113,7 @@ class InProcessRemoteExecutionConnector(RemoteExecutionConnector):
|
|
126
113
|
self._local_executor = local_executor
|
127
114
|
|
128
115
|
@contextlib.asynccontextmanager
|
129
|
-
async def connect(
|
130
|
-
self,
|
131
|
-
tgt: RemoteSpawning.Target,
|
132
|
-
bs: MainBootstrap,
|
133
|
-
) -> ta.AsyncGenerator[RemoteCommandExecutor, None]:
|
116
|
+
async def connect(self) -> ta.AsyncGenerator[RemoteCommandExecutor, None]:
|
134
117
|
r0, w0 = asyncio_create_bytes_channel()
|
135
118
|
r1, w1 = asyncio_create_bytes_channel()
|
136
119
|
|
@@ -144,7 +127,7 @@ class InProcessRemoteExecutionConnector(RemoteExecutionConnector):
|
|
144
127
|
rch_task = asyncio.create_task(rch.run()) # noqa
|
145
128
|
try:
|
146
129
|
rce: RemoteCommandExecutor
|
147
|
-
async with
|
130
|
+
async with aclosing(RemoteCommandExecutor(local_chan)) as rce:
|
148
131
|
await rce.start()
|
149
132
|
|
150
133
|
yield rce
|
@@ -394,7 +394,7 @@ class RemoteCommandExecutor(CommandExecutor):
|
|
394
394
|
self,
|
395
395
|
cmd: Command,
|
396
396
|
*,
|
397
|
-
log: ta.Optional[logging.Logger] = None,
|
397
|
+
log: ta.Optional[logging.Logger] = None, # noqa
|
398
398
|
omit_exc_object: bool = False,
|
399
399
|
) -> CommandOutputOrException:
|
400
400
|
try:
|
ominfra/manage/remote/inject.py
CHANGED
@@ -8,7 +8,6 @@ from omlish.lite.inject import inj
|
|
8
8
|
from .config import RemoteConfig
|
9
9
|
from .connection import InProcessRemoteExecutionConnector
|
10
10
|
from .connection import PyremoteRemoteExecutionConnector
|
11
|
-
from .connection import RemoteExecutionConnector
|
12
11
|
from .payload import RemoteExecutionPayloadFile
|
13
12
|
from .spawning import RemoteSpawning
|
14
13
|
from .spawning import SubprocessRemoteSpawning
|
@@ -23,20 +22,10 @@ def bind_remote(
|
|
23
22
|
|
24
23
|
inj.bind(SubprocessRemoteSpawning, singleton=True),
|
25
24
|
inj.bind(RemoteSpawning, to_key=SubprocessRemoteSpawning),
|
26
|
-
]
|
27
|
-
|
28
|
-
#
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
inj.bind(RemoteExecutionConnector, to_key=InProcessRemoteExecutionConnector),
|
34
|
-
])
|
35
|
-
else:
|
36
|
-
lst.extend([
|
37
|
-
inj.bind(PyremoteRemoteExecutionConnector, singleton=True),
|
38
|
-
inj.bind(RemoteExecutionConnector, to_key=PyremoteRemoteExecutionConnector),
|
39
|
-
])
|
26
|
+
inj.bind(PyremoteRemoteExecutionConnector, singleton=True),
|
27
|
+
inj.bind(InProcessRemoteExecutionConnector, singleton=True),
|
28
|
+
]
|
40
29
|
|
41
30
|
#
|
42
31
|
|
@@ -1,10 +1,14 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
2
|
import dataclasses as dc
|
3
|
+
import typing as ta
|
3
4
|
|
5
|
+
from omlish.lite.check import check
|
4
6
|
from omlish.lite.logs import log
|
5
7
|
|
6
8
|
from ..commands.base import Command
|
7
9
|
from ..commands.base import CommandExecutor
|
10
|
+
from .packages import SystemPackage
|
11
|
+
from .packages import SystemPackageManager
|
8
12
|
|
9
13
|
|
10
14
|
##
|
@@ -12,13 +16,29 @@ from ..commands.base import CommandExecutor
|
|
12
16
|
|
13
17
|
@dc.dataclass(frozen=True)
|
14
18
|
class CheckSystemPackageCommand(Command['CheckSystemPackageCommand.Output']):
|
19
|
+
pkgs: ta.Sequence[str] = ()
|
20
|
+
|
21
|
+
def __post_init__(self) -> None:
|
22
|
+
check.not_isinstance(self.pkgs, str)
|
23
|
+
|
15
24
|
@dc.dataclass(frozen=True)
|
16
25
|
class Output(Command.Output):
|
17
|
-
|
26
|
+
pkgs: ta.Sequence[SystemPackage]
|
18
27
|
|
19
28
|
|
20
29
|
class CheckSystemPackageCommandExecutor(CommandExecutor[CheckSystemPackageCommand, CheckSystemPackageCommand.Output]):
|
30
|
+
def __init__(
|
31
|
+
self,
|
32
|
+
*,
|
33
|
+
mgr: SystemPackageManager,
|
34
|
+
) -> None:
|
35
|
+
super().__init__()
|
36
|
+
|
37
|
+
self._mgr = mgr
|
38
|
+
|
21
39
|
async def execute(self, cmd: CheckSystemPackageCommand) -> CheckSystemPackageCommand.Output:
|
22
40
|
log.info('Checking system package!')
|
23
41
|
|
24
|
-
|
42
|
+
ret = await self._mgr.query(*cmd.pkgs)
|
43
|
+
|
44
|
+
return CheckSystemPackageCommand.Output(list(ret.values()))
|
ominfra/manage/system/config.py
CHANGED
ominfra/manage/system/inject.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
import sys
|
3
2
|
import typing as ta
|
4
3
|
|
5
4
|
from omlish.lite.inject import InjectorBindingOrBindings
|
@@ -13,7 +12,12 @@ from .config import SystemConfig
|
|
13
12
|
from .packages import AptSystemPackageManager
|
14
13
|
from .packages import BrewSystemPackageManager
|
15
14
|
from .packages import SystemPackageManager
|
16
|
-
from .
|
15
|
+
from .packages import YumSystemPackageManager
|
16
|
+
from .platforms import AmazonLinuxPlatform
|
17
|
+
from .platforms import DarwinPlatform
|
18
|
+
from .platforms import LinuxPlatform
|
19
|
+
from .platforms import Platform
|
20
|
+
from .platforms import detect_system_platform
|
17
21
|
|
18
22
|
|
19
23
|
def bind_system(
|
@@ -26,18 +30,24 @@ def bind_system(
|
|
26
30
|
|
27
31
|
#
|
28
32
|
|
29
|
-
platform = system_config.platform or
|
30
|
-
lst.append(inj.bind(platform, key=
|
33
|
+
platform = system_config.platform or detect_system_platform()
|
34
|
+
lst.append(inj.bind(platform, key=Platform))
|
31
35
|
|
32
36
|
#
|
33
37
|
|
34
|
-
if platform
|
38
|
+
if isinstance(platform, AmazonLinuxPlatform):
|
39
|
+
lst.extend([
|
40
|
+
inj.bind(YumSystemPackageManager, singleton=True),
|
41
|
+
inj.bind(SystemPackageManager, to_key=YumSystemPackageManager),
|
42
|
+
])
|
43
|
+
|
44
|
+
elif isinstance(platform, LinuxPlatform):
|
35
45
|
lst.extend([
|
36
46
|
inj.bind(AptSystemPackageManager, singleton=True),
|
37
47
|
inj.bind(SystemPackageManager, to_key=AptSystemPackageManager),
|
38
48
|
])
|
39
49
|
|
40
|
-
elif platform
|
50
|
+
elif isinstance(platform, DarwinPlatform):
|
41
51
|
lst.extend([
|
42
52
|
inj.bind(BrewSystemPackageManager, singleton=True),
|
43
53
|
inj.bind(SystemPackageManager, to_key=BrewSystemPackageManager),
|
@@ -79,28 +79,54 @@ class AptSystemPackageManager(SystemPackageManager):
|
|
79
79
|
}
|
80
80
|
|
81
81
|
async def update(self) -> None:
|
82
|
-
await asyncio_subprocess_check_call('apt', 'update', env={**os.environ, **self._APT_ENV})
|
82
|
+
await asyncio_subprocess_check_call('sudo', 'apt', 'update', env={**os.environ, **self._APT_ENV})
|
83
83
|
|
84
84
|
async def upgrade(self) -> None:
|
85
|
-
await asyncio_subprocess_check_call('apt', 'upgrade', '-y', env={**os.environ, **self._APT_ENV})
|
85
|
+
await asyncio_subprocess_check_call('sudo', 'apt', 'upgrade', '-y', env={**os.environ, **self._APT_ENV})
|
86
86
|
|
87
87
|
async def install(self, *packages: SystemPackageOrStr) -> None:
|
88
88
|
pns = [p.name if isinstance(p, SystemPackage) else p for p in packages] # FIXME: versions
|
89
|
-
await asyncio_subprocess_check_call('apt', 'install', '-y', *pns, env={**os.environ, **self._APT_ENV})
|
89
|
+
await asyncio_subprocess_check_call('sudo', 'apt', 'install', '-y', *pns, env={**os.environ, **self._APT_ENV})
|
90
90
|
|
91
91
|
async def query(self, *packages: SystemPackageOrStr) -> ta.Mapping[str, SystemPackage]:
|
92
92
|
pns = [p.name if isinstance(p, SystemPackage) else p for p in packages]
|
93
|
-
|
94
|
-
|
95
|
-
*cmd,
|
93
|
+
out = await asyncio_subprocess_run(
|
94
|
+
'dpkg-query', '-W', '-f=${Package}=${Version}\n', *pns,
|
96
95
|
capture_output=True,
|
97
96
|
check=False,
|
98
97
|
)
|
99
98
|
d: ta.Dict[str, SystemPackage] = {}
|
100
|
-
for l in check.not_none(stdout).decode('utf-8').strip().splitlines():
|
99
|
+
for l in check.not_none(out.stdout).decode('utf-8').strip().splitlines():
|
101
100
|
n, v = l.split('=', 1)
|
102
101
|
d[n] = SystemPackage(
|
103
102
|
name=n,
|
104
103
|
version=v,
|
105
104
|
)
|
106
105
|
return d
|
106
|
+
|
107
|
+
|
108
|
+
class YumSystemPackageManager(SystemPackageManager):
|
109
|
+
async def update(self) -> None:
|
110
|
+
await asyncio_subprocess_check_call('sudo', 'yum', 'check-update')
|
111
|
+
|
112
|
+
async def upgrade(self) -> None:
|
113
|
+
await asyncio_subprocess_check_call('sudo', 'yum', 'update')
|
114
|
+
|
115
|
+
async def install(self, *packages: SystemPackageOrStr) -> None:
|
116
|
+
pns = [p.name if isinstance(p, SystemPackage) else p for p in packages] # FIXME: versions
|
117
|
+
await asyncio_subprocess_check_call('sudo', 'yum', 'install', *pns)
|
118
|
+
|
119
|
+
async def query(self, *packages: SystemPackageOrStr) -> ta.Mapping[str, SystemPackage]:
|
120
|
+
pns = [p.name if isinstance(p, SystemPackage) else p for p in packages]
|
121
|
+
d: ta.Dict[str, SystemPackage] = {}
|
122
|
+
for pn in pns:
|
123
|
+
out = await asyncio_subprocess_run(
|
124
|
+
'rpm', '-q', pn,
|
125
|
+
capture_output=True,
|
126
|
+
)
|
127
|
+
if not out.proc.returncode:
|
128
|
+
d[pn] = SystemPackage(
|
129
|
+
pn,
|
130
|
+
check.not_none(out.stdout).decode().strip(),
|
131
|
+
)
|
132
|
+
return d
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import abc
|
2
|
+
import dataclasses as dc
|
3
|
+
import sys
|
4
|
+
|
5
|
+
from omlish.lite.cached import cached_nullary
|
6
|
+
from omlish.lite.logs import log
|
7
|
+
from omlish.os.linux import LinuxOsRelease
|
8
|
+
|
9
|
+
|
10
|
+
##
|
11
|
+
|
12
|
+
|
13
|
+
@dc.dataclass(frozen=True)
|
14
|
+
class Platform(abc.ABC): # noqa
|
15
|
+
pass
|
16
|
+
|
17
|
+
|
18
|
+
class LinuxPlatform(Platform, abc.ABC):
|
19
|
+
pass
|
20
|
+
|
21
|
+
|
22
|
+
class UbuntuPlatform(LinuxPlatform):
|
23
|
+
pass
|
24
|
+
|
25
|
+
|
26
|
+
class AmazonLinuxPlatform(LinuxPlatform):
|
27
|
+
pass
|
28
|
+
|
29
|
+
|
30
|
+
class GenericLinuxPlatform(LinuxPlatform):
|
31
|
+
pass
|
32
|
+
|
33
|
+
|
34
|
+
class DarwinPlatform(Platform):
|
35
|
+
pass
|
36
|
+
|
37
|
+
|
38
|
+
class UnknownPlatform(Platform):
|
39
|
+
pass
|
40
|
+
|
41
|
+
|
42
|
+
##
|
43
|
+
|
44
|
+
|
45
|
+
def _detect_system_platform() -> Platform:
|
46
|
+
plat = sys.platform
|
47
|
+
|
48
|
+
if plat == 'linux':
|
49
|
+
if (osr := LinuxOsRelease.read()) is None:
|
50
|
+
return GenericLinuxPlatform()
|
51
|
+
|
52
|
+
if osr.id == 'amzn':
|
53
|
+
return AmazonLinuxPlatform()
|
54
|
+
|
55
|
+
elif osr.id == 'ubuntu':
|
56
|
+
return UbuntuPlatform()
|
57
|
+
|
58
|
+
else:
|
59
|
+
return GenericLinuxPlatform()
|
60
|
+
|
61
|
+
elif plat == 'darwin':
|
62
|
+
return DarwinPlatform()
|
63
|
+
|
64
|
+
else:
|
65
|
+
return UnknownPlatform()
|
66
|
+
|
67
|
+
|
68
|
+
@cached_nullary
|
69
|
+
def detect_system_platform() -> Platform:
|
70
|
+
platform = _detect_system_platform()
|
71
|
+
log.info('Detected platform: %r', platform)
|
72
|
+
return platform
|
File without changes
|