mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-13 04:49:36 +00:00
Merge pull request #65 from jodh-intel/create-config-module
main: Split config code into separate module
This commit is contained in:
471
src/agent/src/config.rs
Normal file
471
src/agent/src/config.rs
Normal file
@@ -0,0 +1,471 @@
|
|||||||
|
// Copyright (c) 2019 Ant Financial
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
use rustjail::errors::*;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
const DEBUG_CONSOLE_FLAG: &'static str = "agent.debug_console";
|
||||||
|
const DEV_MODE_FLAG: &'static str = "agent.devmode";
|
||||||
|
const LOG_LEVEL_FLAG: &'static str = "agent.log";
|
||||||
|
|
||||||
|
const DEFAULT_LOG_LEVEL: slog::Level = slog::Level::Info;
|
||||||
|
|
||||||
|
// FIXME: unused
|
||||||
|
const TRACE_MODE_FLAG: &'static str = "agent.trace";
|
||||||
|
const USE_VSOCK_FLAG: &'static str = "agent.use_vsock";
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct agentConfig {
|
||||||
|
pub debug_console: bool,
|
||||||
|
pub dev_mode: bool,
|
||||||
|
pub log_level: slog::Level,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl agentConfig {
|
||||||
|
pub fn new() -> agentConfig {
|
||||||
|
agentConfig {
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: false,
|
||||||
|
log_level: DEFAULT_LOG_LEVEL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_cmdline(&mut self, file: &str) -> Result<()> {
|
||||||
|
let cmdline = fs::read_to_string(file)?;
|
||||||
|
let params: Vec<&str> = cmdline.split_ascii_whitespace().collect();
|
||||||
|
for param in params.iter() {
|
||||||
|
if param.starts_with(DEBUG_CONSOLE_FLAG) {
|
||||||
|
self.debug_console = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if param.starts_with(DEV_MODE_FLAG) {
|
||||||
|
self.dev_mode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if param.starts_with(LOG_LEVEL_FLAG) {
|
||||||
|
let level = get_log_level(param)?;
|
||||||
|
self.log_level = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map logrus (https://godoc.org/github.com/sirupsen/logrus)
|
||||||
|
// log level to the equivalent slog log levels.
|
||||||
|
//
|
||||||
|
// Note: Logrus names are used for compatability with the previous
|
||||||
|
// golang-based agent.
|
||||||
|
fn logrus_to_slog_level(logrus_level: &str) -> Result<slog::Level> {
|
||||||
|
let level = match logrus_level {
|
||||||
|
// Note: different semantics to logrus: log, but don't panic.
|
||||||
|
"fatal" | "panic" => slog::Level::Critical,
|
||||||
|
|
||||||
|
"critical" => slog::Level::Critical,
|
||||||
|
"error" => slog::Level::Error,
|
||||||
|
"warn" | "warning" => slog::Level::Warning,
|
||||||
|
"info" => slog::Level::Info,
|
||||||
|
"debug" => slog::Level::Debug,
|
||||||
|
|
||||||
|
// Not in logrus
|
||||||
|
"trace" => slog::Level::Trace,
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
return Err(ErrorKind::ErrorCode(String::from("invalid log level")).into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_log_level(param: &str) -> Result<slog::Level> {
|
||||||
|
let fields: Vec<&str> = param.split("=").collect();
|
||||||
|
|
||||||
|
if fields.len() != 2 {
|
||||||
|
return Err(ErrorKind::ErrorCode(String::from("invalid log level parameter")).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let key = fields[0];
|
||||||
|
|
||||||
|
if key != LOG_LEVEL_FLAG {
|
||||||
|
return Err(ErrorKind::ErrorCode(String::from("invalid log level key name").into()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = fields[1];
|
||||||
|
|
||||||
|
let level = logrus_to_slog_level(value)?;
|
||||||
|
|
||||||
|
Ok(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use tempfile::tempdir;
|
||||||
|
|
||||||
|
const ERR_INVALID_LOG_LEVEL: &str = "invalid log level";
|
||||||
|
const ERR_INVALID_LOG_LEVEL_PARAM: &str = "invalid log level parameter";
|
||||||
|
const ERR_INVALID_LOG_LEVEL_KEY: &str = "invalid log level key name";
|
||||||
|
|
||||||
|
// helper function to make errors less crazy-long
|
||||||
|
fn make_err(desc: &str) -> Error {
|
||||||
|
ErrorKind::ErrorCode(desc.to_string()).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameters:
|
||||||
|
//
|
||||||
|
// 1: expected Result
|
||||||
|
// 2: actual Result
|
||||||
|
// 3: string used to identify the test on error
|
||||||
|
macro_rules! assert_log_level {
|
||||||
|
($expected_result:expr, $actual_result:expr, $msg:expr) => {
|
||||||
|
if $expected_result.is_ok() {
|
||||||
|
let expected_level = $expected_result.as_ref().unwrap();
|
||||||
|
let actual_level = $actual_result.unwrap();
|
||||||
|
assert!(*expected_level == actual_level, $msg);
|
||||||
|
} else {
|
||||||
|
let expected_error = $expected_result.as_ref().unwrap_err();
|
||||||
|
let actual_error = $actual_result.unwrap_err();
|
||||||
|
|
||||||
|
let expected_error_msg = format!("{:?}", expected_error);
|
||||||
|
let actual_error_msg = format!("{:?}", actual_error);
|
||||||
|
|
||||||
|
assert!(expected_error_msg == actual_error_msg, $msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new() {
|
||||||
|
let config = agentConfig::new();
|
||||||
|
assert_eq!(config.debug_console, false);
|
||||||
|
assert_eq!(config.dev_mode, false);
|
||||||
|
assert_eq!(config.log_level, DEFAULT_LOG_LEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_cmdline() {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TestData<'a> {
|
||||||
|
contents: &'a str,
|
||||||
|
debug_console: bool,
|
||||||
|
dev_mode: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
let tests = &[
|
||||||
|
TestData {
|
||||||
|
contents: "",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo bar",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo bar",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo agent bar",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo debug_console agent bar devmode",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "agent.debug_console",
|
||||||
|
debug_console: true,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: " agent.debug_console ",
|
||||||
|
debug_console: true,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "agent.debug_console foo",
|
||||||
|
debug_console: true,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: " agent.debug_console foo",
|
||||||
|
debug_console: true,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo agent.debug_console bar",
|
||||||
|
debug_console: true,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo agent.debug_console",
|
||||||
|
debug_console: true,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo agent.debug_console ",
|
||||||
|
debug_console: true,
|
||||||
|
dev_mode: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "agent.devmode",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: true,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: " agent.devmode ",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: true,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "agent.devmode foo",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: true,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: " agent.devmode foo",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: true,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo agent.devmode bar",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: true,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo agent.devmode",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: true,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "foo agent.devmode ",
|
||||||
|
debug_console: false,
|
||||||
|
dev_mode: true,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
contents: "agent.devmode agent.debug_console",
|
||||||
|
debug_console: true,
|
||||||
|
dev_mode: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let dir = tempdir().expect("failed to create tmpdir");
|
||||||
|
|
||||||
|
// First, check a missing file is handled
|
||||||
|
let file_path = dir.path().join("enoent");
|
||||||
|
|
||||||
|
let filename = file_path.to_str().expect("failed to create filename");
|
||||||
|
|
||||||
|
let mut config = agentConfig::new();
|
||||||
|
let result = config.parse_cmdline(&filename.to_owned());
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
// Now, test various combinations of file contents
|
||||||
|
for (i, d) in tests.iter().enumerate() {
|
||||||
|
let msg = format!("test[{}]: {:?}", i, d);
|
||||||
|
|
||||||
|
let file_path = dir.path().join("cmdline");
|
||||||
|
|
||||||
|
let filename = file_path.to_str().expect("failed to create filename");
|
||||||
|
|
||||||
|
let mut file =
|
||||||
|
File::create(filename).expect(&format!("{}: failed to create file", msg));
|
||||||
|
|
||||||
|
file.write_all(d.contents.as_bytes())
|
||||||
|
.expect(&format!("{}: failed to write file contents", msg));
|
||||||
|
|
||||||
|
let mut config = agentConfig::new();
|
||||||
|
assert!(config.debug_console == false, msg);
|
||||||
|
assert!(config.dev_mode == false, msg);
|
||||||
|
|
||||||
|
let result = config.parse_cmdline(filename);
|
||||||
|
assert!(result.is_ok(), "{}", msg);
|
||||||
|
|
||||||
|
assert_eq!(d.debug_console, config.debug_console, "{}", msg);
|
||||||
|
assert_eq!(d.dev_mode, config.dev_mode, "{}", msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_logrus_to_slog_level() {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TestData<'a> {
|
||||||
|
logrus_level: &'a str,
|
||||||
|
result: Result<slog::Level>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let tests = &[
|
||||||
|
TestData {
|
||||||
|
logrus_level: "",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "foo",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "debugging",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "xdebug",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "trace",
|
||||||
|
result: Ok(slog::Level::Trace),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "debug",
|
||||||
|
result: Ok(slog::Level::Debug),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "info",
|
||||||
|
result: Ok(slog::Level::Info),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "warn",
|
||||||
|
result: Ok(slog::Level::Warning),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "warning",
|
||||||
|
result: Ok(slog::Level::Warning),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "error",
|
||||||
|
result: Ok(slog::Level::Error),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "critical",
|
||||||
|
result: Ok(slog::Level::Critical),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "fatal",
|
||||||
|
result: Ok(slog::Level::Critical),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
logrus_level: "panic",
|
||||||
|
result: Ok(slog::Level::Critical),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (i, d) in tests.iter().enumerate() {
|
||||||
|
let msg = format!("test[{}]: {:?}", i, d);
|
||||||
|
|
||||||
|
let result = logrus_to_slog_level(d.logrus_level);
|
||||||
|
|
||||||
|
let msg = format!("{}: result: {:?}", msg, result);
|
||||||
|
|
||||||
|
assert_log_level!(d.result, result, format!("{}", msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_log_level() {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TestData<'a> {
|
||||||
|
param: &'a str,
|
||||||
|
result: Result<slog::Level>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let tests = &[
|
||||||
|
TestData {
|
||||||
|
param: "",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL_PARAM)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "=",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL_KEY)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "x=",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL_KEY)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "=y",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL_KEY)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "==",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL_PARAM)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "= =",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL_PARAM)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "x=y",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL_KEY)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent=debug",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL_KEY)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.logg=debug",
|
||||||
|
result: Err(make_err(ERR_INVALID_LOG_LEVEL_KEY)),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.log=trace",
|
||||||
|
result: Ok(slog::Level::Trace),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.log=debug",
|
||||||
|
result: Ok(slog::Level::Debug),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.log=info",
|
||||||
|
result: Ok(slog::Level::Info),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.log=warn",
|
||||||
|
result: Ok(slog::Level::Warning),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.log=warning",
|
||||||
|
result: Ok(slog::Level::Warning),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.log=error",
|
||||||
|
result: Ok(slog::Level::Error),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.log=critical",
|
||||||
|
result: Ok(slog::Level::Critical),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.log=fatal",
|
||||||
|
result: Ok(slog::Level::Critical),
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
param: "agent.log=panic",
|
||||||
|
result: Ok(slog::Level::Critical),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (i, d) in tests.iter().enumerate() {
|
||||||
|
let msg = format!("test[{}]: {:?}", i, d);
|
||||||
|
|
||||||
|
let result = get_log_level(d.param);
|
||||||
|
|
||||||
|
let msg = format!("{}: result: {:?}", msg, result);
|
||||||
|
|
||||||
|
assert_log_level!(d.result, result, format!("{}", msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -42,6 +42,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
use unistd::Pid;
|
use unistd::Pid;
|
||||||
|
|
||||||
|
mod config;
|
||||||
mod device;
|
mod device;
|
||||||
mod logging;
|
mod logging;
|
||||||
mod mount;
|
mod mount;
|
||||||
@@ -63,6 +64,8 @@ mod grpc;
|
|||||||
const NAME: &'static str = "kata-agent";
|
const NAME: &'static str = "kata-agent";
|
||||||
const VSOCK_ADDR: &'static str = "vsock://-1";
|
const VSOCK_ADDR: &'static str = "vsock://-1";
|
||||||
const VSOCK_PORT: u16 = 1024;
|
const VSOCK_PORT: u16 = 1024;
|
||||||
|
const KERNEL_CMDLINE_FILE: &'static str = "/proc/cmdline";
|
||||||
|
const CONSOLE_PATH: &'static str = "/dev/console";
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref GLOBAL_DEVICE_WATCHER: Arc<Mutex<HashMap<String, Sender<String>>>> =
|
static ref GLOBAL_DEVICE_WATCHER: Arc<Mutex<HashMap<String, Sender<String>>>> =
|
||||||
@@ -84,8 +87,17 @@ fn announce(logger: &Logger) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
|
env::set_var("RUST_BACKTRACE", "full");
|
||||||
|
|
||||||
|
lazy_static::initialize(&SHELLS);
|
||||||
|
|
||||||
|
let mut config = config::agentConfig::new();
|
||||||
|
|
||||||
|
config.parse_cmdline(KERNEL_CMDLINE_FILE)?;
|
||||||
|
|
||||||
let writer = io::stdout();
|
let writer = io::stdout();
|
||||||
let logger = logging::create_logger(NAME, "agent", slog::Level::Info, writer);
|
|
||||||
|
let logger = logging::create_logger(NAME, "agent", config.log_level, writer);
|
||||||
|
|
||||||
announce(&logger);
|
announce(&logger);
|
||||||
|
|
||||||
@@ -93,14 +105,9 @@ fn main() -> Result<()> {
|
|||||||
// which is required to satisfy the the lifetime constraints of the auto-generated gRPC code.
|
// which is required to satisfy the the lifetime constraints of the auto-generated gRPC code.
|
||||||
let _guard = slog_scope::set_global_logger(logger.new(o!("subsystem" => "grpc")));
|
let _guard = slog_scope::set_global_logger(logger.new(o!("subsystem" => "grpc")));
|
||||||
|
|
||||||
env::set_var("RUST_BACKTRACE", "full");
|
|
||||||
|
|
||||||
lazy_static::initialize(&SHELLS);
|
|
||||||
parse_cmdline(KERNEL_CMDLINE_FILE)?;
|
|
||||||
|
|
||||||
let shells = SHELLS.clone();
|
let shells = SHELLS.clone();
|
||||||
|
|
||||||
let shell_handle = if unsafe { DEBUG_CONSOLE } {
|
let shell_handle = if config.debug_console {
|
||||||
let thread_logger = logger.clone();
|
let thread_logger = logger.clone();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
@@ -157,7 +164,7 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
handle.join().unwrap();
|
handle.join().unwrap();
|
||||||
|
|
||||||
if unsafe { DEBUG_CONSOLE } {
|
if config.debug_console {
|
||||||
shell_handle.join().unwrap();
|
shell_handle.join().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,14 +280,6 @@ fn init_agent_as_init(logger: &Logger) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
const LOG_LEVEL_FLAG: &'static str = "agent.log";
|
|
||||||
const DEV_MODE_FLAG: &'static str = "agent.devmode";
|
|
||||||
const TRACE_MODE_FLAG: &'static str = "agent.trace";
|
|
||||||
const USE_VSOCK_FLAG: &'static str = "agent.use_vsock";
|
|
||||||
const DEBUG_CONSOLE_FLAG: &'static str = "agent.debug_console";
|
|
||||||
const KERNEL_CMDLINE_FILE: &'static str = "/proc/cmdline";
|
|
||||||
const CONSOLE_PATH: &'static str = "/dev/console";
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref SHELLS: Arc<Mutex<Vec<String>>> = {
|
static ref SHELLS: Arc<Mutex<Vec<String>>> = {
|
||||||
let mut v = Vec::new();
|
let mut v = Vec::new();
|
||||||
@@ -294,31 +293,9 @@ lazy_static! {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static mut DEBUG_CONSOLE: bool = false;
|
|
||||||
// pub static mut LOG_LEVEL: ;
|
// pub static mut LOG_LEVEL: ;
|
||||||
pub static mut DEV_MODE: bool = false;
|
|
||||||
// pub static mut TRACE_MODE: ;
|
// pub static mut TRACE_MODE: ;
|
||||||
|
|
||||||
fn parse_cmdline(file: &str) -> Result<()> {
|
|
||||||
let cmdline = fs::read_to_string(file)?;
|
|
||||||
let params: Vec<&str> = cmdline.split_ascii_whitespace().collect();
|
|
||||||
for param in params.iter() {
|
|
||||||
if param.starts_with(DEBUG_CONSOLE_FLAG) {
|
|
||||||
unsafe {
|
|
||||||
DEBUG_CONSOLE = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if param.starts_with(DEV_MODE_FLAG) {
|
|
||||||
unsafe {
|
|
||||||
DEV_MODE = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
use nix::fcntl::{self, OFlag};
|
use nix::fcntl::{self, OFlag};
|
||||||
use nix::sys::stat::Mode;
|
use nix::sys::stat::Mode;
|
||||||
use std::os::unix::io::{FromRawFd, RawFd};
|
use std::os::unix::io::{FromRawFd, RawFd};
|
||||||
@@ -401,161 +378,4 @@ mod tests {
|
|||||||
"Error Code: 'invalid shell'"
|
"Error Code: 'invalid shell'"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_cmdline() {
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct TestData<'a> {
|
|
||||||
contents: &'a str,
|
|
||||||
debug_console: bool,
|
|
||||||
dev_mode: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
let tests = &[
|
|
||||||
TestData {
|
|
||||||
contents: "",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo bar",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo bar",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo agent bar",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo debug_console agent bar devmode",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "agent.debug_console",
|
|
||||||
debug_console: true,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: " agent.debug_console ",
|
|
||||||
debug_console: true,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "agent.debug_console foo",
|
|
||||||
debug_console: true,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: " agent.debug_console foo",
|
|
||||||
debug_console: true,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo agent.debug_console bar",
|
|
||||||
debug_console: true,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo agent.debug_console",
|
|
||||||
debug_console: true,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo agent.debug_console ",
|
|
||||||
debug_console: true,
|
|
||||||
dev_mode: false,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "agent.devmode",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: true,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: " agent.devmode ",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: true,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "agent.devmode foo",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: true,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: " agent.devmode foo",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: true,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo agent.devmode bar",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: true,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo agent.devmode",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: true,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "foo agent.devmode ",
|
|
||||||
debug_console: false,
|
|
||||||
dev_mode: true,
|
|
||||||
},
|
|
||||||
TestData {
|
|
||||||
contents: "agent.devmode agent.debug_console",
|
|
||||||
debug_console: true,
|
|
||||||
dev_mode: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
let dir = tempdir().expect("failed to create tmpdir");
|
|
||||||
|
|
||||||
// First, check a missing file is handled
|
|
||||||
let file_path = dir.path().join("enoent");
|
|
||||||
|
|
||||||
let filename = file_path.to_str().expect("failed to create filename");
|
|
||||||
|
|
||||||
let result = parse_cmdline(&filename.to_owned());
|
|
||||||
assert!(result.is_err());
|
|
||||||
|
|
||||||
// Now, test various combinations of file contents
|
|
||||||
for (i, d) in tests.iter().enumerate() {
|
|
||||||
// Reset
|
|
||||||
unsafe {
|
|
||||||
DEBUG_CONSOLE = false;
|
|
||||||
DEV_MODE = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
let msg = format!("test[{}]: {:?}", i, d);
|
|
||||||
|
|
||||||
let file_path = dir.path().join("cmdline");
|
|
||||||
|
|
||||||
let filename = file_path.to_str().expect("failed to create filename");
|
|
||||||
|
|
||||||
let mut file =
|
|
||||||
File::create(filename).expect(&format!("{}: failed to create file", msg));
|
|
||||||
|
|
||||||
file.write_all(d.contents.as_bytes())
|
|
||||||
.expect(&format!("{}: failed to write file contents", msg));
|
|
||||||
|
|
||||||
let result = parse_cmdline(filename);
|
|
||||||
assert!(result.is_ok(), "{}", msg);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
assert_eq!(d.debug_console, DEBUG_CONSOLE, "{}", msg);
|
|
||||||
assert_eq!(d.dev_mode, DEV_MODE, "{}", msg);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user