Skip to content

Commit

Permalink
More flexible cgroupv2 container id parsing (and podman support) (#7361)
Browse files Browse the repository at this point in the history
This is based on a conversation in [opentelemetry-go
#3508](open-telemetry/opentelemetry-go#3508) and
to be more consistent with [the js cgroupv2 parser
impl](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/f0a93685cfb43543b7ca577dd370d56576b49e3f/detectors/node/opentelemetry-resource-detector-container/src/detectors/ContainerDetector.ts#L68).

Unsurprisingly, podman does not include the word `docker` in the
`mountinfo` file. As a result, the container id parsing would fail from
inside a podman container. This fixes that up to be more compatible.
  • Loading branch information
breedx-splk committed Dec 10, 2022
1 parent 4856377 commit 264edd9
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/** Utility for extracting the container ID from runtimes inside cgroup v2 containers. */
class CgroupV2ContainerIdExtractor {
Expand All @@ -23,8 +24,7 @@ class CgroupV2ContainerIdExtractor {
Logger.getLogger(CgroupV2ContainerIdExtractor.class.getName());

static final Path V2_CGROUP_PATH = Paths.get("/proc/self/mountinfo");
private static final Pattern CONTAINER_RE =
Pattern.compile(".*/docker/containers/([0-9a-f]{64})/.*");
private static final Pattern CONTAINER_ID_RE = Pattern.compile("^[0-9a-f]{64}$");

private final ContainerResource.Filesystem filesystem;

Expand All @@ -44,10 +44,12 @@ Optional<String> extractContainerId() {
try {
return filesystem
.lines(V2_CGROUP_PATH)
.map(CONTAINER_RE::matcher)
.filter(line -> line.contains("hostname"))
.flatMap(line -> Stream.of(line.split("/")))
.map(CONTAINER_ID_RE::matcher)
.filter(Matcher::matches)
.findFirst()
.map(matcher -> matcher.group(1));
.map(matcher -> matcher.group(0));
} catch (IOException e) {
logger.log(Level.WARNING, "Unable to read v2 cgroup path", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
package io.opentelemetry.instrumentation.resources;

import static io.opentelemetry.instrumentation.resources.CgroupV2ContainerIdExtractor.V2_CGROUP_PATH;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Optional;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
Expand All @@ -30,39 +34,38 @@ void fileNotReadable() {
}

@Test
void extractSuccess() throws Exception {
void extractSuccess_docker() throws Exception {
when(filesystem.isReadable(V2_CGROUP_PATH)).thenReturn(true);
Stream<String> fileContent = getTestFileContent();
Stream<String> fileContent = getTestDockerFileContent();
when(filesystem.lines(V2_CGROUP_PATH)).thenReturn(fileContent);
CgroupV2ContainerIdExtractor extractor = new CgroupV2ContainerIdExtractor(filesystem);
Optional<String> result = extractor.extractContainerId();
assertThat(result.orElse("fail"))
.isEqualTo("dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183");
.isEqualTo("be522444b60caf2d3934b8b24b916a8a314f4b68d4595aa419874657e8d103f2");
}

private static Stream<String> getTestFileContent() {
return Stream.of(
"456 375 0:143 / / rw,relatime master:175 - overlay overlay rw,lowerdir=/var/lib/docker/overlay2/l/37L57D2IM7MEWLVE2Q2ECNDT67:/var/lib/docker/overlay2/l/46FCA2JFPCSNFGAR5TSYLLNHLK,upperdir=/var/lib/docker/overlay2/4e82c300793d703c19bdf887bfdad8b0354edda884ea27a8a2df89ab292719a4/diff,workdir=/var/lib/docker/overlay2/4e82c300793d703c19bdf887bfdad8b0354edda884ea27a8a2df89ab292719a4/work",
"457 456 0:146 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw",
"466 456 0:147 / /dev rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755",
"467 466 0:148 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666",
"468 456 0:149 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs ro",
"469 468 0:30 / /sys/fs/cgroup ro,nosuid,nodev,noexec,relatime - cgroup2 cgroup rw",
"470 466 0:145 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw",
"471 466 0:150 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=65536k",
"472 456 254:1 /docker/containers/dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183/resolv.conf /etc/resolv.conf rw,relatime - ext4 /dev/vda1 rw",
"473 456 254:1 /docker/containers/dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw",
"474 456 254:1 /docker/containers/dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183/hosts /etc/hosts rw,relatime - ext4 /dev/vda1 rw",
"376 466 0:148 /0 /dev/console rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666",
"377 457 0:146 /bus /proc/bus ro,nosuid,nodev,noexec,relatime - proc proc rw",
"378 457 0:146 /fs /proc/fs ro,nosuid,nodev,noexec,relatime - proc proc rw",
"379 457 0:146 /irq /proc/irq ro,nosuid,nodev,noexec,relatime - proc proc rw",
"380 457 0:146 /sys /proc/sys ro,nosuid,nodev,noexec,relatime - proc proc rw",
"381 457 0:146 /sysrq-trigger /proc/sysrq-trigger ro,nosuid,nodev,noexec,relatime - proc proc rw",
"382 457 0:151 / /proc/acpi ro,relatime - tmpfs tmpfs ro",
"383 457 0:147 /null /proc/kcore rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755",
"384 457 0:147 /null /proc/keys rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755",
"385 457 0:147 /null /proc/timer_list rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755",
"386 468 0:152 / /sys/firmware ro,relatime - tmpfs tmpfs ");
@Test
void extractSuccess_podman() throws Exception {
when(filesystem.isReadable(V2_CGROUP_PATH)).thenReturn(true);
Stream<String> fileContent = getTestPodmanFileContent();
when(filesystem.lines(V2_CGROUP_PATH)).thenReturn(fileContent);
CgroupV2ContainerIdExtractor extractor = new CgroupV2ContainerIdExtractor(filesystem);
Optional<String> result = extractor.extractContainerId();
assertThat(result.orElse("fail"))
.isEqualTo("2a33efc76e519c137fe6093179653788bed6162d4a15e5131c8e835c968afbe6");
}

private static Stream<String> getTestDockerFileContent() throws Exception {
return fileToStreamOfLines("docker_proc_self_mountinfo");
}

private static Stream<String> getTestPodmanFileContent() throws Exception {
return fileToStreamOfLines("podman_proc_self_mountinfo");
}

private static Stream<String> fileToStreamOfLines(String filename) {
InputStream in =
CgroupV2ContainerIdExtractorTest.class.getClassLoader().getResourceAsStream(filename);
return new BufferedReader(new InputStreamReader(in, UTF_8)).lines();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
473 456 254:1 /docker/containers/be522444b60caf2d3934b8b24b916a8a314f4b68d4595aa419874657e8d103f2/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw
root@be522444b60c:/# cat /proc/self/mountinfo
456 375 0:143 / / rw,relatime master:175 - overlay overlay rw,lowerdir=/var/lib/docker/overlay2/l/CBPR2ETR4Z3UMOOGIIRDVT2P27:/var/lib/docker/overlay2/l/46FCA2JFPCSNFGAR5TSYLLNHLK,upperdir=/var/lib/docker/overlay2/3ef3e5a1a87b4e220c1da9a7901654e945b0ef5398e1b67fccb42fdb7750829e/diff,workdir=/var/lib/docker/overlay2/3ef3e5a1a87b4e220c1da9a7901654e945b0ef5398e1b67fccb42fdb7750829e/work
457 456 0:146 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
466 456 0:147 / /dev rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755
467 466 0:148 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666
468 456 0:149 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs ro
469 468 0:30 / /sys/fs/cgroup ro,nosuid,nodev,noexec,relatime - cgroup2 cgroup rw
470 466 0:145 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw
471 466 0:150 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=65536k
472 456 254:1 /docker/containers/be522444b60caf2d3934b8b24b916a8a314f4b68d4595aa419874657e8d103f2/resolv.conf /etc/resolv.conf rw,relatime - ext4 /dev/vda1 rw
473 456 254:1 /docker/containers/be522444b60caf2d3934b8b24b916a8a314f4b68d4595aa419874657e8d103f2/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw
474 456 254:1 /docker/containers/be522444b60caf2d3934b8b24b916a8a314f4b68d4595aa419874657e8d103f2/hosts /etc/hosts rw,relatime - ext4 /dev/vda1 rw
376 466 0:148 /0 /dev/console rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666
377 457 0:146 /bus /proc/bus ro,nosuid,nodev,noexec,relatime - proc proc rw
378 457 0:146 /fs /proc/fs ro,nosuid,nodev,noexec,relatime - proc proc rw
379 457 0:146 /irq /proc/irq ro,nosuid,nodev,noexec,relatime - proc proc rw
380 457 0:146 /sys /proc/sys ro,nosuid,nodev,noexec,relatime - proc proc rw
381 457 0:146 /sysrq-trigger /proc/sysrq-trigger ro,nosuid,nodev,noexec,relatime - proc proc rw
382 457 0:151 / /proc/acpi ro,relatime - tmpfs tmpfs ro
383 457 0:147 /null /proc/kcore rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755
384 457 0:147 /null /proc/keys rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755
385 457 0:147 /null /proc/timer_list rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755
386 468 0:152 / /sys/firmware ro,relatime - tmpfs tmpfs ro
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
983 961 0:56 /containers/overlay-containers/2a33efc76e519c137fe6093179653788bed6162d4a15e5131c8e835c968afbe6/userdata/hostname /etc/hostname ro,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,size=783888k,nr_inodes=195972,mode=700,uid=2024,gid=2024,inode64
[root@2a33efc76e51 /]# cat /proc/self/mountinfo
961 812 0:58 / / ro,relatime - overlay overlay rw,lowerdir=/home/dracula/.local/share/containers/storage/overlay/l/4NB35A5Z4YGWDHXYEUZU4FN6BU,upperdir=/home/dracula/.local/share/containers/storage/overlay/a73044caca1b918335d1db6f0052d21d35045136f3aa86976dbad1ec96e2fdde/diff,workdir=/home/dracula/.local/share/containers/storage/overlay/a73044caca1b918335d1db6f0052d21d35045136f3aa86976dbad1ec96e2fdde/work,userxattr
962 961 0:63 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs rw
963 961 0:64 / /run rw,nosuid,nodev,relatime - tmpfs tmpfs rw,uid=2024,gid=2024,inode64
973 961 0:65 / /tmp rw,nosuid,nodev,relatime - tmpfs tmpfs rw,uid=2024,gid=2024,inode64
974 961 0:66 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
975 961 0:67 / /dev rw,nosuid - tmpfs tmpfs rw,size=65536k,mode=755,uid=2024,gid=2024,inode64
976 961 0:68 / /var/tmp rw,nosuid,nodev,relatime - tmpfs tmpfs rw,uid=2024,gid=2024,inode64
977 975 0:62 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw
978 975 0:69 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=427684,mode=620,ptmxmode=666
979 975 0:57 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=64000k,uid=2024,gid=2024,inode64
980 963 0:56 /containers/overlay-containers/2a33efc76e519c137fe6093179653788bed6162d4a15e5131c8e835c968afbe6/userdata/.containerenv /run/.containerenv ro,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,size=783888k,nr_inodes=195972,mode=700,uid=2024,gid=2024,inode64
981 961 0:56 /containers/overlay-containers/2a33efc76e519c137fe6093179653788bed6162d4a15e5131c8e835c968afbe6/userdata/resolv.conf /etc/resolv.conf ro,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,size=783888k,nr_inodes=195972,mode=700,uid=2024,gid=2024,inode64
982 961 0:56 /containers/overlay-containers/2a33efc76e519c137fe6093179653788bed6162d4a15e5131c8e835c968afbe6/userdata/hosts /etc/hosts ro,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,size=783888k,nr_inodes=195972,mode=700,uid=2024,gid=2024,inode64
983 961 0:56 /containers/overlay-containers/2a33efc76e519c137fe6093179653788bed6162d4a15e5131c8e835c968afbe6/userdata/hostname /etc/hostname ro,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,size=783888k,nr_inodes=195972,mode=700,uid=2024,gid=2024,inode64
984 962 0:70 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs cgroup rw,size=1024k,uid=2024,gid=2024,inode64
985 984 0:44 / /sys/fs/cgroup/misc ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,misc
986 984 0:43 / /sys/fs/cgroup/freezer ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,freezer
987 984 0:42 /user.slice /sys/fs/cgroup/devices ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,devices
988 984 0:41 /user.slice/user-2024.slice/user@2024.service /sys/fs/cgroup/pids ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,pids
989 984 0:40 /user.slice /sys/fs/cgroup/blkio ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,blkio
990 984 0:39 / /sys/fs/cgroup/rdma ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,rdma
991 984 0:38 /user.slice/user-2024.slice/user@2024.service /sys/fs/cgroup/memory ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,memory
992 984 0:37 / /sys/fs/cgroup/cpuset ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpuset
993 984 0:36 / /sys/fs/cgroup/perf_event ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,perf_event
994 984 0:35 / /sys/fs/cgroup/net_cls,net_prio ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,net_cls,net_prio
995 984 0:34 /user.slice /sys/fs/cgroup/cpu,cpuacct ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpu,cpuacct
996 984 0:33 / /sys/fs/cgroup/hugetlb ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,hugetlb
997 984 0:30 /user.slice/user-2024.slice/user@2024.service/user.slice/podman-5094.scope /sys/fs/cgroup/systemd ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,xattr,name=systemd
998 975 0:5 /null /dev/null rw,relatime - devtmpfs devtmpfs rw,size=3912976k,nr_inodes=978244,mode=755,inode64
999 975 0:5 /zero /dev/zero rw,relatime - devtmpfs devtmpfs rw,size=3912976k,nr_inodes=978244,mode=755,inode64
1000 975 0:5 /full /dev/full rw,relatime - devtmpfs devtmpfs rw,size=3912976k,nr_inodes=978244,mode=755,inode64
1001 975 0:5 /tty /dev/tty rw,relatime - devtmpfs devtmpfs rw,size=3912976k,nr_inodes=978244,mode=755,inode64
1002 975 0:5 /random /dev/random rw,relatime - devtmpfs devtmpfs rw,size=3912976k,nr_inodes=978244,mode=755,inode64
1003 975 0:5 /urandom /dev/urandom rw,relatime - devtmpfs devtmpfs rw,size=3912976k,nr_inodes=978244,mode=755,inode64
1004 974 0:71 / /proc/acpi ro,relatime - tmpfs tmpfs rw,size=0k,uid=2024,gid=2024,inode64
1005 974 0:5 /null /proc/kcore rw,relatime - devtmpfs devtmpfs rw,size=3912976k,nr_inodes=978244,mode=755,inode64
1006 974 0:5 /null /proc/keys rw,relatime - devtmpfs devtmpfs rw,size=3912976k,nr_inodes=978244,mode=755,inode64
1007 974 0:5 /null /proc/timer_list rw,relatime - devtmpfs devtmpfs rw,size=3912976k,nr_inodes=978244,mode=755,inode64
1008 974 0:72 / /proc/scsi ro,relatime - tmpfs tmpfs rw,size=0k,uid=2024,gid=2024,inode64
1009 962 0:73 / /sys/firmware ro,relatime - tmpfs tmpfs rw,size=0k,uid=2024,gid=2024,inode64
1010 962 0:74 / /sys/dev/block ro,relatime - tmpfs tmpfs rw,size=0k,uid=2024,gid=2024,inode64
1011 974 0:66 /bus /proc/bus ro,relatime - proc proc rw
1012 974 0:66 /fs /proc/fs ro,relatime - proc proc rw
1013 974 0:66 /irq /proc/irq ro,relatime - proc proc rw
1014 974 0:66 /sys /proc/sys ro,relatime - proc proc rw
1015 974 0:66 /sysrq-trigger /proc/sysrq-trigger ro,relatime - proc proc rw
813 975 0:69 /0 /dev/console rw,nosuid,noexec,relatime - devpts devpts rw,gid=427684,mode=620,ptmxmode=666

0 comments on commit 264edd9

Please sign in to comment.