ominfra 0.0.0.dev167__py3-none-any.whl → 0.0.0.dev169__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/deploy/apps.py +76 -26
- ominfra/manage/deploy/commands.py +3 -3
- ominfra/manage/deploy/conf.py +73 -33
- ominfra/manage/deploy/deploy.py +27 -0
- ominfra/manage/deploy/git.py +1 -1
- ominfra/manage/deploy/inject.py +7 -7
- ominfra/manage/deploy/paths/__init__.py +0 -0
- ominfra/manage/deploy/paths/inject.py +21 -0
- ominfra/manage/deploy/paths/manager.py +36 -0
- ominfra/manage/deploy/paths/owners.py +50 -0
- ominfra/manage/deploy/paths/paths.py +216 -0
- ominfra/manage/deploy/specs.py +1 -2
- ominfra/manage/deploy/tmp.py +1 -1
- ominfra/manage/deploy/types.py +26 -1
- ominfra/scripts/journald2aws.py +24 -0
- ominfra/scripts/manage.py +923 -697
- ominfra/scripts/supervisor.py +24 -0
- {ominfra-0.0.0.dev167.dist-info → ominfra-0.0.0.dev169.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev167.dist-info → ominfra-0.0.0.dev169.dist-info}/RECORD +23 -18
- ominfra/manage/deploy/paths.py +0 -243
- {ominfra-0.0.0.dev167.dist-info → ominfra-0.0.0.dev169.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev167.dist-info → ominfra-0.0.0.dev169.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev167.dist-info → ominfra-0.0.0.dev169.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev167.dist-info → ominfra-0.0.0.dev169.dist-info}/top_level.txt +0 -0
ominfra/scripts/supervisor.py
CHANGED
@@ -1726,6 +1726,8 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
1726
1726
|
"""
|
1727
1727
|
TODO:
|
1728
1728
|
- def maybe(v: lang.Maybe[T])
|
1729
|
+
- def not_ ?
|
1730
|
+
- ** class @dataclass Raise - user message should be able to be an exception type or instance or factory
|
1729
1731
|
"""
|
1730
1732
|
|
1731
1733
|
|
@@ -2412,6 +2414,28 @@ def strip_with_newline(s: str) -> str:
|
|
2412
2414
|
return s.strip() + '\n'
|
2413
2415
|
|
2414
2416
|
|
2417
|
+
@ta.overload
|
2418
|
+
def split_keep_delimiter(s: str, d: str) -> str:
|
2419
|
+
...
|
2420
|
+
|
2421
|
+
|
2422
|
+
@ta.overload
|
2423
|
+
def split_keep_delimiter(s: bytes, d: bytes) -> bytes:
|
2424
|
+
...
|
2425
|
+
|
2426
|
+
|
2427
|
+
def split_keep_delimiter(s, d):
|
2428
|
+
ps = []
|
2429
|
+
i = 0
|
2430
|
+
while i < len(s):
|
2431
|
+
if (n := s.find(d, i)) < i:
|
2432
|
+
ps.append(s[i:])
|
2433
|
+
break
|
2434
|
+
ps.append(s[i:n + 1])
|
2435
|
+
i = n + 1
|
2436
|
+
return ps
|
2437
|
+
|
2438
|
+
|
2415
2439
|
##
|
2416
2440
|
|
2417
2441
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ominfra
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev169
|
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.dev169
|
16
|
+
Requires-Dist: omlish==0.0.0.dev169
|
17
17
|
Provides-Extra: all
|
18
18
|
Requires-Dist: paramiko~=3.5; extra == "all"
|
19
19
|
Requires-Dist: asyncssh~=2.18; extra == "all"
|
@@ -44,18 +44,23 @@ ominfra/manage/commands/ping.py,sha256=DVZFzL1Z_f-Bq53vxMrL3xOi0iK_nMonJE4KvQf9w
|
|
44
44
|
ominfra/manage/commands/subprocess.py,sha256=yHGMbAI-xKe_9BUs5IZ3Yav8qRE-I9aGnBtTwW15Pnw,2440
|
45
45
|
ominfra/manage/commands/types.py,sha256=XFZPeqeIBAaIIQF3pdPbGxLlb-LCrz6WtlDWO2q_vz0,210
|
46
46
|
ominfra/manage/deploy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
|
-
ominfra/manage/deploy/apps.py,sha256=
|
48
|
-
ominfra/manage/deploy/commands.py,sha256=
|
49
|
-
ominfra/manage/deploy/conf.py,sha256=
|
47
|
+
ominfra/manage/deploy/apps.py,sha256=HE2-ThrWR4wplT5hpPSQx0ERAkV-f58hj38al_FaZ7o,4457
|
48
|
+
ominfra/manage/deploy/commands.py,sha256=fKFKhFwqIqC_PsgA-W66qIJ5S32xRgBBaRt3lbPX5Zg,763
|
49
|
+
ominfra/manage/deploy/conf.py,sha256=AvIZFNuURpS0mKZazr36oBMKi4kJDeTlt74JZmDrpcA,5227
|
50
50
|
ominfra/manage/deploy/config.py,sha256=aR6ubMEWqkTI55XtcG1Cczn6YhCVN6eSL8DT5EHQJN0,166
|
51
|
-
ominfra/manage/deploy/
|
52
|
-
ominfra/manage/deploy/
|
51
|
+
ominfra/manage/deploy/deploy.py,sha256=APg8Pbni48ycw83JdsWZRlc1utVDCWlj4q8RCEDXPDg,564
|
52
|
+
ominfra/manage/deploy/git.py,sha256=cfTCx1qD-FQPFkbYW28tkU8nVxQbnfnWxpuJuGQHtBw,3753
|
53
|
+
ominfra/manage/deploy/inject.py,sha256=kzGl2N2jhijUw4-PYUK1LNG8_MJD7BMgCbi6nDViMWg,1965
|
53
54
|
ominfra/manage/deploy/interp.py,sha256=OKkenH8YKEW_mEDR6X7_ZLxK9a1Ox6KHSwFPTHT6OzA,1029
|
54
|
-
ominfra/manage/deploy/
|
55
|
-
ominfra/manage/deploy/
|
56
|
-
ominfra/manage/deploy/
|
57
|
-
ominfra/manage/deploy/types.py,sha256=o95wqvTGNRq8Cxx7VpqeX-9x1tI8k8BpqPFvJZkJYBA,305
|
55
|
+
ominfra/manage/deploy/specs.py,sha256=3VenKZyX_PmAFcqmvNQqRO-EaMuvFwWWaVF8Y_X9fHU,2865
|
56
|
+
ominfra/manage/deploy/tmp.py,sha256=dFJuqGfSf5otCxSaCI01a5UOSaArMlU4MzzYcyr74-s,1237
|
57
|
+
ominfra/manage/deploy/types.py,sha256=HzOTDmj9HcHWA_X1GGiwYZ98CGG7X_hdAGMvit_a_n4,829
|
58
58
|
ominfra/manage/deploy/venvs.py,sha256=1co8l3eSxl2WccrF-XOTqeltoMccRH63o69NblV3yok,1366
|
59
|
+
ominfra/manage/deploy/paths/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
|
+
ominfra/manage/deploy/paths/inject.py,sha256=X81C-Qhef1LQ7tILWvkomBwFTvgooLVmWRnKL7TeVoI,596
|
61
|
+
ominfra/manage/deploy/paths/manager.py,sha256=gxr_CsjLmjxXx8w3J8ookJk9OGltCpyBFYBnxXaw5lg,1050
|
62
|
+
ominfra/manage/deploy/paths/owners.py,sha256=GmLy0E70C8CF3eYIdkAhBtYaZXW4QWmSzvgts5l1i_4,1379
|
63
|
+
ominfra/manage/deploy/paths/paths.py,sha256=gluJ0I-OPfig0YbjlqE1Tepv48oKIIv6lN6kcQLtUg0,6076
|
59
64
|
ominfra/manage/remote/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
65
|
ominfra/manage/remote/_main.py,sha256=p5KoiS2WMw6QAqlDl_Zun-JybmCsy8awIfpBMLBjGMY,4356
|
61
66
|
ominfra/manage/remote/channel.py,sha256=36xR9Ti9ZA8TUBtxmY0u7_3Lv7E6wzQTxlZl7gLR5GE,2224
|
@@ -76,9 +81,9 @@ ominfra/manage/targets/connection.py,sha256=5e8h9Miej2DKJxZfLyxpGe8y-Y0V_b_AuUW1
|
|
76
81
|
ominfra/manage/targets/inject.py,sha256=P4597xWM-V3I_gCt2O71OLhYQkkXtuJvkYRsIbhhMcE,1561
|
77
82
|
ominfra/manage/targets/targets.py,sha256=CFl8Uirgn3gfowO1Fn-LBK-6qYqEMFJ9snPUl0gCRuM,1753
|
78
83
|
ominfra/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
79
|
-
ominfra/scripts/journald2aws.py,sha256=
|
80
|
-
ominfra/scripts/manage.py,sha256=
|
81
|
-
ominfra/scripts/supervisor.py,sha256=
|
84
|
+
ominfra/scripts/journald2aws.py,sha256=OjbemVx-zyCBuWZVgTky66n2-MfyyS7ups4A9hsvHfA,155684
|
85
|
+
ominfra/scripts/manage.py,sha256=Xq28GDDorMsopZqYqZ240lcn1IFCHZi5-YOjZAEXVFY,306243
|
86
|
+
ominfra/scripts/supervisor.py,sha256=viYrsafRW5fLN2KUS1MtxCOm9CO4iOgIu60cmN3joSg,274450
|
82
87
|
ominfra/supervisor/LICENSE.txt,sha256=yvqaMNsDhWxziHa9ien6qCW1SkZv-DQlAg96XjfSee8,1746
|
83
88
|
ominfra/supervisor/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
84
89
|
ominfra/supervisor/__main__.py,sha256=I0yFw-C08OOiZ3BF6lF1Oiv789EQXu-_j6whDhQUTEA,66
|
@@ -120,9 +125,9 @@ ominfra/tailscale/api.py,sha256=C5-t_b6jZXUWcy5k8bXm7CFnk73pSdrlMOgGDeGVrpw,1370
|
|
120
125
|
ominfra/tailscale/cli.py,sha256=h6akQJMl0KuWLHS7Ur6WcBZ2JwF0DJQhsPTnFBdGyNk,3571
|
121
126
|
ominfra/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
122
127
|
ominfra/tools/listresources.py,sha256=4qVg5txsb10EHhvqXXeM6gJ2jx9LbroEnPydDv1uXs0,6176
|
123
|
-
ominfra-0.0.0.
|
124
|
-
ominfra-0.0.0.
|
125
|
-
ominfra-0.0.0.
|
126
|
-
ominfra-0.0.0.
|
127
|
-
ominfra-0.0.0.
|
128
|
-
ominfra-0.0.0.
|
128
|
+
ominfra-0.0.0.dev169.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
129
|
+
ominfra-0.0.0.dev169.dist-info/METADATA,sha256=_6arfj7ECnJB7EoB6PCvXeAJHqqE7JWT825sVwCzr8Q,731
|
130
|
+
ominfra-0.0.0.dev169.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
131
|
+
ominfra-0.0.0.dev169.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
|
132
|
+
ominfra-0.0.0.dev169.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
|
133
|
+
ominfra-0.0.0.dev169.dist-info/RECORD,,
|
ominfra/manage/deploy/paths.py
DELETED
@@ -1,243 +0,0 @@
|
|
1
|
-
# ruff: noqa: UP006 UP007
|
2
|
-
"""
|
3
|
-
TODO:
|
4
|
-
- run/{.pid,.sock}
|
5
|
-
- logs/...
|
6
|
-
- current symlink
|
7
|
-
- conf/{nginx,supervisor}
|
8
|
-
- env/?
|
9
|
-
- apps/<app>/shared
|
10
|
-
"""
|
11
|
-
import abc
|
12
|
-
import dataclasses as dc
|
13
|
-
import os.path
|
14
|
-
import typing as ta
|
15
|
-
|
16
|
-
from omlish.lite.cached import cached_nullary
|
17
|
-
from omlish.lite.check import check
|
18
|
-
|
19
|
-
from .types import DeployHome
|
20
|
-
|
21
|
-
|
22
|
-
DeployPathKind = ta.Literal['dir', 'file'] # ta.TypeAlias
|
23
|
-
DeployPathPlaceholder = ta.Literal['app', 'tag'] # ta.TypeAlias
|
24
|
-
|
25
|
-
|
26
|
-
##
|
27
|
-
|
28
|
-
|
29
|
-
DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER = '@'
|
30
|
-
DEPLOY_PATH_PLACEHOLDER_SEPARATORS = '-.'
|
31
|
-
|
32
|
-
DEPLOY_PATH_PLACEHOLDERS: ta.FrozenSet[str] = frozenset([
|
33
|
-
'app',
|
34
|
-
'tag',
|
35
|
-
])
|
36
|
-
|
37
|
-
|
38
|
-
class DeployPathError(Exception):
|
39
|
-
pass
|
40
|
-
|
41
|
-
|
42
|
-
@dc.dataclass(frozen=True)
|
43
|
-
class DeployPathPart(abc.ABC): # noqa
|
44
|
-
@property
|
45
|
-
@abc.abstractmethod
|
46
|
-
def kind(self) -> DeployPathKind:
|
47
|
-
raise NotImplementedError
|
48
|
-
|
49
|
-
@abc.abstractmethod
|
50
|
-
def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
|
51
|
-
raise NotImplementedError
|
52
|
-
|
53
|
-
|
54
|
-
#
|
55
|
-
|
56
|
-
|
57
|
-
class DirDeployPathPart(DeployPathPart, abc.ABC):
|
58
|
-
@property
|
59
|
-
def kind(self) -> DeployPathKind:
|
60
|
-
return 'dir'
|
61
|
-
|
62
|
-
@classmethod
|
63
|
-
def parse(cls, s: str) -> 'DirDeployPathPart':
|
64
|
-
if DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER in s:
|
65
|
-
check.equal(s[0], DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER)
|
66
|
-
return PlaceholderDirDeployPathPart(s[1:])
|
67
|
-
else:
|
68
|
-
return ConstDirDeployPathPart(s)
|
69
|
-
|
70
|
-
|
71
|
-
class FileDeployPathPart(DeployPathPart, abc.ABC):
|
72
|
-
@property
|
73
|
-
def kind(self) -> DeployPathKind:
|
74
|
-
return 'file'
|
75
|
-
|
76
|
-
@classmethod
|
77
|
-
def parse(cls, s: str) -> 'FileDeployPathPart':
|
78
|
-
if DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER in s:
|
79
|
-
check.equal(s[0], DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER)
|
80
|
-
if not any(c in s for c in DEPLOY_PATH_PLACEHOLDER_SEPARATORS):
|
81
|
-
return PlaceholderFileDeployPathPart(s[1:], '')
|
82
|
-
else:
|
83
|
-
p = min(f for c in DEPLOY_PATH_PLACEHOLDER_SEPARATORS if (f := s.find(c)) > 0)
|
84
|
-
return PlaceholderFileDeployPathPart(s[1:p], s[p:])
|
85
|
-
else:
|
86
|
-
return ConstFileDeployPathPart(s)
|
87
|
-
|
88
|
-
|
89
|
-
#
|
90
|
-
|
91
|
-
|
92
|
-
@dc.dataclass(frozen=True)
|
93
|
-
class ConstDeployPathPart(DeployPathPart, abc.ABC):
|
94
|
-
name: str
|
95
|
-
|
96
|
-
def __post_init__(self) -> None:
|
97
|
-
check.non_empty_str(self.name)
|
98
|
-
check.not_in('/', self.name)
|
99
|
-
check.not_in(DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER, self.name)
|
100
|
-
|
101
|
-
def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
|
102
|
-
return self.name
|
103
|
-
|
104
|
-
|
105
|
-
class ConstDirDeployPathPart(ConstDeployPathPart, DirDeployPathPart):
|
106
|
-
pass
|
107
|
-
|
108
|
-
|
109
|
-
class ConstFileDeployPathPart(ConstDeployPathPart, FileDeployPathPart):
|
110
|
-
pass
|
111
|
-
|
112
|
-
|
113
|
-
#
|
114
|
-
|
115
|
-
|
116
|
-
@dc.dataclass(frozen=True)
|
117
|
-
class PlaceholderDeployPathPart(DeployPathPart, abc.ABC):
|
118
|
-
placeholder: str # DeployPathPlaceholder
|
119
|
-
|
120
|
-
def __post_init__(self) -> None:
|
121
|
-
check.non_empty_str(self.placeholder)
|
122
|
-
for c in [*DEPLOY_PATH_PLACEHOLDER_SEPARATORS, DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER, '/']:
|
123
|
-
check.not_in(c, self.placeholder)
|
124
|
-
check.in_(self.placeholder, DEPLOY_PATH_PLACEHOLDERS)
|
125
|
-
|
126
|
-
def _render_placeholder(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
|
127
|
-
if placeholders is not None:
|
128
|
-
return placeholders[self.placeholder] # type: ignore
|
129
|
-
else:
|
130
|
-
return DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER + self.placeholder
|
131
|
-
|
132
|
-
|
133
|
-
@dc.dataclass(frozen=True)
|
134
|
-
class PlaceholderDirDeployPathPart(PlaceholderDeployPathPart, DirDeployPathPart):
|
135
|
-
def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
|
136
|
-
return self._render_placeholder(placeholders)
|
137
|
-
|
138
|
-
|
139
|
-
@dc.dataclass(frozen=True)
|
140
|
-
class PlaceholderFileDeployPathPart(PlaceholderDeployPathPart, FileDeployPathPart):
|
141
|
-
suffix: str
|
142
|
-
|
143
|
-
def __post_init__(self) -> None:
|
144
|
-
super().__post_init__()
|
145
|
-
if self.suffix:
|
146
|
-
for c in [DEPLOY_PATH_PLACEHOLDER_PLACEHOLDER, '/']:
|
147
|
-
check.not_in(c, self.suffix)
|
148
|
-
|
149
|
-
def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
|
150
|
-
return self._render_placeholder(placeholders) + self.suffix
|
151
|
-
|
152
|
-
|
153
|
-
##
|
154
|
-
|
155
|
-
|
156
|
-
@dc.dataclass(frozen=True)
|
157
|
-
class DeployPath:
|
158
|
-
parts: ta.Sequence[DeployPathPart]
|
159
|
-
|
160
|
-
def __post_init__(self) -> None:
|
161
|
-
hash(self)
|
162
|
-
|
163
|
-
check.not_empty(self.parts)
|
164
|
-
for p in self.parts[:-1]:
|
165
|
-
check.equal(p.kind, 'dir')
|
166
|
-
|
167
|
-
pd = {}
|
168
|
-
for i, p in enumerate(self.parts):
|
169
|
-
if isinstance(p, PlaceholderDeployPathPart):
|
170
|
-
if p.placeholder in pd:
|
171
|
-
raise DeployPathError('Duplicate placeholders in path', self)
|
172
|
-
pd[p.placeholder] = i
|
173
|
-
|
174
|
-
if 'tag' in pd:
|
175
|
-
if 'app' not in pd or pd['app'] >= pd['tag']:
|
176
|
-
raise DeployPathError('Tag placeholder in path without preceding app', self)
|
177
|
-
|
178
|
-
@property
|
179
|
-
def kind(self) -> ta.Literal['file', 'dir']:
|
180
|
-
return self.parts[-1].kind
|
181
|
-
|
182
|
-
def render(self, placeholders: ta.Optional[ta.Mapping[DeployPathPlaceholder, str]] = None) -> str:
|
183
|
-
return os.path.join( # noqa
|
184
|
-
*[p.render(placeholders) for p in self.parts],
|
185
|
-
*([''] if self.kind == 'dir' else []),
|
186
|
-
)
|
187
|
-
|
188
|
-
@classmethod
|
189
|
-
def parse(cls, s: str) -> 'DeployPath':
|
190
|
-
tail_parse: ta.Callable[[str], DeployPathPart]
|
191
|
-
if s.endswith('/'):
|
192
|
-
tail_parse = DirDeployPathPart.parse
|
193
|
-
s = s[:-1]
|
194
|
-
else:
|
195
|
-
tail_parse = FileDeployPathPart.parse
|
196
|
-
ps = check.non_empty_str(s).split('/')
|
197
|
-
return cls((
|
198
|
-
*([DirDeployPathPart.parse(p) for p in ps[:-1]] if len(ps) > 1 else []),
|
199
|
-
tail_parse(ps[-1]),
|
200
|
-
))
|
201
|
-
|
202
|
-
|
203
|
-
##
|
204
|
-
|
205
|
-
|
206
|
-
class DeployPathOwner(abc.ABC):
|
207
|
-
@abc.abstractmethod
|
208
|
-
def get_owned_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
|
209
|
-
raise NotImplementedError
|
210
|
-
|
211
|
-
|
212
|
-
DeployPathOwners = ta.NewType('DeployPathOwners', ta.Sequence[DeployPathOwner])
|
213
|
-
|
214
|
-
|
215
|
-
class SingleDirDeployPathOwner(DeployPathOwner, abc.ABC):
|
216
|
-
def __init__(
|
217
|
-
self,
|
218
|
-
*args: ta.Any,
|
219
|
-
owned_dir: str,
|
220
|
-
deploy_home: ta.Optional[DeployHome],
|
221
|
-
**kwargs: ta.Any,
|
222
|
-
) -> None:
|
223
|
-
super().__init__(*args, **kwargs)
|
224
|
-
|
225
|
-
check.not_in('/', owned_dir)
|
226
|
-
self._owned_dir: str = check.non_empty_str(owned_dir)
|
227
|
-
|
228
|
-
self._deploy_home = deploy_home
|
229
|
-
|
230
|
-
self._owned_deploy_paths = frozenset([DeployPath.parse(self._owned_dir + '/')])
|
231
|
-
|
232
|
-
@cached_nullary
|
233
|
-
def _dir(self) -> str:
|
234
|
-
return os.path.join(check.non_empty_str(self._deploy_home), self._owned_dir)
|
235
|
-
|
236
|
-
@cached_nullary
|
237
|
-
def _make_dir(self) -> str:
|
238
|
-
if not os.path.isdir(d := self._dir()):
|
239
|
-
os.makedirs(d, exist_ok=True)
|
240
|
-
return d
|
241
|
-
|
242
|
-
def get_owned_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
|
243
|
-
return self._owned_deploy_paths
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|