mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-28 19:54:35 +00:00
libs/types: support load Kata hypervisor configuration from file
Add structures to load Kata hypevisor configuration from configuration files. Also define a mechanisms to: 1) for hypervisors to handle the configuration info. 2) for vendor to extend the Kata configuration structure. Signed-off-by: Liu Jiang <gerry@linux.alibaba.com> Signed-off-by: Zhongtao Hu <zhongtaohu.tim@linux.alibaba.com>
This commit is contained in:
parent
21cc02d724
commit
69f10afb71
54
src/libs/Cargo.lock
generated
54
src/libs/Cargo.lock
generated
@ -2,6 +2,15 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.57"
|
||||
@ -225,6 +234,12 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
@ -240,6 +255,15 @@ dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.8.1"
|
||||
@ -287,8 +311,11 @@ checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
name = "kata-types"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
"oci",
|
||||
"regex",
|
||||
"serde",
|
||||
"slog",
|
||||
"slog-scope",
|
||||
@ -427,6 +454,16 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oci"
|
||||
version = "0.1.0"
|
||||
@ -584,6 +621,23 @@ dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
|
@ -11,7 +11,10 @@ license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
glob = "0.3.0"
|
||||
lazy_static = "1.4.0"
|
||||
num_cpus = "1.13.1"
|
||||
regex = "1.5.4"
|
||||
serde = { version = "1.0.100", features = ["derive"] }
|
||||
slog = "2.5.2"
|
||||
slog-scope = "4.4.0"
|
||||
|
@ -21,3 +21,40 @@ lazy_static! {
|
||||
}
|
||||
|
||||
pub const DEFAULT_INTERNETWORKING_MODEL: &str = "tcfilter";
|
||||
|
||||
pub const DEFAULT_BLOCK_DEVICE_TYPE: &str = "virtio-blk";
|
||||
pub const DEFAULT_VHOST_USER_STORE_PATH: &str = "/var/run/vhost-user";
|
||||
pub const DEFAULT_BLOCK_NVDIMM_MEM_OFFSET: u64 = 0;
|
||||
|
||||
pub const DEFAULT_SHARED_FS_TYPE: &str = "virtio-9p";
|
||||
pub const DEFAULT_VIRTIO_FS_CACHE_MODE: &str = "none";
|
||||
pub const DEFAULT_VIRTIO_FS_DAX_SIZE_MB: u32 = 1024;
|
||||
pub const DEFAULT_SHARED_9PFS_SIZE: u32 = 128 * 1024;
|
||||
pub const MIN_SHARED_9PFS_SIZE: u32 = 4 * 1024;
|
||||
pub const MAX_SHARED_9PFS_SIZE: u32 = 8 * 1024 * 1024;
|
||||
|
||||
pub const DEFAULT_GUEST_HOOK_PATH: &str = "/opt";
|
||||
|
||||
pub const DEFAULT_GUEST_VCPUS: u32 = 1;
|
||||
|
||||
// Default configuration for Dragonball
|
||||
pub const DEFAULT_DB_GUEST_KENREL_IMAGE: &str = "vmlinuz";
|
||||
pub const DEFAULT_DB_GUEST_KENREL_PARAMS: &str = "";
|
||||
pub const DEFAULT_DB_ENTROPY_SOURCE: &str = "/dev/urandom";
|
||||
pub const DEFAULT_DB_MEMORY_SIZE: u32 = 128;
|
||||
pub const DEFAULT_DB_MEMORY_SLOTS: u32 = 128;
|
||||
pub const MAX_DB_VCPUS: u32 = 256;
|
||||
|
||||
// Default configuration for qemu
|
||||
pub const DEFAULT_QEMU_BINARY_PATH: &str = "qemu";
|
||||
pub const DEFAULT_QEMU_CONTROL_PATH: &str = "";
|
||||
pub const DEFAULT_QEMU_MACHINE_TYPE: &str = "q35";
|
||||
pub const DEFAULT_QEMU_ENTROPY_SOURCE: &str = "/dev/urandom";
|
||||
pub const DEFAULT_QEMU_GUEST_KENREL_IMAGE: &str = "vmlinuz";
|
||||
pub const DEFAULT_QEMU_GUEST_KENREL_PARAMS: &str = "";
|
||||
pub const DEFAULT_QEMU_FIRMWARE_PATH: &str = "";
|
||||
pub const DEFAULT_QEMU_MEMORY_SIZE: u32 = 128;
|
||||
pub const DEFAULT_QEMU_MEMORY_SLOTS: u32 = 128;
|
||||
pub const DEFAULT_QEMU_PCI_BRIDGES: u32 = 2;
|
||||
pub const MAX_QEMU_PCI_BRIDGES: u32 = 5;
|
||||
pub const MAX_QEMU_VCPUS: u32 = 256;
|
||||
|
176
src/libs/kata-types/src/config/hypervisor/dragonball.rs
Normal file
176
src/libs/kata-types/src/config/hypervisor/dragonball.rs
Normal file
@ -0,0 +1,176 @@
|
||||
// Copyright (c) 2019-2021 Alibaba Cloud
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use std::io::Result;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{default, register_hypervisor_plugin};
|
||||
use crate::config::hypervisor::{
|
||||
VIRTIO_BLK, VIRTIO_BLK_MMIO, VIRTIO_FS, VIRTIO_FS_INLINE, VIRTIO_PMEM,
|
||||
};
|
||||
use crate::config::{ConfigPlugin, TomlConfig};
|
||||
use crate::{eother, resolve_path, validate_path};
|
||||
|
||||
/// Hypervisor name for qemu, used to index `TomlConfig::hypervisor`.
|
||||
pub const HYPERVISOR_NAME_DRAGONBALL: &str = "dragonball";
|
||||
|
||||
/// Configuration information for dragonball.
|
||||
#[derive(Default, Debug)]
|
||||
pub struct DragonballConfig {}
|
||||
|
||||
impl DragonballConfig {
|
||||
/// Create a new instance of `DragonballConfig`.
|
||||
pub fn new() -> Self {
|
||||
DragonballConfig {}
|
||||
}
|
||||
|
||||
/// Register the dragonball plugin.
|
||||
pub fn register(self) {
|
||||
let plugin = Arc::new(self);
|
||||
register_hypervisor_plugin(HYPERVISOR_NAME_DRAGONBALL, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigPlugin for DragonballConfig {
|
||||
fn name(&self) -> &str {
|
||||
HYPERVISOR_NAME_DRAGONBALL
|
||||
}
|
||||
|
||||
/// Adjust the configuration information after loading from configuration file.
|
||||
fn adjust_configuration(&self, conf: &mut TomlConfig) -> Result<()> {
|
||||
if let Some(db) = conf.hypervisor.get_mut(HYPERVISOR_NAME_DRAGONBALL) {
|
||||
resolve_path!(db.jailer_path, "Dragonball jailer path {} is invalid: {}")?;
|
||||
|
||||
if db.boot_info.kernel.is_empty() {
|
||||
db.boot_info.kernel = default::DEFAULT_DB_GUEST_KENREL_IMAGE.to_string();
|
||||
}
|
||||
if db.boot_info.kernel_params.is_empty() {
|
||||
db.boot_info.kernel_params = default::DEFAULT_DB_GUEST_KENREL_PARAMS.to_string();
|
||||
}
|
||||
|
||||
if db.cpu_info.default_maxvcpus > default::MAX_DB_VCPUS {
|
||||
db.cpu_info.default_maxvcpus = default::MAX_DB_VCPUS;
|
||||
}
|
||||
|
||||
if db.machine_info.entropy_source.is_empty() {
|
||||
db.machine_info.entropy_source = default::DEFAULT_DB_ENTROPY_SOURCE.to_string();
|
||||
}
|
||||
|
||||
if db.memory_info.default_memory == 0 {
|
||||
db.memory_info.default_memory = default::DEFAULT_DB_MEMORY_SIZE;
|
||||
}
|
||||
if db.memory_info.memory_slots == 0 {
|
||||
db.memory_info.memory_slots = default::DEFAULT_DB_MEMORY_SLOTS;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validate the configuration information.
|
||||
fn validate(&self, conf: &TomlConfig) -> Result<()> {
|
||||
if let Some(db) = conf.hypervisor.get(HYPERVISOR_NAME_DRAGONBALL) {
|
||||
if !db.path.is_empty() {
|
||||
return Err(eother!("Path for dragonball hypervisor should be empty"));
|
||||
}
|
||||
if !db.valid_hypervisor_paths.is_empty() {
|
||||
return Err(eother!(
|
||||
"Valid hypervisor path for dragonball hypervisor should be empty"
|
||||
));
|
||||
}
|
||||
if !db.ctlpath.is_empty() {
|
||||
return Err(eother!("CtlPath for dragonball hypervisor should be empty"));
|
||||
}
|
||||
if !db.valid_ctlpaths.is_empty() {
|
||||
return Err(eother!("CtlPath for dragonball hypervisor should be empty"));
|
||||
}
|
||||
validate_path!(db.jailer_path, "Dragonball jailer path {} is invalid: {}")?;
|
||||
if db.enable_iothreads {
|
||||
return Err(eother!("Dragonball hypervisor doesn't support IO threads."));
|
||||
}
|
||||
|
||||
if !db.blockdev_info.disable_block_device_use
|
||||
&& db.blockdev_info.block_device_driver != VIRTIO_BLK
|
||||
&& db.blockdev_info.block_device_driver != VIRTIO_BLK_MMIO
|
||||
&& db.blockdev_info.block_device_driver != VIRTIO_PMEM
|
||||
{
|
||||
return Err(eother!(
|
||||
"{} is unsupported block device type.",
|
||||
db.blockdev_info.block_device_driver
|
||||
));
|
||||
}
|
||||
|
||||
if db.boot_info.kernel.is_empty() {
|
||||
return Err(eother!(
|
||||
"Guest kernel image for dragonball hypervisor is empty"
|
||||
));
|
||||
}
|
||||
if db.boot_info.image.is_empty() {
|
||||
return Err(eother!(
|
||||
"Guest boot image for dragonball hypervisor is empty"
|
||||
));
|
||||
}
|
||||
if !db.boot_info.initrd.is_empty() {
|
||||
return Err(eother!("Initrd for dragonball hypervisor should be empty"));
|
||||
}
|
||||
if !db.boot_info.firmware.is_empty() {
|
||||
return Err(eother!(
|
||||
"Firmware for dragonball hypervisor should be empty"
|
||||
));
|
||||
}
|
||||
|
||||
if (db.cpu_info.default_vcpus > 0
|
||||
&& db.cpu_info.default_vcpus as u32 > default::MAX_DB_VCPUS)
|
||||
|| db.cpu_info.default_maxvcpus > default::MAX_DB_VCPUS
|
||||
{
|
||||
return Err(eother!(
|
||||
"Dragonball hypervisor can not support {} vCPUs",
|
||||
db.cpu_info.default_maxvcpus
|
||||
));
|
||||
}
|
||||
|
||||
if db.device_info.enable_iommu || db.device_info.enable_iommu_platform {
|
||||
return Err(eother!("Dragonball hypervisor does not support vIOMMU"));
|
||||
}
|
||||
if db.device_info.hotplug_vfio_on_root_bus
|
||||
|| db.device_info.default_bridges > 0
|
||||
|| db.device_info.pcie_root_port > 0
|
||||
{
|
||||
return Err(eother!(
|
||||
"Dragonball hypervisor does not support PCI hotplug options"
|
||||
));
|
||||
}
|
||||
|
||||
if !db.machine_info.machine_type.is_empty() {
|
||||
return Err(eother!(
|
||||
"Dragonball hypervisor does not support machine_type"
|
||||
));
|
||||
}
|
||||
if !db.machine_info.pflashes.is_empty() {
|
||||
return Err(eother!("Dragonball hypervisor does not support pflashes"));
|
||||
}
|
||||
|
||||
if db.memory_info.enable_guest_swap {
|
||||
return Err(eother!(
|
||||
"Dragonball hypervisor doesn't support enable_guest_swap"
|
||||
));
|
||||
}
|
||||
|
||||
if db.security_info.rootless {
|
||||
return Err(eother!(
|
||||
"Dragonball hypervisor does not support rootless mode"
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(v) = db.shared_fs.shared_fs.as_ref() {
|
||||
if v != VIRTIO_FS && v != VIRTIO_FS_INLINE {
|
||||
return Err(eother!("Dragonball hypervisor doesn't support {}", v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
1052
src/libs/kata-types/src/config/hypervisor/mod.rs
Normal file
1052
src/libs/kata-types/src/config/hypervisor/mod.rs
Normal file
File diff suppressed because it is too large
Load Diff
135
src/libs/kata-types/src/config/hypervisor/qemu.rs
Normal file
135
src/libs/kata-types/src/config/hypervisor/qemu.rs
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright (c) 2019-2021 Alibaba Cloud
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use std::io::Result;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{default, register_hypervisor_plugin};
|
||||
use crate::config::hypervisor::VIRTIO_BLK_MMIO;
|
||||
use crate::config::{ConfigPlugin, TomlConfig};
|
||||
use crate::{eother, resolve_path, validate_path};
|
||||
|
||||
/// Hypervisor name for qemu, used to index `TomlConfig::hypervisor`.
|
||||
pub const HYPERVISOR_NAME_QEMU: &str = "qemu";
|
||||
|
||||
/// Configuration information for qemu.
|
||||
#[derive(Default, Debug)]
|
||||
pub struct QemuConfig {}
|
||||
|
||||
impl QemuConfig {
|
||||
/// Create a new instance of `QemuConfig`.
|
||||
pub fn new() -> Self {
|
||||
QemuConfig {}
|
||||
}
|
||||
|
||||
/// Register the qemu plugin.
|
||||
pub fn register(self) {
|
||||
let plugin = Arc::new(self);
|
||||
register_hypervisor_plugin(HYPERVISOR_NAME_QEMU, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigPlugin for QemuConfig {
|
||||
fn name(&self) -> &str {
|
||||
HYPERVISOR_NAME_QEMU
|
||||
}
|
||||
|
||||
/// Adjust the configuration information after loading from configuration file.
|
||||
fn adjust_configuration(&self, conf: &mut TomlConfig) -> Result<()> {
|
||||
if let Some(qemu) = conf.hypervisor.get_mut(HYPERVISOR_NAME_QEMU) {
|
||||
if qemu.path.is_empty() {
|
||||
qemu.path = default::DEFAULT_QEMU_BINARY_PATH.to_string();
|
||||
}
|
||||
resolve_path!(qemu.path, "Qemu binary path `{}` is invalid: {}")?;
|
||||
if qemu.ctlpath.is_empty() {
|
||||
qemu.ctlpath = default::DEFAULT_QEMU_CONTROL_PATH.to_string();
|
||||
}
|
||||
resolve_path!(qemu.ctlpath, "Qemu ctlpath `{}` is invalid: {}")?;
|
||||
|
||||
if qemu.boot_info.kernel.is_empty() {
|
||||
qemu.boot_info.kernel = default::DEFAULT_QEMU_GUEST_KENREL_IMAGE.to_string();
|
||||
}
|
||||
if qemu.boot_info.kernel_params.is_empty() {
|
||||
qemu.boot_info.kernel_params =
|
||||
default::DEFAULT_QEMU_GUEST_KENREL_PARAMS.to_string();
|
||||
}
|
||||
if qemu.boot_info.firmware.is_empty() {
|
||||
qemu.boot_info.firmware = default::DEFAULT_QEMU_FIRMWARE_PATH.to_string();
|
||||
}
|
||||
|
||||
if qemu.device_info.default_bridges == 0 {
|
||||
qemu.device_info.default_bridges = default::DEFAULT_QEMU_PCI_BRIDGES;
|
||||
if qemu.device_info.default_bridges > default::MAX_QEMU_PCI_BRIDGES {
|
||||
qemu.device_info.default_bridges = default::MAX_QEMU_PCI_BRIDGES;
|
||||
}
|
||||
}
|
||||
|
||||
if qemu.machine_info.machine_type.is_empty() {
|
||||
qemu.machine_info.machine_type = default::DEFAULT_QEMU_MACHINE_TYPE.to_string();
|
||||
}
|
||||
if qemu.machine_info.entropy_source.is_empty() {
|
||||
qemu.machine_info.entropy_source = default::DEFAULT_QEMU_ENTROPY_SOURCE.to_string();
|
||||
}
|
||||
|
||||
if qemu.memory_info.default_memory == 0 {
|
||||
qemu.memory_info.default_memory = default::DEFAULT_QEMU_MEMORY_SIZE;
|
||||
}
|
||||
if qemu.memory_info.memory_slots == 0 {
|
||||
qemu.memory_info.memory_slots = default::DEFAULT_QEMU_MEMORY_SLOTS;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validate the configuration information.
|
||||
fn validate(&self, conf: &TomlConfig) -> Result<()> {
|
||||
if let Some(qemu) = conf.hypervisor.get(HYPERVISOR_NAME_QEMU) {
|
||||
validate_path!(qemu.path, "Qemu binary path `{}` is invalid: {}")?;
|
||||
validate_path!(qemu.ctlpath, "Qemu control path `{}` is invalid: {}")?;
|
||||
if !qemu.jailer_path.is_empty() {
|
||||
return Err(eother!("Path for Qemu jailer should be empty"));
|
||||
}
|
||||
if !qemu.valid_jailer_paths.is_empty() {
|
||||
return Err(eother!("Valid Qemu jailer path list should be empty"));
|
||||
}
|
||||
|
||||
if !qemu.blockdev_info.disable_block_device_use
|
||||
&& qemu.blockdev_info.block_device_driver == VIRTIO_BLK_MMIO
|
||||
{
|
||||
return Err(eother!("Qemu doesn't support virtio-blk-mmio"));
|
||||
}
|
||||
|
||||
if qemu.boot_info.kernel.is_empty() {
|
||||
return Err(eother!("Guest kernel image for qemu is empty"));
|
||||
}
|
||||
if qemu.boot_info.image.is_empty() && qemu.boot_info.initrd.is_empty() {
|
||||
return Err(eother!(
|
||||
"Both guest boot image and initrd for qemu are empty"
|
||||
));
|
||||
}
|
||||
|
||||
if (qemu.cpu_info.default_vcpus > 0
|
||||
&& qemu.cpu_info.default_vcpus as u32 > default::MAX_QEMU_VCPUS)
|
||||
|| qemu.cpu_info.default_maxvcpus > default::MAX_QEMU_VCPUS
|
||||
{
|
||||
return Err(eother!(
|
||||
"Qemu hypervisor can not support {} vCPUs",
|
||||
qemu.cpu_info.default_maxvcpus
|
||||
));
|
||||
}
|
||||
|
||||
if qemu.device_info.default_bridges > default::MAX_QEMU_PCI_BRIDGES {
|
||||
return Err(eother!(
|
||||
"Qemu hypervisor can not support {} PCI bridges",
|
||||
qemu.device_info.default_bridges
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
14
src/libs/kata-types/src/config/hypervisor/vendor.rs
Normal file
14
src/libs/kata-types/src/config/hypervisor/vendor.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2021 Alibaba Cloud
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
//! A sample for vendor to customize the hypervisor implementation.
|
||||
|
||||
use super::*;
|
||||
|
||||
/// Vendor customization runtime configuration.
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct HypervisorVendor {}
|
||||
|
||||
impl ConfigOps for HypervisorVendor {}
|
@ -4,19 +4,38 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::io::{self, Result};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::sl;
|
||||
use crate::{eother, sl};
|
||||
|
||||
/// Default configuration values.
|
||||
pub mod default;
|
||||
|
||||
mod hypervisor;
|
||||
pub use self::hypervisor::{
|
||||
BootInfo, DragonballConfig, Hypervisor, QemuConfig, HYPERVISOR_NAME_DRAGONBALL,
|
||||
HYPERVISOR_NAME_QEMU,
|
||||
};
|
||||
|
||||
mod runtime;
|
||||
pub use self::runtime::{Runtime, RuntimeVendor};
|
||||
|
||||
/// Trait to manipulate global Kata configuration information.
|
||||
pub trait ConfigPlugin: Send + Sync {
|
||||
/// Get the plugin name.
|
||||
fn name(&self) -> &str;
|
||||
|
||||
/// Adjust the configuration information after loading from configuration file.
|
||||
fn adjust_configuration(&self, _conf: &mut TomlConfig) -> Result<()>;
|
||||
|
||||
/// Validate the configuration information.
|
||||
fn validate(&self, _conf: &TomlConfig) -> Result<()>;
|
||||
}
|
||||
|
||||
/// Trait to manipulate Kata configuration information.
|
||||
pub trait ConfigOps {
|
||||
/// Adjust the configuration information after loading from configuration file.
|
||||
fn adjust_configuration(_conf: &mut TomlConfig) -> Result<()> {
|
||||
@ -45,6 +64,9 @@ pub trait ConfigObjectOps {
|
||||
/// Kata configuration information.
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct TomlConfig {
|
||||
/// Configuration information for hypervisors.
|
||||
#[serde(default)]
|
||||
pub hypervisor: HashMap<String, Hypervisor>,
|
||||
/// Kata runtime configuration information.
|
||||
#[serde(default)]
|
||||
pub runtime: Runtime,
|
||||
@ -99,6 +121,7 @@ impl TomlConfig {
|
||||
pub fn load(content: &str) -> Result<TomlConfig> {
|
||||
let mut config: TomlConfig = toml::from_str(content)?;
|
||||
|
||||
Hypervisor::adjust_configuration(&mut config)?;
|
||||
Runtime::adjust_configuration(&mut config)?;
|
||||
info!(sl!(), "get kata config: {:?}", config);
|
||||
|
||||
@ -107,6 +130,7 @@ impl TomlConfig {
|
||||
|
||||
/// Validate Kata configuration information.
|
||||
pub fn validate(&self) -> Result<()> {
|
||||
Hypervisor::validate(self)?;
|
||||
Runtime::validate(self)?;
|
||||
|
||||
Ok(())
|
||||
@ -123,3 +147,49 @@ impl TomlConfig {
|
||||
Err(io::Error::from(io::ErrorKind::NotFound))
|
||||
}
|
||||
}
|
||||
|
||||
/// Validate the `path` matches one of the pattern in `patterns`.
|
||||
///
|
||||
/// Each member in `patterns` is a path pattern as described by glob(3)
|
||||
pub fn validate_path_pattern<P: AsRef<Path>>(patterns: &[String], path: P) -> Result<()> {
|
||||
let path = path
|
||||
.as_ref()
|
||||
.to_str()
|
||||
.ok_or_else(|| eother!("Invalid path {}", path.as_ref().to_string_lossy()))?;
|
||||
|
||||
for p in patterns.iter() {
|
||||
if let Ok(glob) = glob::Pattern::new(p) {
|
||||
if glob.matches(path) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(eother!("Path {} is not permitted", path))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_validate_path_pattern() {
|
||||
let patterns = [];
|
||||
validate_path_pattern(&patterns, "/bin/ls").unwrap_err();
|
||||
|
||||
let patterns = ["/bin".to_string()];
|
||||
validate_path_pattern(&patterns, "/bin/ls").unwrap_err();
|
||||
|
||||
let patterns = ["/bin/*/ls".to_string()];
|
||||
validate_path_pattern(&patterns, "/bin/ls").unwrap_err();
|
||||
|
||||
let patterns = ["/bin/*".to_string()];
|
||||
validate_path_pattern(&patterns, "/bin/ls").unwrap();
|
||||
|
||||
let patterns = ["/*".to_string()];
|
||||
validate_path_pattern(&patterns, "/bin/ls").unwrap();
|
||||
|
||||
let patterns = ["/usr/share".to_string(), "/bin/*".to_string()];
|
||||
validate_path_pattern(&patterns, "/bin/ls").unwrap();
|
||||
}
|
||||
}
|
||||
|
41
src/libs/kata-types/tests/test-config.rs
Normal file
41
src/libs/kata-types/tests/test-config.rs
Normal file
@ -0,0 +1,41 @@
|
||||
use kata_types::config::{QemuConfig, TomlConfig, HYPERVISOR_NAME_QEMU};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn test_load_qemu_config() {
|
||||
let plugin = QemuConfig::new();
|
||||
plugin.register();
|
||||
|
||||
let path = env!("CARGO_MANIFEST_DIR");
|
||||
let path = Path::new(path).join("tests/texture/configuration-qemu.toml");
|
||||
let content = fs::read_to_string(&path).unwrap();
|
||||
let config = TomlConfig::load(&content).unwrap();
|
||||
|
||||
let qemu = config.hypervisor.get(HYPERVISOR_NAME_QEMU).unwrap();
|
||||
assert_eq!(qemu.path, "/usr/bin/ls");
|
||||
assert_eq!(qemu.valid_hypervisor_paths.len(), 2);
|
||||
assert_eq!(qemu.valid_hypervisor_paths[0], "/usr/bin/qemu*");
|
||||
assert_eq!(qemu.valid_hypervisor_paths[1], "/opt/qemu?");
|
||||
qemu.validate_hypervisor_path("/usr/bin/qemu0").unwrap();
|
||||
qemu.validate_hypervisor_path("/usr/bin/qemu1").unwrap();
|
||||
qemu.validate_hypervisor_path("/usr/bin/qemu2222").unwrap();
|
||||
qemu.validate_hypervisor_path("/opt/qemu3").unwrap();
|
||||
qemu.validate_hypervisor_path("/opt/qemu").unwrap_err();
|
||||
qemu.validate_hypervisor_path("/opt/qemu33").unwrap_err();
|
||||
assert_eq!(qemu.ctlpath, "/usr/bin/ls");
|
||||
assert_eq!(qemu.valid_ctlpaths.len(), 0);
|
||||
assert!(qemu.jailer_path.is_empty());
|
||||
assert_eq!(qemu.valid_jailer_paths.len(), 0);
|
||||
assert_eq!(qemu.disable_nesting_checks, true);
|
||||
assert_eq!(qemu.enable_iothreads, true);
|
||||
|
||||
assert_eq!(qemu.boot_info.image, "/usr/bin/echo");
|
||||
assert_eq!(qemu.boot_info.kernel, "/usr/bin/id");
|
||||
assert_eq!(qemu.boot_info.kernel_params, "ro");
|
||||
assert_eq!(qemu.boot_info.firmware, "/etc/hostname");
|
||||
|
||||
assert_eq!(qemu.cpu_info.cpu_features, "pmu=off,vmx=off");
|
||||
assert_eq!(qemu.cpu_info.default_vcpus, 2);
|
||||
assert_eq!(qemu.cpu_info.default_maxvcpus, 64);
|
||||
}
|
78
src/libs/kata-types/tests/texture/configuration-qemu.toml
Normal file
78
src/libs/kata-types/tests/texture/configuration-qemu.toml
Normal file
@ -0,0 +1,78 @@
|
||||
[hypervisor.qemu]
|
||||
path = "/usr/bin/ls"
|
||||
valid_hypervisor_paths = ["/usr/bin/qemu*", "/opt/qemu?"]
|
||||
ctlpath = "/usr/bin/ls"
|
||||
disable_nesting_checks = true
|
||||
enable_iothreads = true
|
||||
|
||||
kernel = "/usr/bin/../bin/id"
|
||||
image = "/usr/bin/./echo"
|
||||
kernel_params = "ro"
|
||||
firmware = "/etc/hostname"
|
||||
|
||||
cpu_features="pmu=off,vmx=off"
|
||||
default_vcpus = 2
|
||||
default_maxvcpus = 64
|
||||
|
||||
machine_type = "q35"
|
||||
confidential_guest = true
|
||||
rootless = true
|
||||
enable_annotations = ["path", "ctlpath"]
|
||||
machine_accelerators="noapic"
|
||||
default_bridges = 2
|
||||
default_memory = 128
|
||||
memory_slots = 128
|
||||
memory_offset = 0x100000
|
||||
enable_virtio_mem = true
|
||||
disable_block_device_use = false
|
||||
shared_fs = "virtio-fs"
|
||||
virtio_fs_daemon = "/usr/bin/id"
|
||||
valid_virtio_fs_daemon_paths = ["/usr/local/bin/virtiofsd*"]
|
||||
virtio_fs_cache_size = 512
|
||||
virtio_fs_extra_args = ["-o", "arg1=xxx,arg2", "-o", "hello world", "--arg3=yyy"]
|
||||
virtio_fs_cache = "always"
|
||||
block_device_driver = "virtio-blk"
|
||||
block_device_cache_set = true
|
||||
block_device_cache_direct = true
|
||||
block_device_cache_noflush = true
|
||||
enable_mem_prealloc = true
|
||||
enable_hugepages = true
|
||||
enable_vhost_user_store = true
|
||||
vhost_user_store_path = "/tmp"
|
||||
valid_vhost_user_store_paths = ["/var/kata/vhost-user-store*", "/tmp/kata?"]
|
||||
enable_iommu = true
|
||||
enable_iommu_platform = true
|
||||
file_mem_backend = "/dev/shm"
|
||||
valid_file_mem_backends = ["/dev/shm"]
|
||||
enable_swap = true
|
||||
pflashes = ["/proc/mounts"]
|
||||
enable_debug = true
|
||||
msize_9p = 16384
|
||||
disable_image_nvdimm = true
|
||||
hotplug_vfio_on_root_bus = true
|
||||
pcie_root_port = 2
|
||||
disable_vhost_net = true
|
||||
entropy_source= "/dev/urandom"
|
||||
valid_entropy_sources = ["/dev/urandom", "/dev/random"]
|
||||
guest_hook_path = "/usr/share/oci/hooks"
|
||||
rx_rate_limiter_max_rate = 10000
|
||||
tx_rate_limiter_max_rate = 10000
|
||||
guest_memory_dump_path="/var/crash/kata"
|
||||
guest_memory_dump_paging = true
|
||||
enable_guest_swap = true
|
||||
|
||||
[runtime]
|
||||
enable_debug = true
|
||||
internetworking_model="macvtap"
|
||||
disable_guest_seccomp=true
|
||||
enable_tracing = true
|
||||
jaeger_endpoint = "localhost:1234"
|
||||
jaeger_user = "user"
|
||||
jaeger_password = "pw"
|
||||
disable_new_netns = true
|
||||
sandbox_cgroup_only=true
|
||||
sandbox_bind_mounts=["/proc/self"]
|
||||
vfio_mode="vfio"
|
||||
experimental=["a", "b"]
|
||||
enable_pprof = true
|
||||
|
Loading…
Reference in New Issue
Block a user