mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
A more reliable way to get the container id.
The hostname is not always the container id. Get the container id from /proc/1/cgroup. Fixes #1918.
This commit is contained in:
parent
68294256a1
commit
3e1020945e
2 changed files with 65 additions and 36 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import socket
|
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
|
|
@ -26,12 +25,24 @@ def _is_in_docker() -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _get_container_id() -> str:
|
||||||
|
# It's assumed that we already check /proc/1/cgroup in _is_in_docker. The
|
||||||
|
# cpuset cgroup controller existed since cgroups were introduced so this
|
||||||
|
# way of getting the container ID is pretty reliable.
|
||||||
|
with open('/proc/1/cgroup', 'rb') as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
if line.split(b':')[1] == b'cpuset':
|
||||||
|
return os.path.basename(line.split(b':')[2]).strip().decode()
|
||||||
|
raise RuntimeError('Failed to find the container ID in /proc/1/cgroup.')
|
||||||
|
|
||||||
|
|
||||||
def _get_docker_path(path: str) -> str:
|
def _get_docker_path(path: str) -> str:
|
||||||
if not _is_in_docker():
|
if not _is_in_docker():
|
||||||
return path
|
return path
|
||||||
hostname = socket.gethostname()
|
|
||||||
|
|
||||||
_, out, _ = cmd_output_b('docker', 'inspect', hostname)
|
container_id = _get_container_id()
|
||||||
|
|
||||||
|
_, out, _ = cmd_output_b('docker', 'inspect', container_id)
|
||||||
|
|
||||||
container, = json.loads(out)
|
container, = json.loads(out)
|
||||||
for mount in container['Mounts']:
|
for mount in container['Mounts']:
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,41 @@ import pytest
|
||||||
|
|
||||||
from pre_commit.languages import docker
|
from pre_commit.languages import docker
|
||||||
|
|
||||||
|
DOCKER_CGROUP_EXAMPLE = b'''\
|
||||||
|
12:hugetlb:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
11:blkio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
10:freezer:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
9:cpu,cpuacct:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
8:pids:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
7:rdma:/
|
||||||
|
6:net_cls,net_prio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
5:cpuset:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
4:devices:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
3:memory:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
2:perf_event:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
1:name=systemd:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
0::/system.slice/containerd.service
|
||||||
|
''' # noqa: E501
|
||||||
|
|
||||||
|
# The ID should match the above cgroup example.
|
||||||
|
CONTAINER_ID = 'c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7' # noqa: E501
|
||||||
|
|
||||||
|
NON_DOCKER_CGROUP_EXAMPLE = b'''\
|
||||||
|
12:perf_event:/
|
||||||
|
11:hugetlb:/
|
||||||
|
10:devices:/
|
||||||
|
9:blkio:/
|
||||||
|
8:rdma:/
|
||||||
|
7:cpuset:/
|
||||||
|
6:cpu,cpuacct:/
|
||||||
|
5:freezer:/
|
||||||
|
4:memory:/
|
||||||
|
3:pids:/
|
||||||
|
2:net_cls,net_prio:/
|
||||||
|
1:name=systemd:/init.scope
|
||||||
|
0::/init.scope
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
def test_docker_fallback_user():
|
def test_docker_fallback_user():
|
||||||
def invalid_attribute():
|
def invalid_attribute():
|
||||||
|
|
@ -37,45 +72,25 @@ def _mock_open(data):
|
||||||
|
|
||||||
|
|
||||||
def test_in_docker_docker_in_file():
|
def test_in_docker_docker_in_file():
|
||||||
docker_cgroup_example = b'''\
|
with _mock_open(DOCKER_CGROUP_EXAMPLE):
|
||||||
12:hugetlb:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
11:blkio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
10:freezer:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
9:cpu,cpuacct:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
8:pids:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
7:rdma:/
|
|
||||||
6:net_cls,net_prio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
5:cpuset:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
4:devices:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
3:memory:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
2:perf_event:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
1:name=systemd:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
|
||||||
0::/system.slice/containerd.service
|
|
||||||
''' # noqa: E501
|
|
||||||
with _mock_open(docker_cgroup_example):
|
|
||||||
assert docker._is_in_docker() is True
|
assert docker._is_in_docker() is True
|
||||||
|
|
||||||
|
|
||||||
def test_in_docker_docker_not_in_file():
|
def test_in_docker_docker_not_in_file():
|
||||||
non_docker_cgroup_example = b'''\
|
with _mock_open(NON_DOCKER_CGROUP_EXAMPLE):
|
||||||
12:perf_event:/
|
|
||||||
11:hugetlb:/
|
|
||||||
10:devices:/
|
|
||||||
9:blkio:/
|
|
||||||
8:rdma:/
|
|
||||||
7:cpuset:/
|
|
||||||
6:cpu,cpuacct:/
|
|
||||||
5:freezer:/
|
|
||||||
4:memory:/
|
|
||||||
3:pids:/
|
|
||||||
2:net_cls,net_prio:/
|
|
||||||
1:name=systemd:/init.scope
|
|
||||||
0::/init.scope
|
|
||||||
'''
|
|
||||||
with _mock_open(non_docker_cgroup_example):
|
|
||||||
assert docker._is_in_docker() is False
|
assert docker._is_in_docker() is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_container_id():
|
||||||
|
with _mock_open(DOCKER_CGROUP_EXAMPLE):
|
||||||
|
assert docker._get_container_id() == CONTAINER_ID
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_container_id_failure():
|
||||||
|
with _mock_open(b''), pytest.raises(RuntimeError):
|
||||||
|
docker._get_container_id()
|
||||||
|
|
||||||
|
|
||||||
def test_get_docker_path_not_in_docker_returns_same():
|
def test_get_docker_path_not_in_docker_returns_same():
|
||||||
with mock.patch.object(docker, '_is_in_docker', return_value=False):
|
with mock.patch.object(docker, '_is_in_docker', return_value=False):
|
||||||
assert docker._get_docker_path('abc') == 'abc'
|
assert docker._get_docker_path('abc') == 'abc'
|
||||||
|
|
@ -84,6 +99,9 @@ def test_get_docker_path_not_in_docker_returns_same():
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def in_docker():
|
def in_docker():
|
||||||
with mock.patch.object(docker, '_is_in_docker', return_value=True):
|
with mock.patch.object(docker, '_is_in_docker', return_value=True):
|
||||||
|
with mock.patch.object(
|
||||||
|
docker, '_get_container_id', return_value=CONTAINER_ID,
|
||||||
|
):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue