container_what/container/
detector.rs

1use std::io;
2use std::fs::File;
3use std::path::Path;
4use std::io::prelude::*;
5
6use super::ContainerEngine;
7use common::{Detector, DetectorContext};
8
9pub struct ContainerDetector;
10
11fn read_to_string(path: &Path) -> Result<String, io::Error> {
12    let mut file = File::open(path)?;
13    let mut contents = String::new();
14    file.read_to_string(&mut contents)?;
15    Ok(contents)
16}
17
18impl ContainerDetector {
19    fn is_openvz(ctx: &DetectorContext) -> bool {
20        /*
21            Copy from virt-what
22            # Check for OpenVZ / Virtuozzo.
23            # Added by Evgeniy Sokolov.
24            # /proc/vz - always exists if OpenVZ kernel is running (inside and outside
25            # container)
26            # /proc/bc - exists on node, but not inside container.
27        */
28        let vz_path = ctx.get_file_path("proc/vz");
29        let bc_path = ctx.get_file_path("proc/bc");
30        if vz_path.is_dir() && !bc_path.exists() {
31            return true;
32        }
33        false
34    }
35
36    fn is_lxc(ctx: &DetectorContext) -> bool {
37        /*
38            Copy from virt-what
39            # Check for LXC containers
40            # http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface
41            # Added by Marc Fournier
42        */
43        let init_proc_env_path = ctx.get_file_path("proc/1/environ");
44        match read_to_string(init_proc_env_path.as_path()) {
45            Ok(content) => {
46                for line in content.split("\x00") {
47                    if line.starts_with("container=") {
48                        return true;
49                    }
50                }
51                return false;
52            }
53            Err(_) => {
54                return false;
55            }
56        }
57    }
58
59    fn is_docker(ctx: &DetectorContext) -> bool {
60        let docker_init = ctx.get_file_path(".dockerinit");
61        let docker_env = ctx.get_file_path(".dockerenv");
62        if docker_init.is_file() || docker_env.is_file() {
63            return true;
64        }
65        false
66    }
67}
68
69impl Detector for ContainerDetector {
70    type D = ContainerEngine;
71
72    fn detect(ctx: &DetectorContext) -> ContainerEngine {
73        if Self::is_openvz(ctx) {
74            return ContainerEngine::OpenVZ;
75        }
76        if Self::is_lxc(ctx) {
77            return ContainerEngine::LXC;
78        }
79        if Self::is_docker(ctx) {
80            return ContainerEngine::Docker;
81        }
82
83        return ContainerEngine::Unknown;
84    }
85}