diff --git a/pre_commit/languages/docker.py b/pre_commit/languages/docker.py index 5b21ec94c..a9452694c 100644 --- a/pre_commit/languages/docker.py +++ b/pre_commit/languages/docker.py @@ -1,7 +1,6 @@ import hashlib import json import os -import socket from typing import Sequence from typing import Tuple @@ -29,9 +28,10 @@ def _is_in_docker() -> bool: def _get_docker_path(path: str) -> str: if not _is_in_docker(): return path - hostname = socket.gethostname() + with open('/proc/1/cgroup', 'rb') as f: + container_id = os.path.basename(f.readlines()[0]).strip().decode() - _, out, _ = cmd_output_b('docker', 'inspect', hostname) + _, out, _ = cmd_output_b('docker', 'inspect', container_id) container, = json.loads(out) for mount in container['Mounts']: diff --git a/tests/languages/docker_test.py b/tests/languages/docker_test.py index 01b5e2773..1eaf3231d 100644 --- a/tests/languages/docker_test.py +++ b/tests/languages/docker_test.py @@ -9,6 +9,38 @@ 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 + +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 invalid_attribute(): @@ -37,47 +69,19 @@ def _mock_open(data): def test_in_docker_docker_in_file(): - 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 with _mock_open(docker_cgroup_example): assert docker._is_in_docker() is True def test_in_docker_docker_not_in_file(): - 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 -''' with _mock_open(non_docker_cgroup_example): assert docker._is_in_docker() is False 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, + ), _mock_open(non_docker_cgroup_example): assert docker._get_docker_path('abc') == 'abc' @@ -103,7 +107,7 @@ def _docker_output(out): def test_get_docker_path_in_docker_no_binds_same_path(in_docker): docker_out = json.dumps([{'Mounts': []}]).encode() - with _docker_output(docker_out): + with _docker_output(docker_out), _mock_open(docker_cgroup_example): assert docker._get_docker_path('abc') == 'abc' @@ -111,7 +115,9 @@ def test_get_docker_path_in_docker_binds_path_equal(in_docker): binds_list = [{'Source': '/opt/my_code', 'Destination': '/project'}] docker_out = json.dumps([{'Mounts': binds_list}]).encode() - with _linux_commonpath(), _docker_output(docker_out): + with _linux_commonpath(), _docker_output(docker_out), _mock_open( + docker_cgroup_example, + ): assert docker._get_docker_path('/project') == '/opt/my_code' @@ -119,7 +125,9 @@ def test_get_docker_path_in_docker_binds_path_complex(in_docker): binds_list = [{'Source': '/opt/my_code', 'Destination': '/project'}] docker_out = json.dumps([{'Mounts': binds_list}]).encode() - with _linux_commonpath(), _docker_output(docker_out): + with _linux_commonpath(), _docker_output(docker_out), _mock_open( + docker_cgroup_example, + ): path = '/project/test/something' assert docker._get_docker_path(path) == '/opt/my_code/test/something' @@ -128,7 +136,9 @@ def test_get_docker_path_in_docker_no_substring(in_docker): binds_list = [{'Source': '/opt/my_code', 'Destination': '/project'}] docker_out = json.dumps([{'Mounts': binds_list}]).encode() - with _linux_commonpath(), _docker_output(docker_out): + with _linux_commonpath(), _docker_output(docker_out), _mock_open( + docker_cgroup_example, + ): path = '/projectSuffix/test/something' assert docker._get_docker_path(path) == path @@ -141,7 +151,9 @@ def test_get_docker_path_in_docker_binds_path_many_binds(in_docker): ] docker_out = json.dumps([{'Mounts': binds_list}]).encode() - with _linux_commonpath(), _docker_output(docker_out): + with _linux_commonpath(), _docker_output(docker_out), _mock_open( + docker_cgroup_example, + ): assert docker._get_docker_path('/project') == '/opt/my_code' @@ -149,7 +161,9 @@ def test_get_docker_path_in_docker_windows(in_docker): binds_list = [{'Source': r'c:\users\user', 'Destination': r'c:\folder'}] docker_out = json.dumps([{'Mounts': binds_list}]).encode() - with _nt_commonpath(), _docker_output(docker_out): + with _nt_commonpath(), _docker_output(docker_out), _mock_open( + docker_cgroup_example, + ): path = r'c:\folder\test\something' expected = r'c:\users\user\test\something' assert docker._get_docker_path(path) == expected