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/manage/deploy/apps.py
CHANGED
@@ -9,8 +9,8 @@ from omlish.os.paths import relative_symlink
|
|
9
9
|
|
10
10
|
from .conf import DeployConfManager
|
11
11
|
from .git import DeployGitManager
|
12
|
-
from .paths import
|
13
|
-
from .paths import
|
12
|
+
from .paths.owners import DeployPathOwner
|
13
|
+
from .paths.paths import DeployPath
|
14
14
|
from .specs import DeploySpec
|
15
15
|
from .types import DeployAppTag
|
16
16
|
from .types import DeployHome
|
@@ -51,20 +51,44 @@ class DeployAppManager(DeployPathOwner):
|
|
51
51
|
self._git = git
|
52
52
|
self._venvs = venvs
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
#
|
55
|
+
|
56
|
+
_APP_TAG_DIR_STR = 'tags/apps/@app/@tag/'
|
57
|
+
_APP_TAG_DIR = DeployPath.parse(_APP_TAG_DIR_STR)
|
58
|
+
|
59
|
+
_CONF_TAG_DIR_STR = 'tags/conf/@tag--@app/'
|
60
|
+
_CONF_TAG_DIR = DeployPath.parse(_CONF_TAG_DIR_STR)
|
61
|
+
|
62
|
+
_DEPLOY_DIR_STR = 'deploys/@tag--@app/'
|
63
|
+
_DEPLOY_DIR = DeployPath.parse(_DEPLOY_DIR_STR)
|
64
|
+
|
65
|
+
_APP_DEPLOY_LINK = DeployPath.parse(f'{_DEPLOY_DIR_STR}apps/@app')
|
66
|
+
_CONF_DEPLOY_LINK = DeployPath.parse(f'{_DEPLOY_DIR_STR}conf')
|
57
67
|
|
68
|
+
@cached_nullary
|
58
69
|
def get_owned_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
|
59
70
|
return {
|
60
|
-
|
61
|
-
|
71
|
+
self._APP_TAG_DIR,
|
72
|
+
|
73
|
+
self._CONF_TAG_DIR,
|
74
|
+
|
75
|
+
self._DEPLOY_DIR,
|
62
76
|
|
63
|
-
|
64
|
-
|
65
|
-
|
77
|
+
self._APP_DEPLOY_LINK,
|
78
|
+
self._CONF_DEPLOY_LINK,
|
79
|
+
|
80
|
+
*[
|
81
|
+
DeployPath.parse(f'{self._APP_TAG_DIR_STR}{sfx}/')
|
82
|
+
for sfx in [
|
83
|
+
'conf',
|
84
|
+
'git',
|
85
|
+
'venv',
|
86
|
+
]
|
87
|
+
],
|
66
88
|
}
|
67
89
|
|
90
|
+
#
|
91
|
+
|
68
92
|
async def prepare_app(
|
69
93
|
self,
|
70
94
|
spec: DeploySpec,
|
@@ -73,26 +97,52 @@ class DeployAppManager(DeployPathOwner):
|
|
73
97
|
|
74
98
|
#
|
75
99
|
|
76
|
-
|
77
|
-
|
100
|
+
deploy_home = check.non_empty_str(self._deploy_home)
|
101
|
+
|
102
|
+
def build_path(pth: DeployPath) -> str:
|
103
|
+
return os.path.join(deploy_home, pth.render(app_tag.placeholders()))
|
104
|
+
|
105
|
+
app_tag_dir = build_path(self._APP_TAG_DIR)
|
106
|
+
conf_tag_dir = build_path(self._CONF_TAG_DIR)
|
107
|
+
deploy_dir = build_path(self._DEPLOY_DIR)
|
108
|
+
app_deploy_link = build_path(self._APP_DEPLOY_LINK)
|
109
|
+
conf_deploy_link_file = build_path(self._CONF_DEPLOY_LINK)
|
78
110
|
|
79
111
|
#
|
80
112
|
|
81
|
-
|
82
|
-
|
113
|
+
os.makedirs(deploy_dir)
|
114
|
+
|
115
|
+
deploying_link = os.path.join(deploy_home, 'deploys/deploying')
|
116
|
+
relative_symlink(
|
117
|
+
deploy_dir,
|
118
|
+
deploying_link,
|
119
|
+
target_is_directory=True,
|
120
|
+
make_dirs=True,
|
121
|
+
)
|
83
122
|
|
84
123
|
#
|
85
124
|
|
86
|
-
|
87
|
-
|
125
|
+
os.makedirs(app_tag_dir)
|
126
|
+
relative_symlink(
|
127
|
+
app_tag_dir,
|
128
|
+
app_deploy_link,
|
129
|
+
target_is_directory=True,
|
130
|
+
make_dirs=True,
|
131
|
+
)
|
132
|
+
|
133
|
+
#
|
88
134
|
|
89
|
-
|
90
|
-
|
91
|
-
|
135
|
+
os.makedirs(conf_tag_dir)
|
136
|
+
relative_symlink(
|
137
|
+
conf_tag_dir,
|
138
|
+
conf_deploy_link_file,
|
139
|
+
target_is_directory=True,
|
140
|
+
make_dirs=True,
|
141
|
+
)
|
92
142
|
|
93
143
|
#
|
94
144
|
|
95
|
-
git_dir = os.path.join(
|
145
|
+
git_dir = os.path.join(app_tag_dir, 'git')
|
96
146
|
await self._git.checkout(
|
97
147
|
spec.git,
|
98
148
|
git_dir,
|
@@ -101,7 +151,7 @@ class DeployAppManager(DeployPathOwner):
|
|
101
151
|
#
|
102
152
|
|
103
153
|
if spec.venv is not None:
|
104
|
-
venv_dir = os.path.join(
|
154
|
+
venv_dir = os.path.join(app_tag_dir, 'venv')
|
105
155
|
await self._venvs.setup_venv(
|
106
156
|
spec.venv,
|
107
157
|
git_dir,
|
@@ -111,15 +161,15 @@ class DeployAppManager(DeployPathOwner):
|
|
111
161
|
#
|
112
162
|
|
113
163
|
if spec.conf is not None:
|
114
|
-
conf_dir = os.path.join(
|
115
|
-
conf_link_dir = os.path.join(current_file, 'conf')
|
164
|
+
conf_dir = os.path.join(app_tag_dir, 'conf')
|
116
165
|
await self._conf.write_conf(
|
117
166
|
spec.conf,
|
118
|
-
conf_dir,
|
119
167
|
app_tag,
|
120
|
-
|
168
|
+
conf_dir,
|
169
|
+
conf_tag_dir,
|
121
170
|
)
|
122
171
|
|
123
172
|
#
|
124
173
|
|
125
|
-
os.
|
174
|
+
current_link = os.path.join(deploy_home, 'deploys/current')
|
175
|
+
os.replace(deploying_link, current_link)
|
@@ -5,7 +5,7 @@ from omlish.lite.logs import log
|
|
5
5
|
|
6
6
|
from ..commands.base import Command
|
7
7
|
from ..commands.base import CommandExecutor
|
8
|
-
from .
|
8
|
+
from .deploy import DeployManager
|
9
9
|
from .specs import DeploySpec
|
10
10
|
|
11
11
|
|
@@ -23,11 +23,11 @@ class DeployCommand(Command['DeployCommand.Output']):
|
|
23
23
|
|
24
24
|
@dc.dataclass(frozen=True)
|
25
25
|
class DeployCommandExecutor(CommandExecutor[DeployCommand, DeployCommand.Output]):
|
26
|
-
|
26
|
+
_deploy: DeployManager
|
27
27
|
|
28
28
|
async def execute(self, cmd: DeployCommand) -> DeployCommand.Output:
|
29
29
|
log.info('Deploying! %r', cmd.spec)
|
30
30
|
|
31
|
-
await self.
|
31
|
+
await self._deploy.run_deploy(cmd.spec)
|
32
32
|
|
33
33
|
return DeployCommand.Output()
|
ominfra/manage/deploy/conf.py
CHANGED
@@ -23,7 +23,7 @@ from omlish.lite.check import check
|
|
23
23
|
from omlish.os.paths import is_path_in_dir
|
24
24
|
from omlish.os.paths import relative_symlink
|
25
25
|
|
26
|
-
from .paths import
|
26
|
+
from .paths.paths import DEPLOY_PATH_PLACEHOLDER_SEPARATOR
|
27
27
|
from .specs import AppDeployConfLink
|
28
28
|
from .specs import DeployConfFile
|
29
29
|
from .specs import DeployConfLink
|
@@ -33,16 +33,17 @@ from .types import DeployAppTag
|
|
33
33
|
from .types import DeployHome
|
34
34
|
|
35
35
|
|
36
|
-
class DeployConfManager
|
36
|
+
class DeployConfManager:
|
37
37
|
def __init__(
|
38
38
|
self,
|
39
39
|
*,
|
40
40
|
deploy_home: ta.Optional[DeployHome] = None,
|
41
41
|
) -> None:
|
42
|
-
super().__init__(
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
super().__init__()
|
43
|
+
|
44
|
+
self._deploy_home = deploy_home
|
45
|
+
|
46
|
+
#
|
46
47
|
|
47
48
|
async def _write_conf_file(
|
48
49
|
self,
|
@@ -57,32 +58,40 @@ class DeployConfManager(SingleDirDeployPathOwner):
|
|
57
58
|
with open(conf_file, 'w') as f: # noqa
|
58
59
|
f.write(cf.body)
|
59
60
|
|
60
|
-
|
61
|
+
#
|
62
|
+
|
63
|
+
class _ComputedConfLink(ta.NamedTuple):
|
64
|
+
is_dir: bool
|
65
|
+
link_src: str
|
66
|
+
link_dst: str
|
67
|
+
|
68
|
+
def _compute_conf_link_dst(
|
61
69
|
self,
|
62
70
|
link: DeployConfLink,
|
63
|
-
conf_dir: str,
|
64
71
|
app_tag: DeployAppTag,
|
72
|
+
conf_dir: str,
|
65
73
|
link_dir: str,
|
66
|
-
) ->
|
74
|
+
) -> _ComputedConfLink:
|
67
75
|
link_src = os.path.join(conf_dir, link.src)
|
68
76
|
check.arg(is_path_in_dir(conf_dir, link_src))
|
69
77
|
|
70
|
-
|
71
|
-
|
78
|
+
#
|
79
|
+
|
80
|
+
if (is_dir := link.src.endswith('/')):
|
81
|
+
# @conf/ - links a directory in root of app conf dir to conf/@conf/@dst/
|
72
82
|
check.arg(link.src.count('/') == 1)
|
73
|
-
check.arg(os.path.isdir(link_src))
|
74
83
|
link_dst_pfx = link.src
|
75
84
|
link_dst_sfx = ''
|
76
85
|
|
77
86
|
elif '/' in link.src:
|
78
|
-
|
87
|
+
# @conf/file - links a single file in a single subdir to conf/@conf/@dst--file
|
79
88
|
d, f = os.path.split(link.src)
|
80
89
|
# TODO: check filename :|
|
81
90
|
link_dst_pfx = d + '/'
|
82
|
-
link_dst_sfx =
|
91
|
+
link_dst_sfx = DEPLOY_PATH_PLACEHOLDER_SEPARATOR + f
|
83
92
|
|
84
|
-
else:
|
85
|
-
|
93
|
+
else: # noqa
|
94
|
+
# @conf(.ext)* - links a single file in root of app conf dir to conf/@conf/@dst(.ext)*
|
86
95
|
if '.' in link.src:
|
87
96
|
l, _, r = link.src.partition('.')
|
88
97
|
link_dst_pfx = l + '/'
|
@@ -91,41 +100,72 @@ class DeployConfManager(SingleDirDeployPathOwner):
|
|
91
100
|
link_dst_pfx = link.src + '/'
|
92
101
|
link_dst_sfx = ''
|
93
102
|
|
103
|
+
#
|
104
|
+
|
94
105
|
if isinstance(link, AppDeployConfLink):
|
95
106
|
link_dst_mid = str(app_tag.app)
|
96
|
-
sym_root = link_dir
|
97
107
|
elif isinstance(link, TagDeployConfLink):
|
98
|
-
link_dst_mid =
|
99
|
-
sym_root = conf_dir
|
108
|
+
link_dst_mid = DEPLOY_PATH_PLACEHOLDER_SEPARATOR.join([app_tag.app, app_tag.tag])
|
100
109
|
else:
|
101
110
|
raise TypeError(link)
|
102
111
|
|
103
|
-
|
112
|
+
#
|
113
|
+
|
114
|
+
link_dst_name = ''.join([
|
104
115
|
link_dst_pfx,
|
105
116
|
link_dst_mid,
|
106
117
|
link_dst_sfx,
|
107
118
|
])
|
119
|
+
link_dst = os.path.join(link_dir, link_dst_name)
|
108
120
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
os.makedirs(os.path.dirname(sym_dst), exist_ok=True)
|
115
|
-
relative_symlink(sym_src, sym_dst, target_is_directory=is_link_dir)
|
121
|
+
return DeployConfManager._ComputedConfLink(
|
122
|
+
is_dir=is_dir,
|
123
|
+
link_src=link_src,
|
124
|
+
link_dst=link_dst,
|
125
|
+
)
|
116
126
|
|
117
|
-
async def
|
127
|
+
async def _make_conf_link(
|
118
128
|
self,
|
119
|
-
|
120
|
-
conf_dir: str,
|
129
|
+
link: DeployConfLink,
|
121
130
|
app_tag: DeployAppTag,
|
131
|
+
conf_dir: str,
|
122
132
|
link_dir: str,
|
123
133
|
) -> None:
|
124
|
-
|
125
|
-
|
134
|
+
comp = self._compute_conf_link_dst(
|
135
|
+
link,
|
136
|
+
app_tag,
|
137
|
+
conf_dir,
|
138
|
+
link_dir,
|
139
|
+
)
|
126
140
|
|
127
141
|
#
|
128
142
|
|
143
|
+
check.arg(is_path_in_dir(conf_dir, comp.link_src))
|
144
|
+
check.arg(is_path_in_dir(link_dir, comp.link_dst))
|
145
|
+
|
146
|
+
if comp.is_dir:
|
147
|
+
check.arg(os.path.isdir(comp.link_src))
|
148
|
+
else:
|
149
|
+
check.arg(os.path.isfile(comp.link_src))
|
150
|
+
|
151
|
+
#
|
152
|
+
|
153
|
+
relative_symlink( # noqa
|
154
|
+
comp.link_src,
|
155
|
+
comp.link_dst,
|
156
|
+
target_is_directory=comp.is_dir,
|
157
|
+
make_dirs=True,
|
158
|
+
)
|
159
|
+
|
160
|
+
#
|
161
|
+
|
162
|
+
async def write_conf(
|
163
|
+
self,
|
164
|
+
spec: DeployConfSpec,
|
165
|
+
app_tag: DeployAppTag,
|
166
|
+
conf_dir: str,
|
167
|
+
link_dir: str,
|
168
|
+
) -> None:
|
129
169
|
for cf in spec.files or []:
|
130
170
|
await self._write_conf_file(
|
131
171
|
cf,
|
@@ -137,7 +177,7 @@ class DeployConfManager(SingleDirDeployPathOwner):
|
|
137
177
|
for link in spec.links or []:
|
138
178
|
await self._make_conf_link(
|
139
179
|
link,
|
140
|
-
conf_dir,
|
141
180
|
app_tag,
|
181
|
+
conf_dir,
|
142
182
|
link_dir,
|
143
183
|
)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
from .apps import DeployAppManager
|
3
|
+
from .paths.manager import DeployPathsManager
|
4
|
+
from .specs import DeploySpec
|
5
|
+
|
6
|
+
|
7
|
+
class DeployManager:
|
8
|
+
def __init__(
|
9
|
+
self,
|
10
|
+
*,
|
11
|
+
apps: DeployAppManager,
|
12
|
+
paths: DeployPathsManager,
|
13
|
+
):
|
14
|
+
super().__init__()
|
15
|
+
|
16
|
+
self._apps = apps
|
17
|
+
self._paths = paths
|
18
|
+
|
19
|
+
async def run_deploy(
|
20
|
+
self,
|
21
|
+
spec: DeploySpec,
|
22
|
+
) -> None:
|
23
|
+
self._paths.validate_deploy_paths()
|
24
|
+
|
25
|
+
#
|
26
|
+
|
27
|
+
await self._apps.prepare_app(spec)
|
ominfra/manage/deploy/git.py
CHANGED
@@ -17,7 +17,7 @@ from omlish.lite.cached import async_cached_nullary
|
|
17
17
|
from omlish.lite.check import check
|
18
18
|
from omlish.os.atomics import AtomicPathSwapping
|
19
19
|
|
20
|
-
from .paths import SingleDirDeployPathOwner
|
20
|
+
from .paths.owners import SingleDirDeployPathOwner
|
21
21
|
from .specs import DeployGitRepo
|
22
22
|
from .specs import DeployGitSpec
|
23
23
|
from .types import DeployHome
|
ominfra/manage/deploy/inject.py
CHANGED
@@ -13,11 +13,12 @@ from .commands import DeployCommand
|
|
13
13
|
from .commands import DeployCommandExecutor
|
14
14
|
from .conf import DeployConfManager
|
15
15
|
from .config import DeployConfig
|
16
|
+
from .deploy import DeployManager
|
16
17
|
from .git import DeployGitManager
|
17
18
|
from .interp import InterpCommand
|
18
19
|
from .interp import InterpCommandExecutor
|
19
|
-
from .paths import
|
20
|
-
from .paths import
|
20
|
+
from .paths.inject import bind_deploy_paths
|
21
|
+
from .paths.owners import DeployPathOwner
|
21
22
|
from .tmp import DeployTmpManager
|
22
23
|
from .types import DeployHome
|
23
24
|
from .venvs import DeployVenvManager
|
@@ -29,6 +30,8 @@ def bind_deploy(
|
|
29
30
|
) -> InjectorBindings:
|
30
31
|
lst: ta.List[InjectorBindingOrBindings] = [
|
31
32
|
inj.bind(deploy_config),
|
33
|
+
|
34
|
+
bind_deploy_paths(),
|
32
35
|
]
|
33
36
|
|
34
37
|
#
|
@@ -40,11 +43,6 @@ def bind_deploy(
|
|
40
43
|
*([inj.bind(DeployPathOwner, to_key=cls, array=True)] if issubclass(cls, DeployPathOwner) else []),
|
41
44
|
)
|
42
45
|
|
43
|
-
lst.extend([
|
44
|
-
inj.bind_array(DeployPathOwner),
|
45
|
-
inj.bind_array_type(DeployPathOwner, DeployPathOwners),
|
46
|
-
])
|
47
|
-
|
48
46
|
#
|
49
47
|
|
50
48
|
lst.extend([
|
@@ -54,6 +52,8 @@ def bind_deploy(
|
|
54
52
|
|
55
53
|
bind_manager(DeployGitManager),
|
56
54
|
|
55
|
+
bind_manager(DeployManager),
|
56
|
+
|
57
57
|
bind_manager(DeployTmpManager),
|
58
58
|
inj.bind(AtomicPathSwapping, to_key=DeployTmpManager),
|
59
59
|
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from omlish.lite.inject import InjectorBindingOrBindings
|
5
|
+
from omlish.lite.inject import InjectorBindings
|
6
|
+
from omlish.lite.inject import inj
|
7
|
+
|
8
|
+
from .manager import DeployPathsManager
|
9
|
+
from .owners import DeployPathOwner
|
10
|
+
from .owners import DeployPathOwners
|
11
|
+
|
12
|
+
|
13
|
+
def bind_deploy_paths() -> InjectorBindings:
|
14
|
+
lst: ta.List[InjectorBindingOrBindings] = [
|
15
|
+
inj.bind_array(DeployPathOwner),
|
16
|
+
inj.bind_array_type(DeployPathOwner, DeployPathOwners),
|
17
|
+
|
18
|
+
inj.bind(DeployPathsManager, singleton=True),
|
19
|
+
]
|
20
|
+
|
21
|
+
return inj.as_bindings(*lst)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from omlish.lite.cached import cached_nullary
|
5
|
+
|
6
|
+
from ..types import DeployHome
|
7
|
+
from .owners import DeployPathOwner
|
8
|
+
from .owners import DeployPathOwners
|
9
|
+
from .paths import DeployPath
|
10
|
+
from .paths import DeployPathError
|
11
|
+
|
12
|
+
|
13
|
+
class DeployPathsManager:
|
14
|
+
def __init__(
|
15
|
+
self,
|
16
|
+
*,
|
17
|
+
deploy_home: ta.Optional[DeployHome],
|
18
|
+
deploy_path_owners: DeployPathOwners,
|
19
|
+
) -> None:
|
20
|
+
super().__init__()
|
21
|
+
|
22
|
+
self._deploy_home = deploy_home
|
23
|
+
self._deploy_path_owners = deploy_path_owners
|
24
|
+
|
25
|
+
@cached_nullary
|
26
|
+
def owners_by_path(self) -> ta.Mapping[DeployPath, DeployPathOwner]:
|
27
|
+
dct: ta.Dict[DeployPath, DeployPathOwner] = {}
|
28
|
+
for o in self._deploy_path_owners:
|
29
|
+
for p in o.get_owned_deploy_paths():
|
30
|
+
if p in dct:
|
31
|
+
raise DeployPathError(f'Duplicate deploy path owner: {p}')
|
32
|
+
dct[p] = o
|
33
|
+
return dct
|
34
|
+
|
35
|
+
def validate_deploy_paths(self) -> None:
|
36
|
+
self.owners_by_path()
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import abc
|
3
|
+
import os.path
|
4
|
+
import typing as ta
|
5
|
+
|
6
|
+
from omlish.lite.cached import cached_nullary
|
7
|
+
from omlish.lite.check import check
|
8
|
+
|
9
|
+
from ..types import DeployHome
|
10
|
+
from .paths import DeployPath
|
11
|
+
|
12
|
+
|
13
|
+
class DeployPathOwner(abc.ABC):
|
14
|
+
@abc.abstractmethod
|
15
|
+
def get_owned_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
|
16
|
+
raise NotImplementedError
|
17
|
+
|
18
|
+
|
19
|
+
DeployPathOwners = ta.NewType('DeployPathOwners', ta.Sequence[DeployPathOwner])
|
20
|
+
|
21
|
+
|
22
|
+
class SingleDirDeployPathOwner(DeployPathOwner, abc.ABC):
|
23
|
+
def __init__(
|
24
|
+
self,
|
25
|
+
*args: ta.Any,
|
26
|
+
owned_dir: str,
|
27
|
+
deploy_home: ta.Optional[DeployHome],
|
28
|
+
**kwargs: ta.Any,
|
29
|
+
) -> None:
|
30
|
+
super().__init__(*args, **kwargs)
|
31
|
+
|
32
|
+
check.not_in('/', owned_dir)
|
33
|
+
self._owned_dir: str = check.non_empty_str(owned_dir)
|
34
|
+
|
35
|
+
self._deploy_home = deploy_home
|
36
|
+
|
37
|
+
self._owned_deploy_paths = frozenset([DeployPath.parse(self._owned_dir + '/')])
|
38
|
+
|
39
|
+
@cached_nullary
|
40
|
+
def _dir(self) -> str:
|
41
|
+
return os.path.join(check.non_empty_str(self._deploy_home), self._owned_dir)
|
42
|
+
|
43
|
+
@cached_nullary
|
44
|
+
def _make_dir(self) -> str:
|
45
|
+
if not os.path.isdir(d := self._dir()):
|
46
|
+
os.makedirs(d, exist_ok=True)
|
47
|
+
return d
|
48
|
+
|
49
|
+
def get_owned_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
|
50
|
+
return self._owned_deploy_paths
|