mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-04 11:06:21 +00:00
Merge pull request #970 from jodh-intel/2.0-dev-agent-ctl-add-missing-apis
tools: Make agent-ctl support more APIs
This commit is contained in:
commit
e5262b1c29
10
tools/agent-ctl/Cargo.lock
generated
10
tools/agent-ctl/Cargo.lock
generated
@ -257,6 +257,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "humantime"
|
name = "humantime"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
@ -274,7 +280,9 @@ name = "kata-agent-ctl"
|
|||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"byteorder",
|
||||||
"clap",
|
"clap",
|
||||||
|
"hex",
|
||||||
"humantime",
|
"humantime",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
@ -435,7 +443,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "059a34f111a9dee2ce1ac2826a68b24601c4298cfeb1a587c3cb493d5ab46f52"
|
checksum = "059a34f111a9dee2ce1ac2826a68b24601c4298cfeb1a587c3cb493d5ab46f52"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"nix 0.17.0",
|
"nix 0.18.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -17,6 +17,8 @@ oci = { path = "../../src/agent/oci" }
|
|||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
anyhow = "1.0.31"
|
anyhow = "1.0.31"
|
||||||
|
hex = "0.4.2"
|
||||||
|
byteorder = "1.3.4"
|
||||||
|
|
||||||
logging = { path = "../../pkg/logging" }
|
logging = { path = "../../pkg/logging" }
|
||||||
slog = "2.5.2"
|
slog = "2.5.2"
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
* [Overview](#overview)
|
* [Overview](#overview)
|
||||||
* [Audience and environment](#audience-and-environment)
|
* [Audience and environment](#audience-and-environment)
|
||||||
* [Full details](#full-details)
|
* [Full details](#full-details)
|
||||||
|
* [Code summary](#code-summary)
|
||||||
|
* [Running the tool](#running-the-tool)
|
||||||
|
* [Prerequisites](#prerequisites)
|
||||||
|
* [Connect to a real Kata Container](#connect-to-a-real-kata-container)
|
||||||
|
* [Run the tool and the agent in the same environment](#run-the-tool-and-the-agent-in-the-same-environment)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@ -37,3 +42,80 @@ To see some examples, run:
|
|||||||
```sh
|
```sh
|
||||||
$ cargo run -- examples
|
$ 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`](../../src/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`](../../src/agent/src/rpc.rs) | `create_container()` | Server function that implements the `CreateContainers` API. |
|
||||||
|
|
||||||
|
## Running 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 -
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connect to a real Kata Container
|
||||||
|
|
||||||
|
1. Start a Kata Container
|
||||||
|
|
||||||
|
1. Establish the VSOCK guest CID number for the virtual machine:
|
||||||
|
|
||||||
|
Assuming you are running a single QEMU based Kata Container, you can look
|
||||||
|
at the program arguments to find the (randomly-generated) `guest-cid=` option
|
||||||
|
value:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ guest_cid=$(ps -ef | grep qemu-system-x86_64 | egrep -o "guest-cid=[^,][^,]*" | cut -d= -f2)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Run the tool to connect to the agent:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ cargo run -- -l debug connect --bundle-dir "${bundle_dir}" --server-address "vsock://${guest_cid}:1024" -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.
|
||||||
|
|
||||||
|
### 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
|
||||||
|
```
|
||||||
|
|
||||||
|
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)`).
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
use crate::types::{Config, Options};
|
use crate::types::{Config, Options};
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use byteorder::ByteOrder;
|
||||||
use nix::sys::socket::{connect, socket, AddressFamily, SockAddr, SockFlag, SockType, UnixAddr};
|
use nix::sys::socket::{connect, socket, AddressFamily, SockAddr, SockFlag, SockType, UnixAddr};
|
||||||
use protocols::agent::*;
|
use protocols::agent::*;
|
||||||
use protocols::agent_ttrpc::*;
|
use protocols::agent_ttrpc::*;
|
||||||
@ -75,6 +76,11 @@ const DEFAULT_PS_FORMAT: &str = "json";
|
|||||||
const ERR_API_FAILED: &str = "API failed";
|
const ERR_API_FAILED: &str = "API failed";
|
||||||
|
|
||||||
static AGENT_CMDS: &'static [AgentCmd] = &[
|
static AGENT_CMDS: &'static [AgentCmd] = &[
|
||||||
|
AgentCmd {
|
||||||
|
name: "AddARPNeighbors",
|
||||||
|
st: ServiceType::Agent,
|
||||||
|
fp: agent_cmd_sandbox_add_arp_neighbors,
|
||||||
|
},
|
||||||
AgentCmd {
|
AgentCmd {
|
||||||
name: "Check",
|
name: "Check",
|
||||||
st: ServiceType::Health,
|
st: ServiceType::Health,
|
||||||
@ -85,6 +91,16 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
|||||||
st: ServiceType::Health,
|
st: ServiceType::Health,
|
||||||
fp: agent_cmd_health_version,
|
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 {
|
AgentCmd {
|
||||||
name: "CreateContainer",
|
name: "CreateContainer",
|
||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
@ -106,9 +122,19 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
|||||||
fp: agent_cmd_container_exec,
|
fp: agent_cmd_container_exec,
|
||||||
},
|
},
|
||||||
AgentCmd {
|
AgentCmd {
|
||||||
name: "GuestDetails",
|
name: "GetGuestDetails",
|
||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
fp: agent_cmd_sandbox_guest_details,
|
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 {
|
AgentCmd {
|
||||||
name: "ListInterfaces",
|
name: "ListInterfaces",
|
||||||
@ -125,11 +151,36 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
|||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
fp: agent_cmd_container_list_processes,
|
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 {
|
AgentCmd {
|
||||||
name: "PauseContainer",
|
name: "PauseContainer",
|
||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
fp: agent_cmd_container_pause,
|
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 {
|
AgentCmd {
|
||||||
name: "RemoveContainer",
|
name: "RemoveContainer",
|
||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
@ -140,6 +191,11 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
|||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
fp: agent_cmd_container_resume,
|
fp: agent_cmd_container_resume,
|
||||||
},
|
},
|
||||||
|
AgentCmd {
|
||||||
|
name: "SetGuestDateTime",
|
||||||
|
st: ServiceType::Agent,
|
||||||
|
fp: agent_cmd_sandbox_set_guest_date_time,
|
||||||
|
},
|
||||||
AgentCmd {
|
AgentCmd {
|
||||||
name: "SignalProcess",
|
name: "SignalProcess",
|
||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
@ -165,6 +221,16 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
|||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
fp: agent_cmd_sandbox_tracing_stop,
|
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 {
|
AgentCmd {
|
||||||
name: "UpdateInterface",
|
name: "UpdateInterface",
|
||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
@ -180,6 +246,11 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
|||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
fp: agent_cmd_container_wait_process,
|
fp: agent_cmd_container_wait_process,
|
||||||
},
|
},
|
||||||
|
AgentCmd {
|
||||||
|
name: "WriteStdin",
|
||||||
|
st: ServiceType::Agent,
|
||||||
|
fp: agent_cmd_container_write_stdin,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
static BUILTIN_CMDS: &'static [BuiltinCmd] = &[
|
static BUILTIN_CMDS: &'static [BuiltinCmd] = &[
|
||||||
@ -684,6 +755,8 @@ fn agent_cmd_health_check(
|
|||||||
// value unused
|
// value unused
|
||||||
req.set_service("".to_string());
|
req.set_service("".to_string());
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = health
|
let reply = health
|
||||||
.check(&req, cfg.timeout_nano)
|
.check(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -707,6 +780,8 @@ fn agent_cmd_health_version(
|
|||||||
// value unused
|
// value unused
|
||||||
req.set_service("".to_string());
|
req.set_service("".to_string());
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = health
|
let reply = health
|
||||||
.version(&req, cfg.timeout_nano)
|
.version(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -729,6 +804,8 @@ fn agent_cmd_sandbox_create(
|
|||||||
let sid = utils::get_option("sid", options, args);
|
let sid = utils::get_option("sid", options, args);
|
||||||
req.set_sandbox_id(sid);
|
req.set_sandbox_id(sid);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.create_sandbox(&req, cfg.timeout_nano)
|
.create_sandbox(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -748,6 +825,8 @@ fn agent_cmd_sandbox_destroy(
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let req = DestroySandboxRequest::default();
|
let req = DestroySandboxRequest::default();
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.destroy_sandbox(&req, cfg.timeout_nano)
|
.destroy_sandbox(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -778,6 +857,8 @@ fn agent_cmd_container_create(
|
|||||||
req.set_exec_id(exec_id);
|
req.set_exec_id(exec_id);
|
||||||
req.set_OCI(grpc_spec);
|
req.set_OCI(grpc_spec);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.create_container(&req, cfg.timeout_nano)
|
.create_container(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -801,6 +882,8 @@ fn agent_cmd_container_remove(
|
|||||||
|
|
||||||
req.set_container_id(cid);
|
req.set_container_id(cid);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.remove_container(&req, cfg.timeout_nano)
|
.remove_container(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -838,6 +921,8 @@ fn agent_cmd_container_exec(
|
|||||||
req.set_exec_id(exec_id);
|
req.set_exec_id(exec_id);
|
||||||
req.set_process(process);
|
req.set_process(process);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.exec_process(&req, cfg.timeout_nano)
|
.exec_process(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -861,6 +946,8 @@ fn agent_cmd_container_stats(
|
|||||||
|
|
||||||
req.set_container_id(cid);
|
req.set_container_id(cid);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.stats_container(&req, cfg.timeout_nano)
|
.stats_container(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -884,6 +971,8 @@ fn agent_cmd_container_pause(
|
|||||||
|
|
||||||
req.set_container_id(cid);
|
req.set_container_id(cid);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.pause_container(&req, cfg.timeout_nano)
|
.pause_container(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -907,6 +996,8 @@ fn agent_cmd_container_resume(
|
|||||||
|
|
||||||
req.set_container_id(cid);
|
req.set_container_id(cid);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.resume_container(&req, cfg.timeout_nano)
|
.resume_container(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -930,6 +1021,8 @@ fn agent_cmd_container_start(
|
|||||||
|
|
||||||
req.set_container_id(cid);
|
req.set_container_id(cid);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.start_container(&req, cfg.timeout_nano)
|
.start_container(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -940,7 +1033,7 @@ fn agent_cmd_container_start(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn agent_cmd_sandbox_guest_details(
|
fn agent_cmd_sandbox_get_guest_details(
|
||||||
cfg: &Config,
|
cfg: &Config,
|
||||||
client: &AgentServiceClient,
|
client: &AgentServiceClient,
|
||||||
_health: &HealthClient,
|
_health: &HealthClient,
|
||||||
@ -951,6 +1044,8 @@ fn agent_cmd_sandbox_guest_details(
|
|||||||
|
|
||||||
req.set_mem_block_size(true);
|
req.set_mem_block_size(true);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.get_guest_details(&req, cfg.timeout_nano)
|
.get_guest_details(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -981,6 +1076,8 @@ fn agent_cmd_container_list_processes(
|
|||||||
req.set_container_id(cid);
|
req.set_container_id(cid);
|
||||||
req.set_format(list_format);
|
req.set_format(list_format);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.list_processes(&req, cfg.timeout_nano)
|
.list_processes(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -1006,6 +1103,8 @@ fn agent_cmd_container_wait_process(
|
|||||||
req.set_container_id(cid);
|
req.set_container_id(cid);
|
||||||
req.set_exec_id(exec_id);
|
req.set_exec_id(exec_id);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.wait_process(&req, cfg.timeout_nano)
|
.wait_process(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -1041,6 +1140,8 @@ fn agent_cmd_container_signal_process(
|
|||||||
req.set_exec_id(exec_id);
|
req.set_exec_id(exec_id);
|
||||||
req.set_signal(signum as u32);
|
req.set_signal(signum as u32);
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.signal_process(&req, cfg.timeout_nano)
|
.signal_process(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -1060,6 +1161,8 @@ fn agent_cmd_sandbox_tracing_start(
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let req = StartTracingRequest::default();
|
let req = StartTracingRequest::default();
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.start_tracing(&req, cfg.timeout_nano)
|
.start_tracing(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -1079,6 +1182,8 @@ fn agent_cmd_sandbox_tracing_stop(
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let req = StopTracingRequest::default();
|
let req = StopTracingRequest::default();
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.stop_tracing(&req, cfg.timeout_nano)
|
.stop_tracing(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -1098,6 +1203,7 @@ fn agent_cmd_sandbox_update_interface(
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let req = UpdateInterfaceRequest::default();
|
let req = UpdateInterfaceRequest::default();
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
let reply = client
|
let reply = client
|
||||||
.update_interface(&req, cfg.timeout_nano)
|
.update_interface(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -1105,9 +1211,6 @@ fn agent_cmd_sandbox_update_interface(
|
|||||||
// FIXME: Implement 'UpdateInterface' fully.
|
// FIXME: Implement 'UpdateInterface' fully.
|
||||||
eprintln!("FIXME: 'UpdateInterface' not fully implemented");
|
eprintln!("FIXME: 'UpdateInterface' not fully implemented");
|
||||||
|
|
||||||
// let if = ...;
|
|
||||||
// req.set_interface(if);
|
|
||||||
|
|
||||||
info!(sl!(), "response received";
|
info!(sl!(), "response received";
|
||||||
"response" => format!("{:?}", reply));
|
"response" => format!("{:?}", reply));
|
||||||
|
|
||||||
@ -1123,6 +1226,8 @@ fn agent_cmd_sandbox_update_routes(
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let req = UpdateRoutesRequest::default();
|
let req = UpdateRoutesRequest::default();
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.update_routes(&req, cfg.timeout_nano)
|
.update_routes(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -1130,9 +1235,6 @@ fn agent_cmd_sandbox_update_routes(
|
|||||||
// FIXME: Implement 'UpdateRoutes' fully.
|
// FIXME: Implement 'UpdateRoutes' fully.
|
||||||
eprintln!("FIXME: 'UpdateRoutes' not fully implemented");
|
eprintln!("FIXME: 'UpdateRoutes' not fully implemented");
|
||||||
|
|
||||||
// let routes = ...;
|
|
||||||
// req.set_routes(routes);
|
|
||||||
|
|
||||||
info!(sl!(), "response received";
|
info!(sl!(), "response received";
|
||||||
"response" => format!("{:?}", reply));
|
"response" => format!("{:?}", reply));
|
||||||
|
|
||||||
@ -1148,6 +1250,8 @@ fn agent_cmd_sandbox_list_interfaces(
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let req = ListInterfacesRequest::default();
|
let req = ListInterfacesRequest::default();
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.list_interfaces(&req, cfg.timeout_nano)
|
.list_interfaces(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -1167,6 +1271,8 @@ fn agent_cmd_sandbox_list_routes(
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let req = ListRoutesRequest::default();
|
let req = ListRoutesRequest::default();
|
||||||
|
|
||||||
|
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
||||||
|
|
||||||
let reply = client
|
let reply = client
|
||||||
.list_routes(&req, cfg.timeout_nano)
|
.list_routes(&req, cfg.timeout_nano)
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||||
@ -1177,9 +1283,531 @@ fn agent_cmd_sandbox_list_routes(
|
|||||||
Ok(())
|
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]
|
#[inline]
|
||||||
fn builtin_cmd_repeat(_cfg: &Config, _options: &mut Options, _args: &str) -> (Result<()>, bool) {
|
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
|
// XXX: NOP implementation. Due to the way repeat has to work, providing a
|
||||||
// handler like this is "too late" to be useful. However, a handler
|
// handler like this is "too late" to be useful. However, a handler
|
||||||
// is required as "repeat" is a valid command.
|
// is required as "repeat" is a valid command.
|
||||||
//
|
//
|
||||||
|
@ -65,7 +65,7 @@ fn make_examples_text(program_name: &str) -> String {
|
|||||||
|
|
||||||
- Query the agent environment:
|
- Query the agent environment:
|
||||||
|
|
||||||
$ {program} connect --server-address "{vsock_server_address}" --cmd GuestDetails
|
$ {program} connect --server-address "{vsock_server_address}" --cmd GetGuestDetails
|
||||||
|
|
||||||
- List all available (built-in and Kata Agent API) commands:
|
- List all available (built-in and Kata Agent API) commands:
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ fn make_examples_text(program_name: &str) -> String {
|
|||||||
|
|
||||||
- Query guest details forever:
|
- Query guest details forever:
|
||||||
|
|
||||||
$ {program} connect --server-address "{vsock_server_address}" --repeat -1 --cmd GuestDetails
|
$ {program} connect --server-address "{vsock_server_address}" --repeat -1 --cmd GetGuestDetails
|
||||||
|
|
||||||
- Send a 'SIGUSR1' signal to a container process:
|
- Send a 'SIGUSR1' signal to a container process:
|
||||||
|
|
||||||
|
@ -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)?)
|
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