CCv0: Merge main into CCv0 branch

Merge remote-tracking branch 'upstream/main' into CCv0

Fixes: #3295

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
This commit is contained in:
stevenhorsman
2021-12-17 10:33:30 +00:00
123 changed files with 1656 additions and 640 deletions

View File

@@ -37,7 +37,7 @@ ipnetwork = "0.17.0"
# Note: this crate sets the slog 'max_*' features which allows the log level
# to be modified at runtime.
logging = { path = "../../pkg/logging" }
logging = { path = "../libs/logging" }
slog = "2.5.2"
slog-scope = "4.1.2"

View File

@@ -104,7 +104,7 @@ default: $(TARGET) show-header
$(TARGET): $(GENERATED_CODE) logging-crate-tests $(TARGET_PATH)
logging-crate-tests:
make -C $(CWD)/../../pkg/logging
make -C $(CWD)/../libs/logging
$(TARGET_PATH): $(SOURCES) | show-summary
@RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo build --target $(TRIPLE) --$(BUILD_TYPE) $(EXTRA_RUSTFEATURES)

View File

@@ -97,7 +97,7 @@ these custom assets to allow you to test your changes.
## Tracing
For details of tracing the operation of the agent, see the
[tracing documentation](../../docs/tracing.md).
[tracing documentation](/docs/tracing.md).
## Run the agent stand alone
@@ -108,4 +108,4 @@ When run in this way, the agent can be controlled using the low-level Kata
agent control tool, rather than the Kata runtime.
For further details, see the
[agent control tool documentation](../../tools/agent-ctl/README.md#run-the-tool-and-the-agent-in-the-same-environment).
[agent control tool documentation](../tools/agent-ctl/README.md#run-the-tool-and-the-agent-in-the-same-environment).

View File

@@ -208,7 +208,17 @@ impl FromStr for AgentConfig {
impl AgentConfig {
#[instrument]
pub fn from_cmdline(file: &str) -> Result<AgentConfig> {
pub fn from_cmdline(file: &str, args: Vec<String>) -> Result<AgentConfig> {
// If config file specified in the args, generate our config from it
let config_position = args.iter().position(|a| a == "--config" || a == "-c");
if let Some(config_position) = config_position {
if let Some(config_file) = args.get(config_position + 1) {
return AgentConfig::from_config_file(config_file);
} else {
panic!("The config argument wasn't formed properly: {:?}", args);
}
}
let mut config: AgentConfig = Default::default();
let cmdline = fs::read_to_string(file)?;
let params: Vec<&str> = cmdline.split_ascii_whitespace().collect();
@@ -948,7 +958,8 @@ mod tests {
vars_to_unset.push(name);
}
let config = AgentConfig::from_cmdline(filename).expect("Failed to parse command line");
let config =
AgentConfig::from_cmdline(filename, vec![]).expect("Failed to parse command line");
assert_eq!(d.debug_console, config.debug_console, "{}", msg);
assert_eq!(d.dev_mode, config.dev_mode, "{}", msg);
@@ -969,6 +980,40 @@ mod tests {
}
}
#[test]
fn test_from_cmdline_with_args_overwrites() {
let expected = AgentConfig {
dev_mode: true,
server_addr: "unix://@/tmp/foo.socket".to_string(),
..Default::default()
};
let example_config_file_contents =
"dev_mode = true\nserver_addr = 'unix://@/tmp/foo.socket'";
let dir = tempdir().expect("failed to create tmpdir");
let file_path = dir.path().join("config.toml");
let filename = file_path.to_str().expect("failed to create filename");
let mut file = File::create(filename).unwrap_or_else(|_| panic!("failed to create file"));
file.write_all(example_config_file_contents.as_bytes())
.unwrap_or_else(|_| panic!("failed to write file contents"));
let config =
AgentConfig::from_cmdline("", vec!["--config".to_string(), filename.to_string()])
.expect("Failed to parse command line");
assert_eq!(expected.debug_console, config.debug_console);
assert_eq!(expected.dev_mode, config.dev_mode);
assert_eq!(
expected.unified_cgroup_hierarchy,
config.unified_cgroup_hierarchy,
);
assert_eq!(expected.log_level, config.log_level);
assert_eq!(expected.hotplug_timeout, config.hotplug_timeout);
assert_eq!(expected.container_pipe_size, config.container_pipe_size);
assert_eq!(expected.server_addr, config.server_addr);
assert_eq!(expected.tracing, config.tracing);
}
#[test]
fn test_logrus_to_slog_level() {
#[derive(Debug)]

View File

@@ -81,7 +81,7 @@ const NAME: &str = "kata-agent";
lazy_static! {
static ref AGENT_CONFIG: Arc<RwLock<AgentConfig>> = Arc::new(RwLock::new(
AgentConfig::from_cmdline("/proc/cmdline").unwrap()
AgentConfig::from_cmdline("/proc/cmdline", env::args().collect()).unwrap()
));
}

319
src/libs/logging/Cargo.lock generated Normal file
View File

@@ -0,0 +1,319 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "arc-swap"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5d78ce20460b82d3fa150275ed9d55e21064fc7951177baacf86a145c4a4b1f"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "itoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"
[[package]]
name = "logging"
version = "0.1.0"
dependencies = [
"serde_json",
"slog",
"slog-async",
"slog-json",
"slog-scope",
"tempfile",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "ppv-lite86"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]]
name = "redox_syscall"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
dependencies = [
"bitflags",
]
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "ryu"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568"
[[package]]
name = "serde"
version = "1.0.131"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1"
[[package]]
name = "serde_json"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "slog"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06"
[[package]]
name = "slog-async"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "766c59b252e62a34651412870ff55d8c4e6d04df19b43eecb2703e417b097ffe"
dependencies = [
"crossbeam-channel",
"slog",
"take_mut",
"thread_local",
]
[[package]]
name = "slog-json"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52e9b96fb6b5e80e371423b4aca6656eb537661ce8f82c2697e619f8ca85d043"
dependencies = [
"chrono",
"serde",
"serde_json",
"slog",
]
[[package]]
name = "slog-scope"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f95a4b4c3274cd2869549da82b57ccc930859bdbf5bcea0424bc5f140b3c786"
dependencies = [
"arc-swap",
"lazy_static",
"slog",
]
[[package]]
name = "take_mut"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
[[package]]
name = "tempfile"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [
"cfg-if",
"libc",
"rand",
"redox_syscall",
"remove_dir_all",
"winapi",
]
[[package]]
name = "thread_local"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
dependencies = [
"once_cell",
]
[[package]]
name = "time"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@@ -0,0 +1,21 @@
[package]
name = "logging"
version = "0.1.0"
authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde_json = "1.0.39"
# slog:
# - Dynamic keys required to allow HashMap keys to be slog::Serialized.
# - The 'max_*' features allow changing the log level at runtime
# (by stopping the compiler from removing log calls).
slog = { version = "2.5.2", features = ["dynamic-keys", "max_level_trace", "release_max_level_debug"] }
slog-json = "2.3.0"
slog-async = "2.3.0"
slog-scope = "4.1.2"
[dev-dependencies]
tempfile = "3.1.0"

18
src/libs/logging/Makefile Normal file
View File

@@ -0,0 +1,18 @@
# Copyright (c) 2021 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
# It is not necessary to have a build target as this crate is built
# automatically by the consumers of it.
#
# However, it is essential that the crate be tested.
default: test
# It is essential to run these tests using *both* build profiles.
# See the `test_logger_levels()` test for further information.
test:
@echo "INFO: testing log levels for development build"
@cargo test
@echo "INFO: testing log levels for release build"
@cargo test --release

602
src/libs/logging/src/lib.rs Normal file
View File

@@ -0,0 +1,602 @@
// Copyright (c) 2019-2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
use slog::{o, record_static, BorrowedKV, Drain, Key, OwnedKV, OwnedKVList, Record, KV};
use std::collections::HashMap;
use std::io;
use std::io::Write;
use std::process;
use std::result;
use std::sync::Mutex;
const LOG_LEVELS: &[(&str, slog::Level)] = &[
("trace", slog::Level::Trace),
("debug", slog::Level::Debug),
("info", slog::Level::Info),
("warn", slog::Level::Warning),
("error", slog::Level::Error),
("critical", slog::Level::Critical),
];
const DEFAULT_SUBSYSTEM: &str = "root";
// XXX: 'writer' param used to make testing possible.
pub fn create_logger<W>(
name: &str,
source: &str,
level: slog::Level,
writer: W,
) -> (slog::Logger, slog_async::AsyncGuard)
where
W: Write + Send + Sync + 'static,
{
let json_drain = slog_json::Json::new(writer)
.add_default_keys()
.build()
.fuse();
// Ensure only a unique set of key/value fields is logged
let unique_drain = UniqueDrain::new(json_drain).fuse();
// Allow runtime filtering of records by log level
let filter_drain = RuntimeLevelFilter::new(unique_drain, level).fuse();
// Ensure the logger is thread-safe
let (async_drain, guard) = slog_async::Async::new(filter_drain)
.thread_name("slog-async-logger".into())
.build_with_guard();
// Add some "standard" fields
let logger = slog::Logger::root(
async_drain.fuse(),
o!("version" => env!("CARGO_PKG_VERSION"),
"subsystem" => DEFAULT_SUBSYSTEM,
"pid" => process::id().to_string(),
"name" => name.to_string(),
"source" => source.to_string()),
);
(logger, guard)
}
pub fn get_log_levels() -> Vec<&'static str> {
let result: Vec<&str> = LOG_LEVELS.iter().map(|value| value.0).collect();
result
}
pub fn level_name_to_slog_level(level_name: &str) -> Result<slog::Level, String> {
for tuple in LOG_LEVELS {
if tuple.0 == level_name {
return Ok(tuple.1);
}
}
Err("invalid level name".to_string())
}
pub fn slog_level_to_level_name(level: slog::Level) -> Result<&'static str, &'static str> {
for tuple in LOG_LEVELS {
if tuple.1 == level {
return Ok(tuple.0);
}
}
Err("invalid slog level")
}
// Used to convert an slog::OwnedKVList into a hash map.
#[derive(Debug)]
struct HashSerializer {
fields: HashMap<String, String>,
}
impl HashSerializer {
fn new() -> HashSerializer {
HashSerializer {
fields: HashMap::new(),
}
}
fn add_field(&mut self, key: String, value: String) {
// Take care to only add the first instance of a key. This matters for loggers (but not
// Records) since a child loggers have parents and the loggers are serialised child first
// meaning the *newest* fields are serialised first.
self.fields.entry(key).or_insert(value);
}
fn remove_field(&mut self, key: &str) {
self.fields.remove(key);
}
}
impl KV for HashSerializer {
fn serialize(&self, _record: &Record, serializer: &mut dyn slog::Serializer) -> slog::Result {
for (key, value) in self.fields.iter() {
serializer.emit_str(Key::from(key.to_string()), value)?;
}
Ok(())
}
}
impl slog::Serializer for HashSerializer {
fn emit_arguments(&mut self, key: Key, value: &std::fmt::Arguments) -> slog::Result {
self.add_field(format!("{}", key), format!("{}", value));
Ok(())
}
}
struct UniqueDrain<D> {
drain: D,
}
impl<D> UniqueDrain<D> {
fn new(drain: D) -> Self {
UniqueDrain { drain }
}
}
impl<D> Drain for UniqueDrain<D>
where
D: Drain,
{
type Ok = ();
type Err = io::Error;
fn log(&self, record: &Record, values: &OwnedKVList) -> Result<Self::Ok, Self::Err> {
let mut logger_serializer = HashSerializer::new();
values.serialize(record, &mut logger_serializer)?;
let mut record_serializer = HashSerializer::new();
record.kv().serialize(record, &mut record_serializer)?;
for (key, _) in record_serializer.fields.iter() {
logger_serializer.remove_field(key);
}
let record_owned_kv = OwnedKV(record_serializer);
let record_static = record_static!(record.level(), "");
let new_record = Record::new(&record_static, record.msg(), BorrowedKV(&record_owned_kv));
let logger_owned_kv = OwnedKV(logger_serializer);
let result = self
.drain
.log(&new_record, &OwnedKVList::from(logger_owned_kv));
match result {
Ok(_) => Ok(()),
Err(_) => Err(std::io::Error::new(
std::io::ErrorKind::Other,
"failed to drain log".to_string(),
)),
}
}
}
// A RuntimeLevelFilter will discard all log records whose log level is less than the level
// specified in the struct.
struct RuntimeLevelFilter<D> {
drain: D,
level: Mutex<slog::Level>,
}
impl<D> RuntimeLevelFilter<D> {
fn new(drain: D, level: slog::Level) -> Self {
RuntimeLevelFilter {
drain,
level: Mutex::new(level),
}
}
}
impl<D> Drain for RuntimeLevelFilter<D>
where
D: Drain,
{
type Ok = Option<D::Ok>;
type Err = Option<D::Err>;
fn log(
&self,
record: &slog::Record,
values: &slog::OwnedKVList,
) -> result::Result<Self::Ok, Self::Err> {
let log_level = self.level.lock().unwrap();
if record.level().is_at_least(*log_level) {
self.drain.log(record, values)?;
}
Ok(None)
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::{json, Value};
use slog::{crit, debug, error, info, warn, Logger};
use std::io::prelude::*;
use tempfile::NamedTempFile;
#[test]
fn test_get_log_levels() {
let expected = vec!["trace", "debug", "info", "warn", "error", "critical"];
let log_levels = get_log_levels();
assert_eq!(log_levels, expected);
}
#[test]
fn test_level_name_to_slog_level() {
#[derive(Debug)]
struct TestData<'a> {
name: &'a str,
result: Result<slog::Level, &'a str>,
}
let invalid_msg = "invalid level name";
let tests = &[
TestData {
name: "",
result: Err(invalid_msg),
},
TestData {
name: "foo",
result: Err(invalid_msg),
},
TestData {
name: "x",
result: Err(invalid_msg),
},
TestData {
name: ".",
result: Err(invalid_msg),
},
TestData {
name: "trace",
result: Ok(slog::Level::Trace),
},
TestData {
name: "debug",
result: Ok(slog::Level::Debug),
},
TestData {
name: "info",
result: Ok(slog::Level::Info),
},
TestData {
name: "warn",
result: Ok(slog::Level::Warning),
},
TestData {
name: "error",
result: Ok(slog::Level::Error),
},
TestData {
name: "critical",
result: Ok(slog::Level::Critical),
},
];
for (i, d) in tests.iter().enumerate() {
let msg = format!("test[{}]: {:?}", i, d);
let result = level_name_to_slog_level(d.name);
let msg = format!("{}, result: {:?}", msg, result);
if d.result.is_ok() {
assert!(result.is_ok());
let result_level = result.unwrap();
let expected_level = d.result.unwrap();
assert!(result_level == expected_level, "{}", msg);
continue;
} else {
assert!(result.is_err(), "{}", msg);
}
let expected_error = d.result.as_ref().unwrap_err();
let actual_error = result.unwrap_err();
assert!(&actual_error == expected_error, "{}", msg);
}
}
#[test]
fn test_slog_level_to_level_name() {
#[derive(Debug)]
struct TestData<'a> {
level: slog::Level,
result: Result<&'a str, &'a str>,
}
let tests = &[
TestData {
level: slog::Level::Trace,
result: Ok("trace"),
},
TestData {
level: slog::Level::Debug,
result: Ok("debug"),
},
TestData {
level: slog::Level::Info,
result: Ok("info"),
},
TestData {
level: slog::Level::Warning,
result: Ok("warn"),
},
TestData {
level: slog::Level::Error,
result: Ok("error"),
},
TestData {
level: slog::Level::Critical,
result: Ok("critical"),
},
];
for (i, d) in tests.iter().enumerate() {
let msg = format!("test[{}]: {:?}", i, d);
let result = slog_level_to_level_name(d.level);
let msg = format!("{}, result: {:?}", msg, result);
if d.result.is_ok() {
assert!(result == d.result, "{}", msg);
continue;
}
let expected_error = d.result.as_ref().unwrap_err();
let actual_error = result.unwrap_err();
assert!(&actual_error == expected_error, "{}", msg);
}
}
#[test]
fn test_create_logger_write_to_tmpfile() {
// Create a writer for the logger drain to use
let writer = NamedTempFile::new().expect("failed to create tempfile");
// Used to check file contents before the temp file is unlinked
let mut writer_ref = writer.reopen().expect("failed to clone tempfile");
let level = slog::Level::Trace;
let name = "name";
let source = "source";
let record_subsystem = "record-subsystem";
let record_key = "record-key-1";
let record_value = "record-key-2";
let (logger, guard) = create_logger(name, source, level, writer);
let msg = "foo, bar, baz";
// Call the logger (which calls the drain)
// Note: This "mid level" log level should be available in debug or
// release builds.
info!(&logger, "{}", msg; "subsystem" => record_subsystem, record_key => record_value);
// Force temp file to be flushed
drop(guard);
drop(logger);
let mut contents = String::new();
writer_ref
.read_to_string(&mut contents)
.expect("failed to read tempfile contents");
// Convert file to JSON
let fields: Value =
serde_json::from_str(&contents).expect("failed to convert logfile to json");
// Check the expected JSON fields
let field_ts = fields.get("ts").expect("failed to find timestamp field");
assert_ne!(field_ts, "");
let field_version = fields.get("version").expect("failed to find version field");
assert_eq!(field_version, env!("CARGO_PKG_VERSION"));
let field_pid = fields.get("pid").expect("failed to find pid field");
assert_ne!(field_pid, "");
let field_level = fields.get("level").expect("failed to find level field");
assert_eq!(field_level, "INFO");
let field_msg = fields.get("msg").expect("failed to find msg field");
assert_eq!(field_msg, msg);
let field_name = fields.get("name").expect("failed to find name field");
assert_eq!(field_name, name);
let field_source = fields.get("source").expect("failed to find source field");
assert_eq!(field_source, source);
let field_subsystem = fields
.get("subsystem")
.expect("failed to find subsystem field");
// The records field should take priority over the loggers field of the same name
assert_eq!(field_subsystem, record_subsystem);
let field_record_value = fields
.get(record_key)
.expect("failed to find record key field");
assert_eq!(field_record_value, record_value);
}
#[test]
fn test_logger_levels() {
let name = "name";
let source = "source";
let debug_msg = "a debug log level message";
let info_msg = "an info log level message";
let warn_msg = "a warn log level message";
let error_msg = "an error log level message";
let critical_msg = "a critical log level message";
// The slog crate will *remove* macro calls for log levels "above" the
// configured log level.lock
//
// At the time of writing, the default slog log
// level is "info", but this crate overrides that using the magic
// "*max_level*" features in the "Cargo.toml" manifest.
// However, there are two log levels:
//
// - max_level_${level}
//
// This is the log level for normal "cargo build" (development/debug)
// builds.
//
// - release_max_level_${level}
//
// This is the log level for "cargo install" and
// "cargo build --release" (release) builds.
//
// This crate sets them to different values, which is sensible and
// standard practice. However, that causes a problem: there is
// currently no clean way for this test code to detect _which_
// profile the test is being built for (development or release),
// meaning we cannot know which macros are expected to produce output
// and which aren't ;(
//
// The best we can do is test the following log levels which
// are expected to work in all build profiles.
let debug_closure = |logger: &Logger, msg: String| debug!(logger, "{}", msg);
let info_closure = |logger: &Logger, msg: String| info!(logger, "{}", msg);
let warn_closure = |logger: &Logger, msg: String| warn!(logger, "{}", msg);
let error_closure = |logger: &Logger, msg: String| error!(logger, "{}", msg);
let critical_closure = |logger: &Logger, msg: String| crit!(logger, "{}", msg);
struct TestData<'a> {
slog_level: slog::Level,
slog_level_tag: &'a str,
msg: String,
closure: Box<dyn Fn(&Logger, String)>,
}
let tests = &[
TestData {
slog_level: slog::Level::Debug,
// Looks like a typo but tragically it isn't! ;(
slog_level_tag: "DEBG",
msg: debug_msg.into(),
closure: Box::new(debug_closure),
},
TestData {
slog_level: slog::Level::Info,
slog_level_tag: "INFO",
msg: info_msg.into(),
closure: Box::new(info_closure),
},
TestData {
slog_level: slog::Level::Warning,
slog_level_tag: "WARN",
msg: warn_msg.into(),
closure: Box::new(warn_closure),
},
TestData {
slog_level: slog::Level::Error,
// Another language tragedy
slog_level_tag: "ERRO",
msg: error_msg.into(),
closure: Box::new(error_closure),
},
TestData {
slog_level: slog::Level::Critical,
slog_level_tag: "CRIT",
msg: critical_msg.into(),
closure: Box::new(critical_closure),
},
];
for (i, d) in tests.iter().enumerate() {
let msg = format!("test[{}]", i);
// Create a writer for the logger drain to use
let writer =
NamedTempFile::new().expect(&format!("{:}: failed to create tempfile", msg));
// Used to check file contents before the temp file is unlinked
let mut writer_ref = writer
.reopen()
.expect(&format!("{:?}: failed to clone tempfile", msg));
let (logger, logger_guard) = create_logger(name, source, d.slog_level, writer);
// Call the logger (which calls the drain)
(d.closure)(&logger, d.msg.to_owned());
// Force temp file to be flushed
drop(logger_guard);
drop(logger);
let mut contents = String::new();
writer_ref
.read_to_string(&mut contents)
.expect(&format!("{:?}: failed to read tempfile contents", msg));
// Convert file to JSON
let fields: Value = serde_json::from_str(&contents)
.expect(&format!("{:?}: failed to convert logfile to json", msg));
// Check the expected JSON fields
let field_ts = fields
.get("ts")
.expect(&format!("{:?}: failed to find timestamp field", msg));
assert_ne!(field_ts, "", "{}", msg);
let field_version = fields
.get("version")
.expect(&format!("{:?}: failed to find version field", msg));
assert_eq!(field_version, env!("CARGO_PKG_VERSION"), "{}", msg);
let field_pid = fields
.get("pid")
.expect(&format!("{:?}: failed to find pid field", msg));
assert_ne!(field_pid, "", "{}", msg);
let field_level = fields
.get("level")
.expect(&format!("{:?}: failed to find level field", msg));
assert_eq!(field_level, d.slog_level_tag, "{}", msg);
let field_msg = fields
.get("msg")
.expect(&format!("{:?}: failed to find msg field", msg));
assert_eq!(field_msg, &json!(d.msg), "{}", msg);
let field_name = fields
.get("name")
.expect(&format!("{:?}: failed to find name field", msg));
assert_eq!(field_name, name, "{}", msg);
let field_source = fields
.get("source")
.expect(&format!("{:?}: failed to find source field", msg));
assert_eq!(field_source, source, "{}", msg);
let field_subsystem = fields
.get("subsystem")
.expect(&format!("{:?}: failed to find subsystem field", msg));
// No explicit subsystem, so should be the default
assert_eq!(field_subsystem, &json!(DEFAULT_SUBSYSTEM), "{}", msg);
}
}
}

View File

@@ -8,7 +8,6 @@ package main
import (
"context"
"flag"
"io/ioutil"
"os"
"testing"
@@ -44,7 +43,7 @@ func TestFactoryCLIFunctionNoRuntimeConfig(t *testing.T) {
func TestFactoryCLIFunctionInit(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -93,7 +92,7 @@ func TestFactoryCLIFunctionInit(t *testing.T) {
func TestFactoryCLIFunctionDestroy(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -127,7 +126,7 @@ func TestFactoryCLIFunctionDestroy(t *testing.T) {
func TestFactoryCLIFunctionStatus(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)

View File

@@ -7,7 +7,7 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
"syscall"
"unsafe"
@@ -212,7 +212,7 @@ func setCPUtype(hypervisorType vc.HypervisorType) error {
}
func getCPUtype() int {
content, err := ioutil.ReadFile("/proc/cpuinfo")
content, err := os.ReadFile("/proc/cpuinfo")
if err != nil {
kataLog.WithError(err).Error("failed to read file")
return cpuTypeUnknown

View File

@@ -8,7 +8,6 @@ package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
@@ -72,7 +71,7 @@ func TestCCCheckCLIFunction(t *testing.T) {
func TestCheckCheckKernelModulesNoNesting(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -157,7 +156,7 @@ func TestCheckCheckKernelModulesNoNesting(t *testing.T) {
func TestCheckCheckKernelModulesNoUnrestrictedGuest(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -256,7 +255,7 @@ func TestCheckHostIsVMContainerCapable(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -406,7 +405,7 @@ func TestArchKernelParamHandler(t *testing.T) {
func TestKvmIsUsable(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -458,7 +457,7 @@ foo : bar
func TestSetCPUtype(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)

View File

@@ -7,7 +7,6 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
@@ -68,7 +67,7 @@ foo : bar
{validContents, validNormalizeVendorName, validNormalizeModelName, false},
}
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}

View File

@@ -6,8 +6,9 @@
package main
import (
"os"
"github.com/sirupsen/logrus"
"io/ioutil"
)
var testCPUInfoTemplate = setTestCPUInfoTemplate()
@@ -15,7 +16,7 @@ var testCPUInfoTemplate = setTestCPUInfoTemplate()
func setTestCPUInfoTemplate() string {
var kataLog *logrus.Entry
content, err := ioutil.ReadFile("/proc/cpuinfo")
content, err := os.ReadFile("/proc/cpuinfo")
if err != nil {
kataLog.WithError(err).Error("failed to read file /proc/cpuinfo")

View File

@@ -9,7 +9,6 @@
package main
import (
"io/ioutil"
"os"
"testing"
@@ -19,7 +18,7 @@ import (
func testSetCPUTypeGeneric(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)

View File

@@ -7,7 +7,6 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
@@ -119,7 +118,7 @@ func TestArchKernelParamHandler(t *testing.T) {
func TestKvmIsUsable(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}

View File

@@ -7,7 +7,6 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
@@ -118,7 +117,7 @@ func TestArchKernelParamHandler(t *testing.T) {
func TestKvmIsUsable(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}

View File

@@ -10,7 +10,6 @@ import (
"flag"
"fmt"
"html/template"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -50,7 +49,7 @@ type testCPUDetail struct {
var fakeCPUData = testCPUData{"", "", false}
func createFile(file, contents string) error {
return ioutil.WriteFile(file, []byte(contents), testFileMode)
return os.WriteFile(file, []byte(contents), testFileMode)
}
func createModules(assert *assert.Assertions, cpuInfoFile string, moduleData []testModuleData) {
@@ -151,12 +150,12 @@ func makeCPUInfoFile(path, vendorID, flags string) error {
return err
}
return ioutil.WriteFile(path, contents.Bytes(), testFileMode)
return os.WriteFile(path, contents.Bytes(), testFileMode)
}
// nolint: unused, deadcode
func genericTestGetCPUDetails(t *testing.T, validVendor string, validModel string, validContents string, data []testCPUDetail) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -198,7 +197,7 @@ func genericTestGetCPUDetails(t *testing.T, validVendor string, validModel strin
func genericCheckCLIFunction(t *testing.T, cpuData []testCPUData, moduleData []testModuleData) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -308,7 +307,7 @@ func TestCheckGetCPUInfo(t *testing.T) {
{"foo\n\nbar\nbaz\n\n", "foo", false},
}
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -320,7 +319,7 @@ func TestCheckGetCPUInfo(t *testing.T) {
assert.Error(err)
for _, d := range data {
err = ioutil.WriteFile(file, []byte(d.contents), testFileMode)
err = os.WriteFile(file, []byte(d.contents), testFileMode)
if err != nil {
t.Fatal(err)
}
@@ -528,7 +527,7 @@ func TestCheckHaveKernelModule(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -578,7 +577,7 @@ func TestCheckHaveKernelModule(t *testing.T) {
func TestCheckCheckKernelModules(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -663,7 +662,7 @@ func TestCheckCheckKernelModulesUnreadableFile(t *testing.T) {
t.Skip(ktu.TestDisabledNeedNonRoot)
}
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -711,7 +710,7 @@ func TestCheckCheckKernelModulesUnreadableFile(t *testing.T) {
func TestCheckCheckKernelModulesInvalidFileContents(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -756,7 +755,7 @@ func TestCheckCheckKernelModulesInvalidFileContents(t *testing.T) {
func TestCheckCLIFunctionFail(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -789,7 +788,7 @@ func TestCheckCLIFunctionFail(t *testing.T) {
func TestCheckKernelParamHandler(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -871,7 +870,7 @@ func TestCheckKernelParamHandler(t *testing.T) {
func TestArchRequiredKernelModules(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -886,7 +885,7 @@ func TestArchRequiredKernelModules(t *testing.T) {
return
}
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}

View File

@@ -6,7 +6,6 @@
package main
import (
"io/ioutil"
"os"
"testing"
@@ -23,7 +22,7 @@ func getExpectedHostDetails(tmpdir string) (HostInfo, error) {
func TestEnvGetEnvInfoSetsCPUType(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)

View File

@@ -9,7 +9,6 @@
package main
import (
"io/ioutil"
"os"
"testing"
@@ -19,7 +18,7 @@ import (
func testEnvGetEnvInfoSetsCPUTypeGeneric(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)

View File

@@ -10,7 +10,6 @@ import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -65,7 +64,7 @@ func makeVersionBinary(file, version string) error {
func createConfig(configPath string, fileData string) error {
err := ioutil.WriteFile(configPath, []byte(fileData), testFileMode)
err := os.WriteFile(configPath, []byte(fileData), testFileMode)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to create config file %s %v\n", configPath, err)
return err
@@ -365,7 +364,7 @@ func TestEnvGetMetaInfo(t *testing.T) {
}
func TestEnvGetHostInfo(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -390,7 +389,7 @@ func TestEnvGetHostInfo(t *testing.T) {
}
func TestEnvGetHostInfoNoProcCPUInfo(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -407,7 +406,7 @@ func TestEnvGetHostInfoNoProcCPUInfo(t *testing.T) {
}
func TestEnvGetHostInfoNoOSRelease(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -424,7 +423,7 @@ func TestEnvGetHostInfoNoOSRelease(t *testing.T) {
}
func TestEnvGetHostInfoNoProcVersion(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -441,7 +440,7 @@ func TestEnvGetHostInfoNoProcVersion(t *testing.T) {
}
func TestEnvGetEnvInfo(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -475,7 +474,7 @@ func TestEnvGetEnvInfo(t *testing.T) {
func TestEnvGetEnvInfoNoHypervisorVersion(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -502,7 +501,7 @@ func TestEnvGetEnvInfoNoHypervisorVersion(t *testing.T) {
func TestEnvGetEnvInfoAgentError(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -511,7 +510,7 @@ func TestEnvGetEnvInfoAgentError(t *testing.T) {
}
func TestEnvGetEnvInfoNoOSRelease(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -531,7 +530,7 @@ func TestEnvGetEnvInfoNoOSRelease(t *testing.T) {
}
func TestEnvGetEnvInfoNoProcCPUInfo(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -551,7 +550,7 @@ func TestEnvGetEnvInfoNoProcCPUInfo(t *testing.T) {
}
func TestEnvGetEnvInfoNoProcVersion(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -571,7 +570,7 @@ func TestEnvGetEnvInfoNoProcVersion(t *testing.T) {
}
func TestEnvGetRuntimeInfo(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -588,7 +587,7 @@ func TestEnvGetRuntimeInfo(t *testing.T) {
}
func TestEnvGetAgentInfo(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -727,13 +726,13 @@ func testEnvShowJSONSettings(t *testing.T, tmpdir string, tmpfile *os.File) erro
}
func TestEnvShowSettings(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
defer os.RemoveAll(tmpdir)
tmpfile, err := ioutil.TempFile("", "envShowSettings-")
tmpfile, err := os.CreateTemp("", "envShowSettings-")
assert.NoError(t, err)
defer os.Remove(tmpfile.Name())
@@ -748,13 +747,13 @@ func TestEnvShowSettings(t *testing.T) {
}
func TestEnvShowSettingsInvalidFile(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
defer os.RemoveAll(tmpdir)
tmpfile, err := ioutil.TempFile("", "envShowSettings-")
tmpfile, err := os.CreateTemp("", "envShowSettings-")
assert.NoError(t, err)
defer os.Remove(tmpfile.Name())
@@ -772,7 +771,7 @@ func TestEnvShowSettingsInvalidFile(t *testing.T) {
}
func TestEnvHandleSettings(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -790,7 +789,7 @@ func TestEnvHandleSettings(t *testing.T) {
ctx.App.Metadata["configFile"] = configFile
ctx.App.Metadata["runtimeConfig"] = config
tmpfile, err := ioutil.TempFile("", "")
tmpfile, err := os.CreateTemp("", "")
assert.NoError(t, err)
defer os.Remove(tmpfile.Name())
@@ -806,7 +805,7 @@ func TestEnvHandleSettings(t *testing.T) {
func TestEnvHandleSettingsInvalidParams(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -860,7 +859,7 @@ func TestEnvHandleSettingsInvalidRuntimeConfigType(t *testing.T) {
}
func TestEnvCLIFunction(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -905,7 +904,7 @@ func TestEnvCLIFunction(t *testing.T) {
}
func TestEnvCLIFunctionFail(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -941,7 +940,7 @@ func TestEnvCLIFunctionFail(t *testing.T) {
func TestGetHypervisorInfo(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -963,7 +962,7 @@ func TestGetHypervisorInfo(t *testing.T) {
func TestGetHypervisorInfoSocket(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)

View File

@@ -9,7 +9,6 @@ package main
import (
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
@@ -170,7 +169,7 @@ func getConn(sandboxID string, port uint64) (net.Conn, error) {
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

View File

@@ -11,7 +11,6 @@ import (
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -100,7 +99,7 @@ func TestMain(m *testing.M) {
}
func createEmptyFile(path string) (err error) {
return ioutil.WriteFile(path, []byte(""), testFileMode)
return os.WriteFile(path, []byte(""), testFileMode)
}
func grep(pattern, file string) error {
@@ -108,7 +107,7 @@ func grep(pattern, file string) error {
return errors.New("need file")
}
bytes, err := ioutil.ReadFile(file)
bytes, err := os.ReadFile(file)
if err != nil {
return err
}
@@ -259,7 +258,7 @@ func TestMainBeforeSubCommands(t *testing.T) {
func TestMainBeforeSubCommandsInvalidLogFile(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "katatest")
tmpdir, err := os.MkdirTemp("", "katatest")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -282,7 +281,7 @@ func TestMainBeforeSubCommandsInvalidLogFile(t *testing.T) {
func TestMainBeforeSubCommandsInvalidLogFormat(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "katatest")
tmpdir, err := os.MkdirTemp("", "katatest")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -311,7 +310,7 @@ func TestMainBeforeSubCommandsInvalidLogFormat(t *testing.T) {
func TestMainBeforeSubCommandsLoadConfigurationFail(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "katatest")
tmpdir, err := os.MkdirTemp("", "katatest")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -346,7 +345,7 @@ func TestMainBeforeSubCommandsLoadConfigurationFail(t *testing.T) {
func TestMainBeforeSubCommandsShowCCConfigPaths(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "katatest")
tmpdir, err := os.MkdirTemp("", "katatest")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -410,7 +409,7 @@ func TestMainBeforeSubCommandsShowCCConfigPaths(t *testing.T) {
func TestMainFatal(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "katatest")
tmpdir, err := os.MkdirTemp("", "katatest")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -634,7 +633,7 @@ func TestMainCreateRuntime(t *testing.T) {
func TestMainVersionPrinter(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "katatest")
tmpdir, err := os.MkdirTemp("", "katatest")
assert.NoError(err)
defer os.RemoveAll(tmpdir)

View File

@@ -10,7 +10,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"io"
"net/http"
"os"
"strings"
@@ -279,7 +279,7 @@ func getReleases(releaseURL string, includeAll bool) ([]semver.Version, map[stri
releasesArray := []map[string]interface{}{}
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, nil, fmt.Errorf("failed to read release details: %v", err)
} else if resp.StatusCode == http.StatusForbidden && bytes.Contains(body, []byte("limit exceeded")) {

View File

@@ -7,7 +7,6 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
@@ -18,7 +17,7 @@ import (
)
func TestFileExists(t *testing.T) {
dir, err := ioutil.TempDir("", "katatest")
dir, err := os.MkdirTemp("", "katatest")
if err != nil {
t.Fatal(err)
}
@@ -55,7 +54,7 @@ func TestGetKernelVersion(t *testing.T) {
{validContents, validVersion, false},
}
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}
@@ -104,7 +103,7 @@ func TestGetDistroDetails(t *testing.T) {
const unknown = "<<unknown>>"
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
panic(err)
}

View File

@@ -7,7 +7,6 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"testing"
@@ -38,7 +37,7 @@ func TestVersion(t *testing.T) {
fn, ok := versionCLICommand.Action.(func(context *cli.Context) error)
assert.True(t, ok)
tmpfile, err := ioutil.TempFile("", "")
tmpfile, err := os.CreateTemp("", "")
assert.NoError(t, err)
defer os.Remove(tmpfile.Name())

View File

@@ -70,7 +70,7 @@ func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*con
rootfs := filepath.Join(r.Bundle, "rootfs")
switch containerType {
case vc.PodSandbox:
case vc.PodSandbox, vc.SingleContainer:
if s.sandbox != nil {
return nil, fmt.Errorf("cannot create another sandbox in sandbox: %s", s.sandbox.ID())
}

View File

@@ -9,7 +9,6 @@ package containerdshim
import (
"context"
"fmt"
"io/ioutil"
"os"
"path"
"testing"
@@ -362,7 +361,7 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config string, err err
runtimeConfigFileData := ktu.MakeRuntimeConfigFileData(configFileOptions)
configPath := path.Join(dir, "runtime.toml")
err = ioutil.WriteFile(configPath, []byte(runtimeConfigFileData), os.FileMode(0640))
err = os.WriteFile(configPath, []byte(runtimeConfigFileData), os.FileMode(0640))
if err != nil {
return "", err
}
@@ -371,7 +370,7 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config string, err err
for _, file := range files {
// create the resource (which must be >0 bytes)
err := ioutil.WriteFile(file, []byte("foo"), os.FileMode(0640))
err := os.WriteFile(file, []byte("foo"), os.FileMode(0640))
if err != nil {
return "", err
}
@@ -383,7 +382,7 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config string, err err
func TestCreateLoadRuntimeConfig(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)

View File

@@ -7,7 +7,7 @@ package containerdshim
import (
"context"
"io/ioutil"
"io"
"os"
sysexec "os/exec"
"sync"
@@ -80,7 +80,7 @@ func New(ctx context.Context, id string, publisher cdshim.Publisher, shutdown fu
// Discard the log before shim init its log output. Otherwise
// it will output into stdio, from which containerd would like
// to get the shim's socket address.
logrus.SetOutput(ioutil.Discard)
logrus.SetOutput(io.Discard)
opts := ctx.Value(cdshim.OptsKey{}).(cdshim.Opts)
if !opts.Debug {
logrus.SetLevel(logrus.WarnLevel)
@@ -345,7 +345,7 @@ func (s *service) Cleanup(ctx context.Context) (_ *taskAPI.DeleteResponse, err e
}
switch containerType {
case vc.PodSandbox:
case vc.PodSandbox, vc.SingleContainer:
err = cleanupContainer(spanCtx, s.id, s.id, path)
if err != nil {
return nil, err

View File

@@ -8,7 +8,6 @@ package containerdshim
import (
"context"
"io"
"io/ioutil"
"os"
"path/filepath"
"syscall"
@@ -26,11 +25,11 @@ func TestNewTtyIOFifoReopen(t *testing.T) {
assert := assert.New(t)
ctx := context.TODO()
testDir, err := ioutil.TempDir("", "kata-")
testDir, err := os.MkdirTemp("", "kata-")
assert.NoError(err)
defer os.RemoveAll(testDir)
fifoPath, err := ioutil.TempDir(testDir, "fifo-path-")
fifoPath, err := os.MkdirTemp(testDir, "fifo-path-")
assert.NoError(err)
stdout := filepath.Join(fifoPath, "stdout")
stderr := filepath.Join(fifoPath, "stderr")
@@ -104,11 +103,11 @@ func TestIoCopy(t *testing.T) {
testBytes2 := []byte("Test2")
testBytes3 := []byte("Test3")
testDir, err := ioutil.TempDir("", "kata-")
testDir, err := os.MkdirTemp("", "kata-")
assert.NoError(err)
defer os.RemoveAll(testDir)
fifoPath, err := ioutil.TempDir(testDir, "fifo-path-")
fifoPath, err := os.MkdirTemp(testDir, "fifo-path-")
assert.NoError(err)
dstStdoutPath := filepath.Join(fifoPath, "dststdout")
dstStderrPath := filepath.Join(fifoPath, "dststderr")

View File

@@ -8,7 +8,6 @@ package containerdshim
import (
"fmt"
"io/ioutil"
"os"
"path"
"testing"
@@ -60,7 +59,7 @@ func init() {
}
func createEmptyFile(path string) (err error) {
return ioutil.WriteFile(path, []byte(""), testFileMode)
return os.WriteFile(path, []byte(""), testFileMode)
}
// newTestHypervisorConfig creaets a new virtcontainers

View File

@@ -7,7 +7,7 @@ package katamonitor
import (
"fmt"
"io/ioutil"
"io"
"net"
"net/http"
"os"
@@ -90,7 +90,7 @@ func doGet(sandboxID string, timeoutInSeconds time.Duration, urlPath string) ([]
resp.Body.Close()
}()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

View File

@@ -8,7 +8,6 @@ package katatestutils
import (
"errors"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
@@ -63,7 +62,7 @@ type Result struct {
// GetFileContents return the file contents as a string.
func getFileContents(file string) (string, error) {
bytes, err := ioutil.ReadFile(file)
bytes, err := os.ReadFile(file)
if err != nil {
return "", err
}

View File

@@ -8,7 +8,6 @@ package katatestutils
import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -316,7 +315,7 @@ func testGetDistro() (name, version string, err error) {
func testGetKernelVersion() (version string, err error) {
const file = "/proc/version"
bytes, err := ioutil.ReadFile(file)
bytes, err := os.ReadFile(file)
if err != nil {
return "", err
}
@@ -416,7 +415,7 @@ func TestGetFileContents(t *testing.T) {
{"foo\nbar"},
}
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(dir)
@@ -428,7 +427,7 @@ func TestGetFileContents(t *testing.T) {
for _, d := range data {
// create the file
err = ioutil.WriteFile(file, []byte(d.contents), testFileMode)
err = os.WriteFile(file, []byte(d.contents), testFileMode)
assert.NoError(err)
defer os.Remove(file)

View File

@@ -9,7 +9,6 @@ package katatestutils
import (
"encoding/json"
"errors"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -347,7 +346,7 @@ func IsInGitHubActions() bool {
func SetupOCIConfigFile(t *testing.T) (rootPath string, bundlePath, ociConfigFile string) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "katatest-")
tmpdir, err := os.MkdirTemp("", "katatest-")
assert.NoError(err)
bundlePath = filepath.Join(tmpdir, "bundle")
@@ -355,7 +354,7 @@ func SetupOCIConfigFile(t *testing.T) (rootPath string, bundlePath, ociConfigFil
assert.NoError(err)
ociConfigFile = filepath.Join(bundlePath, "config.json")
err = ioutil.WriteFile(ociConfigFile, []byte(busyboxConfigJson), testFileMode)
err = os.WriteFile(ociConfigFile, []byte(busyboxConfigJson), testFileMode)
assert.NoError(err)
return tmpdir, bundlePath, ociConfigFile
@@ -372,5 +371,5 @@ func WriteOCIConfigFile(spec specs.Spec, configPath string) error {
return err
}
return ioutil.WriteFile(configPath, bytes, testFileMode)
return os.WriteFile(configPath, bytes, testFileMode)
}

View File

@@ -9,7 +9,7 @@ package katautils
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
goruntime "runtime"
"strings"
@@ -1200,7 +1200,7 @@ func decodeConfig(configPath string) (tomlConfig, string, error) {
return tomlConf, "", fmt.Errorf("Cannot find usable config file (%v)", err)
}
configData, err := ioutil.ReadFile(resolved)
configData, err := os.ReadFile(resolved)
if err != nil {
return tomlConf, resolved, err
}

View File

@@ -9,7 +9,6 @@ package katautils
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -49,7 +48,7 @@ type testRuntimeConfig struct {
func createConfig(configPath string, fileData string) error {
err := ioutil.WriteFile(configPath, []byte(fileData), testFileMode)
err := os.WriteFile(configPath, []byte(fileData), testFileMode)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to create config file %s %v\n", configPath, err)
return err
@@ -280,7 +279,7 @@ func testLoadConfiguration(t *testing.T, dir string,
}
func TestConfigLoadConfiguration(t *testing.T) {
tmpdir, err := ioutil.TempDir(testDir, "load-config-")
tmpdir, err := os.MkdirTemp(testDir, "load-config-")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
@@ -288,7 +287,7 @@ func TestConfigLoadConfiguration(t *testing.T) {
}
func TestConfigLoadConfigurationFailBrokenSymLink(t *testing.T) {
tmpdir, err := ioutil.TempDir(testDir, "runtime-config-")
tmpdir, err := os.MkdirTemp(testDir, "runtime-config-")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
@@ -311,7 +310,7 @@ func TestConfigLoadConfigurationFailBrokenSymLink(t *testing.T) {
}
func TestConfigLoadConfigurationFailSymLinkLoop(t *testing.T) {
tmpdir, err := ioutil.TempDir(testDir, "runtime-config-")
tmpdir, err := os.MkdirTemp(testDir, "runtime-config-")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
@@ -340,7 +339,7 @@ func TestConfigLoadConfigurationFailSymLinkLoop(t *testing.T) {
}
func TestConfigLoadConfigurationFailMissingHypervisor(t *testing.T) {
tmpdir, err := ioutil.TempDir(testDir, "runtime-config-")
tmpdir, err := os.MkdirTemp(testDir, "runtime-config-")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
@@ -358,7 +357,7 @@ func TestConfigLoadConfigurationFailMissingHypervisor(t *testing.T) {
}
func TestConfigLoadConfigurationFailMissingImage(t *testing.T) {
tmpdir, err := ioutil.TempDir(testDir, "runtime-config-")
tmpdir, err := os.MkdirTemp(testDir, "runtime-config-")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
@@ -376,7 +375,7 @@ func TestConfigLoadConfigurationFailMissingImage(t *testing.T) {
}
func TestConfigLoadConfigurationFailMissingKernel(t *testing.T) {
tmpdir, err := ioutil.TempDir(testDir, "runtime-config-")
tmpdir, err := os.MkdirTemp(testDir, "runtime-config-")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
@@ -398,7 +397,7 @@ func TestConfigLoadConfigurationFailUnreadableConfig(t *testing.T) {
t.Skip(ktu.TestDisabledNeedNonRoot)
}
tmpdir, err := ioutil.TempDir(testDir, "runtime-config-")
tmpdir, err := os.MkdirTemp(testDir, "runtime-config-")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
@@ -421,7 +420,7 @@ func TestConfigLoadConfigurationFailTOMLConfigFileInvalidContents(t *testing.T)
t.Skip(ktu.TestDisabledNeedNonRoot)
}
tmpdir, err := ioutil.TempDir(testDir, "runtime-config-")
tmpdir, err := os.MkdirTemp(testDir, "runtime-config-")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
@@ -447,7 +446,7 @@ func TestConfigLoadConfigurationFailTOMLConfigFileDuplicatedData(t *testing.T) {
t.Skip(ktu.TestDisabledNeedNonRoot)
}
tmpdir, err := ioutil.TempDir(testDir, "runtime-config-")
tmpdir, err := os.MkdirTemp(testDir, "runtime-config-")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
@@ -472,7 +471,7 @@ func TestConfigLoadConfigurationFailTOMLConfigFileDuplicatedData(t *testing.T) {
}
func TestMinimalRuntimeConfig(t *testing.T) {
dir, err := ioutil.TempDir(testDir, "minimal-runtime-config-")
dir, err := os.MkdirTemp(testDir, "minimal-runtime-config-")
if err != nil {
t.Fatal(err)
}
@@ -602,7 +601,7 @@ func TestMinimalRuntimeConfig(t *testing.T) {
}
func TestNewQemuHypervisorConfig(t *testing.T) {
dir, err := ioutil.TempDir(testDir, "hypervisor-config-")
dir, err := os.MkdirTemp(testDir, "hypervisor-config-")
if err != nil {
t.Fatal(err)
}
@@ -699,7 +698,7 @@ func TestNewQemuHypervisorConfig(t *testing.T) {
}
func TestNewFirecrackerHypervisorConfig(t *testing.T) {
dir, err := ioutil.TempDir(testDir, "hypervisor-config-")
dir, err := os.MkdirTemp(testDir, "hypervisor-config-")
if err != nil {
t.Fatal(err)
}
@@ -794,7 +793,7 @@ func TestNewFirecrackerHypervisorConfig(t *testing.T) {
func TestNewQemuHypervisorConfigImageAndInitrd(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir(testDir, "")
tmpdir, err := os.MkdirTemp(testDir, "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -836,7 +835,7 @@ func TestNewClhHypervisorConfig(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir(testDir, "")
tmpdir, err := os.MkdirTemp(testDir, "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -931,7 +930,7 @@ func TestHypervisorDefaults(t *testing.T) {
func TestHypervisorDefaultsHypervisor(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir(testDir, "")
tmpdir, err := os.MkdirTemp(testDir, "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -967,7 +966,7 @@ func TestHypervisorDefaultsHypervisor(t *testing.T) {
func TestHypervisorDefaultsKernel(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir(testDir, "")
tmpdir, err := os.MkdirTemp(testDir, "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -1010,7 +1009,7 @@ func TestHypervisorDefaultsKernel(t *testing.T) {
func TestHypervisorDefaultsInitrd(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir(testDir, "")
tmpdir, err := os.MkdirTemp(testDir, "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -1047,7 +1046,7 @@ func TestHypervisorDefaultsInitrd(t *testing.T) {
func TestHypervisorDefaultsImage(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir(testDir, "")
tmpdir, err := os.MkdirTemp(testDir, "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -1142,7 +1141,7 @@ func TestGetDefaultConfigFilePaths(t *testing.T) {
func TestGetDefaultConfigFile(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir(testDir, "")
tmpdir, err := os.MkdirTemp(testDir, "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -1232,7 +1231,7 @@ func TestDefaultFirmware(t *testing.T) {
// save default firmware path
oldDefaultFirmwarePath := defaultFirmwarePath
f, err := ioutil.TempFile(os.TempDir(), "qboot.bin")
f, err := os.CreateTemp(os.TempDir(), "qboot.bin")
assert.NoError(err)
assert.NoError(f.Close())
defer os.RemoveAll(f.Name())
@@ -1420,7 +1419,7 @@ func TestUpdateRuntimeConfigurationInvalidKernelParams(t *testing.T) {
func TestCheckHypervisorConfig(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir(testDir, "")
dir, err := os.MkdirTemp(testDir, "")
if err != nil {
t.Fatal(err)
}
@@ -1583,11 +1582,11 @@ func TestCheckFactoryConfig(t *testing.T) {
func TestValidateBindMounts(t *testing.T) {
assert := assert.New(t)
tmpdir1, err := ioutil.TempDir(testDir, "tmp1-")
tmpdir1, err := os.MkdirTemp(testDir, "tmp1-")
assert.NoError(err)
defer os.RemoveAll(tmpdir1)
tmpdir2, err := ioutil.TempDir(testDir, "tmp2-")
tmpdir2, err := os.MkdirTemp(testDir, "tmp2-")
assert.NoError(err)
defer os.RemoveAll(tmpdir2)
@@ -1595,13 +1594,13 @@ func TestValidateBindMounts(t *testing.T) {
duplicate2 := filepath.Join(tmpdir2, "cat.txt")
unique := filepath.Join(tmpdir1, "foobar.txt")
err = ioutil.WriteFile(duplicate1, []byte("kibble-monster"), 0644)
err = os.WriteFile(duplicate1, []byte("kibble-monster"), 0644)
assert.NoError(err)
err = ioutil.WriteFile(duplicate2, []byte("furbag"), 0644)
err = os.WriteFile(duplicate2, []byte("furbag"), 0644)
assert.NoError(err)
err = ioutil.WriteFile(unique, []byte("fuzzball"), 0644)
err = os.WriteFile(unique, []byte("fuzzball"), 0644)
assert.NoError(err)
type testData struct {

View File

@@ -9,7 +9,7 @@ package katautils
import (
"context"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
@@ -183,7 +183,7 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeCo
var procFIPS = "/proc/sys/crypto/fips_enabled"
func checkForFIPS(sandboxConfig *vc.SandboxConfig) error {
content, err := ioutil.ReadFile(procFIPS)
content, err := os.ReadFile(procFIPS)
if err != nil {
// In case file cannot be found or read, simply return
return nil

View File

@@ -10,7 +10,6 @@ import (
"context"
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -124,7 +123,7 @@ func TestSetEphemeralStorageType(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir(testDir, "foo")
dir, err := os.MkdirTemp(testDir, "foo")
if err != nil {
t.Fatal(err)
}
@@ -268,7 +267,7 @@ func TestCreateSandboxFail(t *testing.T) {
func TestCheckForFips(t *testing.T) {
assert := assert.New(t)
path, err := ioutil.TempDir("", "")
path, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(path)
@@ -278,7 +277,7 @@ func TestCheckForFips(t *testing.T) {
procFIPS = val
}()
err = ioutil.WriteFile(procFIPS, []byte("1"), 0644)
err = os.WriteFile(procFIPS, []byte("1"), 0644)
assert.NoError(err)
hconfig := vc.HypervisorConfig{
@@ -297,7 +296,7 @@ func TestCheckForFips(t *testing.T) {
assert.Equal(params[1].Value, "1")
config.HypervisorConfig = hconfig
err = ioutil.WriteFile(procFIPS, []byte("unexpected contents"), 0644)
err = os.WriteFile(procFIPS, []byte("unexpected contents"), 0644)
assert.NoError(err)
assert.NoError(checkForFIPS(&config))
assert.Equal(config.HypervisorConfig, hconfig)

View File

@@ -8,7 +8,7 @@ package katautils
import (
"fmt"
"io/ioutil"
"io"
"regexp"
"strings"
"testing"
@@ -29,7 +29,7 @@ func init() {
kataUtilsLogger.Logger.Level = logrus.DebugLevel
// Discard log output
kataUtilsLogger.Logger.Out = ioutil.Discard
kataUtilsLogger.Logger.Out = io.Discard
}
func TestHandleSystemLog(t *testing.T) {
@@ -71,7 +71,7 @@ func TestNewSystemLogHook(t *testing.T) {
// throw away all stdout so that the Format() call
// below returns the data in structured form.
logger.Out = ioutil.Discard
logger.Out = io.Discard
entry := &logrus.Entry{
Logger: logger,

View File

@@ -7,7 +7,6 @@ package katautils
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"syscall"
@@ -24,7 +23,7 @@ import (
func TestGetNetNsFromBindMount(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -53,7 +52,7 @@ func TestGetNetNsFromBindMount(t *testing.T) {
}
for i, d := range data {
err := ioutil.WriteFile(mountFile, []byte(d.contents), 0640)
err := os.WriteFile(mountFile, []byte(d.contents), 0640)
assert.NoError(err)
path, err := getNetNsFromBindMount(tmpNSPath, mountFile)
@@ -86,7 +85,7 @@ func TestHostNetworkingRequested(t *testing.T) {
assert.Error(err)
// Bind-mounted Netns
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)

View File

@@ -9,7 +9,6 @@ package katautils
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
@@ -99,7 +98,7 @@ func WriteFile(filePath string, data string, fileMode os.FileMode) error {
return fmt.Errorf("no such file for %s", filePath)
}
if err := ioutil.WriteFile(filePath, []byte(data), fileMode); err != nil {
if err := os.WriteFile(filePath, []byte(data), fileMode); err != nil {
return fmt.Errorf("failed to write %v to %v: %v", data, filePath, err)
}
@@ -108,7 +107,7 @@ func WriteFile(filePath string, data string, fileMode os.FileMode) error {
// GetFileContents return the file contents as a string.
func GetFileContents(file string) (string, error) {
bytes, err := ioutil.ReadFile(file)
bytes, err := os.ReadFile(file)
if err != nil {
return "", err
}

View File

@@ -8,7 +8,6 @@ package katautils
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -32,11 +31,11 @@ var (
)
func createFile(file, contents string) error {
return ioutil.WriteFile(file, []byte(contents), testFileMode)
return os.WriteFile(file, []byte(contents), testFileMode)
}
func createEmptyFile(path string) (err error) {
return ioutil.WriteFile(path, []byte(""), testFileMode)
return os.WriteFile(path, []byte(""), testFileMode)
}
func TestUtilsResolvePathEmptyPath(t *testing.T) {
@@ -45,7 +44,7 @@ func TestUtilsResolvePathEmptyPath(t *testing.T) {
}
func TestUtilsResolvePathValidPath(t *testing.T) {
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -77,7 +76,7 @@ func TestUtilsResolvePathValidPath(t *testing.T) {
}
func TestUtilsResolvePathENOENT(t *testing.T) {
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
if err != nil {
t.Fatal(err)
}
@@ -112,7 +111,7 @@ func TestUtilsResolvePathENOENT(t *testing.T) {
func TestFileSize(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir(testDir, "")
dir, err := os.MkdirTemp(testDir, "")
if err != nil {
t.Fatal(err)
}
@@ -153,7 +152,7 @@ func TestWriteFileErrWriteFail(t *testing.T) {
func TestWriteFileErrNoPath(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir(testDir, "")
dir, err := os.MkdirTemp(testDir, "")
assert.NoError(err)
defer os.RemoveAll(dir)
@@ -178,7 +177,7 @@ func TestGetFileContents(t *testing.T) {
{"processor : 0\nvendor_id : GenuineIntel\n"},
}
dir, err := ioutil.TempDir(testDir, "")
dir, err := os.MkdirTemp(testDir, "")
if err != nil {
t.Fatal(err)
}
@@ -192,7 +191,7 @@ func TestGetFileContents(t *testing.T) {
for _, d := range data {
// create the file
err = ioutil.WriteFile(file, []byte(d.contents), testFileMode)
err = os.WriteFile(file, []byte(d.contents), testFileMode)
if err != nil {
t.Fatal(err)
}

View File

@@ -17,7 +17,7 @@ import (
"strings"
"syscall"
criContainerdAnnotations "github.com/containerd/cri-containerd/pkg/annotations"
ctrAnnotations "github.com/containerd/containerd/pkg/cri/annotations"
crioAnnotations "github.com/cri-o/cri-o/pkg/annotations"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
@@ -42,19 +42,19 @@ var (
// CRIContainerTypeKeyList lists all the CRI keys that could define
// the container type from annotations in the config.json.
CRIContainerTypeKeyList = []string{criContainerdAnnotations.ContainerType, crioAnnotations.ContainerType, dockershimAnnotations.ContainerTypeLabelKey}
CRIContainerTypeKeyList = []string{ctrAnnotations.ContainerType, crioAnnotations.ContainerType, dockershimAnnotations.ContainerTypeLabelKey}
// CRISandboxNameKeyList lists all the CRI keys that could define
// the sandbox ID (sandbox ID) from annotations in the config.json.
CRISandboxNameKeyList = []string{criContainerdAnnotations.SandboxID, crioAnnotations.SandboxID, dockershimAnnotations.SandboxIDLabelKey}
CRISandboxNameKeyList = []string{ctrAnnotations.SandboxID, crioAnnotations.SandboxID, dockershimAnnotations.SandboxIDLabelKey}
// CRIContainerTypeList lists all the maps from CRI ContainerTypes annotations
// to a virtcontainers ContainerType.
CRIContainerTypeList = []annotationContainerType{
{crioAnnotations.ContainerTypeSandbox, vc.PodSandbox},
{crioAnnotations.ContainerTypeContainer, vc.PodContainer},
{criContainerdAnnotations.ContainerTypeSandbox, vc.PodSandbox},
{criContainerdAnnotations.ContainerTypeContainer, vc.PodContainer},
{ctrAnnotations.ContainerTypeSandbox, vc.PodSandbox},
{ctrAnnotations.ContainerTypeContainer, vc.PodContainer},
{dockershimAnnotations.ContainerTypeLabelSandbox, vc.PodSandbox},
{dockershimAnnotations.ContainerTypeLabelContainer, vc.PodContainer},
}
@@ -320,7 +320,7 @@ func networkConfig(ocispec specs.Spec, config RuntimeConfig) (vc.NetworkConfig,
}
// ContainerType returns the type of container and if the container type was
// found from CRI servers annotations.
// found from CRI server's annotations in the container spec.
func ContainerType(spec specs.Spec) (vc.ContainerType, error) {
for _, key := range CRIContainerTypeKeyList {
containerTypeVal, ok := spec.Annotations[key]
@@ -334,11 +334,10 @@ func ContainerType(spec specs.Spec) (vc.ContainerType, error) {
}
}
return vc.UnknownContainerType, fmt.Errorf("Unknown container type %s", containerTypeVal)
}
return vc.PodSandbox, nil
return vc.SingleContainer, nil
}
func GetSandboxConfigPath(annotations map[string]string) string {

View File

@@ -7,7 +7,6 @@ package oci
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -16,7 +15,7 @@ import (
"strings"
"testing"
"github.com/cri-o/cri-o/pkg/annotations"
ctrAnnotations "github.com/containerd/containerd/pkg/cri/annotations"
crioAnnotations "github.com/cri-o/cri-o/pkg/annotations"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
@@ -25,6 +24,7 @@ import (
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
dockerAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations/dockershim"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
)
@@ -44,7 +44,7 @@ var (
func createConfig(fileName string, fileData string) (string, error) {
configPath := path.Join(tempBundlePath, fileName)
err := ioutil.WriteFile(configPath, []byte(fileData), fileMode)
err := os.WriteFile(configPath, []byte(fileData), fileMode)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to create config file %s %v\n", configPath, err)
return "", err
@@ -152,7 +152,7 @@ func TestMinimalSandboxConfig(t *testing.T) {
Cmd: expectedCmd,
Annotations: map[string]string{
vcAnnotations.BundlePathKey: tempBundlePath,
vcAnnotations.ContainerTypeKey: string(vc.PodSandbox),
vcAnnotations.ContainerTypeKey: string(vc.SingleContainer),
},
Mounts: expectedMounts,
DeviceInfos: expectedDeviceInfo,
@@ -188,51 +188,100 @@ func TestMinimalSandboxConfig(t *testing.T) {
assert.NoError(os.Remove(configPath))
}
func testContainerTypeSuccessful(t *testing.T, ociSpec specs.Spec, expected vc.ContainerType) {
containerType, err := ContainerType(ociSpec)
func TestContainerType(t *testing.T) {
assert := assert.New(t)
assert.NoError(err)
assert.Equal(containerType, expected)
}
func TestContainerTypePodSandbox(t *testing.T) {
var ociSpec specs.Spec
ociSpec.Annotations = map[string]string{
annotations.ContainerType: annotations.ContainerTypeSandbox,
tests := []struct {
description string
annotationKey string
annotationValue string
expectedType vc.ContainerType
expectedErr bool
}{
{
description: "no annotation, expect single container",
annotationKey: "",
annotationValue: "",
expectedType: vc.SingleContainer,
expectedErr: false,
},
{
description: "unexpected annotation, expect error",
annotationKey: ctrAnnotations.ContainerType,
annotationValue: "foo",
expectedType: vc.UnknownContainerType,
expectedErr: true,
},
{
description: "containerd sandbox",
annotationKey: ctrAnnotations.ContainerType,
annotationValue: string(ctrAnnotations.ContainerTypeSandbox),
expectedType: vc.PodSandbox,
expectedErr: false,
},
{
description: "containerd container",
annotationKey: ctrAnnotations.ContainerType,
annotationValue: string(ctrAnnotations.ContainerTypeContainer),
expectedType: vc.PodContainer,
expectedErr: false,
},
{
description: "crio unexpected annotation, expect error",
annotationKey: crioAnnotations.ContainerType,
annotationValue: "foo",
expectedType: vc.UnknownContainerType,
expectedErr: true,
},
{
description: "crio sandbox",
annotationKey: crioAnnotations.ContainerType,
annotationValue: string(crioAnnotations.ContainerTypeSandbox),
expectedType: vc.PodSandbox,
expectedErr: false,
},
{
description: "crio container",
annotationKey: crioAnnotations.ContainerType,
annotationValue: string(crioAnnotations.ContainerTypeContainer),
expectedType: vc.PodContainer,
expectedErr: false,
},
{
description: "dockershim unexpected annotation, expect error",
annotationKey: dockerAnnotations.ContainerTypeLabelKey,
annotationValue: "foo",
expectedType: vc.UnknownContainerType,
expectedErr: true,
},
{
description: "dockershim sandbox",
annotationKey: dockerAnnotations.ContainerTypeLabelKey,
annotationValue: string(dockerAnnotations.ContainerTypeLabelSandbox),
expectedType: vc.PodSandbox,
expectedErr: false,
},
{
description: "dockershim container",
annotationKey: dockerAnnotations.ContainerTypeLabelKey,
annotationValue: string(dockerAnnotations.ContainerTypeLabelContainer),
expectedType: vc.PodContainer,
expectedErr: false,
},
}
testContainerTypeSuccessful(t, ociSpec, vc.PodSandbox)
}
func TestContainerTypePodContainer(t *testing.T) {
var ociSpec specs.Spec
ociSpec.Annotations = map[string]string{
annotations.ContainerType: annotations.ContainerTypeContainer,
for _, tt := range tests {
ociSpec := specs.Spec{
Annotations: map[string]string{
tt.annotationKey: tt.annotationValue,
},
}
containerType, err := ContainerType(ociSpec)
if tt.expectedErr {
assert.Error(err)
} else {
assert.NoError(err)
}
assert.Equal(tt.expectedType, containerType, "test fail: %v", tt.description)
}
testContainerTypeSuccessful(t, ociSpec, vc.PodContainer)
}
func TestContainerTypePodSandboxEmptyAnnotation(t *testing.T) {
testContainerTypeSuccessful(t, specs.Spec{}, vc.PodSandbox)
}
func TestContainerTypeFailure(t *testing.T) {
var ociSpec specs.Spec
expected := vc.UnknownContainerType
unknownType := "unknown_type"
assert := assert.New(t)
ociSpec.Annotations = map[string]string{
annotations.ContainerType: unknownType,
}
containerType, err := ContainerType(ociSpec)
assert.Error(err)
assert.Equal(containerType, expected)
}
func TestSandboxIDSuccessful(t *testing.T) {
@@ -241,7 +290,7 @@ func TestSandboxIDSuccessful(t *testing.T) {
assert := assert.New(t)
ociSpec.Annotations = map[string]string{
annotations.SandboxID: testSandboxID,
crioAnnotations.SandboxID: testSandboxID,
}
sandboxID, err := SandboxID(ociSpec)
@@ -361,7 +410,7 @@ func TestGetShmSizeBindMounted(t *testing.T) {
t.Skip("Test disabled as requires root privileges")
}
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
assert.Nil(t, err)
defer os.RemoveAll(dir)
@@ -399,7 +448,7 @@ func TestGetShmSizeBindMounted(t *testing.T) {
func TestMain(m *testing.M) {
var err error
tempRoot, err = ioutil.TempDir("", "virtc-")
tempRoot, err = os.MkdirTemp("", "virtc-")
if err != nil {
panic(err)
}
@@ -424,7 +473,7 @@ func TestMain(m *testing.M) {
func TestAddAssetAnnotations(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -432,7 +481,7 @@ func TestAddAssetAnnotations(t *testing.T) {
// (required since the existence of binary asset annotations is verified).
fakeAssetFile := filepath.Join(tmpdir, "fake-binary")
err = ioutil.WriteFile(fakeAssetFile, []byte(""), fileMode)
err = os.WriteFile(fakeAssetFile, []byte(""), fileMode)
assert.NoError(err)
expectedAnnotations := map[string]string{

View File

@@ -7,7 +7,6 @@ package utils
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
@@ -52,7 +51,7 @@ func TestGzipAccepted(t *testing.T) {
func TestEnsureDir(t *testing.T) {
const testMode = 0755
tmpdir, err := ioutil.TempDir("", "TestEnsureDir")
tmpdir, err := os.MkdirTemp("", "TestEnsureDir")
assert := assert.New(t)
assert.NoError(err)
@@ -121,7 +120,7 @@ func TestEnsureDir(t *testing.T) {
func TestFirstValidExecutable(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "TestFirstValidPath")
tmpdir, err := os.MkdirTemp("", "TestFirstValidPath")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
@@ -145,7 +144,7 @@ func TestFirstValidExecutable(t *testing.T) {
err := os.MkdirAll(path.Join(tmpdir, "a", "b"), 0755)
assert.NoError(err)
// create a non-executable file
err = ioutil.WriteFile(path.Join(tmpdir, "a", "b", "c"), []byte("test\n"), 0644)
err = os.WriteFile(path.Join(tmpdir, "a", "b", "c"), []byte("test\n"), 0644)
assert.NoError(err)
},
paths: []string{path.Join(tmpdir, "a", "b", "c"), "c/d"},
@@ -158,7 +157,7 @@ func TestFirstValidExecutable(t *testing.T) {
err := os.MkdirAll(path.Join(tmpdir, "d", "e"), 0755)
assert.NoError(err)
// create an executable file
err = ioutil.WriteFile(path.Join(tmpdir, "d", "e", "f"), []byte("test\n"), 0755)
err = os.WriteFile(path.Join(tmpdir, "d", "e", "f"), []byte("test\n"), 0755)
assert.NoError(err)
},
paths: []string{path.Join(tmpdir, "d", "e", "f"), "c/d"},
@@ -171,7 +170,7 @@ func TestFirstValidExecutable(t *testing.T) {
err := os.MkdirAll(path.Join(tmpdir, "g", "h"), 0755)
assert.NoError(err)
// create an executable file
err = ioutil.WriteFile(path.Join(tmpdir, "g", "h", "i"), []byte("test\n"), 0755)
err = os.WriteFile(path.Join(tmpdir, "g", "h", "i"), []byte("test\n"), 0755)
assert.NoError(err)
},
paths: []string{"c/d", path.Join(tmpdir, "g", "h", "i")},

View File

@@ -0,0 +1,62 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package annotations
// ContainerType values
// Following OCI annotations are used by katacontainers now.
// We'll switch to standard secure pod API after it is defined in CRI.
const (
// ContainerTypeSandbox represents a pod sandbox container
ContainerTypeSandbox = "sandbox"
// ContainerTypeContainer represents a container running within a pod
ContainerTypeContainer = "container"
// ContainerType is the container type (sandbox or container) annotation
ContainerType = "io.kubernetes.cri.container-type"
// SandboxID is the sandbox ID annotation
SandboxID = "io.kubernetes.cri.sandbox-id"
// SandboxLogDir is the pod log directory annotation.
// If the sandbox needs to generate any log, it will put it into this directory.
// Kubelet will be responsible for:
// 1) Monitoring the disk usage of the log, and including it as part of the pod
// ephemeral storage usage.
// 2) Cleaning up the logs when the pod is deleted.
// NOTE: Kubelet is not responsible for rotating the logs.
SandboxLogDir = "io.kubernetes.cri.sandbox-log-directory"
// UntrustedWorkload is the sandbox annotation for untrusted workload. Untrusted
// workload can only run on dedicated runtime for untrusted workload.
UntrustedWorkload = "io.kubernetes.cri.untrusted-workload"
// SandboxNamespace is the name of the namespace of the sandbox (pod)
SandboxNamespace = "io.kubernetes.cri.sandbox-namespace"
// SandboxName is the name of the sandbox (pod)
SandboxName = "io.kubernetes.cri.sandbox-name"
// ContainerName is the name of the container in the pod
ContainerName = "io.kubernetes.cri.container-name"
// ImageName is the name of the image used to create the container
ImageName = "io.kubernetes.cri.image-name"
// PodAnnotations are the annotations of the pod
PodAnnotations = "io.kubernetes.cri.pod-annotations"
)

View File

@@ -1,38 +0,0 @@
/*
Copyright 2018 The Containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package annotations
// ContainerType values
// Following OCI annotations are used by katacontainers now.
// We'll switch to standard secure pod API after it is defined in CRI.
const (
// ContainerTypeSandbox represents a pod sandbox container
ContainerTypeSandbox = "sandbox"
// ContainerTypeContainer represents a container running within a pod
ContainerTypeContainer = "container"
// ContainerType is the container type (sandbox or container) annotation
ContainerType = "io.kubernetes.cri.container-type"
// SandboxID is the sandbox ID annotation
SandboxID = "io.kubernetes.cri.sandbox-id"
// UntrustedWorkload is the sandbox annotation for untrusted workload. Untrusted
// workload can only run on dedicated runtime for untrusted workload.
UntrustedWorkload = "io.kubernetes.cri.untrusted-workload"
)

View File

@@ -70,6 +70,7 @@ github.com/containerd/containerd/identifiers
github.com/containerd/containerd/log
github.com/containerd/containerd/mount
github.com/containerd/containerd/namespaces
github.com/containerd/containerd/pkg/cri/annotations
github.com/containerd/containerd/pkg/dialer
github.com/containerd/containerd/pkg/runtimeoptions/v1
github.com/containerd/containerd/pkg/ttrpcutil
@@ -91,7 +92,6 @@ github.com/containerd/containerd/api/types
github.com/containerd/containerd/api/types/task
# github.com/containerd/cri-containerd v1.11.1-0.20190125013620-4dd6735020f5
## explicit
github.com/containerd/cri-containerd/pkg/annotations
github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1
# github.com/containerd/fifo v1.0.0
## explicit

View File

@@ -7,7 +7,6 @@ package virtcontainers
import (
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
@@ -127,7 +126,7 @@ func TestAcrnArchBaseAppendImage(t *testing.T) {
assert := assert.New(t)
acrnArchBase := newAcrnArchBase()
image, err := ioutil.TempFile("", "img")
image, err := os.CreateTemp("", "img")
assert.NoError(err)
defer os.Remove(image.Name())
err = image.Close()

View File

@@ -77,7 +77,7 @@ func newBasicTestCmd() types.Cmd {
func newTestSandboxConfigNoop() SandboxConfig {
bundlePath := filepath.Join(testDir, testBundle)
containerAnnotations[annotations.BundlePathKey] = bundlePath
// containerAnnotations["com.github.containers.virtcontainers.pkg.oci.container_type"] = "pod_sandbox"
containerAnnotations[annotations.ContainerTypeKey] = "pod_sandbox"
emptySpec := newEmptySpec()

View File

@@ -7,7 +7,6 @@ package virtcontainers
import (
"context"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -131,7 +130,7 @@ func TestUnmountHostMountsRemoveBindHostPath(t *testing.T) {
}
createFakeMountDir := func(t *testing.T, dir, prefix string) string {
name, err := ioutil.TempDir(dir, "test-mnt-"+prefix+"-")
name, err := os.MkdirTemp(dir, "test-mnt-"+prefix+"-")
if err != nil {
t.Fatal(err)
}
@@ -139,7 +138,7 @@ func TestUnmountHostMountsRemoveBindHostPath(t *testing.T) {
}
createFakeMountFile := func(t *testing.T, dir, prefix string) string {
f, err := ioutil.TempFile(dir, "test-mnt-"+prefix+"-")
f, err := os.CreateTemp(dir, "test-mnt-"+prefix+"-")
if err != nil {
t.Fatal(err)
}
@@ -245,7 +244,7 @@ func testSetupFakeRootfs(t *testing.T) (testRawFile, loopDev, mntDir string, err
t.Skip(testDisabledAsNonRoot)
}
tmpDir, err := ioutil.TempDir("", "")
tmpDir, err := os.MkdirTemp("", "")
assert.NoError(err)
testRawFile = filepath.Join(tmpDir, "raw.img")
@@ -556,13 +555,13 @@ func TestMountSharedDirMounts(t *testing.T) {
assert := assert.New(t)
testMountPath, err := ioutil.TempDir("", "sandbox-test")
testMountPath, err := os.MkdirTemp("", "sandbox-test")
assert.NoError(err)
defer os.RemoveAll(testMountPath)
// create a new shared directory for our test:
kataHostSharedDirSaved := kataHostSharedDir
testHostDir, err := ioutil.TempDir("", "kata-Cleanup")
testHostDir, err := os.MkdirTemp("", "kata-Cleanup")
assert.NoError(err)
kataHostSharedDir = func() string {
return testHostDir

View File

@@ -8,7 +8,6 @@ package config
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -353,7 +352,7 @@ func GetHostPath(devInfo DeviceInfo, vhostUserStoreEnabled bool, vhostUserStoreP
// getBackingFile is used to fetch the backing file for the device.
func getBackingFile(devInfo DeviceInfo) (string, error) {
backingFilePath := filepath.Join(getSysDevPath(devInfo), "loop", "backing_file")
data, err := ioutil.ReadFile(backingFilePath)
data, err := os.ReadFile(backingFilePath)
if err != nil {
return "", err
}
@@ -409,7 +408,7 @@ func GetVhostUserNodeStat(devNodePath string, devNodeStat *unix.Stat_t) (err err
// Filter out name of the device node whose device type is Major:Minor from directory
func getVhostUserDevName(dirname string, majorNum, minorNum uint32) (string, error) {
files, err := ioutil.ReadDir(dirname)
files, err := os.ReadDir(dirname)
if err != nil {
return "", err
}

View File

@@ -7,7 +7,6 @@ package config
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
@@ -18,7 +17,7 @@ import (
func TestGetBackingFile(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "backing")
dir, err := os.MkdirTemp("", "backing")
assert.NoError(err)
defer os.RemoveAll(dir)
@@ -39,7 +38,7 @@ func TestGetBackingFile(t *testing.T) {
backingFile := "/fake-img"
err = ioutil.WriteFile(filepath.Join(loopDir, "backing_file"), []byte(backingFile), os.FileMode(0755))
err = os.WriteFile(filepath.Join(loopDir, "backing_file"), []byte(backingFile), os.FileMode(0755))
assert.NoError(err)
path, err = getBackingFile(info)

View File

@@ -6,7 +6,6 @@
package config
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
@@ -33,7 +32,7 @@ func TestHasPFNSignature(t *testing.T) {
b := hasPFNSignature("/abc/xyz/123/sw")
assert.False(b)
f, err := ioutil.TempFile("", "pfn")
f, err := os.CreateTemp("", "pfn")
assert.NoError(err)
f.Close()
defer os.Remove(f.Name())

View File

@@ -8,7 +8,6 @@ package drivers
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@@ -85,7 +84,7 @@ func readPCIProperty(propertyPath string) (string, error) {
buf []byte
err error
)
if buf, err = ioutil.ReadFile(propertyPath); err != nil {
if buf, err = os.ReadFile(propertyPath); err != nil {
return "", fmt.Errorf("failed to read pci sysfs %v, error:%v", propertyPath, err)
}
return strings.Split(string(buf), "\n")[0], nil

View File

@@ -9,7 +9,6 @@ package drivers
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -75,7 +74,7 @@ func (device *VFIODevice) Attach(ctx context.Context, devReceiver api.DeviceRece
vfioGroup := filepath.Base(device.DeviceInfo.HostPath)
iommuDevicesPath := filepath.Join(config.SysIOMMUPath, vfioGroup, "devices")
deviceFiles, err := ioutil.ReadDir(iommuDevicesPath)
deviceFiles, err := os.ReadDir(iommuDevicesPath)
if err != nil {
return err
}

View File

@@ -9,7 +9,6 @@ package manager
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -39,7 +38,7 @@ func TestNewDevice(t *testing.T) {
major := int64(252)
minor := int64(3)
tmpDir, err := ioutil.TempDir("", "")
tmpDir, err := os.MkdirTemp("", "")
assert.Nil(t, err)
config.SysDevPrefix = tmpDir
@@ -75,14 +74,14 @@ func TestNewDevice(t *testing.T) {
// Should return error for bad data in uevent file
content := []byte("nonkeyvaluedata")
err = ioutil.WriteFile(ueventPath, content, fileMode0640)
err = os.WriteFile(ueventPath, content, fileMode0640)
assert.Nil(t, err)
_, err = dm.NewDevice(deviceInfo)
assert.NotNil(t, err)
content = []byte("MAJOR=252\nMINOR=3\nDEVNAME=vfio/2")
err = ioutil.WriteFile(ueventPath, content, fileMode0640)
err = os.WriteFile(ueventPath, content, fileMode0640)
assert.Nil(t, err)
device, err := dm.NewDevice(deviceInfo)
@@ -104,7 +103,7 @@ func TestAttachVFIODevice(t *testing.T) {
blockDriver: VirtioBlock,
devices: make(map[string]api.Device),
}
tmpDir, err := ioutil.TempDir("", "")
tmpDir, err := os.MkdirTemp("", "")
assert.Nil(t, err)
defer os.RemoveAll(tmpDir)
@@ -225,7 +224,7 @@ func TestAttachVhostUserBlkDevice(t *testing.T) {
rootEnabled = false
}
tmpDir, err := ioutil.TempDir("", "")
tmpDir, err := os.MkdirTemp("", "")
dm := &deviceManager{
blockDriver: VirtioBlock,
devices: make(map[string]api.Device),

View File

@@ -8,7 +8,7 @@ package manager
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
@@ -49,7 +49,7 @@ func IsVFIOLargeBarSpaceDevice(hostPath string) (bool, error) {
}
iommuDevicesPath := filepath.Join(config.SysIOMMUPath, filepath.Base(hostPath), "devices")
deviceFiles, err := ioutil.ReadDir(iommuDevicesPath)
deviceFiles, err := os.ReadDir(iommuDevicesPath)
if err != nil {
return false, err
}
@@ -89,7 +89,7 @@ func IsVFIOLargeBarSpaceDevice(hostPath string) (bool, error) {
}
func isLargeBarSpace(resourcePath string) (bool, error) {
buf, err := ioutil.ReadFile(resourcePath)
buf, err := os.ReadFile(resourcePath)
if err != nil {
return false, fmt.Errorf("failed to read sysfs resource: %v", err)
}

View File

@@ -7,7 +7,6 @@
package manager
import (
"io/ioutil"
"os"
"testing"
@@ -114,7 +113,7 @@ func TestIsLargeBarSpace(t *testing.T) {
assert.Error(err)
assert.False(bs)
f, err := ioutil.TempFile("", "pci")
f, err := os.CreateTemp("", "pci")
assert.NoError(err)
defer f.Close()
defer os.RemoveAll(f.Name())

View File

@@ -6,7 +6,6 @@
package virtcontainers
import (
"io/ioutil"
"net"
"os"
"reflect"
@@ -87,7 +86,7 @@ func TestIncorrectEndpointTypeString(t *testing.T) {
func TestSaveLoadIfPair(t *testing.T) {
macAddr := net.HardwareAddr{0x02, 0x00, 0xCA, 0xFE, 0x00, 0x04}
tmpfile, err := ioutil.TempFile("", "vc-Save-Load-net-")
tmpfile, err := os.CreateTemp("", "vc-Save-Load-net-")
assert.Nil(t, err)
defer os.Remove(tmpfile.Name())

View File

@@ -10,7 +10,6 @@ import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
@@ -778,7 +777,7 @@ func (fc *firecracker) StartVM(ctx context.Context, timeout int) error {
return errJSON
}
if err := ioutil.WriteFile(fc.fcConfigPath, data, 0640); err != nil {
if err := os.WriteFile(fc.fcConfigPath, data, 0640); err != nil {
return err
}

View File

@@ -8,7 +8,7 @@ package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"io"
"os"
"strconv"
"time"
@@ -55,7 +55,7 @@ func main() {
os.Exit(1)
}
stateBuf, err := ioutil.ReadAll(os.Stdin)
stateBuf, err := io.ReadAll(os.Stdin)
if err != nil {
fmt.Fprintf(f, "Could not read on stdin: %s\n", err)
os.Exit(1)

View File

@@ -6,7 +6,6 @@
package virtcontainers
import "os"
import "io/ioutil"
// Implementation of this function is architecture specific
func availableGuestProtection() (guestProtection, error) {
@@ -21,7 +20,7 @@ func availableGuestProtection() (guestProtection, error) {
}
// SEV is supported and enabled when the kvm module `sev` parameter is set to `1`
if _, err := os.Stat(sevKvmParameterPath); err == nil {
if c, err := ioutil.ReadFile(sevKvmParameterPath); err == nil && len(c) > 0 && c[0] == '1' {
if c, err := os.ReadFile(sevKvmParameterPath); err == nil && len(c) > 0 && c[0] == '1' {
return sevProtection, nil
}
}

View File

@@ -6,7 +6,6 @@
package virtcontainers
import (
"io/ioutil"
"os"
"testing"
@@ -70,7 +69,7 @@ func TestRunningOnVMM(t *testing.T) {
}
func TestRunningOnVMMNotExistingCPUInfoPathFailure(t *testing.T) {
f, err := ioutil.TempFile("", "cpuinfo")
f, err := os.CreateTemp("", "cpuinfo")
assert.NoError(t, err)
filePath := f.Name()

View File

@@ -6,7 +6,6 @@
package virtcontainers
import (
"io/ioutil"
"os"
"testing"
@@ -17,7 +16,7 @@ func TestRunningOnVMM(t *testing.T) {
assert := assert.New(t)
expectedOutput := false
f, err := ioutil.TempFile("", "cpuinfo")
f, err := os.CreateTemp("", "cpuinfo")
assert.NoError(err)
defer os.Remove(f.Name())
defer f.Close()

View File

@@ -7,7 +7,6 @@ package virtcontainers
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
@@ -391,7 +390,7 @@ func TestGetHostMemorySizeKb(t *testing.T) {
},
}
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(dir)
@@ -400,7 +399,7 @@ func TestGetHostMemorySizeKb(t *testing.T) {
assert.Error(err)
for _, d := range data {
err = ioutil.WriteFile(file, []byte(d.contents), os.FileMode(0640))
err = os.WriteFile(file, []byte(d.contents), os.FileMode(0640))
assert.NoError(err)
defer os.Remove(file)
@@ -415,7 +414,7 @@ func TestGetHostMemorySizeKb(t *testing.T) {
func TestCheckCmdline(t *testing.T) {
assert := assert.New(t)
cmdlineFp, err := ioutil.TempFile("", "")
cmdlineFp, err := os.CreateTemp("", "")
assert.NoError(err)
_, err = cmdlineFp.WriteString("quiet root=/dev/sda2")
assert.NoError(err)
@@ -438,7 +437,7 @@ type testNestedVMMData struct {
func genericTestRunningOnVMM(t *testing.T, data []testNestedVMMData) {
assert := assert.New(t)
for _, d := range data {
f, err := ioutil.TempFile("", "cpuinfo")
f, err := os.CreateTemp("", "cpuinfo")
assert.NoError(err)
defer os.Remove(f.Name())
defer f.Close()

View File

@@ -9,7 +9,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -750,7 +749,7 @@ func (k *kataAgent) getDNS(sandbox *Sandbox) ([]string, error) {
for _, m := range ociMounts {
if m.Destination == GuestDNSFile {
content, err := ioutil.ReadFile(m.Source)
content, err := os.ReadFile(m.Source)
if err != nil {
return nil, fmt.Errorf("Could not read file %s: %s", m.Source, err)
}
@@ -2137,7 +2136,7 @@ func (k *kataAgent) copyFile(ctx context.Context, src, dst string) error {
return fmt.Errorf("Could not get file %s information: %v", src, err)
}
b, err := ioutil.ReadFile(src)
b, err := os.ReadFile(src)
if err != nil {
return fmt.Errorf("Could not read file %s: %v", src, err)
}

View File

@@ -9,7 +9,6 @@ import (
"bufio"
"context"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -740,7 +739,7 @@ func TestHandlePidNamespace(t *testing.T) {
func TestAgentConfigure(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "kata-agent-test")
dir, err := os.MkdirTemp("", "kata-agent-test")
assert.Nil(err)
defer os.RemoveAll(dir)
@@ -856,7 +855,7 @@ func TestAgentCreateContainer(t *testing.T) {
},
}
dir, err := ioutil.TempDir("", "kata-agent-test")
dir, err := os.MkdirTemp("", "kata-agent-test")
assert.Nil(err)
defer os.RemoveAll(dir)
@@ -937,7 +936,7 @@ func TestKataCopyFile(t *testing.T) {
err = k.copyFile(context.Background(), "/abc/xyz/123", "/tmp")
assert.Error(err)
src, err := ioutil.TempFile("", "src")
src, err := os.CreateTemp("", "src")
assert.NoError(err)
defer os.Remove(src.Name())
@@ -946,7 +945,7 @@ func TestKataCopyFile(t *testing.T) {
assert.NoError(err)
assert.NoError(src.Close())
dst, err := ioutil.TempFile("", "dst")
dst, err := os.CreateTemp("", "dst")
assert.NoError(err)
assert.NoError(dst.Close())
defer os.Remove(dst.Name())
@@ -966,7 +965,7 @@ func TestKataCleanupSandbox(t *testing.T) {
kataHostSharedDirSaved := kataHostSharedDir
kataHostSharedDir = func() string {
td, _ := ioutil.TempDir("", "kata-Cleanup")
td, _ := os.MkdirTemp("", "kata-Cleanup")
return td
}
defer func() {
@@ -1117,13 +1116,13 @@ func TestSandboxBindMount(t *testing.T) {
assert := assert.New(t)
// create temporary files to mount:
testMountPath, err := ioutil.TempDir("", "sandbox-test")
testMountPath, err := os.MkdirTemp("", "sandbox-test")
assert.NoError(err)
defer os.RemoveAll(testMountPath)
// create a new shared directory for our test:
kataHostSharedDirSaved := kataHostSharedDir
testHostDir, err := ioutil.TempDir("", "kata-Cleanup")
testHostDir, err := os.MkdirTemp("", "kata-Cleanup")
assert.NoError(err)
kataHostSharedDir = func() string {
return testHostDir

View File

@@ -9,7 +9,6 @@ import (
"context"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@@ -490,7 +489,7 @@ func countFiles(path string, limit int) (numFiles int, err error) {
return 1, nil
}
files, err := ioutil.ReadDir(path)
files, err := os.ReadDir(path)
if err != nil {
return 0, err
}

View File

@@ -9,7 +9,6 @@ import (
"bytes"
"context"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -241,7 +240,7 @@ func TestIsEphemeralStorage(t *testing.T) {
t.Skip(ktu.TestDisabledNeedRoot)
}
dir, err := ioutil.TempDir(testDir, "foo")
dir, err := os.MkdirTemp(testDir, "foo")
assert.NoError(err)
defer os.RemoveAll(dir)
@@ -319,7 +318,7 @@ func TestIsWatchable(t *testing.T) {
result = isWatchableMount(path)
assert.False(result)
testPath, err := ioutil.TempDir("", "")
testPath, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(testPath)

View File

@@ -9,12 +9,13 @@ package fs
import (
"encoding/json"
"fmt"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
"io/ioutil"
"io"
"os"
"path/filepath"
"syscall"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api"
"github.com/sirupsen/logrus"
)
@@ -142,7 +143,7 @@ func (fs *FS) ToDisk(ss persistapi.SandboxState, cs map[string]persistapi.Contai
}
// Walk sandbox dir and find container.
files, err := ioutil.ReadDir(sandboxDir)
files, err := os.ReadDir(sandboxDir)
if err != nil {
return err
}
@@ -190,7 +191,7 @@ func (fs *FS) FromDisk(sid string) (persistapi.SandboxState, map[string]persista
}
// walk sandbox dir and find container
files, err := ioutil.ReadDir(sandboxDir)
files, err := os.ReadDir(sandboxDir)
if err != nil {
return ss, nil, err
}
@@ -325,7 +326,7 @@ func (fs *FS) GlobalRead(relativePath string) ([]byte, error) {
}
defer f.Close()
data, err := ioutil.ReadAll(f)
data, err := io.ReadAll(f)
if err != nil {
fs.Logger().WithError(err).WithField("file", path).Error("failed to read file")
return nil, err

View File

@@ -8,7 +8,6 @@ package virtcontainers
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@@ -185,7 +184,7 @@ func createPhysicalEndpoint(netInfo NetworkInfo) (*PhysicalEndpoint, error) {
// Get vendor and device id from pci space (sys/bus/pci/devices/$bdf)
ifaceDevicePath := filepath.Join(sysPCIDevicesPath, bdf, "device")
contents, err := ioutil.ReadFile(ifaceDevicePath)
contents, err := os.ReadFile(ifaceDevicePath)
if err != nil {
return nil, err
}
@@ -194,7 +193,7 @@ func createPhysicalEndpoint(netInfo NetworkInfo) (*PhysicalEndpoint, error) {
// Vendor id
ifaceVendorPath := filepath.Join(sysPCIDevicesPath, bdf, "vendor")
contents, err = ioutil.ReadFile(ifaceVendorPath)
contents, err = os.ReadFile(ifaceVendorPath)
if err != nil {
return nil, err
}

View File

@@ -8,7 +8,7 @@ package grpc
import (
"encoding/json"
"io/ioutil"
"os"
"reflect"
"testing"
@@ -82,7 +82,7 @@ func TestOCItoGRPC(t *testing.T) {
assert := assert.New(t)
var ociSpec specs.Spec
configJSONBytes, err := ioutil.ReadFile(ociConfigFile)
configJSONBytes, err := os.ReadFile(ociConfigFile)
assert.NoError(err, "Could not open OCI config file")
err = json.Unmarshal(configJSONBytes, &ociSpec)
@@ -97,7 +97,7 @@ func TestProcessOCItoGRPC(t *testing.T) {
assert := assert.New(t)
var ociSpec specs.Spec
configJSONBytes, err := ioutil.ReadFile(ociConfigFile)
configJSONBytes, err := os.ReadFile(ociConfigFile)
assert.NoError(err, "Could not open OCI config file")
err = json.Unmarshal(configJSONBytes, &ociSpec)
@@ -113,7 +113,7 @@ func TestProcessGRPCtoOCI(t *testing.T) {
var ociSpec specs.Spec
configJSONBytes, err := ioutil.ReadFile(ociConfigFile)
configJSONBytes, err := os.ReadFile(ociConfigFile)
assert.NoError(err, "Could not open OCI config file")
err = json.Unmarshal(configJSONBytes, &ociSpec)

View File

@@ -6,7 +6,6 @@
package cgroups
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
@@ -110,7 +109,7 @@ func TestValidCgroupPath(t *testing.T) {
func TestDeviceToCgroupDeviceRule(t *testing.T) {
assert := assert.New(t)
f, err := ioutil.TempFile("", "device")
f, err := os.CreateTemp("", "device")
assert.NoError(err)
f.Close()

View File

@@ -8,7 +8,7 @@ package compatoci
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
specs "github.com/opencontainers/runtime-spec/specs-go"
@@ -126,7 +126,7 @@ func ParseConfigJSON(bundlePath string) (specs.Spec, error) {
configPath := getConfigPath(bundlePath)
ociLog.Debugf("converting %s", configPath)
configByte, err := ioutil.ReadFile(configPath)
configByte, err := os.ReadFile(configPath)
if err != nil {
return specs.Spec{}, err
}

View File

@@ -8,9 +8,9 @@ package mock
import (
"context"
"fmt"
"io/ioutil"
"net"
"net/url"
"os"
"github.com/containerd/ttrpc"
gpb "github.com/gogo/protobuf/types"
@@ -21,7 +21,7 @@ import (
var testKataMockHybridVSockURLTempl = "mock://%s/kata-mock-hybrid-vsock.sock"
func GenerateKataMockHybridVSock() (string, error) {
dir, err := ioutil.TempDir("", "kata-mock-hybrid-vsock-test")
dir, err := os.MkdirTemp("", "kata-mock-hybrid-vsock-test")
if err != nil {
return "", err
}

View File

@@ -11,7 +11,6 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"math"
"os"
"os/user"
@@ -834,7 +833,7 @@ func (q *qemu) StartVM(ctx context.Context, timeout int) error {
strErr, err = govmmQemu.LaunchQemu(q.qemuConfig, newQMPLogger())
if err != nil {
if q.config.Debug && q.qemuConfig.LogFile != "" {
b, err := ioutil.ReadFile(q.qemuConfig.LogFile)
b, err := os.ReadFile(q.qemuConfig.LogFile)
if err == nil {
strErr += string(b)
}
@@ -1152,7 +1151,7 @@ func (q *qemu) dumpSandboxMetaInfo(dumpSavePath string) {
// Save hypervisor meta information
fileName := filepath.Join(dumpSavePath, "hypervisor.conf")
data, _ := json.MarshalIndent(q.config, "", " ")
if err := ioutil.WriteFile(fileName, data, defaultFilePerms); err != nil {
if err := os.WriteFile(fileName, data, defaultFilePerms); err != nil {
q.Logger().WithError(err).WithField("hypervisor.conf", data).Error("write to hypervisor.conf file failed")
}
@@ -1163,7 +1162,7 @@ func (q *qemu) dumpSandboxMetaInfo(dumpSavePath string) {
}
fileName = filepath.Join(dumpSavePath, "hypervisor.version")
if err := ioutil.WriteFile(fileName, []byte(hyperVisorVersion), defaultFilePerms); err != nil {
if err := os.WriteFile(fileName, []byte(hyperVisorVersion), defaultFilePerms); err != nil {
q.Logger().WithError(err).WithField("hypervisor.version", data).Error("write to hypervisor.version file failed")
}
}
@@ -2384,7 +2383,7 @@ func (q *qemu) Cleanup(ctx context.Context) error {
}
func (q *qemu) GetPids() []int {
data, err := ioutil.ReadFile(q.qemuConfig.PidFile)
data, err := os.ReadFile(q.qemuConfig.PidFile)
if err != nil {
q.Logger().WithError(err).Error("Could not read qemu pid file")
return []int{0}

View File

@@ -8,7 +8,6 @@ package virtcontainers
import (
"context"
"fmt"
"io/ioutil"
"os"
"testing"
@@ -111,7 +110,7 @@ func TestQemuAmd64MemoryTopology(t *testing.T) {
func TestQemuAmd64AppendImage(t *testing.T) {
assert := assert.New(t)
f, err := ioutil.TempFile("", "img")
f, err := os.CreateTemp("", "img")
assert.NoError(err)
defer func() { _ = f.Close() }()
defer func() { _ = os.Remove(f.Name()) }()

View File

@@ -8,7 +8,6 @@ package virtcontainers
import (
"context"
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
@@ -264,7 +263,7 @@ func TestQemuArchBaseAppendImage(t *testing.T) {
assert := assert.New(t)
qemuArchBase := newQemuArchBase()
image, err := ioutil.TempFile("", "img")
image, err := os.CreateTemp("", "img")
assert.NoError(err)
defer os.Remove(image.Name())
err = image.Close()

View File

@@ -8,7 +8,6 @@ package virtcontainers
import (
"context"
"fmt"
"io/ioutil"
"os"
"testing"
@@ -97,7 +96,7 @@ func TestQemuArm64AppendImage(t *testing.T) {
var devices []govmmQemu.Device
assert := assert.New(t)
f, err := ioutil.TempFile("", "img")
f, err := os.CreateTemp("", "img")
assert.NoError(err)
defer func() { _ = f.Close() }()
defer func() { _ = os.Remove(f.Name()) }()
@@ -131,7 +130,7 @@ func TestQemuArm64AppendNvdimmImage(t *testing.T) {
var devices []govmmQemu.Device
assert := assert.New(t)
f, err := ioutil.TempFile("", "img")
f, err := os.CreateTemp("", "img")
assert.NoError(err)
defer func() { _ = f.Close() }()
defer func() { _ = os.Remove(f.Name()) }()

View File

@@ -8,7 +8,6 @@ package virtcontainers
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
@@ -299,7 +298,7 @@ func TestQemuAddDeviceSerialPortDev(t *testing.T) {
func TestQemuAddDeviceKataVSOCK(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir("", "")
dir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(dir)
@@ -363,7 +362,7 @@ func TestQemuCapabilities(t *testing.T) {
func TestQemuQemuPath(t *testing.T) {
assert := assert.New(t)
f, err := ioutil.TempFile("", "qemu")
f, err := os.CreateTemp("", "qemu")
assert.NoError(err)
defer func() { _ = f.Close() }()
defer func() { _ = os.Remove(f.Name()) }()
@@ -588,7 +587,7 @@ func TestQemuGetpids(t *testing.T) {
q = &qemu{
config: qemuConfig,
}
f, err := ioutil.TempFile("", "qemu-test-")
f, err := os.CreateTemp("", "qemu-test-")
assert.Nil(err)
tmpfile := f.Name()
f.Close()
@@ -599,7 +598,7 @@ func TestQemuGetpids(t *testing.T) {
assert.True(len(pids) == 1)
assert.True(pids[0] == 0)
err = ioutil.WriteFile(tmpfile, []byte("100"), 0)
err = os.WriteFile(tmpfile, []byte("100"), 0)
assert.Nil(err)
pids = q.GetPids()
assert.True(len(pids) == 1)

View File

@@ -8,7 +8,6 @@ package virtcontainers
import (
"context"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -255,7 +254,7 @@ func writeContainerConfig() (string, error) {
}
}`
configDir, err := ioutil.TempDir("", "vc-tmp-")
configDir, err := os.MkdirTemp("", "vc-tmp-")
if err != nil {
return "", err
}
@@ -266,7 +265,7 @@ func writeContainerConfig() (string, error) {
}
configFilePath := filepath.Join(configDir, "config.json")
err = ioutil.WriteFile(configFilePath, []byte(basicSpec), 0644)
err = os.WriteFile(configFilePath, []byte(basicSpec), 0644)
if err != nil {
return "", err
}
@@ -512,7 +511,7 @@ func TestContainerStateSetFstype(t *testing.T) {
}
func TestSandboxAttachDevicesVFIO(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "")
tmpDir, err := os.MkdirTemp("", "")
assert.Nil(t, err)
os.RemoveAll(tmpDir)
@@ -582,7 +581,7 @@ func TestSandboxAttachDevicesVhostUserBlk(t *testing.T) {
rootEnabled = false
}
tmpDir, err := ioutil.TempDir("", "")
tmpDir, err := os.MkdirTemp("", "")
assert.Nil(t, err)
os.RemoveAll(tmpDir)
dm := manager.NewDeviceManager(manager.VirtioSCSI, true, tmpDir, nil)
@@ -683,7 +682,7 @@ func TestSandboxCreateAssets(t *testing.T) {
annotations map[string]string
}
tmpfile, err := ioutil.TempFile("", "virtcontainers-test-")
tmpfile, err := os.CreateTemp("", "virtcontainers-test-")
assert.Nil(err)
filename := tmpfile.Name()

View File

@@ -10,13 +10,30 @@ type ContainerType string
// List different types of containers
const (
PodContainer ContainerType = "pod_container"
PodSandbox ContainerType = "pod_sandbox"
// PodContainer identifies a container that should be associated with an existing pod
PodContainer ContainerType = "pod_container"
// PodSandbox identifies an infra container that will be used to create the pod
PodSandbox ContainerType = "pod_sandbox"
// SingleContainer is utilized to describe a container that didn't have a container/sandbox
// annotation applied. This is expected when dealing with non-pod container (ie, running
// from ctr, podman, etc).
SingleContainer ContainerType = "single_container"
// UnknownContainerType specifies a container that provides container type annotation, but
// it is unknown.
UnknownContainerType ContainerType = "unknown_container_type"
)
// IsSandbox determines if the container type can be considered as a sandbox.
// We can consider a sandbox in case we have a PodSandbox or a RegularContainer.
// We can consider a sandbox in case we have a PodSandbox or a "regular" container
func (cType ContainerType) IsSandbox() bool {
return cType == PodSandbox
return cType == PodSandbox || cType == SingleContainer
}
func (t ContainerType) IsCriSandbox() bool {
return t == PodSandbox
}
// "Regular" Container
func (t ContainerType) IsSingleContainer() bool {
return t == SingleContainer
}

View File

@@ -9,7 +9,7 @@ import (
"crypto/sha512"
"encoding/hex"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
@@ -132,7 +132,7 @@ func (a *Asset) Hash(hashType string) (string, error) {
var hash string
// We read the actual asset content
bytes, err := ioutil.ReadFile(a.path)
bytes, err := os.ReadFile(a.path)
if err != nil {
return "", err
}

View File

@@ -7,7 +7,6 @@ package types
import (
"fmt"
"io/ioutil"
"os"
"testing"
@@ -22,7 +21,7 @@ var assetContentWrongHash = "92549f8d2018a95a294d28a65e795ed7d1a9d150009a28cea10
func TestAssetWrongHashType(t *testing.T) {
assert := assert.New(t)
tmpfile, err := ioutil.TempFile("", "virtcontainers-test-")
tmpfile, err := os.CreateTemp("", "virtcontainers-test-")
assert.Nil(err)
defer func() {
@@ -45,7 +44,7 @@ func TestAssetWrongHashType(t *testing.T) {
func TestAssetHash(t *testing.T) {
assert := assert.New(t)
tmpfile, err := ioutil.TempFile("", "virtcontainers-test-")
tmpfile, err := os.CreateTemp("", "virtcontainers-test-")
assert.Nil(err)
defer func() {
@@ -90,7 +89,7 @@ func testValid(t *testing.T, a *Asset, msg string) {
func TestAssetNew(t *testing.T) {
assert := assert.New(t)
tmpfile, err := ioutil.TempFile("", "virtcontainers-test-")
tmpfile, err := os.CreateTemp("", "virtcontainers-test-")
assert.Nil(err)
defer func() {

View File

@@ -6,7 +6,7 @@
package utils
import (
"io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -32,7 +32,7 @@ func NewProc(pid int) (*Proc, error) {
// We should try to upstream this but let's keep it until upstream supports it.
func (p *Proc) Children() ([]*Proc, error) {
parent := strconv.Itoa(p.PID)
infos, err := ioutil.ReadDir(filepath.Join(procfs.DefaultMountPoint, parent, taskPath))
infos, err := os.ReadDir(filepath.Join(procfs.DefaultMountPoint, parent, taskPath))
if err != nil {
return nil, errors.Wrapf(err, "Fail to read pid %v proc task dir", p.PID)
}

View File

@@ -7,7 +7,6 @@ package utils
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
@@ -27,12 +26,12 @@ func TestFileCopySuccessful(t *testing.T) {
assert := assert.New(t)
fileContent := "testContent"
srcFile, err := ioutil.TempFile("", "test_src_copy")
srcFile, err := os.CreateTemp("", "test_src_copy")
assert.NoError(err)
defer os.Remove(srcFile.Name())
defer srcFile.Close()
dstFile, err := ioutil.TempFile("", "test_dst_copy")
dstFile, err := os.CreateTemp("", "test_dst_copy")
assert.NoError(err)
defer os.Remove(dstFile.Name())
@@ -46,7 +45,7 @@ func TestFileCopySuccessful(t *testing.T) {
err = FileCopy(srcFile.Name(), dstPath)
assert.NoError(err)
dstContent, err := ioutil.ReadFile(dstPath)
dstContent, err := os.ReadFile(dstPath)
assert.NoError(err)
assert.Equal(string(dstContent), fileContent)
@@ -75,7 +74,7 @@ func TestFileCopyDestinationEmptyFailure(t *testing.T) {
func TestFileCopySourceNotExistFailure(t *testing.T) {
assert := assert.New(t)
srcFile, err := ioutil.TempFile("", "test_src_copy")
srcFile, err := os.CreateTemp("", "test_src_copy")
assert.NoError(err)
srcPath := srcFile.Name()
@@ -104,7 +103,7 @@ func TestRevereString(t *testing.T) {
func TestCleanupFds(t *testing.T) {
assert := assert.New(t)
tmpFile, err := ioutil.TempFile("", "testFds1")
tmpFile, err := os.CreateTemp("", "testFds1")
assert.NoError(err)
filename := tmpFile.Name()
defer os.Remove(filename)
@@ -129,7 +128,7 @@ func TestWriteToFile(t *testing.T) {
err := WriteToFile("/file-does-not-exist", []byte("test-data"))
assert.NotNil(err)
tmpFile, err := ioutil.TempFile("", "test_append_file")
tmpFile, err := os.CreateTemp("", "test_append_file")
assert.NoError(err)
filename := tmpFile.Name()
@@ -141,7 +140,7 @@ func TestWriteToFile(t *testing.T) {
err = WriteToFile(filename, testData)
assert.NoError(err)
data, err := ioutil.ReadFile(filename)
data, err := os.ReadFile(filename)
assert.NoError(err)
assert.True(reflect.DeepEqual(testData, data))
@@ -319,7 +318,7 @@ func TestSupportsVsocks(t *testing.T) {
VHostVSockDevicePath = "/abc/xyz/123"
assert.False(SupportsVsocks())
vHostVSockFile, err := ioutil.TempFile("", "vhost-vsock")
vHostVSockFile, err := os.CreateTemp("", "vhost-vsock")
assert.NoError(err)
defer os.Remove(vHostVSockFile.Name())
defer vHostVSockFile.Close()
@@ -459,10 +458,10 @@ func TestMkdirAllWithInheritedOwnerSuccessful(t *testing.T) {
t.Skip("Test disabled as requires root user")
}
assert := assert.New(t)
tmpDir1, err := ioutil.TempDir("", "test")
tmpDir1, err := os.MkdirTemp("", "test")
assert.NoError(err)
defer os.RemoveAll(tmpDir1)
tmpDir2, err := ioutil.TempDir("", "test")
tmpDir2, err := os.MkdirTemp("", "test")
assert.NoError(err)
defer os.RemoveAll(tmpDir2)
@@ -521,7 +520,7 @@ func TestChownToParent(t *testing.T) {
t.Skip("Test disabled as requires root user")
}
assert := assert.New(t)
rootDir, err := ioutil.TempDir("", "root")
rootDir, err := os.MkdirTemp("", "root")
assert.NoError(err)
defer os.RemoveAll(rootDir)
uid := 1234

View File

@@ -9,7 +9,6 @@ import (
"context"
"flag"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -121,7 +120,7 @@ func TestMain(m *testing.M) {
}
SetLogger(context.Background(), logger)
testDir, err = ioutil.TempDir("", "vc-tmp-")
testDir, err = os.MkdirTemp("", "vc-tmp-")
if err != nil {
panic(err)
}

View File

@@ -7,7 +7,6 @@ package virtcontainers
import (
"context"
"io/ioutil"
"os"
"path"
"strings"
@@ -30,11 +29,11 @@ func TestVirtiofsdStart(t *testing.T) {
ctx context.Context
}
sourcePath, err := ioutil.TempDir("", "")
sourcePath, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(sourcePath)
socketDir, err := ioutil.TempDir("", "")
socketDir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(socketDir)
@@ -104,11 +103,11 @@ func TestVirtiofsdArgs(t *testing.T) {
func TestValid(t *testing.T) {
assert := assert.New(t)
sourcePath, err := ioutil.TempDir("", "")
sourcePath, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(sourcePath)
socketDir, err := ioutil.TempDir("", "")
socketDir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(socketDir)

View File

@@ -7,7 +7,6 @@ package virtcontainers
import (
"context"
"io/ioutil"
"os"
"path/filepath"
"testing"
@@ -19,7 +18,7 @@ import (
func TestNewVM(t *testing.T) {
assert := assert.New(t)
testDir, err := ioutil.TempDir("", "vmfactory-tmp-")
testDir, err := os.MkdirTemp("", "vmfactory-tmp-")
assert.Nil(err)
defer os.RemoveAll(testDir)
@@ -66,12 +65,12 @@ func TestNewVM(t *testing.T) {
defer func() {
urandomDev = savedUrandomDev
}()
tmpdir, err := ioutil.TempDir("", "")
tmpdir, err := os.MkdirTemp("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
urandomDev = filepath.Join(tmpdir, "urandom")
data := make([]byte, 512)
err = ioutil.WriteFile(urandomDev, data, os.FileMode(0640))
err = os.WriteFile(urandomDev, data, os.FileMode(0640))
assert.NoError(err)
err = vm.ReseedRNG(context.Background())
@@ -99,7 +98,7 @@ func TestVMConfigValid(t *testing.T) {
err := config.Valid()
assert.Error(err)
testDir, err := ioutil.TempDir("", "vmfactory-tmp-")
testDir, err := os.MkdirTemp("", "vmfactory-tmp-")
assert.Nil(err)
defer os.RemoveAll(testDir)

1
src/tools/agent-ctl/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/vendor/

1414
src/tools/agent-ctl/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
# Copyright (c) 2020 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
[package]
name = "kata-agent-ctl"
version = "0.0.1"
authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>"]
edition = "2018"
[dependencies]
protocols = { path = "../../agent/protocols", features = ["with-serde"] }
rustjail = { path = "../../agent/rustjail" }
oci = { path = "../../agent/oci" }
clap = "2.33.0"
lazy_static = "1.4.0"
anyhow = "1.0.31"
hex = "0.4.2"
byteorder = "1.3.4"
# Note: this crate sets the slog 'max_*' features which allows the log level
# to be modified at runtime.
logging = { path = "../../libs/logging" }
slog = "2.5.2"
slog-scope = "4.3.0"
rand = "0.7.3"
protobuf = "2.14.0"
nix = "0.21.0"
libc = "0.2.69"
# XXX: Must be the same as the version used by the agent
ttrpc = { version = "0.5.0" }
# For parsing timeouts
humantime = "2.0.0"
# For Options (state passing)
serde = { version = "1.0.130", features = ["derive"] }
serde_json = "1.0.68"

View File

@@ -0,0 +1,36 @@
# Copyright (c) 2020 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
include ../../../utils.mk
default: build
build: logging-crate-tests
@RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo build --target $(TRIPLE) --$(BUILD_TYPE)
logging-crate-tests:
make -C $(CWD)/../../libs/logging
clean:
cargo clean
vendor:
cargo vendor
test:
install:
@RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo install --target $(TRIPLE) --path .
check:
.PHONY: \
build \
check \
clean \
install \
logging-crate-tests \
test \
vendor

View File

@@ -0,0 +1,235 @@
# Agent Control tool
## Overview
The Kata Containers agent control tool (`kata-agent-ctl`) is a low-level test
tool. It allows basic interaction with the Kata Containers agent,
`kata-agent`, that runs inside the virtual machine.
Unlike the Kata Runtime, which only ever makes sequences of correctly ordered
and valid agent API calls, this tool allows users to make arbitrary agent API
calls and to control their parameters.
## Audience and environment
> **Warning:**
>
> This tool is for *advanced* users familiar with the low-level agent API calls.
> Further, it is designed to be run on test and development systems **only**: since
> the tool can make arbitrary API calls, it is possible to easily confuse
> irrevocably other parts of the system or even kill a running container or
> sandbox.
## Full details
For a usage statement, run:
```sh
$ cargo run -- --help
```
To see some examples, run:
```sh
$ cargo run -- examples
```
## Code summary
The table below summarises where to look to learn more about both this tool,
the agent protocol and the client and server implementations.
| Description | File | Example RPC or function | Example summary |
|-|-|-|-|
| Protocol buffers definition of the Kata Containers Agent API protocol | [`agent.proto`](../../agent/protocols/protos/agent.proto) | `CreateContainer` | API to create a Kata container. |
| Agent Control (client) API calls | [`src/client.rs`](src/client.rs) | `agent_cmd_container_create()` | Agent Control tool function that calls the `CreateContainer` API. |
| Agent (server) API implementations | [`rpc.rs`](../../agent/src/rpc.rs) | `create_container()` | Server function that implements the `CreateContainers` API. |
## Run the tool
### Prerequisites
It is necessary to create an OCI bundle to use the tool. The simplest method
is:
```sh
$ bundle_dir="bundle"
$ rootfs_dir="$bundle_dir/rootfs"
$ image="busybox"
$ mkdir -p "$rootfs_dir" && (cd "$bundle_dir" && runc spec)
$ sudo docker export $(sudo docker create "$image") | tar -C "$rootfs_dir" -xvf -
```
### Specify API commands to run
The tool allows one or more API commands to be specified using the `-c` or
`--cmd` command-line options. At their simplest, these are just the name of
the API commands, which will make the API command using default values
(generally blank or empty) where possible. However, some API calls require
some basic value to be specified such as a sandbox ID or container ID. For
these calls, the tool will generate a value by default unless told not to.
If the user wishes to, they may specify these values as part of the command
using `name=value` syntax.
In addition to this, it is possible to specify either a complete or partial
set of values for the API call using JSON syntax, either directly on the
command-line or via a file URI.
The table below summarises the possible ways of specifying an API call to
make.
| CLI values | API Query |
|-|-|
| `-c 'SomeAPIName' -n` | Calls the API using the default values for all request options |
| `-c 'SomeAPIName'` | Calls the API specifying some values automatically if possible |
| `-c 'SomeAPIName foo=bar baz="hello world" x=3 y="a cat"'` | Calls the API specifying various values in name/value form |
| `-c 'SomeAPIName json://{}' -n` | Calls the API specifying empty values via an empty JSON document |
| `-c 'SomeAPIName json://{"foo": true, "bar": "hello world"}' -n` | Calls the API specifying _some_ values in JSON syntax |
| `-c 'SomeAPIName file:///foo.json' -n` | Calls the API passing the JSON values from the specified file |
#### JSON Example
An example showing how to specify the messages fields for an API call
(`GetGuestDetails`):
```sh
$ cargo run -- -l debug connect --server-address "unix://@/tmp/foo.socket" --bundle-dir "$bundle_dir" -c Check -c 'GetGuestDetails json://{"mem_block_size": true, "mem_hotplug_probe": true}'
```
> **Note:**
>
> For details of the names of the APIs to call and the available fields
> in each API, see the [Code Summary](#code-summary) section.
### Connect to a real Kata Container
The method used to connect to Kata Containers agent depends on the configured
hypervisor. Although by default the Kata Containers agent listens for API calls on a
VSOCK socket, the way that socket is exposed to the host depends on the
hypervisor.
#### QEMU
Since QEMU supports VSOCK sockets in the standard way, it is only necessary to
establish the VSOCK guest CID value to connect to the agent.
1. Start a Kata Container
1. Establish the VSOCK guest CID number for the virtual machine:
```sh
$ guest_cid=$(sudo ss -H --vsock | awk '{print $6}' | cut -d: -f1)
```
1. Run the tool to connect to the agent:
```sh
# Default VSOCK port the agent listens on
$ agent_vsock_port=1024
$ cargo run -- -l debug connect --bundle-dir "${bundle_dir}" --server-address "vsock://${guest_cid}:${agent_vsock_port}" -c Check -c GetGuestDetails
```
This examples makes two API calls:
- It runs `Check` to see if the agent's RPC server is serving.
- It then runs `GetGuestDetails` to establish some details of the
environment the agent is running in.
#### Cloud Hypervisor and Firecracker
Cloud Hypervisor and Firecracker both use "hybrid VSOCK" which uses a local
UNIX socket rather than the host kernel to handle communication with the
guest. As such, you need to specify the path to the UNIX socket.
Since the UNIX socket path is sandbox-specific, you need to run the
`kata-runtime env` command to determine the socket's "template path". This
path includes a `{ID}` tag that represents the real sandbox ID or name.
Further, since the socket path is below the sandbox directory and since that
directory is `root` owned, it is necessary to run the tool as `root` when
using a Hybrid VSOCKS hypervisor.
##### Determine socket path template value
###### Configured hypervisor is Cloud Hypervisor
```bash
$ socket_path_template=$(sudo kata-runtime env --json | jq '.Hypervisor.SocketPath')
$ echo "$socket_path_template"
"/run/vc/vm/{ID}/clh.sock"
```
###### Configured hypervisor is Firecracker
```bash
$ socket_path_template=$(sudo kata-runtime env --json | jq '.Hypervisor.SocketPath')
$ echo "$socket_path_template"
"/run/vc/firecracker/{ID}/root/kata.hvsock"
```
> **Note:**
>
> Do not rely on the paths shown above: you should run the command yourself
> as these paths _may_ change.
Once you have determined the template path, build and install the tool to make
it easier to run as the `root` user.
##### Build and install
```bash
# Install for user
$ make install
# Install centrally
$ sudo install -o root -g root -m 0755 ~/.cargo/bin/kata-agent-ctl /usr/local/bin
```
1. Start a Kata Container
Create a container called `foo`.
1. Run the tool
```bash
# Name of container
$ sandbox_id="foo"
# Create actual socket path
$ socket_path=$(echo "$socket_path_template" | sed "s/{ID}/${sandbox_id}/g" | tr -d '"')
$ sudo kata-agent-ctl -l debug connect --bundle-dir "${bundle_dir}" --server-address "unix://${socket_path}" --hybrid-vsock -c Check -c GetGuestDetails
```
> **Note:** The `socket_path_template` variable was set in the
> [Determine socket path template value](#determine-socket-path-template-value) section.
### Run the tool and the agent in the same environment
> **Warnings:**
>
> - This method is **only** for testing and development!
> - Only continue if you are using a non-critical system
> (such as a freshly installed VM environment).
1. Start the agent, specifying a local socket for it to communicate on:
```sh
$ sudo KATA_AGENT_SERVER_ADDR=unix:///tmp/foo.socket target/x86_64-unknown-linux-musl/release/kata-agent
```
> **Note:** This example assumes an Intel x86-64 system.
1. Run the tool in the same environment:
```sh
$ cargo run -- -l debug connect --server-address "unix://@/tmp/foo.socket" --bundle-dir "$bundle_dir" -c Check -c GetGuestDetails
```
> **Note:**
>
> The `@` in the server address is required - it denotes an abstract
> socket which the agent requires (see `unix(7)`).

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,330 @@
// Copyright (c) 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
#[macro_use]
extern crate lazy_static;
use crate::types::Config;
use anyhow::{anyhow, Result};
use clap::{crate_name, crate_version, App, Arg, SubCommand};
use std::io;
use std::process::exit;
// Convenience macro to obtain the scope logger
#[macro_export]
macro_rules! sl {
() => {
slog_scope::logger()
};
}
mod client;
mod rpc;
mod types;
mod utils;
const DEFAULT_LOG_LEVEL: slog::Level = slog::Level::Info;
const DESCRIPTION_TEXT: &str = r#"DESCRIPTION:
Low-level test tool that allows basic interaction with
the Kata Containers agent using agent API calls."#;
const ABOUT_TEXT: &str = "Kata Containers agent tool";
const WARNING_TEXT: &str = r#"WARNING:
This tool is for *advanced* users familiar with the low-level agent API calls.
Further, it is designed to be run on test and development systems **only**:
since the tool can make arbitrary API calls, it is possible to easily confuse
irrevocably other parts of the system or even kill a running container or
sandbox."#;
// The VSOCK port number the Kata agent uses to listen to API requests on.
const DEFAULT_KATA_AGENT_API_VSOCK_PORT: &str = "1024";
fn make_examples_text(program_name: &str) -> String {
let abstract_server_address = "unix://@/foo/bar/abstract.socket";
let bundle = "$bundle_dir";
let config_file_uri = "file:///tmp/config.json";
let container_id = "$container_id";
let local_server_address = "unix:///tmp/local.socket";
let sandbox_id = "$sandbox_id";
let vsock_server_address = "vsock://3:1024";
let hybrid_vsock_server_address = "unix:///run/vc/vm/foo/clh.sock";
format!(
r#"EXAMPLES:
- Check if the agent is running:
$ {program} connect --server-address "{vsock_server_address}" --cmd Check
- Connect to the agent using a Hybrid VSOCK hypervisor (here Cloud Hypervisor):
$ {program} connect --server-address "{hybrid_vsock_server_address}" --hybrid-vsock --cmd Check
- Connect to the agent using local sockets (when running in same environment as the agent):
# Local socket
$ {program} connect --server-address "{local_server_address}" --cmd Check
# Abstract socket
$ {program} connect --server-address "{abstract_server_address}" --cmd Check
- Query the agent environment:
$ {program} connect --server-address "{vsock_server_address}" --cmd GetGuestDetails
- List all available (built-in and Kata Agent API) commands:
$ {program} connect --server-address "{vsock_server_address}" --cmd list
- Generate a random container ID:
$ {program} generate-cid
- Generate a random sandbox ID:
$ {program} generate-sid
- Attempt to create 7 sandboxes, ignoring any errors:
$ {program} connect --server-address "{vsock_server_address}" --repeat 7 --cmd CreateSandbox
- Query guest details forever:
$ {program} connect --server-address "{vsock_server_address}" --repeat -1 --cmd GetGuestDetails
- Query guest details, asking for full details by specifying the API request object in JSON format:
$ {program} connect --server-address "{vsock_server_address}" -c 'GetGuestDetails json://{{"mem_block_size": true, "mem_hotplug_probe": true}}'
- Query guest details, asking for extra detail by partially specifying the API request object in JSON format from a file:
$ echo '{{"mem_block_size": true}}' > /tmp/api.json
$ {program} connect --server-address "{vsock_server_address}" -c 'GetGuestDetails file:///tmp/api.json'
- Send a 'SIGUSR1' signal to a container process:
$ {program} connect --server-address "{vsock_server_address}" --cmd 'SignalProcess signal=usr1 sid={sandbox_id} cid={container_id}'
- Create a sandbox with a single container, and then destroy everything:
$ {program} connect --server-address "{vsock_server_address}" --cmd CreateSandbox
$ {program} connect --server-address "{vsock_server_address}" --bundle-dir {bundle:?} --cmd CreateContainer
$ {program} connect --server-address "{vsock_server_address}" --cmd DestroySandbox
- Create a Container using a custom configuration file:
$ {program} connect --server-address "{vsock_server_address}" --bundle-dir {bundle:?} --cmd 'CreateContainer spec={config_file_uri}'
"#,
abstract_server_address = abstract_server_address,
bundle = bundle,
config_file_uri = config_file_uri,
container_id = container_id,
local_server_address = local_server_address,
program = program_name,
sandbox_id = sandbox_id,
vsock_server_address = vsock_server_address,
hybrid_vsock_server_address = hybrid_vsock_server_address,
)
}
fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
let args = global_args
.subcommand_matches("connect")
.ok_or_else(|| anyhow!("BUG: missing sub-command arguments"))?;
let interactive = args.is_present("interactive");
let ignore_errors = args.is_present("ignore-errors");
let server_address = args
.value_of("server-address")
.ok_or_else(|| anyhow!("need server adddress"))?
.to_string();
let mut commands: Vec<&str> = Vec::new();
if !interactive {
commands = args
.values_of("cmd")
.ok_or_else(|| anyhow!("need commands to send to the server"))?
.collect();
}
let log_level_name = global_args
.value_of("log-level")
.ok_or_else(|| anyhow!("cannot get log level"))?;
let log_level = logging::level_name_to_slog_level(log_level_name).map_err(|e| anyhow!(e))?;
let writer = io::stdout();
let (logger, _guard) = logging::create_logger(name, crate_name!(), log_level, writer);
let timeout_nano: i64 = match args.value_of("timeout") {
Some(t) => utils::human_time_to_ns(t).map_err(|e| e)?,
None => 0,
};
let hybrid_vsock_port = args
.value_of("hybrid-vsock-port")
.ok_or_else(|| anyhow!("Need Hybrid VSOCK port number"))?
.parse::<u64>()
.map_err(|e| anyhow!("VSOCK port number must be an integer: {:?}", e))?;
let bundle_dir = args.value_of("bundle-dir").unwrap_or("").to_string();
let hybrid_vsock = args.is_present("hybrid-vsock");
let no_auto_values = args.is_present("no-auto-values");
let cfg = Config {
server_address,
bundle_dir,
interactive,
ignore_errors,
timeout_nano,
hybrid_vsock_port,
hybrid_vsock,
no_auto_values,
};
let result = rpc::run(&logger, &cfg, commands);
if result.is_err() {
return result;
}
Ok(())
}
fn real_main() -> Result<()> {
let name = crate_name!();
let hybrid_vsock_port_help = format!(
"Kata agent VSOCK port number (only useful with --hybrid-vsock) [default: {}]",
DEFAULT_KATA_AGENT_API_VSOCK_PORT
);
let app = App::new(name)
.version(crate_version!())
.about(ABOUT_TEXT)
.long_about(DESCRIPTION_TEXT)
.after_help(WARNING_TEXT)
.arg(
Arg::with_name("log-level")
.long("log-level")
.short("l")
.help("specific log level")
.default_value(logging::slog_level_to_level_name(DEFAULT_LOG_LEVEL).map_err(|e| anyhow!(e))?)
.possible_values(&logging::get_log_levels())
.takes_value(true)
.required(false),
)
.subcommand(
SubCommand::with_name("connect")
.about("Connect to agent")
.after_help(WARNING_TEXT)
.arg(
Arg::with_name("bundle-dir")
.long("bundle-dir")
.help("OCI bundle directory")
.takes_value(true)
.value_name("directory"),
)
.arg(
Arg::with_name("cmd")
.long("cmd")
.short("c")
.takes_value(true)
.multiple(true)
.help("API command (with optional arguments) to send to the server"),
)
.arg(
Arg::with_name("ignore-errors")
.long("ignore-errors")
.help("Don't exit on first error"),
)
.arg(
Arg::with_name("hybrid-vsock")
.long("hybrid-vsock")
.help("Treat a unix:// server address as a Hybrid VSOCK one"),
)
.arg(
Arg::with_name("hybrid-vsock-port")
.long("hybrid-vsock-port")
.help(&hybrid_vsock_port_help)
.default_value(DEFAULT_KATA_AGENT_API_VSOCK_PORT)
.takes_value(true)
.value_name("PORT")
)
.arg(
Arg::with_name("interactive")
.short("i")
.long("interactive")
.help("Allow interactive client"),
)
.arg(
Arg::with_name("no-auto-values")
.short("n")
.long("no-auto-values")
.help("Disable automatic generation of values for sandbox ID, container ID, etc"),
)
.arg(
Arg::with_name("server-address")
.long("server-address")
.help("server URI (vsock:// or unix://)")
.takes_value(true)
.value_name("URI"),
)
.arg(
Arg::with_name("timeout")
.long("timeout")
.help("timeout value as nanoseconds or using human-readable suffixes (0 [forever], 99ns, 30us, 2ms, 5s, 7m, etc)")
.takes_value(true)
.value_name("human-time"),
)
)
.subcommand(
SubCommand::with_name("generate-cid")
.about("Create a random container ID")
)
.subcommand(
SubCommand::with_name("generate-sid")
.about("Create a random sandbox ID")
)
.subcommand(
SubCommand::with_name("examples")
.about("Show usage examples")
);
let args = app.get_matches();
let subcmd = args
.subcommand_name()
.ok_or_else(|| anyhow!("need sub-command"))?;
match subcmd {
"generate-cid" => {
println!("{}", utils::random_container_id());
Ok(())
}
"generate-sid" => {
println!("{}", utils::random_sandbox_id());
Ok(())
}
"examples" => {
println!("{}", make_examples_text(name));
Ok(())
}
"connect" => connect(name, args),
_ => return Err(anyhow!(format!("invalid sub-command: {:?}", subcmd))),
}
}
fn main() {
if let Err(e) = real_main() {
eprintln!("ERROR: {}", e);
exit(1);
}
}

View File

@@ -0,0 +1,19 @@
// Copyright (c) 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
// Description: ttRPC logic entry point
use anyhow::Result;
use slog::{o, Logger};
use crate::client::client;
use crate::types::Config;
pub fn run(logger: &Logger, cfg: &Config, commands: Vec<&str>) -> Result<()> {
// Maintain the global logger for the duration of the ttRPC comms
let _guard = slog_scope::set_global_logger(logger.new(o!("subsystem" => "rpc")));
client(cfg, commands)
}

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
// Type used to pass optional state between cooperating API calls.
pub type Options = HashMap<String, String>;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub server_address: String,
pub bundle_dir: String,
pub timeout_nano: i64,
pub hybrid_vsock_port: u64,
pub interactive: bool,
pub hybrid_vsock: bool,
pub ignore_errors: bool,
pub no_auto_values: bool,
}

Some files were not shown because too many files have changed in this diff Show More