Skip to content

Commit f80801d

Browse files
br-rhrbacekasottile
authored andcommitted
Fix docker-in-docker detection for cgroups v2
1 parent 9143fc3 commit f80801d

File tree

2 files changed

+201
-69
lines changed

2 files changed

+201
-69
lines changed

pre_commit/languages/docker.py

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from __future__ import annotations
22

3+
import contextlib
34
import functools
45
import hashlib
56
import json
67
import os
8+
import re
79
from collections.abc import Sequence
810

911
from pre_commit import lang_base
@@ -17,31 +19,33 @@
1719
health_check = lang_base.basic_health_check
1820
in_env = lang_base.no_env # no special environment for docker
1921

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+
)
2032

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
2733

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()
2841

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
3843

3944

4045
def _get_docker_path(path: str) -> str:
41-
if not _is_in_docker():
42-
return path
43-
4446
container_id = _get_container_id()
47+
if container_id is None:
48+
return path
4549

4650
try:
4751
_, out, _ = cmd_output_b('docker', 'inspect', container_id)

0 commit comments

Comments
 (0)