Skip to content

Commit 083e63a

Browse files
committed
Untested Centos provider for Telemetry
1 parent 9ee218a commit 083e63a

File tree

10 files changed

+228
-19
lines changed

10 files changed

+228
-19
lines changed

core/src/errors.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66

77
error_chain! {
88
errors {
9-
InvalidSysctlKey(k: String) {
10-
description("Provided key not found in sysctl output"),
11-
display("Provided key '{}' not found in sysctl output", k),
9+
InvalidTelemetryKey {
10+
cmd: &'static str,
11+
key: String,
12+
} {
13+
description("Provided key not found in output"),
14+
display("Provided key '{}' not found in {} output", key, cmd),
1215
}
1316

1417
ProviderUnavailable(p: &'static str) {
@@ -18,7 +21,7 @@ error_chain! {
1821

1922
RemoteProvider {
2023
endpoint: &'static str,
21-
func: &'static str
24+
func: &'static str,
2225
} {
2326
description("Could not run provider function on host"),
2427
display("Could not run {}::{}() on host", endpoint, func),

core/src/target/linux.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2015-2017 Intecture Developers.
2+
//
3+
// Licensed under the Mozilla Public License 2.0 <LICENSE or
4+
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
5+
// modified, or distributed except according to those terms.
6+
7+
use errors::*;
8+
use regex::Regex;
9+
use std::{fs, process, str};
10+
use std::io::Read;
11+
12+
pub fn cpu_vendor() -> Result<String> {
13+
get_cpu_item("vendor_id")
14+
}
15+
16+
pub fn cpu_brand_string() -> Result<String> {
17+
get_cpu_item("model name")
18+
}
19+
20+
pub fn cpu_cores() -> Result<u32> {
21+
Ok(get_cpu_item("cpu cores")?
22+
.parse::<u32>()
23+
.chain_err(|| ErrorKind::InvalidTelemetryKey {
24+
cmd: "/proc/cpuinfo",
25+
key: "cpu cores".into()
26+
})?)
27+
}
28+
29+
fn get_cpu_item(item: &str) -> Result<String> {
30+
// @todo Cache file content
31+
let mut fh = fs::File::open("/proc/cpuinfo").chain_err(|| ErrorKind::SystemFile("/proc/cpuinfo"))?;
32+
let mut cpuinfo = String::new();
33+
fh.read_to_string(&mut cpuinfo).chain_err(|| ErrorKind::SystemFileOutput("/proc/cpuinfo"))?;;
34+
35+
let pattern = format!(r"(?m)^{}\s+: (.+)$", item);
36+
let regex = Regex::new(&pattern).unwrap();
37+
let capture = regex.captures(&cpuinfo);
38+
39+
if let Some(cap) = capture {
40+
Ok(cap.get(1).unwrap().as_str().to_string())
41+
} else {
42+
Err(ErrorKind::InvalidTelemetryKey { cmd: "/proc/cpuinfo", key: item.into() }.into())
43+
}
44+
}
45+
46+
pub fn memory() -> Result<u64> {
47+
let output = process::Command::new("free").arg("-b").output().chain_err(|| ErrorKind::SystemCommand("free"))?;
48+
let regex = Regex::new(r"(?m)^Mem:\s+([0-9]+)").chain_err(|| "could not create new Regex instance")?;
49+
let capture = regex.captures(str::from_utf8(&output.stdout).chain_err(|| ErrorKind::SystemCommandOutput("free"))?.trim());
50+
51+
if let Some(cap) = capture {
52+
Ok(cap.get(1).unwrap().as_str().parse::<u64>().chain_err(|| ErrorKind::SystemFileOutput("/etc/redhat-release"))?)
53+
} else {
54+
Err(ErrorKind::SystemCommandOutput("free").into())
55+
}
56+
}

core/src/target/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@
55
// modified, or distributed except according to those terms.
66

77
pub mod default;
8+
pub mod linux;
9+
pub mod redhat;
810
pub mod unix;

core/src/target/redhat.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2015-2017 Intecture Developers.
2+
//
3+
// Licensed under the Mozilla Public License 2.0 <LICENSE or
4+
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
5+
// modified, or distributed except according to those terms.
6+
7+
use errors::*;
8+
use regex::Regex;
9+
use std::fs;
10+
use std::io::Read;
11+
12+
pub fn version() -> Result<(String, u32, u32, u32)> {
13+
let mut fh = fs::File::open("/etc/redhat-release").chain_err(|| ErrorKind::SystemFile("/etc/redhat-release"))?;
14+
let mut fc = String::new();
15+
fh.read_to_string(&mut fc).unwrap();
16+
17+
let regex = Regex::new(r"release ([0-9]+)(?:\.([0-9]+)(?:\.([0-9]+))?)?").unwrap();
18+
if let Some(cap) = regex.captures(&fc) {
19+
let version_maj = cap.get(1).unwrap().as_str()
20+
.parse().chain_err(|| ErrorKind::SystemFileOutput("/etc/redhat-release"))?;
21+
let version_min = match cap.get(2) {
22+
Some(v) => v.as_str().parse().chain_err(|| ErrorKind::SystemFileOutput("/etc/redhat-release"))?,
23+
None => 0,
24+
};
25+
let version_patch = match cap.get(3) {
26+
Some(v) => v.as_str().parse().chain_err(|| ErrorKind::SystemFileOutput("/etc/redhat-release"))?,
27+
None => 0,
28+
};
29+
let version_str = format!("{}.{}.{}", version_maj, version_min, version_patch);
30+
Ok((version_str, version_maj, version_min, version_patch))
31+
} else {
32+
Err(ErrorKind::SystemFileOutput("/etc/redhat-release").into())
33+
}
34+
}

core/src/target/unix.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub fn version() -> Result<(String, u32, u32)> {
2929
.output()
3030
.chain_err(|| ErrorKind::SystemCommand("uname"))?;
3131
let version_str = str::from_utf8(&output.stdout).unwrap().trim();
32-
let regex = Regex::new(r"([0-9]+)\.([0-9]+)-[A-Z]+").unwrap();
32+
let regex = Regex::new(r"([0-9]+)\.([0-9]+)-[A-Z]+").chain_err(|| "could not create new Regex instance")?;
3333
let errstr = format!("Expected OS version format `u32.u32`, got: '{}'", version_str);
3434
if let Some(cap) = regex.captures(version_str) {
3535
let version_maj = cap.get(1).unwrap().as_str().parse().chain_err(|| ErrorKind::SystemCommandOutput("uname"))?;
@@ -54,6 +54,6 @@ pub fn get_sysctl_item(item: &str) -> Result<String> {
5454
if let Some(cap) = regex.captures(&sysctl) {
5555
Ok(cap.get(1).unwrap().as_str().into())
5656
} else {
57-
Err(ErrorKind::InvalidSysctlKey(item.into()).into())
57+
Err(ErrorKind::InvalidTelemetryKey { cmd: "sysctl", key: item.into() }.into())
5858
}
5959
}

core/src/telemetry/mod.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
mod providers;
1010
mod serializable;
1111

12-
pub use self::providers::Macos;
12+
pub use self::providers::{Centos, Freebsd, Macos};
1313

1414
use erased_serde::Serialize;
1515
use errors::*;
1616
use ExecutableProvider;
1717
use host::Host;
1818
use pnet::datalink::NetworkInterface;
19-
use self::providers::MacosRemoteProvider;
19+
use self::providers::{CentosRemoteProvider, FreebsdRemoteProvider, MacosRemoteProvider};
2020

2121
pub trait TelemetryProvider {
2222
fn available(&Host) -> bool where Self: Sized;
@@ -25,12 +25,16 @@ pub trait TelemetryProvider {
2525

2626
#[derive(Serialize, Deserialize)]
2727
pub enum RemoteProvider {
28-
Macos(MacosRemoteProvider)
28+
Centos(CentosRemoteProvider),
29+
Freebsd(FreebsdRemoteProvider),
30+
Macos(MacosRemoteProvider),
2931
}
3032

3133
impl <'de>ExecutableProvider<'de> for RemoteProvider {
3234
fn exec(&self, host: &Host) -> Result<Box<Serialize>> {
3335
match *self {
36+
RemoteProvider::Centos(ref p) => p.exec(host),
37+
RemoteProvider::Freebsd(ref p) => p.exec(host),
3438
RemoteProvider::Macos(ref p) => p.exec(host)
3539
}
3640
}
@@ -66,16 +70,40 @@ pub struct FsMount {
6670
#[derive(Debug, Serialize, Deserialize)]
6771
pub struct Os {
6872
pub arch: String,
69-
pub family: String,
70-
pub platform: String,
73+
pub family: OsFamily,
74+
pub platform: OsPlatform,
7175
pub version_str: String,
7276
pub version_maj: u32,
7377
pub version_min: u32,
7478
pub version_patch: u32,
7579
}
7680

81+
#[derive(Debug, Serialize, Deserialize)]
82+
pub enum OsFamily {
83+
Bsd,
84+
Darwin,
85+
Linux,
86+
}
87+
88+
#[derive(Debug, Serialize, Deserialize)]
89+
pub enum OsPlatform {
90+
Centos,
91+
Debian,
92+
Fedora,
93+
Freebsd,
94+
Macos,
95+
Nixos,
96+
Ubuntu,
97+
}
98+
7799
pub fn load(host: &Host) -> Result<Telemetry> {
78-
if Macos::available(host) {
100+
if Centos::available(host) {
101+
Centos::load(host)
102+
}
103+
else if Freebsd::available(host) {
104+
Freebsd::load(host)
105+
}
106+
else if Macos::available(host) {
79107
Macos::load(host)
80108
} else {
81109
Err(ErrorKind::ProviderUnavailable("Telemetry").into())
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2015-2017 Intecture Developers.
2+
//
3+
// Licensed under the Mozilla Public License 2.0 <LICENSE or
4+
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
5+
// modified, or distributed except according to those terms.
6+
7+
use erased_serde::Serialize;
8+
use errors::*;
9+
use ExecutableProvider;
10+
use host::*;
11+
use pnet::datalink::interfaces;
12+
use std::{env, str};
13+
use target::{default, linux, redhat};
14+
use telemetry::{Cpu, Os, OsFamily, OsPlatform, Telemetry, TelemetryProvider, serializable};
15+
16+
pub struct Centos;
17+
18+
#[derive(Serialize, Deserialize)]
19+
pub enum RemoteProvider {
20+
Available,
21+
Load,
22+
}
23+
24+
impl <'de>ExecutableProvider<'de> for RemoteProvider {
25+
fn exec(&self, host: &Host) -> Result<Box<Serialize>> {
26+
match *self {
27+
RemoteProvider::Available => Ok(Box::new(Centos::available(host))),
28+
RemoteProvider::Load => {
29+
let t: serializable::Telemetry = Centos::load(host)?.into();
30+
Ok(Box::new(t))
31+
},
32+
}
33+
}
34+
}
35+
36+
impl TelemetryProvider for Centos {
37+
fn available(host: &Host) -> bool {
38+
if host.is_local() {
39+
cfg!(target_os="linux")
40+
} else {
41+
unimplemented!();
42+
// let r = RemoteProvider::Available;
43+
// self.host.send(r).chain_err(|| ErrorKind::RemoteProvider("Telemetry", "available"))?;
44+
// let t: Telemetry = self.host.recv()?;
45+
// Ok(t)
46+
}
47+
}
48+
49+
fn load(host: &Host) -> Result<Telemetry> {
50+
if host.is_local() {
51+
let cpu_vendor = linux::cpu_vendor()?;
52+
let cpu_brand = linux::cpu_brand_string()?;
53+
let hostname = default::hostname()?;
54+
let (version_str, version_maj, version_min, version_patch) = redhat::version()?;
55+
56+
Ok(Telemetry {
57+
cpu: Cpu {
58+
vendor: cpu_vendor,
59+
brand_string: cpu_brand,
60+
cores: linux::cpu_cores()?,
61+
},
62+
fs: default::fs().chain_err(|| "could not resolve telemetry data")?,
63+
hostname: hostname,
64+
memory: linux::memory().chain_err(|| "could not resolve telemetry data")?,
65+
net: interfaces(),
66+
os: Os {
67+
arch: env::consts::ARCH.into(),
68+
family: OsFamily::Linux,
69+
platform: OsPlatform::Centos,
70+
version_str: version_str,
71+
version_maj: version_maj,
72+
version_min: version_min,
73+
version_patch: version_patch
74+
},
75+
})
76+
} else {
77+
unimplemented!();
78+
// let r = RemoteProvider::Load;
79+
// self.host.send(r).chain_err(|| ErrorKind::RemoteProvider("Telemetry", "load"))?;
80+
// let t: Telemetry = self.host.recv()?;
81+
// Ok(t)
82+
}
83+
}
84+
}

core/src/telemetry/providers/freebsd.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use regex::Regex;
1313
use std::{env, fs, str};
1414
use std::io::Read;
1515
use target::{default, unix};
16-
use telemetry::{Cpu, Os, Telemetry, TelemetryProvider, serializable};
16+
use telemetry::{Cpu, Os, OsFamily, OsPlatform, Telemetry, TelemetryProvider, serializable};
1717

1818
pub struct Freebsd;
1919

@@ -73,8 +73,8 @@ impl TelemetryProvider for Freebsd {
7373
net: interfaces(),
7474
os: Os {
7575
arch: env::consts::ARCH.into(),
76-
family: "bsd".into(),
77-
platform: "freebsd".into(),
76+
family: OsFamily::Bsd,
77+
platform: OsPlatform::Freebsd,
7878
version_str: version_str,
7979
version_maj: version_maj,
8080
version_min: version_min,
@@ -95,7 +95,7 @@ fn telemetry_cpu_vendor() -> Result<String> {
9595
let mut fh = fs::File::open("/var/run/dmesg.boot")
9696
.chain_err(|| ErrorKind::SystemFile("/var/run/dmesg.boot"))?;
9797
let mut fc = String::new();
98-
fh.read_to_string(&mut fc).unwrap();
98+
fh.read_to_string(&mut fc).chain_err(|| ErrorKind::SystemFileOutput("/var/run/dmesg.boot"))?;
9999

100100
let regex = Regex::new(r#"(?m)^CPU:.+$\n\s+Origin="([A-Za-z]+)""#).unwrap();
101101
if let Some(cap) = regex.captures(&fc) {

core/src/telemetry/providers/macos.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use host::*;
1111
use pnet::datalink::interfaces;
1212
use std::{env, process, str};
1313
use target::{default, unix};
14-
use telemetry::{Cpu, Os, Telemetry, TelemetryProvider, serializable};
14+
use telemetry::{Cpu, Os, OsFamily, OsPlatform, Telemetry, TelemetryProvider, serializable};
1515

1616
pub struct Macos;
1717

@@ -81,8 +81,8 @@ impl TelemetryProvider for Macos {
8181
net: interfaces(),
8282
os: Os {
8383
arch: env::consts::ARCH.into(),
84-
family: "darwin".into(),
85-
platform: "macos".into(),
84+
family: OsFamily::Darwin,
85+
platform: OsPlatform::Macos,
8686
version_str: version_str,
8787
version_maj: version_maj,
8888
version_min: version_min,

core/src/telemetry/providers/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
55
// modified, or distributed except according to those terms.
66

7+
mod centos;
78
mod freebsd;
89
mod macos;
910

11+
pub use self::centos::{Centos, RemoteProvider as CentosRemoteProvider};
1012
pub use self::freebsd::{Freebsd, RemoteProvider as FreebsdRemoteProvider};
1113
pub use self::macos::{Macos, RemoteProvider as MacosRemoteProvider};

0 commit comments

Comments
 (0)