mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-05-01 05:04:26 +00:00
agent-ctl: Update for Hybrid VSOCK
Allow the `agent-ctl` tool to connect to a Hybrid VSOCK hypervisor such as Cloud Hypervisor or Firecracker. Fixes: #2914. Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
This commit is contained in:
parent
d1bcf105ff
commit
82de838e5f
@ -19,6 +19,7 @@ vendor:
|
|||||||
test:
|
test:
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
@RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo install --target $(TRIPLE) --path .
|
||||||
|
|
||||||
check:
|
check:
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ the agent protocol and the client and server implementations.
|
|||||||
| 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 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. |
|
| Agent (server) API implementations | [`rpc.rs`](../../src/agent/src/rpc.rs) | `create_container()` | Server function that implements the `CreateContainers` API. |
|
||||||
|
|
||||||
## Running the tool
|
## Run the tool
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
@ -62,22 +62,31 @@ $ sudo docker export $(sudo docker create "$image") | tar -C "$rootfs_dir" -xvf
|
|||||||
|
|
||||||
### Connect to a real Kata Container
|
### Connect to a real Kata Container
|
||||||
|
|
||||||
|
The method used to connect to Kata Containers agent depends on the configured
|
||||||
|
hypervisor. Although by default the Kata Containers agent listens for API calls on a
|
||||||
|
VSOCK socket, the way that socket is exposed to the host depends on the
|
||||||
|
hypervisor.
|
||||||
|
|
||||||
|
#### QEMU
|
||||||
|
|
||||||
|
Since QEMU supports VSOCK sockets in the standard way, it is only necessary to
|
||||||
|
establish the VSOCK guest CID value to connect to the agent.
|
||||||
|
|
||||||
1. Start a Kata Container
|
1. Start a Kata Container
|
||||||
|
|
||||||
1. Establish the VSOCK guest CID number for the virtual machine:
|
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
|
```sh
|
||||||
$ guest_cid=$(ps -ef | grep qemu-system-x86_64 | egrep -o "guest-cid=[0-9]*" | cut -d= -f2)
|
$ guest_cid=$(sudo ss -H --vsock | awk '{print $6}' | cut -d: -f1)
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Run the tool to connect to the agent:
|
1. Run the tool to connect to the agent:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ cargo run -- -l debug connect --bundle-dir "${bundle_dir}" --server-address "vsock://${guest_cid}:1024" -c Check -c GetGuestDetails
|
# Default VSOCK port the agent listens on
|
||||||
|
$ agent_vsock_port=1024
|
||||||
|
|
||||||
|
$ cargo run -- -l debug connect --bundle-dir "${bundle_dir}" --server-address "vsock://${guest_cid}:${agent_vsock_port}" -c Check -c GetGuestDetails
|
||||||
```
|
```
|
||||||
|
|
||||||
This examples makes two API calls:
|
This examples makes two API calls:
|
||||||
@ -86,6 +95,75 @@ $ sudo docker export $(sudo docker create "$image") | tar -C "$rootfs_dir" -xvf
|
|||||||
- It then runs `GetGuestDetails` to establish some details of the
|
- It then runs `GetGuestDetails` to establish some details of the
|
||||||
environment the agent is running in.
|
environment the agent is running in.
|
||||||
|
|
||||||
|
#### Cloud Hypervisor and Firecracker
|
||||||
|
|
||||||
|
Cloud Hypervisor and Firecracker both use "hybrid VSOCK" which uses a local
|
||||||
|
UNIX socket rather than the host kernel to handle communication with the
|
||||||
|
guest. As such, you need to specify the path to the UNIX socket.
|
||||||
|
|
||||||
|
Since the UNIX socket path is sandbox-specific, you need to run the
|
||||||
|
`kata-runtime env` command to determine the socket's "template path". This
|
||||||
|
path includes a `{ID}` tag that represents the real sandbox ID or name.
|
||||||
|
|
||||||
|
Further, since the socket path is below the sandbox directory and since that
|
||||||
|
directory is `root` owned, it is necessary to run the tool as `root` when
|
||||||
|
using a Hybrid VSOCKS hypervisor.
|
||||||
|
|
||||||
|
##### Determine socket path template value
|
||||||
|
|
||||||
|
###### Configured hypervisor is Cloud Hypervisor
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ socket_path_template=$(sudo kata-runtime env --json | jq '.Hypervisor.SocketPath')
|
||||||
|
$ echo "$socket_path_template"
|
||||||
|
"/run/vc/vm/{ID}/clh.sock"
|
||||||
|
```
|
||||||
|
|
||||||
|
###### Configured hypervisor is Firecracker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ socket_path_template=$(sudo kata-runtime env --json | jq '.Hypervisor.SocketPath')
|
||||||
|
$ echo "$socket_path_template"
|
||||||
|
"/run/vc/firecracker/{ID}/root/kata.hvsock"
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:**
|
||||||
|
>
|
||||||
|
> Do not rely on the paths shown above: you should run the command yourself
|
||||||
|
> as these paths _may_ change.
|
||||||
|
|
||||||
|
Once you have determined the template path, build and install the tool to make
|
||||||
|
it easier to run as the `root` user.
|
||||||
|
|
||||||
|
##### Build and install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install for user
|
||||||
|
$ make install
|
||||||
|
|
||||||
|
# Install centrally
|
||||||
|
$ sudo install -o root -g root -m 0755 ~/.cargo/bin/kata-agent-ctl /usr/local/bin
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Start a Kata Container
|
||||||
|
|
||||||
|
Create a container called `foo`.
|
||||||
|
|
||||||
|
1. Run the tool
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Name of container
|
||||||
|
$ sandbox_id="foo"
|
||||||
|
|
||||||
|
# Create actual socket path
|
||||||
|
$ socket_path=$(echo "$socket_path_template" | sed "s/{ID}/${sandbox_id}/g" | tr -d '"')
|
||||||
|
|
||||||
|
$ sudo kata-agent-ctl -l debug connect --bundle-dir "${bundle_dir}" --server-address "unix://${socket_path}" --hybrid-vsock -c Check -c GetGuestDetails
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** The `socket_path_template` variable was set in the
|
||||||
|
> [Determine socket path template value](#determine-socket-path-template-value) section.
|
||||||
|
|
||||||
### Run the tool and the agent in the same environment
|
### Run the tool and the agent in the same environment
|
||||||
|
|
||||||
> **Warnings:**
|
> **Warnings:**
|
||||||
@ -100,6 +178,8 @@ $ sudo docker export $(sudo docker create "$image") | tar -C "$rootfs_dir" -xvf
|
|||||||
$ sudo KATA_AGENT_SERVER_ADDR=unix:///tmp/foo.socket target/x86_64-unknown-linux-musl/release/kata-agent
|
$ sudo KATA_AGENT_SERVER_ADDR=unix:///tmp/foo.socket target/x86_64-unknown-linux-musl/release/kata-agent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note:** This example assumes an Intel x86-64 system.
|
||||||
|
|
||||||
1. Run the tool in the same environment:
|
1. Run the tool in the same environment:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
@ -17,6 +17,7 @@ use protocols::health_ttrpc::*;
|
|||||||
use slog::{debug, info};
|
use slog::{debug, info};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Write; // XXX: for flush()
|
use std::io::Write; // XXX: for flush()
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
use std::os::unix::io::{IntoRawFd, RawFd};
|
use std::os::unix::io::{IntoRawFd, RawFd};
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
@ -87,11 +88,6 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
|
|||||||
st: ServiceType::Agent,
|
st: ServiceType::Agent,
|
||||||
fp: agent_cmd_sandbox_add_arp_neighbors,
|
fp: agent_cmd_sandbox_add_arp_neighbors,
|
||||||
},
|
},
|
||||||
AgentCmd {
|
|
||||||
name: "AddSwap",
|
|
||||||
st: ServiceType::Agent,
|
|
||||||
fp: agent_cmd_sandbox_add_swap,
|
|
||||||
},
|
|
||||||
AgentCmd {
|
AgentCmd {
|
||||||
name: "Check",
|
name: "Check",
|
||||||
st: ServiceType::Health,
|
st: ServiceType::Health,
|
||||||
@ -372,7 +368,59 @@ fn client_create_vsock_fd(cid: libc::c_uint, port: u32) -> Result<RawFd> {
|
|||||||
Ok(fd)
|
Ok(fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_ttrpc_client(server_address: String) -> Result<ttrpc::Client> {
|
// Setup the existing stream by making a Hybrid VSOCK host-initiated
|
||||||
|
// connection request to the Hybrid VSOCK-capable hypervisor (CLH or FC),
|
||||||
|
// asking it to route the connection to the Kata Agent running inside the VM.
|
||||||
|
fn setup_hybrid_vsock(mut stream: &UnixStream, hybrid_vsock_port: u64) -> Result<()> {
|
||||||
|
// Challenge message sent to the Hybrid VSOCK capable hypervisor asking
|
||||||
|
// for a connection to a real VSOCK server running in the VM on the
|
||||||
|
// port specified as part of this message.
|
||||||
|
const CONNECT_CMD: &str = "CONNECT";
|
||||||
|
|
||||||
|
// Expected response message returned by the Hybrid VSOCK capable
|
||||||
|
// hypervisor informing the client that the CONNECT_CMD was successful.
|
||||||
|
const OK_CMD: &str = "OK";
|
||||||
|
|
||||||
|
// Contact the agent by dialing it's port number and
|
||||||
|
// waiting for the hybrid vsock hypervisor to route the call for us ;)
|
||||||
|
//
|
||||||
|
// See: https://github.com/firecracker-microvm/firecracker/blob/main/docs/vsock.md#host-initiated-connections
|
||||||
|
let msg = format!("{} {}\n", CONNECT_CMD, hybrid_vsock_port);
|
||||||
|
|
||||||
|
stream.write_all(msg.as_bytes())?;
|
||||||
|
|
||||||
|
// Now, see if we get the expected response
|
||||||
|
let stream_reader = stream.try_clone()?;
|
||||||
|
let mut reader = BufReader::new(&stream_reader);
|
||||||
|
|
||||||
|
let mut msg = String::new();
|
||||||
|
reader.read_line(&mut msg)?;
|
||||||
|
|
||||||
|
if msg.starts_with(OK_CMD) {
|
||||||
|
let response = msg
|
||||||
|
.strip_prefix(OK_CMD)
|
||||||
|
.ok_or(format!("invalid response: {:?}", msg))
|
||||||
|
.map_err(|e| anyhow!(e))?
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
debug!(sl!(), "Hybrid VSOCK host-side port: {:?}", response);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"failed to setup Hybrid VSOCK connection: response was: {:?}",
|
||||||
|
msg
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Unix stream is now connected directly to the VSOCK socket
|
||||||
|
// the Kata agent is listening to in the VM.
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_ttrpc_client(
|
||||||
|
server_address: String,
|
||||||
|
hybrid_vsock_port: u64,
|
||||||
|
hybrid_vsock: bool,
|
||||||
|
) -> Result<ttrpc::Client> {
|
||||||
if server_address == "" {
|
if server_address == "" {
|
||||||
return Err(anyhow!("server address cannot be blank"));
|
return Err(anyhow!("server address cannot be blank"));
|
||||||
}
|
}
|
||||||
@ -388,7 +436,7 @@ fn create_ttrpc_client(server_address: String) -> Result<ttrpc::Client> {
|
|||||||
let fd: RawFd = match scheme.as_str() {
|
let fd: RawFd = match scheme.as_str() {
|
||||||
// Formats:
|
// Formats:
|
||||||
//
|
//
|
||||||
// - "unix://absolute-path" (domain socket)
|
// - "unix://absolute-path" (domain socket, or hybrid vsock!)
|
||||||
// (example: "unix:///tmp/domain.socket")
|
// (example: "unix:///tmp/domain.socket")
|
||||||
//
|
//
|
||||||
// - "unix://@absolute-path" (abstract socket)
|
// - "unix://@absolute-path" (abstract socket)
|
||||||
@ -445,6 +493,10 @@ fn create_ttrpc_client(server_address: String) -> Result<ttrpc::Client> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if hybrid_vsock {
|
||||||
|
setup_hybrid_vsock(&stream, hybrid_vsock_port)?
|
||||||
|
}
|
||||||
|
|
||||||
stream.into_raw_fd()
|
stream.into_raw_fd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -481,14 +533,22 @@ fn create_ttrpc_client(server_address: String) -> Result<ttrpc::Client> {
|
|||||||
Ok(ttrpc::client::Client::new(fd))
|
Ok(ttrpc::client::Client::new(fd))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kata_service_agent(server_address: String) -> Result<AgentServiceClient> {
|
fn kata_service_agent(
|
||||||
let ttrpc_client = create_ttrpc_client(server_address)?;
|
server_address: String,
|
||||||
|
hybrid_vsock_port: u64,
|
||||||
|
hybrid_vsock: bool,
|
||||||
|
) -> Result<AgentServiceClient> {
|
||||||
|
let ttrpc_client = create_ttrpc_client(server_address, hybrid_vsock_port, hybrid_vsock)?;
|
||||||
|
|
||||||
Ok(AgentServiceClient::new(ttrpc_client))
|
Ok(AgentServiceClient::new(ttrpc_client))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kata_service_health(server_address: String) -> Result<HealthClient> {
|
fn kata_service_health(
|
||||||
let ttrpc_client = create_ttrpc_client(server_address)?;
|
server_address: String,
|
||||||
|
hybrid_vsock_port: u64,
|
||||||
|
hybrid_vsock: bool,
|
||||||
|
) -> Result<HealthClient> {
|
||||||
|
let ttrpc_client = create_ttrpc_client(server_address, hybrid_vsock_port, hybrid_vsock)?;
|
||||||
|
|
||||||
Ok(HealthClient::new(ttrpc_client))
|
Ok(HealthClient::new(ttrpc_client))
|
||||||
}
|
}
|
||||||
@ -522,8 +582,17 @@ pub fn client(cfg: &Config, commands: Vec<&str>) -> Result<()> {
|
|||||||
|
|
||||||
// Create separate connections for each of the services provided
|
// Create separate connections for each of the services provided
|
||||||
// by the agent.
|
// by the agent.
|
||||||
let client = kata_service_agent(cfg.server_address.clone())?;
|
let client = kata_service_agent(
|
||||||
let health = kata_service_health(cfg.server_address.clone())?;
|
cfg.server_address.clone(),
|
||||||
|
cfg.hybrid_vsock_port,
|
||||||
|
cfg.hybrid_vsock,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let health = kata_service_health(
|
||||||
|
cfg.server_address.clone(),
|
||||||
|
cfg.hybrid_vsock_port,
|
||||||
|
cfg.hybrid_vsock,
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut options = Options::new();
|
let mut options = Options::new();
|
||||||
|
|
||||||
@ -1923,29 +1992,3 @@ fn get_repeat_count(cmdline: &str) -> i64 {
|
|||||||
Err(_) => return default_repeat_count,
|
Err(_) => return default_repeat_count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn agent_cmd_sandbox_add_swap(
|
|
||||||
ctx: &Context,
|
|
||||||
client: &AgentServiceClient,
|
|
||||||
_health: &HealthClient,
|
|
||||||
_options: &mut Options,
|
|
||||||
_args: &str,
|
|
||||||
) -> Result<()> {
|
|
||||||
let req = AddSwapRequest::default();
|
|
||||||
|
|
||||||
let ctx = clone_context(ctx);
|
|
||||||
|
|
||||||
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
|
|
||||||
|
|
||||||
let reply = client
|
|
||||||
.add_swap(ctx, &req)
|
|
||||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
|
||||||
|
|
||||||
// FIXME: Implement 'AddSwap' fully.
|
|
||||||
eprintln!("FIXME: 'AddSwap' not fully implemented");
|
|
||||||
|
|
||||||
info!(sl!(), "response received";
|
|
||||||
"response" => format!("{:?}", reply));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
use crate::types::Config;
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use clap::{crate_name, crate_version, App, Arg, SubCommand};
|
use clap::{crate_name, crate_version, App, Arg, SubCommand};
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -39,6 +40,9 @@ const WARNING_TEXT: &str = r#"WARNING:
|
|||||||
irrevocably other parts of the system or even kill a running container or
|
irrevocably other parts of the system or even kill a running container or
|
||||||
sandbox."#;
|
sandbox."#;
|
||||||
|
|
||||||
|
// The VSOCK port number the Kata agent uses to listen to API requests on.
|
||||||
|
const DEFAULT_KATA_AGENT_API_VSOCK_PORT: &str = "1024";
|
||||||
|
|
||||||
fn make_examples_text(program_name: &str) -> String {
|
fn make_examples_text(program_name: &str) -> String {
|
||||||
let abstract_server_address = "unix://@/foo/bar/abstract.socket";
|
let abstract_server_address = "unix://@/foo/bar/abstract.socket";
|
||||||
let bundle = "$bundle_dir";
|
let bundle = "$bundle_dir";
|
||||||
@ -47,6 +51,7 @@ fn make_examples_text(program_name: &str) -> String {
|
|||||||
let local_server_address = "unix:///tmp/local.socket";
|
let local_server_address = "unix:///tmp/local.socket";
|
||||||
let sandbox_id = "$sandbox_id";
|
let sandbox_id = "$sandbox_id";
|
||||||
let vsock_server_address = "vsock://3:1024";
|
let vsock_server_address = "vsock://3:1024";
|
||||||
|
let hybrid_vsock_server_address = "unix:///run/vc/vm/foo/clh.sock";
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
r#"EXAMPLES:
|
r#"EXAMPLES:
|
||||||
@ -55,6 +60,10 @@ fn make_examples_text(program_name: &str) -> String {
|
|||||||
|
|
||||||
$ {program} connect --server-address "{vsock_server_address}" --cmd Check
|
$ {program} connect --server-address "{vsock_server_address}" --cmd Check
|
||||||
|
|
||||||
|
- Connect to the agent using a Hybrid VSOCK hypervisor (here Cloud Hypervisor):
|
||||||
|
|
||||||
|
$ {program} connect --server-address "{hybrid_vsock_server_address}" --hybrid-vsock --cmd Check
|
||||||
|
|
||||||
- Connect to the agent using local sockets (when running in same environment as the agent):
|
- Connect to the agent using local sockets (when running in same environment as the agent):
|
||||||
|
|
||||||
# Local socket
|
# Local socket
|
||||||
@ -109,6 +118,7 @@ fn make_examples_text(program_name: &str) -> String {
|
|||||||
program = program_name,
|
program = program_name,
|
||||||
sandbox_id = sandbox_id,
|
sandbox_id = sandbox_id,
|
||||||
vsock_server_address = vsock_server_address,
|
vsock_server_address = vsock_server_address,
|
||||||
|
hybrid_vsock_server_address = hybrid_vsock_server_address,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +134,8 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
|
|||||||
let server_address = args
|
let server_address = args
|
||||||
.value_of("server-address")
|
.value_of("server-address")
|
||||||
.ok_or("need server adddress".to_string())
|
.ok_or("need server adddress".to_string())
|
||||||
.map_err(|e| anyhow!(e))?;
|
.map_err(|e| anyhow!(e))?
|
||||||
|
.to_string();
|
||||||
|
|
||||||
let mut commands: Vec<&str> = Vec::new();
|
let mut commands: Vec<&str> = Vec::new();
|
||||||
|
|
||||||
@ -149,17 +160,28 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
|
|||||||
None => 0,
|
None => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bundle_dir = args.value_of("bundle-dir").unwrap_or("");
|
let hybrid_vsock_port: u64 = args
|
||||||
|
.value_of("hybrid-vsock-port")
|
||||||
|
.ok_or("Need Hybrid VSOCK port number")
|
||||||
|
.map(|p| p.parse::<u64>().unwrap())
|
||||||
|
.map_err(|e| anyhow!("VSOCK port number must be an integer: {:?}", e))?;
|
||||||
|
|
||||||
let result = rpc::run(
|
let bundle_dir = args.value_of("bundle-dir").unwrap_or("").to_string();
|
||||||
&logger,
|
|
||||||
|
let hybrid_vsock = args.is_present("hybrid-vsock");
|
||||||
|
|
||||||
|
let cfg = Config {
|
||||||
server_address,
|
server_address,
|
||||||
bundle_dir,
|
bundle_dir,
|
||||||
interactive,
|
interactive,
|
||||||
ignore_errors,
|
ignore_errors,
|
||||||
timeout_nano,
|
timeout_nano,
|
||||||
commands,
|
hybrid_vsock_port,
|
||||||
);
|
hybrid_vsock,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = rpc::run(&logger, &cfg, commands);
|
||||||
|
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -170,6 +192,11 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
|
|||||||
fn real_main() -> Result<()> {
|
fn real_main() -> Result<()> {
|
||||||
let name = crate_name!();
|
let name = crate_name!();
|
||||||
|
|
||||||
|
let hybrid_vsock_port_help = format!(
|
||||||
|
"Kata agent VSOCK port number (only useful with --hybrid-vsock) [default: {}]",
|
||||||
|
DEFAULT_KATA_AGENT_API_VSOCK_PORT
|
||||||
|
);
|
||||||
|
|
||||||
let app = App::new(name)
|
let app = App::new(name)
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
.about(ABOUT_TEXT)
|
.about(ABOUT_TEXT)
|
||||||
@ -209,6 +236,19 @@ fn real_main() -> Result<()> {
|
|||||||
.long("ignore-errors")
|
.long("ignore-errors")
|
||||||
.help("Don't exit on first error"),
|
.help("Don't exit on first error"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("hybrid-vsock")
|
||||||
|
.long("hybrid-vsock")
|
||||||
|
.help("Treat a unix:// server address as a Hybrid VSOCK one"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("hybrid-vsock-port")
|
||||||
|
.long("hybrid-vsock-port")
|
||||||
|
.help(&hybrid_vsock_port_help)
|
||||||
|
.default_value(DEFAULT_KATA_AGENT_API_VSOCK_PORT)
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("PORT")
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("interactive")
|
Arg::with_name("interactive")
|
||||||
.short("i")
|
.short("i")
|
||||||
|
@ -11,25 +11,9 @@ use slog::{o, Logger};
|
|||||||
use crate::client::client;
|
use crate::client::client;
|
||||||
use crate::types::Config;
|
use crate::types::Config;
|
||||||
|
|
||||||
pub fn run(
|
pub fn run(logger: &Logger, cfg: &Config, commands: Vec<&str>) -> Result<()> {
|
||||||
logger: &Logger,
|
|
||||||
server_address: &str,
|
|
||||||
bundle_dir: &str,
|
|
||||||
interactive: bool,
|
|
||||||
ignore_errors: bool,
|
|
||||||
timeout_nano: i64,
|
|
||||||
commands: Vec<&str>,
|
|
||||||
) -> Result<()> {
|
|
||||||
let cfg = Config {
|
|
||||||
server_address: server_address.to_string(),
|
|
||||||
bundle_dir: bundle_dir.to_string(),
|
|
||||||
timeout_nano: timeout_nano,
|
|
||||||
interactive: interactive,
|
|
||||||
ignore_errors: ignore_errors,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Maintain the global logger for the duration of the ttRPC comms
|
// Maintain the global logger for the duration of the ttRPC comms
|
||||||
let _guard = slog_scope::set_global_logger(logger.new(o!("subsystem" => "rpc")));
|
let _guard = slog_scope::set_global_logger(logger.new(o!("subsystem" => "rpc")));
|
||||||
|
|
||||||
client(&cfg, commands)
|
client(cfg, commands)
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ pub struct Config {
|
|||||||
pub server_address: String,
|
pub server_address: String,
|
||||||
pub bundle_dir: String,
|
pub bundle_dir: String,
|
||||||
pub timeout_nano: i64,
|
pub timeout_nano: i64,
|
||||||
|
pub hybrid_vsock_port: u64,
|
||||||
pub interactive: bool,
|
pub interactive: bool,
|
||||||
|
pub hybrid_vsock: bool,
|
||||||
pub ignore_errors: bool,
|
pub ignore_errors: bool,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user