mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-24 22:43:05 +00:00
tools: Make agent-ctl support more APIs
Added new `agent-ctl` commands to allow the following agent API calls to be made: - `AddARPNeighborsRequest` - `CloseStdinRequest` - `CopyFileRequest` - `GetMetricsRequest` - `GetOOMEventRequest` - `MemHotplugByProbeRequest` - `OnlineCPUMemRequest` - `ReadStreamRequest` - `ReseedRandomDevRequest` - `SetGuestDateTimeRequest` - `TtyWinResizeRequest` - `UpdateContainerRequest` - `WriteStreamRequest` Fixes: #969. Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
This commit is contained in:
parent
5620180302
commit
edf02af1d4
10
tools/agent-ctl/Cargo.lock
generated
10
tools/agent-ctl/Cargo.lock
generated
@ -257,6 +257,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.0.1"
|
||||
@ -274,7 +280,9 @@ name = "kata-agent-ctl"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"byteorder",
|
||||
"clap",
|
||||
"hex",
|
||||
"humantime",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
@ -435,7 +443,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "059a34f111a9dee2ce1ac2826a68b24601c4298cfeb1a587c3cb493d5ab46f52"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"nix 0.17.0",
|
||||
"nix 0.18.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -17,6 +17,8 @@ oci = { path = "../../src/agent/oci" }
|
||||
clap = "2.33.0"
|
||||
lazy_static = "1.4.0"
|
||||
anyhow = "1.0.31"
|
||||
hex = "0.4.2"
|
||||
byteorder = "1.3.4"
|
||||
|
||||
logging = { path = "../../pkg/logging" }
|
||||
slog = "2.5.2"
|
||||
|
@ -8,6 +8,7 @@
|
||||
use crate::types::{Config, Options};
|
||||
use crate::utils;
|
||||
use anyhow::{anyhow, Result};
|
||||
use byteorder::ByteOrder;
|
||||
use nix::sys::socket::{connect, socket, AddressFamily, SockAddr, SockFlag, SockType, UnixAddr};
|
||||
use protocols::agent::*;
|
||||
use protocols::agent_ttrpc::*;
|
||||
@ -75,6 +76,11 @@ const DEFAULT_PS_FORMAT: &str = "json";
|
||||
const ERR_API_FAILED: &str = "API failed";
|
||||
|
||||
static AGENT_CMDS: &'static [AgentCmd] = &[
|
||||
AgentCmd {
|
||||
name: "AddARPNeighbors",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_add_arp_neighbors,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "Check",
|
||||
st: ServiceType::Health,
|
||||
@ -85,6 +91,16 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
||||
st: ServiceType::Health,
|
||||
fp: agent_cmd_health_version,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "CloseStdin",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_container_close_stdin,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "CopyFile",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_copy_file,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "CreateContainer",
|
||||
st: ServiceType::Agent,
|
||||
@ -110,6 +126,16 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_get_guest_details,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "GetMetrics",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_get_metrics,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "GetOOMEvent",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_get_oom_event,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "ListInterfaces",
|
||||
st: ServiceType::Agent,
|
||||
@ -125,11 +151,36 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_container_list_processes,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "MemHotplugByProbe",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_mem_hotplug_by_probe,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "OnlineCPUMem",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_online_cpu_mem,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "PauseContainer",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_container_pause,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "ReadStderr",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_container_read_stderr,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "ReadStdout",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_container_read_stdout,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "ReseedRandomDev",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_reseed_random_dev,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "RemoveContainer",
|
||||
st: ServiceType::Agent,
|
||||
@ -140,6 +191,11 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_container_resume,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "SetGuestDateTime",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_set_guest_date_time,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "SignalProcess",
|
||||
st: ServiceType::Agent,
|
||||
@ -165,6 +221,16 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_tracing_stop,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "TtyWinResize",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_container_tty_win_resize,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "UpdateContainer",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_sandbox_update_container,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "UpdateInterface",
|
||||
st: ServiceType::Agent,
|
||||
@ -180,6 +246,11 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_container_wait_process,
|
||||
},
|
||||
AgentCmd {
|
||||
name: "WriteStdin",
|
||||
st: ServiceType::Agent,
|
||||
fp: agent_cmd_container_write_stdin,
|
||||
},
|
||||
];
|
||||
|
||||
static BUILTIN_CMDS: &'static [BuiltinCmd] = &[
|
||||
@ -1212,6 +1283,528 @@ fn agent_cmd_sandbox_list_routes(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_container_tty_win_resize(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = TtyWinResizeRequest::default();
|
||||
|
||||
let cid = utils::get_option("cid", options, args);
|
||||
let exec_id = utils::get_option("exec_id", options, args);
|
||||
|
||||
req.set_container_id(cid);
|
||||
req.set_exec_id(exec_id);
|
||||
|
||||
let rows_str = utils::get_option("row", options, args);
|
||||
|
||||
if rows_str != "" {
|
||||
let rows = rows_str
|
||||
.parse::<u32>()
|
||||
.map_err(|e| anyhow!(e).context("invalid row size"))?;
|
||||
req.set_row(rows);
|
||||
}
|
||||
|
||||
let cols_str = utils::get_option("column", options, args);
|
||||
|
||||
if cols_str != "" {
|
||||
let cols = cols_str
|
||||
.parse::<u32>()
|
||||
.map_err(|e| anyhow!(e).context("invalid column size"))?;
|
||||
|
||||
req.set_column(cols);
|
||||
}
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.tty_win_resize(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_container_close_stdin(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = CloseStdinRequest::default();
|
||||
|
||||
let cid = utils::get_option("cid", options, args);
|
||||
let exec_id = utils::get_option("exec_id", options, args);
|
||||
|
||||
req.set_container_id(cid);
|
||||
req.set_exec_id(exec_id);
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.close_stdin(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_container_read_stdout(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = ReadStreamRequest::default();
|
||||
|
||||
let cid = utils::get_option("cid", options, args);
|
||||
let exec_id = utils::get_option("exec_id", options, args);
|
||||
|
||||
req.set_container_id(cid);
|
||||
req.set_exec_id(exec_id);
|
||||
|
||||
let length_str = utils::get_option("len", options, args);
|
||||
|
||||
if length_str != "" {
|
||||
let length = length_str
|
||||
.parse::<u32>()
|
||||
.map_err(|e| anyhow!(e).context("invalid length"))?;
|
||||
req.set_len(length);
|
||||
}
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.read_stdout(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_container_read_stderr(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = ReadStreamRequest::default();
|
||||
|
||||
let cid = utils::get_option("cid", options, args);
|
||||
let exec_id = utils::get_option("exec_id", options, args);
|
||||
|
||||
req.set_container_id(cid);
|
||||
req.set_exec_id(exec_id);
|
||||
|
||||
let length_str = utils::get_option("len", options, args);
|
||||
|
||||
if length_str != "" {
|
||||
let length = length_str
|
||||
.parse::<u32>()
|
||||
.map_err(|e| anyhow!(e).context("invalid length"))?;
|
||||
req.set_len(length);
|
||||
}
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.read_stderr(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_container_write_stdin(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = WriteStreamRequest::default();
|
||||
|
||||
let cid = utils::get_option("cid", options, args);
|
||||
let exec_id = utils::get_option("exec_id", options, args);
|
||||
|
||||
let str_data = utils::get_option("data", options, args);
|
||||
let data = utils::str_to_bytes(&str_data)?;
|
||||
|
||||
req.set_container_id(cid);
|
||||
req.set_exec_id(exec_id);
|
||||
req.set_data(data.to_vec());
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.write_stdin(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_sandbox_get_metrics(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
_options: &mut Options,
|
||||
_args: &str,
|
||||
) -> Result<()> {
|
||||
let req = GetMetricsRequest::default();
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.get_metrics(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_sandbox_get_oom_event(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
_options: &mut Options,
|
||||
_args: &str,
|
||||
) -> Result<()> {
|
||||
let req = GetOOMEventRequest::default();
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.get_oom_event(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_sandbox_copy_file(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = CopyFileRequest::default();
|
||||
|
||||
let path = utils::get_option("path", options, args);
|
||||
if path != "" {
|
||||
req.set_path(path);
|
||||
}
|
||||
|
||||
let file_size_str = utils::get_option("file_size", options, args);
|
||||
|
||||
if file_size_str != "" {
|
||||
let file_size = file_size_str
|
||||
.parse::<i64>()
|
||||
.map_err(|e| anyhow!(e).context("invalid file_size"))?;
|
||||
|
||||
req.set_file_size(file_size);
|
||||
}
|
||||
|
||||
let file_mode_str = utils::get_option("file_mode", options, args);
|
||||
|
||||
if file_mode_str != "" {
|
||||
let file_mode = file_mode_str
|
||||
.parse::<u32>()
|
||||
.map_err(|e| anyhow!(e).context("invalid file_mode"))?;
|
||||
|
||||
req.set_file_mode(file_mode);
|
||||
}
|
||||
|
||||
let dir_mode_str = utils::get_option("dir_mode", options, args);
|
||||
|
||||
if dir_mode_str != "" {
|
||||
let dir_mode = dir_mode_str
|
||||
.parse::<u32>()
|
||||
.map_err(|e| anyhow!(e).context("invalid dir_mode"))?;
|
||||
|
||||
req.set_dir_mode(dir_mode);
|
||||
}
|
||||
|
||||
let uid_str = utils::get_option("uid", options, args);
|
||||
|
||||
if uid_str != "" {
|
||||
let uid = uid_str
|
||||
.parse::<i32>()
|
||||
.map_err(|e| anyhow!(e).context("invalid uid"))?;
|
||||
|
||||
req.set_uid(uid);
|
||||
}
|
||||
|
||||
let gid_str = utils::get_option("gid", options, args);
|
||||
|
||||
if gid_str != "" {
|
||||
let gid = gid_str
|
||||
.parse::<i32>()
|
||||
.map_err(|e| anyhow!(e).context("invalid gid"))?;
|
||||
req.set_gid(gid);
|
||||
}
|
||||
|
||||
let offset_str = utils::get_option("offset", options, args);
|
||||
|
||||
if offset_str != "" {
|
||||
let offset = offset_str
|
||||
.parse::<i64>()
|
||||
.map_err(|e| anyhow!(e).context("invalid offset"))?;
|
||||
req.set_offset(offset);
|
||||
}
|
||||
|
||||
let data_str = utils::get_option("data", options, args);
|
||||
if data_str != "" {
|
||||
let data = utils::str_to_bytes(&data_str)?;
|
||||
req.set_data(data.to_vec());
|
||||
}
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.copy_file(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_sandbox_reseed_random_dev(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = ReseedRandomDevRequest::default();
|
||||
|
||||
let str_data = utils::get_option("data", options, args);
|
||||
let data = utils::str_to_bytes(&str_data)?;
|
||||
|
||||
req.set_data(data.to_vec());
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.reseed_random_dev(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_sandbox_online_cpu_mem(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = OnlineCPUMemRequest::default();
|
||||
|
||||
let wait_str = utils::get_option("wait", options, args);
|
||||
|
||||
if wait_str != "" {
|
||||
let wait = wait_str
|
||||
.parse::<bool>()
|
||||
.map_err(|e| anyhow!(e).context("invalid wait bool"))?;
|
||||
|
||||
req.set_wait(wait);
|
||||
}
|
||||
|
||||
let nb_cpus_str = utils::get_option("nb_cpus", options, args);
|
||||
|
||||
if nb_cpus_str != "" {
|
||||
let nb_cpus = nb_cpus_str
|
||||
.parse::<u32>()
|
||||
.map_err(|e| anyhow!(e).context("invalid nb_cpus value"))?;
|
||||
|
||||
req.set_nb_cpus(nb_cpus);
|
||||
}
|
||||
|
||||
let cpu_only_str = utils::get_option("cpu_only", options, args);
|
||||
|
||||
if cpu_only_str != "" {
|
||||
let cpu_only = cpu_only_str
|
||||
.parse::<bool>()
|
||||
.map_err(|e| anyhow!(e).context("invalid cpu_only bool"))?;
|
||||
|
||||
req.set_cpu_only(cpu_only);
|
||||
}
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.online_cpu_mem(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_sandbox_set_guest_date_time(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = SetGuestDateTimeRequest::default();
|
||||
|
||||
let secs_str = utils::get_option("sec", options, args);
|
||||
|
||||
if secs_str != "" {
|
||||
let secs = secs_str
|
||||
.parse::<i64>()
|
||||
.map_err(|e| anyhow!(e).context("invalid seconds"))?;
|
||||
|
||||
req.set_Sec(secs);
|
||||
}
|
||||
|
||||
let usecs_str = utils::get_option("usec", options, args);
|
||||
|
||||
if usecs_str != "" {
|
||||
let usecs = usecs_str
|
||||
.parse::<i64>()
|
||||
.map_err(|e| anyhow!(e).context("invalid useconds"))?;
|
||||
|
||||
req.set_Usec(usecs);
|
||||
}
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.set_guest_date_time(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_sandbox_add_arp_neighbors(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
_options: &mut Options,
|
||||
_args: &str,
|
||||
) -> Result<()> {
|
||||
let req = AddARPNeighborsRequest::default();
|
||||
|
||||
// FIXME: Implement fully.
|
||||
eprintln!("FIXME: 'AddARPNeighbors' not fully implemented");
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.add_arp_neighbors(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_sandbox_update_container(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = UpdateContainerRequest::default();
|
||||
|
||||
let cid = utils::get_option("cid", options, args);
|
||||
|
||||
req.set_container_id(cid);
|
||||
|
||||
// FIXME: Implement fully
|
||||
eprintln!("FIXME: 'UpdateContainer' not fully implemented");
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.update_container(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn agent_cmd_sandbox_mem_hotplug_by_probe(
|
||||
cfg: &Config,
|
||||
client: &AgentServiceClient,
|
||||
_health: &HealthClient,
|
||||
options: &mut Options,
|
||||
args: &str,
|
||||
) -> Result<()> {
|
||||
let mut req = MemHotplugByProbeRequest::default();
|
||||
|
||||
// Expected to be a comma separated list of hex addresses
|
||||
let addr_list = utils::get_option("memHotplugProbeAddr", options, args);
|
||||
|
||||
if addr_list != "" {
|
||||
let addrs: Vec<u64> = addr_list
|
||||
// Convert into a list of string values.
|
||||
.split(",")
|
||||
// Convert each string element into a u8 array of bytes, ignoring
|
||||
// those elements that fail the conversion.
|
||||
.filter_map(|s| hex::decode(s.trim_start_matches("0x")).ok())
|
||||
// "Stretch" the u8 byte slice into one of length 8
|
||||
// (to allow each 8 byte chunk to be converted into a u64).
|
||||
.map(|mut v| -> Vec<u8> {
|
||||
v.resize(8, 0x0);
|
||||
v
|
||||
})
|
||||
// Convert the slice of u8 bytes into a u64
|
||||
.map(|b| byteorder::LittleEndian::read_u64(&b))
|
||||
.collect();
|
||||
|
||||
req.set_memHotplugProbeAddr(addrs);
|
||||
}
|
||||
|
||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||
|
||||
let reply = client
|
||||
.mem_hotplug_by_probe(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn builtin_cmd_repeat(_cfg: &Config, _options: &mut Options, _args: &str) -> (Result<()>, bool) {
|
||||
// XXX: NOP implementation. Due to the way repeat has to work, providing a
|
||||
|
@ -408,3 +408,17 @@ pub fn get_grpc_spec(options: &mut Options, cid: &str) -> Result<grpcSpec> {
|
||||
|
||||
Ok(oci_to_grpc(&bundle_dir, cid, &oci_spec)?)
|
||||
}
|
||||
|
||||
pub fn str_to_bytes(s: &str) -> Result<Vec<u8>> {
|
||||
let prefix = "hex:";
|
||||
|
||||
if s.starts_with(prefix) {
|
||||
let hex_str = s.trim_start_matches(prefix);
|
||||
|
||||
let decoded = hex::decode(hex_str).map_err(|e| anyhow!(e))?;
|
||||
|
||||
Ok(decoded)
|
||||
} else {
|
||||
Ok(s.as_bytes().to_vec())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user