ominfra 0.0.0.dev174__tar.gz → 0.0.0.dev176__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. {ominfra-0.0.0.dev174/ominfra.egg-info → ominfra-0.0.0.dev176}/PKG-INFO +3 -3
  2. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/configs.py +4 -2
  3. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/commands/marshal.py +1 -1
  4. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/apps.py +2 -0
  5. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/conf.py +12 -6
  6. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/paths/paths.py +2 -2
  7. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/specs.py +3 -9
  8. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/tags.py +4 -0
  9. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/venvs.py +11 -1
  10. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/main.py +12 -3
  11. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/scripts/journald2aws.py +40 -5
  12. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/scripts/manage.py +1429 -1373
  13. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/scripts/supervisor.py +40 -5
  14. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176/ominfra.egg-info}/PKG-INFO +3 -3
  15. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra.egg-info/requires.txt +2 -2
  16. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/pyproject.toml +3 -3
  17. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/LICENSE +0 -0
  18. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/MANIFEST.in +0 -0
  19. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/README.rst +0 -0
  20. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/.manifests.json +0 -0
  21. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/__about__.py +0 -0
  22. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/__init__.py +0 -0
  23. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/__init__.py +0 -0
  24. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/__init__.py +0 -0
  25. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/__main__.py +0 -0
  26. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/auth.py +0 -0
  27. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/cli.py +0 -0
  28. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/dataclasses.py +0 -0
  29. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/journald2aws/__init__.py +0 -0
  30. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/journald2aws/__main__.py +0 -0
  31. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/journald2aws/cursor.py +0 -0
  32. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/journald2aws/driver.py +0 -0
  33. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/journald2aws/main.py +0 -0
  34. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/journald2aws/poster.py +0 -0
  35. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/logs.py +0 -0
  36. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/aws/metadata.py +0 -0
  37. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/gcp/__init__.py +0 -0
  38. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/clouds/gcp/auth.py +0 -0
  39. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/cmds.py +0 -0
  40. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/journald/__init__.py +0 -0
  41. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/journald/fields.py +0 -0
  42. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/journald/genmessages.py +0 -0
  43. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/journald/messages.py +0 -0
  44. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/journald/tailer.py +0 -0
  45. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/__init__.py +0 -0
  46. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/__main__.py +0 -0
  47. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/bootstrap.py +0 -0
  48. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/bootstrap_.py +0 -0
  49. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/commands/__init__.py +0 -0
  50. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/commands/base.py +0 -0
  51. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/commands/inject.py +0 -0
  52. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/commands/local.py +0 -0
  53. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/commands/ping.py +0 -0
  54. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/commands/subprocess.py +0 -0
  55. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/commands/types.py +0 -0
  56. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/config.py +0 -0
  57. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/__init__.py +0 -0
  58. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/commands.py +0 -0
  59. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/config.py +0 -0
  60. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/deploy.py +0 -0
  61. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/git.py +0 -0
  62. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/inject.py +0 -0
  63. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/interp.py +0 -0
  64. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/paths/__init__.py +0 -0
  65. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/paths/inject.py +0 -0
  66. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/paths/manager.py +0 -0
  67. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/paths/owners.py +0 -0
  68. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/paths/types.py +0 -0
  69. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/tmp.py +0 -0
  70. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/deploy/types.py +0 -0
  71. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/inject.py +0 -0
  72. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/marshal.py +0 -0
  73. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/remote/__init__.py +0 -0
  74. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/remote/_main.py +0 -0
  75. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/remote/channel.py +0 -0
  76. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/remote/config.py +0 -0
  77. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/remote/connection.py +0 -0
  78. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/remote/execution.py +0 -0
  79. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/remote/inject.py +0 -0
  80. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/remote/payload.py +0 -0
  81. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/remote/spawning.py +0 -0
  82. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/system/__init__.py +0 -0
  83. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/system/commands.py +0 -0
  84. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/system/config.py +0 -0
  85. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/system/inject.py +0 -0
  86. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/system/packages.py +0 -0
  87. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/system/platforms.py +0 -0
  88. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/targets/__init__.py +0 -0
  89. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/targets/bestpython.py +0 -0
  90. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/targets/bestpython.sh +0 -0
  91. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/targets/connection.py +0 -0
  92. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/targets/inject.py +0 -0
  93. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/manage/targets/targets.py +0 -0
  94. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/pyremote.py +0 -0
  95. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/scripts/__init__.py +0 -0
  96. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/ssh.py +0 -0
  97. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/LICENSE.txt +0 -0
  98. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/__init__.py +0 -0
  99. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/__main__.py +0 -0
  100. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/configs.py +0 -0
  101. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/dispatchers.py +0 -0
  102. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/dispatchersimpl.py +0 -0
  103. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/events.py +0 -0
  104. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/exceptions.py +0 -0
  105. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/groups.py +0 -0
  106. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/groupsimpl.py +0 -0
  107. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/http.py +0 -0
  108. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/inject.py +0 -0
  109. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/io.py +0 -0
  110. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/main.py +0 -0
  111. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/pipes.py +0 -0
  112. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/privileges.py +0 -0
  113. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/process.py +0 -0
  114. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/processimpl.py +0 -0
  115. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/setup.py +0 -0
  116. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/setupimpl.py +0 -0
  117. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/signals.py +0 -0
  118. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/spawning.py +0 -0
  119. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/spawningimpl.py +0 -0
  120. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/states.py +0 -0
  121. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/supervisor.py +0 -0
  122. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/types.py +0 -0
  123. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/__init__.py +0 -0
  124. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/collections.py +0 -0
  125. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/diag.py +0 -0
  126. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/fds.py +0 -0
  127. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/fs.py +0 -0
  128. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/os.py +0 -0
  129. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/ostypes.py +0 -0
  130. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/signals.py +0 -0
  131. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/strings.py +0 -0
  132. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/supervisor/utils/users.py +0 -0
  133. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/tailscale/__init__.py +0 -0
  134. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/tailscale/api.py +0 -0
  135. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/tailscale/cli.py +0 -0
  136. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/threadworkers.py +0 -0
  137. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/tools/__init__.py +0 -0
  138. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra/tools/listresources.py +0 -0
  139. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra.egg-info/SOURCES.txt +0 -0
  140. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra.egg-info/dependency_links.txt +0 -0
  141. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra.egg-info/entry_points.txt +0 -0
  142. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/ominfra.egg-info/top_level.txt +0 -0
  143. {ominfra-0.0.0.dev174 → ominfra-0.0.0.dev176}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ominfra
3
- Version: 0.0.0.dev174
3
+ Version: 0.0.0.dev176
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.dev174
16
- Requires-Dist: omlish==0.0.0.dev174
15
+ Requires-Dist: omdev==0.0.0.dev176
16
+ Requires-Dist: omlish==0.0.0.dev176
17
17
  Provides-Extra: all
18
18
  Requires-Dist: paramiko~=3.5; extra == "all"
19
19
  Requires-Dist: asyncssh~=2.18; extra == "all"
@@ -6,7 +6,8 @@ import typing as ta
6
6
 
7
7
  from omdev.toml.parser import toml_loads
8
8
  from omlish.lite.check import check
9
- from omlish.lite.marshal import unmarshal_obj
9
+ from omlish.lite.marshal import OBJ_MARSHALER_MANAGER
10
+ from omlish.lite.marshal import ObjMarshalerManager
10
11
 
11
12
 
12
13
  T = ta.TypeVar('T')
@@ -46,6 +47,7 @@ def read_config_file(
46
47
  cls: ta.Type[T],
47
48
  *,
48
49
  prepare: ta.Optional[ta.Callable[[ConfigMapping], ConfigMapping]] = None,
50
+ msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
49
51
  ) -> T:
50
52
  with open(path) as cf:
51
53
  config_dct = parse_config_file(os.path.basename(path), cf)
@@ -53,7 +55,7 @@ def read_config_file(
53
55
  if prepare is not None:
54
56
  config_dct = prepare(config_dct)
55
57
 
56
- return unmarshal_obj(config_dct, cls)
58
+ return msh.unmarshal_obj(config_dct, cls)
57
59
 
58
60
 
59
61
  def build_config_named_children(
@@ -13,7 +13,7 @@ def install_command_marshaling(
13
13
  lambda c: c,
14
14
  lambda c: c.Output,
15
15
  ]:
16
- msh.register_opj_marshaler(
16
+ msh.set_obj_marshaler(
17
17
  fn(Command),
18
18
  PolymorphicObjMarshaler.of([
19
19
  PolymorphicObjMarshaler.Impl(
@@ -86,6 +86,8 @@ class DeployAppManager(DeployPathOwner):
86
86
  os.makedirs(deploy_dir, exist_ok=True)
87
87
 
88
88
  deploying_link = os.path.join(deploy_home, 'deploys/deploying')
89
+ if os.path.exists(deploying_link):
90
+ os.unlink(deploying_link)
89
91
  relative_symlink(
90
92
  deploy_dir,
91
93
  deploying_link,
@@ -24,13 +24,12 @@ from omlish.os.paths import is_path_in_dir
24
24
  from omlish.os.paths import relative_symlink
25
25
 
26
26
  from .paths.paths import DeployPath
27
- from .specs import AllActiveDeployAppConfLink
28
- from .specs import CurrentOnlyDeployAppConfLink
29
27
  from .specs import DeployAppConfFile
30
28
  from .specs import DeployAppConfLink
31
29
  from .specs import DeployAppConfSpec
32
30
  from .tags import DEPLOY_TAG_SEPARATOR
33
31
  from .tags import DeployApp
32
+ from .tags import DeployConf
34
33
  from .tags import DeployTagMap
35
34
  from .types import DeployHome
36
35
 
@@ -63,6 +62,7 @@ class DeployConfManager:
63
62
  #
64
63
 
65
64
  class _ComputedConfLink(ta.NamedTuple):
65
+ conf: DeployConf
66
66
  is_dir: bool
67
67
  link_src: str
68
68
  link_dst: str
@@ -70,8 +70,9 @@ class DeployConfManager:
70
70
  _UNIQUE_LINK_NAME_STR = '@app--@time--@app-key'
71
71
  _UNIQUE_LINK_NAME = DeployPath.parse(_UNIQUE_LINK_NAME_STR)
72
72
 
73
+ @classmethod
73
74
  def _compute_app_conf_link_dst(
74
- self,
75
+ cls,
75
76
  link: DeployAppConfLink,
76
77
  tags: DeployTagMap,
77
78
  app_conf_dir: str,
@@ -85,6 +86,7 @@ class DeployConfManager:
85
86
  if (is_dir := link.src.endswith('/')):
86
87
  # @conf/ - links a directory in root of app conf dir to conf/@conf/@dst/
87
88
  check.arg(link.src.count('/') == 1)
89
+ conf = DeployConf(link.src.split('/')[0])
88
90
  link_dst_pfx = link.src
89
91
  link_dst_sfx = ''
90
92
 
@@ -92,6 +94,7 @@ class DeployConfManager:
92
94
  # @conf/file - links a single file in a single subdir to conf/@conf/@dst--file
93
95
  d, f = os.path.split(link.src)
94
96
  # TODO: check filename :|
97
+ conf = DeployConf(d)
95
98
  link_dst_pfx = d + '/'
96
99
  link_dst_sfx = DEPLOY_TAG_SEPARATOR + f
97
100
 
@@ -99,18 +102,20 @@ class DeployConfManager:
99
102
  # @conf(.ext)* - links a single file in root of app conf dir to conf/@conf/@dst(.ext)*
100
103
  if '.' in link.src:
101
104
  l, _, r = link.src.partition('.')
105
+ conf = DeployConf(l)
102
106
  link_dst_pfx = l + '/'
103
107
  link_dst_sfx = '.' + r
104
108
  else:
109
+ conf = DeployConf(link.src)
105
110
  link_dst_pfx = link.src + '/'
106
111
  link_dst_sfx = ''
107
112
 
108
113
  #
109
114
 
110
- if isinstance(link, CurrentOnlyDeployAppConfLink):
115
+ if link.kind == 'current_only':
111
116
  link_dst_mid = str(tags[DeployApp].s)
112
- elif isinstance(link, AllActiveDeployAppConfLink):
113
- link_dst_mid = self._UNIQUE_LINK_NAME.render(tags)
117
+ elif link.kind == 'all_active':
118
+ link_dst_mid = cls._UNIQUE_LINK_NAME.render(tags)
114
119
  else:
115
120
  raise TypeError(link)
116
121
 
@@ -124,6 +129,7 @@ class DeployConfManager:
124
129
  link_dst = os.path.join(conf_link_dir, link_dst_name)
125
130
 
126
131
  return DeployConfManager._ComputedConfLink(
132
+ conf=conf,
127
133
  is_dir=is_dir,
128
134
  link_src=link_src,
129
135
  link_dst=link_dst,
@@ -170,7 +170,7 @@ class FileDeployPathPart(DeployPathPart):
170
170
  return 'file'
171
171
 
172
172
 
173
- #
173
+ ##
174
174
 
175
175
 
176
176
  @dc.dataclass(frozen=True)
@@ -197,7 +197,7 @@ class DeployPath:
197
197
  return pd
198
198
 
199
199
  @property
200
- def kind(self) -> ta.Literal['file', 'dir']:
200
+ def kind(self) -> DeployPathKind:
201
201
  return self.parts[-1].kind
202
202
 
203
203
  def render(self, tags: ta.Optional[DeployTagMap] = None) -> str:
@@ -95,7 +95,7 @@ class DeployAppConfFile:
95
95
 
96
96
 
97
97
  @dc.dataclass(frozen=True)
98
- class DeployAppConfLink(abc.ABC): # noqa
98
+ class DeployAppConfLink: # noqa
99
99
  """
100
100
  May be either:
101
101
  - @conf(.ext)* - links a single file in root of app conf dir to conf/@conf/@dst(.ext)*
@@ -105,20 +105,14 @@ class DeployAppConfLink(abc.ABC): # noqa
105
105
 
106
106
  src: str
107
107
 
108
+ kind: ta.Literal['current_only', 'all_active'] = 'current_only'
109
+
108
110
  def __post_init__(self) -> None:
109
111
  check_valid_deploy_spec_path(self.src)
110
112
  if '/' in self.src:
111
113
  check.equal(self.src.count('/'), 1)
112
114
 
113
115
 
114
- class CurrentOnlyDeployAppConfLink(DeployAppConfLink):
115
- pass
116
-
117
-
118
- class AllActiveDeployAppConfLink(DeployAppConfLink):
119
- pass
120
-
121
-
122
116
  #
123
117
 
124
118
 
@@ -4,6 +4,8 @@ import dataclasses as dc
4
4
  import typing as ta
5
5
 
6
6
  from omlish.lite.check import check
7
+ from omlish.lite.marshal import SingleFieldObjMarshaler
8
+ from omlish.lite.marshal import register_type_obj_marshaler
7
9
 
8
10
 
9
11
  ##
@@ -82,6 +84,8 @@ def _register_deploy_tag(cls):
82
84
  _DEPLOY_TAGS_BY_NAME[cls.tag_name] = cls
83
85
  _DEPLOY_TAGS_BY_KWARG[cls.tag_kwarg] = cls
84
86
 
87
+ register_type_obj_marshaler(cls, SingleFieldObjMarshaler(cls, 's'))
88
+
85
89
  return cls
86
90
 
87
91
 
@@ -6,7 +6,10 @@ TODO:
6
6
  """
7
7
  import os.path
8
8
 
9
+ from omdev.interp.resolvers import DEFAULT_INTERP_RESOLVER
10
+ from omdev.interp.types import InterpSpecifier
9
11
  from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
12
+ from omlish.lite.check import check
10
13
  from omlish.os.atomics import AtomicPathSwapping
11
14
 
12
15
  from .specs import DeployVenvSpec
@@ -28,7 +31,14 @@ class DeployVenvManager:
28
31
  git_dir: str,
29
32
  venv_dir: str,
30
33
  ) -> None:
31
- sys_exe = 'python3'
34
+ if spec.interp is not None:
35
+ i = InterpSpecifier.parse(check.not_none(spec.interp))
36
+ o = check.not_none(await DEFAULT_INTERP_RESOLVER.resolve(i))
37
+ sys_exe = o.exe
38
+ else:
39
+ sys_exe = 'python3'
40
+
41
+ #
32
42
 
33
43
  # !! NOTE: (most) venvs cannot be relocated, so an atomic swap can't be used. it's up to the path manager to
34
44
  # garbage collect orphaned dirs.
@@ -35,6 +35,8 @@ from .targets.targets import ManageTarget
35
35
 
36
36
  @dc.dataclass(frozen=True)
37
37
  class ManageConfig:
38
+ deploy_home: ta.Optional[str] = None
39
+
38
40
  targets: ta.Optional[ta.Mapping[str, ManageTarget]] = None
39
41
 
40
42
 
@@ -69,7 +71,8 @@ class MainCli(ArgparseCli):
69
71
  argparse_arg('--deploy-home'),
70
72
 
71
73
  argparse_arg('target'),
72
- argparse_arg('command', nargs='+'),
74
+ argparse_arg('-f', '--command-file', action='append'),
75
+ argparse_arg('command', nargs='*'),
73
76
  )
74
77
  async def run(self) -> None:
75
78
  bs = MainBootstrap(
@@ -80,7 +83,7 @@ class MainCli(ArgparseCli):
80
83
  ),
81
84
 
82
85
  deploy_config=DeployConfig(
83
- deploy_home=self.args.deploy_home,
86
+ deploy_home=self.args.deploy_home or self.config().deploy_home,
84
87
  ),
85
88
 
86
89
  remote_config=RemoteConfig(
@@ -115,13 +118,19 @@ class MainCli(ArgparseCli):
115
118
  #
116
119
 
117
120
  cmds: ta.List[Command] = []
121
+
118
122
  cmd: Command
119
- for c in self.args.command:
123
+
124
+ for c in self.args.command or []:
120
125
  if not c.startswith('{'):
121
126
  c = json.dumps({c: {}})
122
127
  cmd = msh.unmarshal_obj(json.loads(c), Command)
123
128
  cmds.append(cmd)
124
129
 
130
+ for cf in self.args.command_file or []:
131
+ cmd = read_config_file(cf, Command, msh=msh)
132
+ cmds.append(cmd)
133
+
125
134
  #
126
135
 
127
136
  async with injector[ManageTargetConnector].connect(tgt) as ce:
@@ -2686,6 +2686,18 @@ class FieldsObjMarshaler(ObjMarshaler):
2686
2686
  })
2687
2687
 
2688
2688
 
2689
+ @dc.dataclass(frozen=True)
2690
+ class SingleFieldObjMarshaler(ObjMarshaler):
2691
+ ty: type
2692
+ fld: str
2693
+
2694
+ def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
2695
+ return getattr(o, self.fld)
2696
+
2697
+ def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
2698
+ return self.ty(**{self.fld: o})
2699
+
2700
+
2689
2701
  @dc.dataclass(frozen=True)
2690
2702
  class PolymorphicObjMarshaler(ObjMarshaler):
2691
2703
  class Impl(ta.NamedTuple):
@@ -2760,7 +2772,7 @@ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
2760
2772
  **{t: IterableObjMarshaler(t, DynamicObjMarshaler()) for t in (list, tuple, set, frozenset)},
2761
2773
  **{t: MappingObjMarshaler(t, DynamicObjMarshaler(), DynamicObjMarshaler()) for t in (dict,)},
2762
2774
 
2763
- ta.Any: DynamicObjMarshaler(),
2775
+ **{t: DynamicObjMarshaler() for t in (ta.Any, object)},
2764
2776
 
2765
2777
  **{t: DatetimeObjMarshaler(t) for t in (datetime.date, datetime.time, datetime.datetime)},
2766
2778
  decimal.Decimal: DecimalObjMarshaler(),
@@ -2785,6 +2797,16 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
2785
2797
  ##
2786
2798
 
2787
2799
 
2800
+ _REGISTERED_OBJ_MARSHALERS_BY_TYPE: ta.MutableMapping[type, ObjMarshaler] = weakref.WeakKeyDictionary()
2801
+
2802
+
2803
+ def register_type_obj_marshaler(ty: type, om: ObjMarshaler) -> None:
2804
+ _REGISTERED_OBJ_MARSHALERS_BY_TYPE[ty] = om
2805
+
2806
+
2807
+ ##
2808
+
2809
+
2788
2810
  class ObjMarshalerManager:
2789
2811
  def __init__(
2790
2812
  self,
@@ -2794,6 +2816,8 @@ class ObjMarshalerManager:
2794
2816
  default_obj_marshalers: ta.Dict[ta.Any, ObjMarshaler] = _DEFAULT_OBJ_MARSHALERS, # noqa
2795
2817
  generic_mapping_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_MAPPING_TYPES, # noqa
2796
2818
  generic_iterable_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES, # noqa
2819
+
2820
+ registered_obj_marshalers: ta.Mapping[type, ObjMarshaler] = _REGISTERED_OBJ_MARSHALERS_BY_TYPE,
2797
2821
  ) -> None:
2798
2822
  super().__init__()
2799
2823
 
@@ -2802,6 +2826,7 @@ class ObjMarshalerManager:
2802
2826
  self._obj_marshalers = dict(default_obj_marshalers)
2803
2827
  self._generic_mapping_types = generic_mapping_types
2804
2828
  self._generic_iterable_types = generic_iterable_types
2829
+ self._registered_obj_marshalers = registered_obj_marshalers
2805
2830
 
2806
2831
  self._lock = threading.RLock()
2807
2832
  self._marshalers: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
@@ -2817,6 +2842,9 @@ class ObjMarshalerManager:
2817
2842
  non_strict_fields: bool = False,
2818
2843
  ) -> ObjMarshaler:
2819
2844
  if isinstance(ty, type):
2845
+ if (reg := self._registered_obj_marshalers.get(ty)) is not None:
2846
+ return reg
2847
+
2820
2848
  if abc.ABC in ty.__bases__:
2821
2849
  impls = [ity for ity in deep_subclasses(ty) if abc.ABC not in ity.__bases__] # type: ignore
2822
2850
  if all(ity.__qualname__.endswith(ty.__name__) for ity in impls):
@@ -2881,9 +2909,15 @@ class ObjMarshalerManager:
2881
2909
 
2882
2910
  #
2883
2911
 
2884
- def register_opj_marshaler(self, ty: ta.Any, m: ObjMarshaler) -> None:
2912
+ def set_obj_marshaler(
2913
+ self,
2914
+ ty: ta.Any,
2915
+ m: ObjMarshaler,
2916
+ *,
2917
+ override: bool = False,
2918
+ ) -> None:
2885
2919
  with self._lock:
2886
- if ty in self._obj_marshalers:
2920
+ if not override and ty in self._obj_marshalers:
2887
2921
  raise KeyError(ty)
2888
2922
  self._obj_marshalers[ty] = m
2889
2923
 
@@ -2974,7 +3008,7 @@ class ObjMarshalContext:
2974
3008
 
2975
3009
  OBJ_MARSHALER_MANAGER = ObjMarshalerManager()
2976
3010
 
2977
- register_opj_marshaler = OBJ_MARSHALER_MANAGER.register_opj_marshaler
3011
+ set_obj_marshaler = OBJ_MARSHALER_MANAGER.set_obj_marshaler
2978
3012
  get_obj_marshaler = OBJ_MARSHALER_MANAGER.get_obj_marshaler
2979
3013
 
2980
3014
  marshal_obj = OBJ_MARSHALER_MANAGER.marshal_obj
@@ -3259,6 +3293,7 @@ def read_config_file(
3259
3293
  cls: ta.Type[T],
3260
3294
  *,
3261
3295
  prepare: ta.Optional[ta.Callable[[ConfigMapping], ConfigMapping]] = None,
3296
+ msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
3262
3297
  ) -> T:
3263
3298
  with open(path) as cf:
3264
3299
  config_dct = parse_config_file(os.path.basename(path), cf)
@@ -3266,7 +3301,7 @@ def read_config_file(
3266
3301
  if prepare is not None:
3267
3302
  config_dct = prepare(config_dct)
3268
3303
 
3269
- return unmarshal_obj(config_dct, cls)
3304
+ return msh.unmarshal_obj(config_dct, cls)
3270
3305
 
3271
3306
 
3272
3307
  def build_config_named_children(