omdev 0.0.0.dev212__py3-none-any.whl → 0.0.0.dev214__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
omdev/ci/compose.py CHANGED
@@ -1,5 +1,4 @@
1
1
  # ruff: noqa: UP006 UP007
2
- # @omlish-lite
3
2
  """
4
3
  TODO:
5
4
  - fix rmi - only when not referenced anymore
@@ -11,15 +10,16 @@ import os.path
11
10
  import shlex
12
11
  import typing as ta
13
12
 
13
+ from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
14
14
  from omlish.lite.cached import cached_nullary
15
15
  from omlish.lite.check import check
16
- from omlish.lite.contextmanagers import ExitStacked
16
+ from omlish.lite.contextmanagers import AsyncExitStacked
17
+ from omlish.lite.contextmanagers import adefer
17
18
  from omlish.lite.contextmanagers import defer
18
19
  from omlish.lite.json import json_dumps_pretty
19
- from omlish.subprocesses import subprocesses
20
+ from omlish.os.temp import make_temp_file
20
21
 
21
22
  from .shell import ShellCmd
22
- from .utils import make_temp_file
23
23
  from .utils import read_yaml_file
24
24
 
25
25
 
@@ -46,7 +46,7 @@ def get_compose_service_dependencies(
46
46
  ##
47
47
 
48
48
 
49
- class DockerComposeRun(ExitStacked):
49
+ class DockerComposeRun(AsyncExitStacked):
50
50
  @dc.dataclass(frozen=True)
51
51
  class Config:
52
52
  compose_file: str
@@ -64,6 +64,7 @@ class DockerComposeRun(ExitStacked):
64
64
 
65
65
  #
66
66
 
67
+ no_dependencies: bool = False
67
68
  no_dependency_cleanup: bool = False
68
69
 
69
70
  #
@@ -82,40 +83,6 @@ class DockerComposeRun(ExitStacked):
82
83
 
83
84
  #
84
85
 
85
- @property
86
- def image_tag(self) -> str:
87
- pfx = 'sha256:'
88
- if (image := self._cfg.image).startswith(pfx):
89
- image = image[len(pfx):]
90
-
91
- return f'{self._cfg.service}:{image}'
92
-
93
- @cached_nullary
94
- def tag_image(self) -> str:
95
- image_tag = self.image_tag
96
-
97
- subprocesses.check_call(
98
- 'docker',
99
- 'tag',
100
- self._cfg.image,
101
- image_tag,
102
- **self._subprocess_kwargs,
103
- )
104
-
105
- def delete_tag() -> None:
106
- subprocesses.check_call(
107
- 'docker',
108
- 'rmi',
109
- image_tag,
110
- **self._subprocess_kwargs,
111
- )
112
-
113
- self._enter_context(defer(delete_tag)) # noqa
114
-
115
- return image_tag
116
-
117
- #
118
-
119
86
  def _rewrite_compose_dct(self, in_dct: ta.Dict[str, ta.Any]) -> ta.Dict[str, ta.Any]:
120
87
  out = dict(in_dct)
121
88
 
@@ -129,29 +96,28 @@ class DockerComposeRun(ExitStacked):
129
96
  in_service: dict = in_services[self._cfg.service]
130
97
  out_services[self._cfg.service] = out_service = dict(in_service)
131
98
 
132
- out_service['image'] = self.image_tag
99
+ out_service['image'] = self._cfg.image
133
100
 
134
101
  for k in ['build', 'platform']:
135
102
  if k in out_service:
136
103
  del out_service[k]
137
104
 
138
- out_service['links'] = [
139
- f'{l}:{l}' if ':' not in l else l
140
- for l in out_service.get('links', [])
141
- ]
142
-
143
105
  #
144
106
 
145
- depends_on = in_service.get('depends_on', [])
107
+ if not self._cfg.no_dependencies:
108
+ depends_on = in_service.get('depends_on', [])
146
109
 
147
- for dep_service, in_dep_service_dct in list(in_services.items()):
148
- if dep_service not in depends_on:
149
- continue
110
+ for dep_service, in_dep_service_dct in list(in_services.items()):
111
+ if dep_service not in depends_on:
112
+ continue
150
113
 
151
- out_dep_service: dict = dict(in_dep_service_dct)
152
- out_services[dep_service] = out_dep_service
114
+ out_dep_service: dict = dict(in_dep_service_dct)
115
+ out_services[dep_service] = out_dep_service
153
116
 
154
- out_dep_service['ports'] = []
117
+ out_dep_service['ports'] = []
118
+
119
+ else:
120
+ out_service['depends_on'] = []
155
121
 
156
122
  #
157
123
 
@@ -177,22 +143,20 @@ class DockerComposeRun(ExitStacked):
177
143
 
178
144
  #
179
145
 
180
- def _cleanup_dependencies(self) -> None:
181
- subprocesses.check_call(
146
+ async def _cleanup_dependencies(self) -> None:
147
+ await asyncio_subprocesses.check_call(
182
148
  'docker',
183
149
  'compose',
184
150
  '-f', self.rewrite_compose_file(),
185
151
  'down',
186
152
  )
187
153
 
188
- def run(self) -> None:
189
- self.tag_image()
190
-
154
+ async def run(self) -> None:
191
155
  compose_file = self.rewrite_compose_file()
192
156
 
193
- with contextlib.ExitStack() as es:
194
- if not self._cfg.no_dependency_cleanup:
195
- es.enter_context(defer(self._cleanup_dependencies)) # noqa
157
+ async with contextlib.AsyncExitStack() as es:
158
+ if not (self._cfg.no_dependencies or self._cfg.no_dependency_cleanup):
159
+ await es.enter_async_context(adefer(self._cleanup_dependencies)) # noqa
196
160
 
197
161
  sh_cmd = ' '.join([
198
162
  'docker',
@@ -211,7 +175,7 @@ class DockerComposeRun(ExitStacked):
211
175
 
212
176
  run_cmd = dc.replace(self._cfg.cmd, s=sh_cmd)
213
177
 
214
- run_cmd.run(
215
- subprocesses.check_call,
178
+ await run_cmd.run(
179
+ asyncio_subprocesses.check_call,
216
180
  **self._subprocess_kwargs,
217
181
  )
omdev/ci/consts.py ADDED
@@ -0,0 +1 @@
1
+ CI_CACHE_VERSION = 1
omdev/ci/docker.py CHANGED
@@ -1,5 +1,4 @@
1
1
  # ruff: noqa: UP006 UP007
2
- # @omlish-lite
3
2
  """
4
3
  TODO:
5
4
  - some less stupid Dockerfile hash
@@ -13,12 +12,11 @@ import shlex
13
12
  import tarfile
14
13
  import typing as ta
15
14
 
15
+ from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
16
16
  from omlish.lite.check import check
17
- from omlish.lite.contextmanagers import defer
18
- from omlish.subprocesses import subprocesses
17
+ from omlish.os.temp import temp_file_context
19
18
 
20
19
  from .shell import ShellCmd
21
- from .utils import make_temp_file
22
20
  from .utils import sha256_str
23
21
 
24
22
 
@@ -60,8 +58,8 @@ def read_docker_tar_image_id(tar_file: str) -> str:
60
58
  ##
61
59
 
62
60
 
63
- def is_docker_image_present(image: str) -> bool:
64
- out = subprocesses.check_output(
61
+ async def is_docker_image_present(image: str) -> bool:
62
+ out = await asyncio_subprocesses.check_output(
65
63
  'docker',
66
64
  'images',
67
65
  '--format', 'json',
@@ -76,55 +74,74 @@ def is_docker_image_present(image: str) -> bool:
76
74
  return True
77
75
 
78
76
 
79
- def pull_docker_image(
77
+ async def pull_docker_image(
80
78
  image: str,
81
79
  ) -> None:
82
- subprocesses.check_call(
80
+ await asyncio_subprocesses.check_call(
83
81
  'docker',
84
82
  'pull',
85
83
  image,
86
84
  )
87
85
 
88
86
 
89
- def build_docker_image(
87
+ async def build_docker_image(
90
88
  docker_file: str,
91
89
  *,
90
+ tag: ta.Optional[str] = None,
92
91
  cwd: ta.Optional[str] = None,
92
+ run_options: ta.Optional[ta.Sequence[str]] = None,
93
93
  ) -> str:
94
- id_file = make_temp_file()
95
- with defer(lambda: os.unlink(id_file)):
96
- subprocesses.check_call(
94
+ with temp_file_context() as id_file:
95
+ await asyncio_subprocesses.check_call(
97
96
  'docker',
98
97
  'build',
99
98
  '-f', os.path.abspath(docker_file),
100
99
  '--iidfile', id_file,
101
- '--squash',
100
+ *(['--tag', tag] if tag is not None else []),
101
+ *(run_options or []),
102
102
  '.',
103
103
  **(dict(cwd=cwd) if cwd is not None else {}),
104
104
  )
105
105
 
106
- with open(id_file) as f:
106
+ with open(id_file) as f: # noqa
107
107
  image_id = check.single(f.read().strip().splitlines()).strip()
108
108
 
109
109
  return image_id
110
110
 
111
111
 
112
+ async def tag_docker_image(image: str, tag: str) -> None:
113
+ await asyncio_subprocesses.check_call(
114
+ 'docker',
115
+ 'tag',
116
+ image,
117
+ tag,
118
+ )
119
+
120
+
121
+ async def delete_docker_tag(tag: str) -> None:
122
+ await asyncio_subprocesses.check_call(
123
+ 'docker',
124
+ 'rmi',
125
+ tag,
126
+ )
127
+
128
+
112
129
  ##
113
130
 
114
131
 
115
- def save_docker_tar_cmd(
132
+ async def save_docker_tar_cmd(
116
133
  image: str,
117
134
  output_cmd: ShellCmd,
118
135
  ) -> None:
119
136
  cmd = dc.replace(output_cmd, s=f'docker save {image} | {output_cmd.s}')
120
- cmd.run(subprocesses.check_call)
137
+ await cmd.run(asyncio_subprocesses.check_call)
121
138
 
122
139
 
123
- def save_docker_tar(
140
+ async def save_docker_tar(
124
141
  image: str,
125
142
  tar_file: str,
126
143
  ) -> None:
127
- return save_docker_tar_cmd(
144
+ return await save_docker_tar_cmd(
128
145
  image,
129
146
  ShellCmd(f'cat > {shlex.quote(tar_file)}'),
130
147
  )
@@ -133,19 +150,19 @@ def save_docker_tar(
133
150
  #
134
151
 
135
152
 
136
- def load_docker_tar_cmd(
153
+ async def load_docker_tar_cmd(
137
154
  input_cmd: ShellCmd,
138
155
  ) -> str:
139
156
  cmd = dc.replace(input_cmd, s=f'{input_cmd.s} | docker load')
140
157
 
141
- out = cmd.run(subprocesses.check_output).decode()
158
+ out = (await cmd.run(asyncio_subprocesses.check_output)).decode()
142
159
 
143
160
  line = check.single(out.strip().splitlines())
144
161
  loaded = line.partition(':')[2].strip()
145
162
  return loaded
146
163
 
147
164
 
148
- def load_docker_tar(
165
+ async def load_docker_tar(
149
166
  tar_file: str,
150
167
  ) -> str:
151
- return load_docker_tar_cmd(ShellCmd(f'cat {shlex.quote(tar_file)}'))
168
+ return await load_docker_tar_cmd(ShellCmd(f'cat {shlex.quote(tar_file)}'))
@@ -1,5 +1,4 @@
1
1
  # ruff: noqa: UP006 UP007
2
- # @omlish-lite
3
2
  """
4
3
  export FILE_SIZE=$(stat --format="%s" $FILE)
5
4
 
@@ -93,7 +92,7 @@ class GithubCacheServiceV1:
93
92
  @dc.dataclass(frozen=True)
94
93
  class ReserveCacheRequest:
95
94
  key: str
96
- cache_size: ta.Optional[int]
95
+ cache_size: ta.Optional[int] = None
97
96
  version: ta.Optional[str] = None
98
97
 
99
98
  @dc.dataclass(frozen=True)
@@ -1,5 +1,4 @@
1
1
  # ruff: noqa: UP006 UP007
2
- # @omlish-lite
3
2
  """
4
3
  sudo rm -rf \
5
4
  /usr/local/.ghcup \
@@ -9,3 +8,11 @@ sudo rm -rf \
9
8
  /opt/hostedtoolcache 8.0G, 14843980 files
10
9
  /usr/local/lib/android 6.4G, 17251667 files
11
10
  """
11
+ from .env import register_github_env_var
12
+
13
+
14
+ GITHUB_ACTIONS_ENV_VAR = register_github_env_var('GITHUB_ACTIONS')
15
+
16
+
17
+ def is_in_github_actions() -> bool:
18
+ return GITHUB_ACTIONS_ENV_VAR() is not None