mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-02-21 14:22:24 +00:00
runtime-rs: Properly parse containerd runtime options to extract ConfigPath
The runtime-rs shim was failing to load its configuration when deployed via kata-deploy because it couldn't correctly parse the ConfigPath passed by containerd. The previous implementation naively skipped the first 2 bytes of the options and interpreted the rest as a UTF-8 string, which doesn't work since containerd passes a properly serialized protobuf message of type runtimeoptions.v1.Options. This change adds the runtimeoptions.proto definition to the protocols crate and updates the load_config function to correctly deserialize the protobuf message and extract the config_path field, matching how the Go runtime handles this via typeurl.UnmarshalAny. Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -4047,6 +4047,8 @@ dependencies = [
|
||||
"persist",
|
||||
"procfs 0.12.0",
|
||||
"prometheus",
|
||||
"protobuf",
|
||||
"protocols",
|
||||
"resource",
|
||||
"runtime-spec",
|
||||
"serde_json",
|
||||
|
||||
@@ -191,6 +191,7 @@ fn real_main() -> Result<(), std::io::Error> {
|
||||
"protos/oci.proto",
|
||||
"protos/types.proto",
|
||||
"protos/csi.proto",
|
||||
"protos/runtimeoptions.proto",
|
||||
],
|
||||
false,
|
||||
)?;
|
||||
|
||||
20
src/libs/protocols/protos/runtimeoptions.proto
Normal file
20
src/libs/protocols/protos/runtimeoptions.proto
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2024 The containerd Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// This proto definition is based on containerd's runtimeoptions/v1/api.proto
|
||||
// https://github.com/containerd/containerd/blob/main/api/types/runtimeoptions/v1/api.proto
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package runtimeoptions.v1;
|
||||
|
||||
message Options {
|
||||
// TypeUrl specifies the type of the content inside the config file.
|
||||
string type_url = 1;
|
||||
// ConfigPath specifies the filesystem location of the config file
|
||||
// used by the runtime.
|
||||
string config_path = 2;
|
||||
// Blob specifies an in-memory TOML blob passed from containerd's configuration section
|
||||
// for this runtime. This will be used if config_path is not specified.
|
||||
bytes config_body = 3;
|
||||
}
|
||||
@@ -22,6 +22,7 @@ pub mod remote;
|
||||
pub mod remote_ttrpc;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod remote_ttrpc_async;
|
||||
pub mod runtimeoptions;
|
||||
#[cfg(feature = "with-serde")]
|
||||
mod serde_config;
|
||||
pub mod trans;
|
||||
|
||||
@@ -38,6 +38,8 @@ oci-spec = { workspace = true }
|
||||
agent = { workspace = true }
|
||||
common = { workspace = true }
|
||||
kata-types = { workspace = true }
|
||||
protocols = { workspace = true }
|
||||
protobuf = { workspace = true }
|
||||
kata-sys-util = { workspace = true }
|
||||
logging = { workspace = true }
|
||||
runtime-spec = { workspace = true }
|
||||
|
||||
@@ -10,7 +10,7 @@ license = { workspace = true }
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
containerd-shim-protos = { workspace = true }
|
||||
containerd-shim-protos = { workspace = true, features = ["sandbox"] }
|
||||
lazy_static = { workspace = true }
|
||||
nix = { workspace = true }
|
||||
protobuf = { workspace = true }
|
||||
|
||||
@@ -39,13 +39,14 @@ use resource::{
|
||||
};
|
||||
use runtime_spec as spec;
|
||||
use shim_interface::shim_mgmt::ERR_NO_SHIM_SERVER;
|
||||
use protobuf::Message as ProtobufMessage;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
env,
|
||||
ops::Deref,
|
||||
os::unix::fs::{chown, MetadataExt},
|
||||
path::{Path, PathBuf},
|
||||
str::{from_utf8, FromStr},
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
time::SystemTime,
|
||||
};
|
||||
@@ -700,11 +701,21 @@ fn load_config(an: &HashMap<String, String>, option: &Option<Vec<u8>>) -> Result
|
||||
} else if let Ok(path) = std::env::var(KATA_CONF_FILE) {
|
||||
path
|
||||
} else if let Some(option) = option {
|
||||
// get rid of the special characters in options to get the config path
|
||||
if option.len() > 2 {
|
||||
from_utf8(&option[2..])?.to_string()
|
||||
} else {
|
||||
String::from("")
|
||||
// Parse the containerd runtime options protobuf message to extract the config path.
|
||||
// The options are passed as a serialized runtimeoptions.v1.Options protobuf message
|
||||
// from containerd's configuration (e.g., [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata.options]).
|
||||
match <protocols::runtimeoptions::Options as ProtobufMessage>::parse_from_bytes(option) {
|
||||
Ok(opts) => opts.config_path,
|
||||
Err(e) => {
|
||||
// Log the error but don't fail - fall back to default config paths
|
||||
let logger = slog::Logger::clone(&slog_scope::logger());
|
||||
slog::warn!(
|
||||
logger,
|
||||
"failed to parse containerd runtime options: {}, falling back to default config paths",
|
||||
e
|
||||
);
|
||||
String::from("")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String::from("")
|
||||
|
||||
Reference in New Issue
Block a user