|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +import contextlib |
3 | 4 | import functools |
4 | 5 | import hashlib |
5 | 6 | import json |
6 | 7 | import os |
| 8 | +import re |
7 | 9 | from collections.abc import Sequence |
8 | 10 |
|
9 | 11 | from pre_commit import lang_base |
|
17 | 19 | health_check = lang_base.basic_health_check |
18 | 20 | in_env = lang_base.no_env # no special environment for docker |
19 | 21 |
|
| 22 | +_HOSTNAME_MOUNT_RE = re.compile( |
| 23 | + rb""" |
| 24 | + /containers |
| 25 | + (?:/overlay-containers)? |
| 26 | + /([a-z0-9]{64}) |
| 27 | + (?:/userdata)? |
| 28 | + /hostname |
| 29 | + """, |
| 30 | + re.VERBOSE, |
| 31 | +) |
20 | 32 |
|
21 | | -def _is_in_docker() -> bool: |
22 | | - try: |
23 | | - with open('/proc/1/cgroup', 'rb') as f: |
24 | | - return b'docker' in f.read() |
25 | | - except FileNotFoundError: |
26 | | - return False |
27 | 33 |
|
| 34 | +def _get_container_id() -> str | None: |
| 35 | + with contextlib.suppress(FileNotFoundError): |
| 36 | + with open('/proc/1/mountinfo', 'rb') as f: |
| 37 | + for line in f: |
| 38 | + m = _HOSTNAME_MOUNT_RE.search(line) |
| 39 | + if m: |
| 40 | + return m[1].decode() |
28 | 41 |
|
29 | | -def _get_container_id() -> str: |
30 | | - # It's assumed that we already check /proc/1/cgroup in _is_in_docker. The |
31 | | - # cpuset cgroup controller existed since cgroups were introduced so this |
32 | | - # way of getting the container ID is pretty reliable. |
33 | | - with open('/proc/1/cgroup', 'rb') as f: |
34 | | - for line in f.readlines(): |
35 | | - if line.split(b':')[1] == b'cpuset': |
36 | | - return os.path.basename(line.split(b':')[2]).strip().decode() |
37 | | - raise RuntimeError('Failed to find the container ID in /proc/1/cgroup.') |
| 42 | + return None |
38 | 43 |
|
39 | 44 |
|
40 | 45 | def _get_docker_path(path: str) -> str: |
41 | | - if not _is_in_docker(): |
42 | | - return path |
43 | | - |
44 | 46 | container_id = _get_container_id() |
| 47 | + if container_id is None: |
| 48 | + return path |
45 | 49 |
|
46 | 50 | try: |
47 | 51 | _, out, _ = cmd_output_b('docker', 'inspect', container_id) |
|
0 commit comments