|
1 | 1 | from __future__importannotations |
2 | 2 |
|
| 3 | +importcontextlib |
3 | 4 | importfunctools |
4 | 5 | importhashlib |
5 | 6 | importjson |
6 | 7 | importos |
| 8 | +importre |
7 | 9 | fromcollections.abcimportSequence |
8 | 10 |
|
9 | 11 | frompre_commitimportlang_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 | | -withopen('/proc/1/cgroup','rb')asf: |
24 | | -returnb'docker'inf.read() |
25 | | -exceptFileNotFoundError: |
26 | | -returnFalse |
27 | 33 |
|
| 34 | +def_get_container_id()->str|None: |
| 35 | +withcontextlib.suppress(FileNotFoundError): |
| 36 | +withopen('/proc/1/mountinfo','rb')asf: |
| 37 | +forlineinf: |
| 38 | +m=_HOSTNAME_MOUNT_RE.search(line) |
| 39 | +ifm: |
| 40 | +returnm[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 | | -withopen('/proc/1/cgroup','rb')asf: |
34 | | -forlineinf.readlines(): |
35 | | -ifline.split(b':')[1]==b'cpuset': |
36 | | -returnos.path.basename(line.split(b':')[2]).strip().decode() |
37 | | -raiseRuntimeError('Failed to find the container ID in /proc/1/cgroup.') |
| 42 | +returnNone |
38 | 43 |
|
39 | 44 |
|
40 | 45 | def_get_docker_path(path:str)->str: |
41 | | -ifnot_is_in_docker(): |
42 | | -returnpath |
43 | | - |
44 | 46 | container_id=_get_container_id() |
| 47 | +ifcontainer_idisNone: |
| 48 | +returnpath |
45 | 49 |
|
46 | 50 | try: |
47 | 51 | _,out,_=cmd_output_b('docker','inspect',container_id) |
|