mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-04-15 18:11:48 +04:00
docker: support detection and container-id extraction for cgroups v2
This commit is contained in:
parent
d2b61d0ef2
commit
561a19d372
1 changed files with 56 additions and 11 deletions
|
|
@ -18,22 +18,67 @@ in_env = lang_base.no_env # no special environment for docker
|
||||||
|
|
||||||
|
|
||||||
def _is_in_docker() -> bool:
|
def _is_in_docker() -> bool:
|
||||||
|
"""Determine if we're running inside a docker container.
|
||||||
|
|
||||||
|
Uses multiple detection methods:
|
||||||
|
1. Check for "docker" in /proc/1/cgroup (cgroups v1)
|
||||||
|
2. Check /proc/self/mountinfo for container indicators
|
||||||
|
3. Check for /.dockerenv file existence
|
||||||
|
4. Check for IS_CONTAINER environment variable
|
||||||
|
"""
|
||||||
|
# Method 1 (cgroups v1): Check /proc/1/cgroup
|
||||||
try:
|
try:
|
||||||
with open('/proc/1/cgroup', 'rb') as f:
|
with open("/proc/1/cgroup", "rb") as f:
|
||||||
return b'docker' in f.read()
|
cgroup_content = f.read()
|
||||||
|
if b"docker" in cgroup_content or b"containerd" in cgroup_content:
|
||||||
|
return True
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Method 2 (cgroups v2): Check /proc/self/mountinfo for container indicators
|
||||||
|
try:
|
||||||
|
with open("/proc/self/mountinfo", "rb") as f:
|
||||||
|
mountinfo = f.read()
|
||||||
|
if b"overlay" in mountinfo and (b"docker" in mountinfo or b"containerd" in mountinfo):
|
||||||
|
return True
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Method 3: Check for /.dockerenv file
|
||||||
|
if os.path.exists("/.dockerenv"):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Method 4: Check for IS_CONTAINER environment variable
|
||||||
|
if os.environ.get("IS_CONTAINER"):
|
||||||
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _get_container_id() -> str:
|
def _get_container_id() -> str:
|
||||||
# It's assumed that we already check /proc/1/cgroup in _is_in_docker. The
|
# Method 1 (cgroups v1): Parse /proc/1/cgroup
|
||||||
# cpuset cgroup controller existed since cgroups were introduced so this
|
try:
|
||||||
# way of getting the container ID is pretty reliable.
|
|
||||||
with open('/proc/1/cgroup', 'rb') as f:
|
with open('/proc/1/cgroup', 'rb') as f:
|
||||||
for line in f.readlines():
|
for line in f.readlines():
|
||||||
if line.split(b':')[1] == b'cpuset':
|
if line.split(b':')[1] == b'cpuset':
|
||||||
return os.path.basename(line.split(b':')[2]).strip().decode()
|
return os.path.basename(line.split(b':')[2]).strip().decode()
|
||||||
raise RuntimeError('Failed to find the container ID in /proc/1/cgroup.')
|
except (FileNotFoundError, IndexError, ValueError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Method 2 (cgroups v2): Parse /proc/self/mountinfo
|
||||||
|
try:
|
||||||
|
with open('/proc/self/mountinfo', 'rb') as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
if b'/docker/containers/' in line:
|
||||||
|
parts = line.split(b'/docker/containers/')
|
||||||
|
if len(parts) >= 2:
|
||||||
|
container_id = parts[1].split(b'/')[0].decode()
|
||||||
|
if container_id:
|
||||||
|
return container_id
|
||||||
|
except (FileNotFoundError, IndexError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
raise RuntimeError('Failed to find the container ID in either /proc/1/cgroup or /proc/self/mountinfo.')
|
||||||
|
|
||||||
|
|
||||||
def _get_docker_path(path: str) -> str:
|
def _get_docker_path(path: str) -> str:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue