mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-20 12:44:38 +00:00
kata-env: Implement the kata-env command.
Command implements functionality to get user environment settings. Fixes: #5339 Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
This commit is contained in:
parent
f2ebdd81c2
commit
f2b2621dec
12
src/tools/kata-ctl/Cargo.lock
generated
12
src/tools/kata-ctl/Cargo.lock
generated
@ -742,10 +742,12 @@ dependencies = [
|
||||
"slog-scope",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"sys-info",
|
||||
"tempfile",
|
||||
"test-utils",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"toml",
|
||||
"url",
|
||||
"vmm-sys-util",
|
||||
]
|
||||
@ -1653,6 +1655,16 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys-info"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "take_mut"
|
||||
version = "0.2.2"
|
||||
|
@ -25,6 +25,8 @@ serde = { version = "1.0.149", features = ["derive"] }
|
||||
url = "2.3.1"
|
||||
futures = "0.3.24"
|
||||
base64 = "0.13.0"
|
||||
toml = "0.5.8"
|
||||
sys-info = "0.9.1"
|
||||
|
||||
shim-interface = { path = "../../libs/shim-interface"}
|
||||
kata-types = { path = "../../libs/kata-types" }
|
||||
|
@ -23,7 +23,7 @@ pub enum Commands {
|
||||
DirectVolume(DirectVolumeCommand),
|
||||
|
||||
/// Display settings
|
||||
Env,
|
||||
Env(EnvArgument),
|
||||
|
||||
/// Enter into guest VM by debug console
|
||||
Exec(ExecArguments),
|
||||
@ -69,6 +69,12 @@ pub enum CheckSubCommand {
|
||||
List,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct EnvArgument {
|
||||
/// Format output as JSON
|
||||
#[arg(long)]
|
||||
pub json: bool,
|
||||
}
|
||||
#[derive(Debug, Args)]
|
||||
pub struct MetricsCommand {
|
||||
#[clap(subcommand)]
|
||||
|
@ -17,8 +17,9 @@ use std::process::exit;
|
||||
use args::{Commands, KataCtlCli};
|
||||
|
||||
use ops::check_ops::{
|
||||
handle_check, handle_env, handle_factory, handle_iptables, handle_metrics, handle_version,
|
||||
handle_check, handle_factory, handle_iptables, handle_metrics, handle_version,
|
||||
};
|
||||
use ops::env_ops::handle_env;
|
||||
use ops::exec_ops::handle_exec;
|
||||
use ops::volume_ops::handle_direct_volume;
|
||||
|
||||
@ -29,7 +30,7 @@ fn real_main() -> Result<()> {
|
||||
Commands::Check(args) => handle_check(args),
|
||||
Commands::DirectVolume(args) => handle_direct_volume(args),
|
||||
Commands::Exec(args) => handle_exec(args),
|
||||
Commands::Env => handle_env(),
|
||||
Commands::Env(args) => handle_env(args),
|
||||
Commands::Factory => handle_factory(),
|
||||
Commands::Iptables(args) => handle_iptables(args),
|
||||
Commands::Metrics(args) => handle_metrics(args),
|
||||
|
@ -4,6 +4,7 @@
|
||||
//
|
||||
|
||||
pub mod check_ops;
|
||||
pub mod env_ops;
|
||||
pub mod exec_ops;
|
||||
pub mod version;
|
||||
pub mod volume_ops;
|
||||
|
@ -107,10 +107,6 @@ pub fn handle_check(checkcmd: CheckArgument) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_env() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_factory() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
431
src/tools/kata-ctl/src/ops/env_ops.rs
Normal file
431
src/tools/kata-ctl/src/ops/env_ops.rs
Normal file
@ -0,0 +1,431 @@
|
||||
// Copyright (c) 2022 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
// Contains checks that are not architecture-specific
|
||||
|
||||
use crate::arch::arch_specific;
|
||||
use crate::args::EnvArgument;
|
||||
use crate::check;
|
||||
use crate::ops::version;
|
||||
use crate::utils;
|
||||
use kata_types::config::TomlConfig;
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::process::Command;
|
||||
use sys_info;
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct HostInfo {
|
||||
#[serde(default)]
|
||||
available_guest_protection: String,
|
||||
#[serde(default)]
|
||||
kernel: String,
|
||||
#[serde(default)]
|
||||
architecture: String,
|
||||
#[serde(default)]
|
||||
vm_container_capable: bool,
|
||||
#[serde(default)]
|
||||
support_vsocks: bool,
|
||||
#[serde(default)]
|
||||
distro: DistroInfo,
|
||||
#[serde(default)]
|
||||
cpu: CPUInfo,
|
||||
#[serde(default)]
|
||||
memory: MemoryInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct DistroInfo {
|
||||
#[serde(default)]
|
||||
name: String,
|
||||
#[serde(default)]
|
||||
version: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct CPUInfo {
|
||||
#[serde(default)]
|
||||
vendor: String,
|
||||
#[serde(default)]
|
||||
model: String,
|
||||
#[serde(default)]
|
||||
cpus: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct MemoryInfo {
|
||||
#[serde(default)]
|
||||
total: u64,
|
||||
#[serde(default)]
|
||||
available: u64,
|
||||
#[serde(default)]
|
||||
free: u64,
|
||||
}
|
||||
|
||||
// Semantic version for the output of the command.
|
||||
//
|
||||
// XXX: Increment for every change to the output format
|
||||
// (meaning any change to the EnvInfo type).
|
||||
const FORMAT_VERSION: &str = "0.0.1-kata-ctl";
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct MetaInfo {
|
||||
#[serde(default)]
|
||||
version: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct VersionInfo {
|
||||
#[serde(default)]
|
||||
semver: String,
|
||||
#[serde(default)]
|
||||
commit: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct RuntimeConfigInfo {
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct RuntimeInfo {
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
#[serde(default)]
|
||||
guest_selinux_label: String,
|
||||
#[serde(default)]
|
||||
pub experimental: Vec<String>,
|
||||
#[serde(default)]
|
||||
debug: bool,
|
||||
#[serde(default)]
|
||||
trace: bool,
|
||||
#[serde(default)]
|
||||
disable_guest_seccomp: bool,
|
||||
#[serde(default)]
|
||||
disable_new_net_ns: bool,
|
||||
#[serde(default)]
|
||||
sandbox_cgroup_only: bool,
|
||||
#[serde(default)]
|
||||
static_sandbox_resource_mgmt: bool,
|
||||
#[serde(default)]
|
||||
config: RuntimeConfigInfo,
|
||||
#[serde(default)]
|
||||
version: VersionInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct AgentInfo {
|
||||
#[serde(default)]
|
||||
debug: bool,
|
||||
#[serde(default)]
|
||||
trace: bool,
|
||||
}
|
||||
// KernelInfo stores kernel details
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct KernelInfo {
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
#[serde(default)]
|
||||
parameters: String,
|
||||
}
|
||||
|
||||
// InitrdInfo stores initrd image details
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct InitrdInfo {
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
}
|
||||
|
||||
// ImageInfo stores root filesystem image details
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct ImageInfo {
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
}
|
||||
|
||||
// HypervisorInfo stores hypervisor details
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct HypervisorInfo {
|
||||
#[serde(default)]
|
||||
machine_type: String,
|
||||
#[serde(default)]
|
||||
machine_accelerators: String,
|
||||
#[serde(default)]
|
||||
version: String,
|
||||
#[serde(default)]
|
||||
path: String,
|
||||
#[serde(default)]
|
||||
block_device_driver: String,
|
||||
#[serde(default)]
|
||||
entropy_source: String,
|
||||
#[serde(default)]
|
||||
shared_fs: String,
|
||||
#[serde(default)]
|
||||
virtio_fs_daemon: String,
|
||||
#[serde(default)]
|
||||
msize_9p: u32,
|
||||
#[serde(default)]
|
||||
memory_slots: u32,
|
||||
#[serde(default)]
|
||||
pcie_root_port: u32,
|
||||
#[serde(default)]
|
||||
hotplug_vfio_on_rootbus: bool,
|
||||
#[serde(default)]
|
||||
debug: bool,
|
||||
#[serde(default)]
|
||||
enable_iommu: bool,
|
||||
#[serde(default)]
|
||||
enable_iommu_platform: bool,
|
||||
#[serde(default)]
|
||||
default_vcpus: i32,
|
||||
#[serde(default)]
|
||||
cpu_features: String,
|
||||
}
|
||||
|
||||
// EnvInfo collects all information that will be displayed by the
|
||||
// env command.
|
||||
//
|
||||
// XXX: Any changes must be coupled with a change to formatVersion.
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct EnvInfo {
|
||||
#[serde(default)]
|
||||
kernel: KernelInfo,
|
||||
#[serde(default)]
|
||||
meta: MetaInfo,
|
||||
#[serde(default)]
|
||||
image: ImageInfo,
|
||||
#[serde(default)]
|
||||
initrd: InitrdInfo,
|
||||
#[serde(default)]
|
||||
hypervisor: HypervisorInfo,
|
||||
#[serde(default)]
|
||||
runtime: RuntimeInfo,
|
||||
#[serde(default)]
|
||||
host: HostInfo,
|
||||
#[serde(default)]
|
||||
agent: AgentInfo,
|
||||
}
|
||||
|
||||
pub fn get_meta_info() -> MetaInfo {
|
||||
MetaInfo {
|
||||
version: String::from(FORMAT_VERSION),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_memory_info() -> Result<MemoryInfo> {
|
||||
let mem_info = sys_info::mem_info().context("get host memory information")?;
|
||||
Ok(MemoryInfo {
|
||||
total: mem_info.total,
|
||||
available: mem_info.avail,
|
||||
free: mem_info.free,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_host_info() -> Result<HostInfo> {
|
||||
let host_kernel_version = utils::get_kernel_version(utils::PROC_VERSION_FILE)?;
|
||||
let (host_distro_name, host_distro_version) =
|
||||
utils::get_distro_details(utils::OS_RELEASE, utils::OS_RELEASE_CLR)?;
|
||||
let (cpu_vendor, cpu_model) = utils::get_generic_cpu_details(check::PROC_CPUINFO)?;
|
||||
|
||||
let host_distro = DistroInfo {
|
||||
name: host_distro_name,
|
||||
version: host_distro_version,
|
||||
};
|
||||
|
||||
let cores: usize = std::thread::available_parallelism()
|
||||
.context("get available parallelism")?
|
||||
.into();
|
||||
|
||||
let host_cpu = CPUInfo {
|
||||
vendor: cpu_vendor,
|
||||
model: cpu_model,
|
||||
cpus: cores,
|
||||
};
|
||||
|
||||
let memory_info = get_memory_info()?;
|
||||
|
||||
let guest_protection =
|
||||
arch_specific::available_guest_protection().map_err(|e| anyhow!(e.to_string()))?;
|
||||
|
||||
let guest_protection = guest_protection.to_string();
|
||||
|
||||
let support_vsocks = utils::supports_vsocks(utils::VHOST_VSOCK_DEVICE)?;
|
||||
|
||||
Ok(HostInfo {
|
||||
kernel: host_kernel_version,
|
||||
architecture: String::from(std::env::consts::ARCH),
|
||||
distro: host_distro,
|
||||
cpu: host_cpu,
|
||||
memory: memory_info,
|
||||
available_guest_protection: guest_protection,
|
||||
// TODO: See https://github.com/kata-containers/kata-containers/issues/6727
|
||||
vm_container_capable: true,
|
||||
support_vsocks,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_runtime_info(toml_config: &TomlConfig) -> Result<RuntimeInfo> {
|
||||
let version = VersionInfo {
|
||||
semver: String::from(version::VERSION),
|
||||
commit: String::from(version::COMMIT),
|
||||
};
|
||||
|
||||
let config_path = TomlConfig::get_default_config_file();
|
||||
let mut toml_path = String::new();
|
||||
if config_path.is_ok() {
|
||||
let p = config_path?;
|
||||
let path_str = p.to_str();
|
||||
toml_path = match path_str {
|
||||
Some(s) => String::from(s),
|
||||
None => String::new(),
|
||||
};
|
||||
}
|
||||
|
||||
Ok(RuntimeInfo {
|
||||
// TODO: Needs to be implemented: https://github.com/kata-containers/kata-containers/issues/6518
|
||||
path: String::from("not implemented yet. See: https://github.com/kata-containers/kata-containers/issues/6518"),
|
||||
version,
|
||||
experimental: toml_config.runtime.experimental.clone(),
|
||||
// TODO: See https://github.com/kata-containers/kata-containers/issues/6667
|
||||
guest_selinux_label: String::from("not implemented yet: See https://github.com/kata-containers/kata-containers/issues/6667"),
|
||||
debug: toml_config.runtime.debug,
|
||||
trace: toml_config.runtime.enable_tracing,
|
||||
disable_guest_seccomp: toml_config.runtime.disable_guest_seccomp,
|
||||
disable_new_net_ns: toml_config.runtime.disable_new_netns,
|
||||
sandbox_cgroup_only: toml_config.runtime.sandbox_cgroup_only,
|
||||
static_sandbox_resource_mgmt: toml_config.runtime.static_sandbox_resource_mgmt,
|
||||
config: RuntimeConfigInfo { path: toml_path },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_agent_info(toml_config: &TomlConfig) -> Result<AgentInfo> {
|
||||
let agent_config = toml_config
|
||||
.agent
|
||||
.get(&toml_config.runtime.agent_name)
|
||||
.ok_or("could not find agent config in configuration")
|
||||
.map_err(|e| anyhow!(e))?;
|
||||
|
||||
Ok(AgentInfo {
|
||||
debug: agent_config.debug,
|
||||
trace: agent_config.enable_tracing,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_command_version(cmd: &str) -> Result<String> {
|
||||
// Path is empty in case of dragonball hypervisor
|
||||
if cmd.is_empty() {
|
||||
return Ok("unknown".to_string());
|
||||
}
|
||||
let output = Command::new(cmd)
|
||||
.arg("--version")
|
||||
.output()
|
||||
.map_err(|e| anyhow!(e))?;
|
||||
|
||||
let version = String::from_utf8(output.stdout).map_err(|e| anyhow!(e))?;
|
||||
|
||||
Ok(version)
|
||||
}
|
||||
|
||||
pub fn get_hypervisor_info(
|
||||
toml_config: &TomlConfig,
|
||||
) -> Result<(HypervisorInfo, ImageInfo, KernelInfo, InitrdInfo)> {
|
||||
let hypervisor_config = toml_config
|
||||
.hypervisor
|
||||
.get(&toml_config.runtime.hypervisor_name)
|
||||
.ok_or("could not find hypervisor config in configuration")
|
||||
.map_err(|e| anyhow!(e))?;
|
||||
|
||||
let version =
|
||||
get_command_version(&hypervisor_config.path).context("error getting hypervisor version")?;
|
||||
|
||||
let hypervisor_info = HypervisorInfo {
|
||||
machine_type: hypervisor_config.machine_info.machine_type.to_string(),
|
||||
machine_accelerators: hypervisor_config
|
||||
.machine_info
|
||||
.machine_accelerators
|
||||
.to_string(),
|
||||
version,
|
||||
path: hypervisor_config.path.to_string(),
|
||||
block_device_driver: hypervisor_config
|
||||
.blockdev_info
|
||||
.block_device_driver
|
||||
.to_string(),
|
||||
entropy_source: hypervisor_config.machine_info.entropy_source.to_string(),
|
||||
shared_fs: hypervisor_config
|
||||
.shared_fs
|
||||
.shared_fs
|
||||
.clone()
|
||||
.unwrap_or_else(|| String::from("none")),
|
||||
virtio_fs_daemon: hypervisor_config.shared_fs.virtio_fs_daemon.to_string(),
|
||||
msize_9p: hypervisor_config.shared_fs.msize_9p,
|
||||
memory_slots: hypervisor_config.memory_info.memory_slots,
|
||||
pcie_root_port: hypervisor_config.device_info.pcie_root_port,
|
||||
hotplug_vfio_on_rootbus: hypervisor_config.device_info.hotplug_vfio_on_root_bus,
|
||||
debug: hypervisor_config.debug_info.enable_debug,
|
||||
enable_iommu: hypervisor_config.device_info.enable_iommu,
|
||||
enable_iommu_platform: hypervisor_config.device_info.enable_iommu_platform,
|
||||
default_vcpus: hypervisor_config.cpu_info.default_vcpus,
|
||||
cpu_features: hypervisor_config.cpu_info.cpu_features.to_string(),
|
||||
};
|
||||
|
||||
let image_info = ImageInfo {
|
||||
path: hypervisor_config.boot_info.image.clone(),
|
||||
};
|
||||
|
||||
let kernel_info = KernelInfo {
|
||||
path: hypervisor_config.boot_info.kernel.to_string(),
|
||||
parameters: hypervisor_config.boot_info.kernel_params.to_string(),
|
||||
};
|
||||
|
||||
let initrd_info = InitrdInfo {
|
||||
path: hypervisor_config.boot_info.initrd.to_string(),
|
||||
};
|
||||
|
||||
Ok((hypervisor_info, image_info, kernel_info, initrd_info))
|
||||
}
|
||||
|
||||
pub fn get_env_info(toml_config: &TomlConfig) -> Result<EnvInfo> {
|
||||
let metainfo = get_meta_info();
|
||||
|
||||
let runtime_info = get_runtime_info(toml_config).context("get runtime info")?;
|
||||
|
||||
let agent_info = get_agent_info(toml_config).context("get agent configuration")?;
|
||||
|
||||
let host_info = get_host_info().context("get host information")?;
|
||||
|
||||
let (hypervisor_info, _image_info, kernel_info, initrd_info) =
|
||||
get_hypervisor_info(toml_config).context("get hypervisor configuration")?;
|
||||
|
||||
let env_info = EnvInfo {
|
||||
meta: metainfo,
|
||||
runtime: runtime_info,
|
||||
kernel: kernel_info,
|
||||
image: _image_info,
|
||||
initrd: initrd_info,
|
||||
hypervisor: hypervisor_info,
|
||||
host: host_info,
|
||||
agent: agent_info,
|
||||
};
|
||||
|
||||
Ok(env_info)
|
||||
}
|
||||
|
||||
pub fn handle_env(env_args: EnvArgument) -> Result<()> {
|
||||
let (toml_config, _) = TomlConfig::load_raw_from_file("").context("load toml config")?;
|
||||
|
||||
let env_info = get_env_info(&toml_config)?;
|
||||
|
||||
if env_args.json {
|
||||
let serialized_json = serde_json::to_string_pretty(&env_info)?;
|
||||
println!("{}", serialized_json);
|
||||
} else {
|
||||
let toml = toml::to_string(&env_info)?;
|
||||
println!("{}", toml);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
@ -145,7 +145,12 @@ pub fn get_generic_cpu_details(cpu_info_file: &str) -> Result<(String, String)>
|
||||
|
||||
pub const VHOST_VSOCK_DEVICE: &str = "/dev/vhost-vsock";
|
||||
pub fn supports_vsocks(vsock_path: &str) -> Result<bool> {
|
||||
let metadata = fs::metadata(vsock_path)?;
|
||||
let metadata = fs::metadata(vsock_path).map_err(|err| {
|
||||
anyhow!(
|
||||
"Host system does not support vhost-vsock (try running (`sudo modprobe vhost_vsock`) : {}",
|
||||
err.to_string()
|
||||
)
|
||||
})?;
|
||||
Ok(metadata.is_file())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user