mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 12:14:48 +00:00
tools: Add Unix socket support to agentl-ctl
Rather than specifying the VSOCK address as two CLI options (`--vsock-cid` and `--vsock-port`), allow the agent's ttRPC server address to be specified to the `agent-ctl` tool using a single URI `--server-address` CLI option. Since the ttrpc crate supports VSOCK and UNIX schemes, this allows the tool to be run inside the VM by specifying a UNIX address. Fixes: #549. Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
This commit is contained in:
parent
7be95b15eb
commit
10b1deb274
@ -8,7 +8,7 @@
|
||||
use crate::types::{Config, Options};
|
||||
use crate::utils;
|
||||
use anyhow::{anyhow, Result};
|
||||
use nix::sys::socket::{connect, socket, AddressFamily, SockAddr, SockFlag, SockType};
|
||||
use nix::sys::socket::{connect, socket, AddressFamily, SockAddr, SockFlag, SockType, UnixAddr};
|
||||
use protocols::agent::*;
|
||||
use protocols::agent_ttrpc::*;
|
||||
use protocols::health::*;
|
||||
@ -16,7 +16,8 @@ use protocols::health_ttrpc::*;
|
||||
use slog::{debug, info};
|
||||
use std::io;
|
||||
use std::io::Write; // XXX: for flush()
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::os::unix::io::{IntoRawFd, RawFd};
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use ttrpc;
|
||||
@ -294,25 +295,123 @@ fn client_create_vsock_fd(cid: libc::c_uint, port: u32) -> Result<RawFd> {
|
||||
Ok(fd)
|
||||
}
|
||||
|
||||
fn create_ttrpc_client(cid: libc::c_uint, port: u32) -> Result<ttrpc::Client> {
|
||||
let fd = client_create_vsock_fd(cid, port).map_err(|e| {
|
||||
anyhow!(format!(
|
||||
"failed to create VSOCK connection (check agent is running): {:?}",
|
||||
e
|
||||
))
|
||||
fn create_ttrpc_client(server_address: String) -> Result<ttrpc::Client> {
|
||||
if server_address == "" {
|
||||
return Err(anyhow!("server address cannot be blank"));
|
||||
}
|
||||
|
||||
let fields: Vec<&str> = server_address.split("://").collect();
|
||||
|
||||
if fields.len() != 2 {
|
||||
return Err(anyhow!("invalid server address URI"));
|
||||
}
|
||||
|
||||
let scheme = fields[0].to_lowercase();
|
||||
|
||||
let fd: RawFd = match scheme.as_str() {
|
||||
// Formats:
|
||||
//
|
||||
// - "unix://absolute-path" (domain socket)
|
||||
// (example: "unix:///tmp/domain.socket")
|
||||
//
|
||||
// - "unix://@absolute-path" (abstract socket)
|
||||
// (example: "unix://@/tmp/abstract.socket")
|
||||
//
|
||||
"unix" => {
|
||||
let mut abstract_socket = false;
|
||||
|
||||
let mut path = fields[1].to_string();
|
||||
|
||||
if path.starts_with('@') {
|
||||
abstract_socket = true;
|
||||
|
||||
// Remove the magic abstract-socket request character ('@')
|
||||
// and crucially add a trailing nul terminator (required to
|
||||
// interoperate with the ttrpc crate).
|
||||
path = path[1..].to_string() + &"\x00".to_string();
|
||||
}
|
||||
|
||||
if abstract_socket {
|
||||
let socket_fd = match socket(
|
||||
AddressFamily::Unix,
|
||||
SockType::Stream,
|
||||
SockFlag::empty(),
|
||||
None,
|
||||
) {
|
||||
Ok(s) => s,
|
||||
Err(e) => return Err(anyhow!(e).context("Failed to create Unix Domain socket")),
|
||||
};
|
||||
|
||||
let unix_addr = match UnixAddr::new_abstract(path.as_bytes()) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
return Err(
|
||||
anyhow!(e).context("Failed to create Unix Domain abstract socket")
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let sock_addr = SockAddr::Unix(unix_addr);
|
||||
|
||||
connect(socket_fd, &sock_addr).map_err(|e| {
|
||||
anyhow!(e).context("Failed to connect to Unix Domain abstract socket")
|
||||
})?;
|
||||
|
||||
socket_fd
|
||||
} else {
|
||||
let stream = match UnixStream::connect(path) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
return Err(
|
||||
anyhow!(e).context("failed to create named UNIX Domain stream socket")
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
stream.into_raw_fd()
|
||||
}
|
||||
}
|
||||
// Format: "vsock://cid:port"
|
||||
"vsock" => {
|
||||
let addr: Vec<&str> = fields[1].split(':').collect();
|
||||
|
||||
if addr.len() != 2 {
|
||||
return Err(anyhow!("invalid VSOCK server address URI"));
|
||||
}
|
||||
|
||||
let cid: u32 = match addr[0] {
|
||||
"-1" | "" => libc::VMADDR_CID_ANY,
|
||||
_ => match addr[0].parse::<u32>() {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(anyhow!(e).context("VSOCK CID is not numeric")),
|
||||
},
|
||||
};
|
||||
|
||||
let port: u32 = match addr[1].parse::<u32>() {
|
||||
Ok(r) => r,
|
||||
Err(e) => return Err(anyhow!(e).context("VSOCK port is not numeric")),
|
||||
};
|
||||
|
||||
client_create_vsock_fd(cid, port).map_err(|e| {
|
||||
anyhow!(e).context("failed to create VSOCK connection (check agent is running)")
|
||||
})?
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow!("invalid server address URI scheme: {:?}", scheme));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(ttrpc::client::Client::new(fd))
|
||||
}
|
||||
|
||||
fn kata_service_agent(cid: libc::c_uint, port: u32) -> Result<AgentServiceClient> {
|
||||
let ttrpc_client = create_ttrpc_client(cid, port)?;
|
||||
fn kata_service_agent(server_address: String) -> Result<AgentServiceClient> {
|
||||
let ttrpc_client = create_ttrpc_client(server_address)?;
|
||||
|
||||
Ok(AgentServiceClient::new(ttrpc_client))
|
||||
}
|
||||
|
||||
fn kata_service_health(cid: libc::c_uint, port: u32) -> Result<HealthClient> {
|
||||
let ttrpc_client = create_ttrpc_client(cid, port)?;
|
||||
fn kata_service_health(server_address: String) -> Result<HealthClient> {
|
||||
let ttrpc_client = create_ttrpc_client(server_address)?;
|
||||
|
||||
Ok(HealthClient::new(ttrpc_client))
|
||||
}
|
||||
@ -344,15 +443,10 @@ pub fn client(cfg: &Config, commands: Vec<&str>) -> Result<()> {
|
||||
|
||||
announce(cfg);
|
||||
|
||||
let cid = cfg.cid;
|
||||
let port = cfg.port;
|
||||
|
||||
let addr = format!("vsock://{}:{}", cid, port);
|
||||
|
||||
// Create separate connections for each of the services provided
|
||||
// by the agent.
|
||||
let client = kata_service_agent(cid, port as u32)?;
|
||||
let health = kata_service_health(cid, port as u32)?;
|
||||
let client = kata_service_agent(cfg.server_address.clone())?;
|
||||
let health = kata_service_health(cfg.server_address.clone())?;
|
||||
|
||||
let mut options = Options::new();
|
||||
|
||||
@ -365,7 +459,7 @@ pub fn client(cfg: &Config, commands: Vec<&str>) -> Result<()> {
|
||||
options.insert("bundle-dir".to_string(), cfg.bundle_dir.clone());
|
||||
|
||||
info!(sl!(), "client setup complete";
|
||||
"server-address" => addr);
|
||||
"server-address" => cfg.server_address.to_string());
|
||||
|
||||
if cfg.interactive {
|
||||
return interactive_client_loop(&cfg, &mut options, &client, &health);
|
||||
@ -533,8 +627,8 @@ fn interactive_client_loop(
|
||||
let mut repeat_count: i64 = 1;
|
||||
|
||||
loop {
|
||||
let cmdline = readline("Enter command")
|
||||
.map_err(|e| anyhow!(format!("failed to read line: {}", e)))?;
|
||||
let cmdline =
|
||||
readline("Enter command").map_err(|e| anyhow!(e).context("failed to read line"))?;
|
||||
|
||||
if cmdline == "" {
|
||||
continue;
|
||||
@ -592,7 +686,7 @@ fn agent_cmd_health_check(
|
||||
|
||||
let reply = health
|
||||
.check(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -615,7 +709,7 @@ fn agent_cmd_health_version(
|
||||
|
||||
let reply = health
|
||||
.version(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -637,7 +731,7 @@ fn agent_cmd_sandbox_create(
|
||||
|
||||
let reply = client
|
||||
.create_sandbox(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -656,7 +750,7 @@ fn agent_cmd_sandbox_destroy(
|
||||
|
||||
let reply = client
|
||||
.destroy_sandbox(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -686,7 +780,7 @@ fn agent_cmd_container_create(
|
||||
|
||||
let reply = client
|
||||
.create_container(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -709,7 +803,7 @@ fn agent_cmd_container_remove(
|
||||
|
||||
let reply = client
|
||||
.remove_container(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -746,7 +840,7 @@ fn agent_cmd_container_exec(
|
||||
|
||||
let reply = client
|
||||
.exec_process(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -769,7 +863,7 @@ fn agent_cmd_container_stats(
|
||||
|
||||
let reply = client
|
||||
.stats_container(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -792,7 +886,7 @@ fn agent_cmd_container_pause(
|
||||
|
||||
let reply = client
|
||||
.pause_container(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -815,7 +909,7 @@ fn agent_cmd_container_resume(
|
||||
|
||||
let reply = client
|
||||
.resume_container(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -838,7 +932,7 @@ fn agent_cmd_container_start(
|
||||
|
||||
let reply = client
|
||||
.start_container(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -859,7 +953,7 @@ fn agent_cmd_sandbox_guest_details(
|
||||
|
||||
let reply = client
|
||||
.get_guest_details(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -889,7 +983,7 @@ fn agent_cmd_container_list_processes(
|
||||
|
||||
let reply = client
|
||||
.list_processes(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -914,7 +1008,7 @@ fn agent_cmd_container_wait_process(
|
||||
|
||||
let reply = client
|
||||
.wait_process(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -949,7 +1043,7 @@ fn agent_cmd_container_signal_process(
|
||||
|
||||
let reply = client
|
||||
.signal_process(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -968,7 +1062,7 @@ fn agent_cmd_sandbox_tracing_start(
|
||||
|
||||
let reply = client
|
||||
.start_tracing(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -987,7 +1081,7 @@ fn agent_cmd_sandbox_tracing_stop(
|
||||
|
||||
let reply = client
|
||||
.stop_tracing(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -1006,7 +1100,7 @@ fn agent_cmd_sandbox_update_interface(
|
||||
|
||||
let reply = client
|
||||
.update_interface(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
// FIXME: Implement 'UpdateInterface' fully.
|
||||
eprintln!("FIXME: 'UpdateInterface' not fully implemented");
|
||||
@ -1031,7 +1125,7 @@ fn agent_cmd_sandbox_update_routes(
|
||||
|
||||
let reply = client
|
||||
.update_routes(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
// FIXME: Implement 'UpdateRoutes' fully.
|
||||
eprintln!("FIXME: 'UpdateRoutes' not fully implemented");
|
||||
@ -1056,7 +1150,7 @@ fn agent_cmd_sandbox_list_interfaces(
|
||||
|
||||
let reply = client
|
||||
.list_interfaces(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
@ -1075,7 +1169,7 @@ fn agent_cmd_sandbox_list_routes(
|
||||
|
||||
let reply = client
|
||||
.list_routes(&req, cfg.timeout_nano)
|
||||
.map_err(|e| anyhow!(format!("{}: {:?}", ERR_API_FAILED, e)))?;
|
||||
.map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
|
||||
|
||||
info!(sl!(), "response received";
|
||||
"response" => format!("{:?}", reply));
|
||||
|
@ -40,27 +40,36 @@ const WARNING_TEXT: &str = r#"WARNING:
|
||||
sandbox."#;
|
||||
|
||||
fn make_examples_text(program_name: &str) -> String {
|
||||
let abstract_server_address = "unix://@/foo/bar/abstract.socket";
|
||||
let bundle = "$bundle_dir";
|
||||
let cid = 3;
|
||||
let container_id = "$container_id";
|
||||
let config_file_uri = "file:///tmp/config.json";
|
||||
let port = 1024;
|
||||
let container_id = "$container_id";
|
||||
let local_server_address = "unix:///tmp/local.socket";
|
||||
let sandbox_id = "$sandbox_id";
|
||||
let vsock_server_address = "vsock://3:1024";
|
||||
|
||||
format!(
|
||||
r#"EXAMPLES:
|
||||
|
||||
- Check if the agent is running:
|
||||
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --cmd Check
|
||||
$ {program} connect --server-address "{vsock_server_address}" --cmd Check
|
||||
|
||||
- Connect to the agent using local sockets (when running in same environment as the agent):
|
||||
|
||||
# Local socket
|
||||
$ {program} connect --server-address "{local_server_address}" --cmd Check
|
||||
|
||||
# Abstract socket
|
||||
$ {program} connect --server-address "{abstract_server_address}" --cmd Check
|
||||
|
||||
- Query the agent environment:
|
||||
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --cmd GuestDetails
|
||||
$ {program} connect --server-address "{vsock_server_address}" --cmd GuestDetails
|
||||
|
||||
- List all available (built-in and Kata Agent API) commands:
|
||||
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --cmd list
|
||||
$ {program} connect --server-address "{vsock_server_address}" --cmd list
|
||||
|
||||
- Generate a random container ID:
|
||||
|
||||
@ -72,33 +81,34 @@ fn make_examples_text(program_name: &str) -> String {
|
||||
|
||||
- Attempt to create 7 sandboxes, ignoring any errors:
|
||||
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --repeat 7 --cmd CreateSandbox
|
||||
$ {program} connect --server-address "{vsock_server_address}" --repeat 7 --cmd CreateSandbox
|
||||
|
||||
- Query guest details forever:
|
||||
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --repeat -1 --cmd GuestDetails
|
||||
$ {program} connect --server-address "{vsock_server_address}" --repeat -1 --cmd GuestDetails
|
||||
|
||||
- Send a 'SIGUSR1' signal to a container process:
|
||||
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --cmd 'SignalProcess signal=usr1 sid={sandbox_id} cid={container_id}'
|
||||
$ {program} connect --server-address "{vsock_server_address}" --cmd 'SignalProcess signal=usr1 sid={sandbox_id} cid={container_id}'
|
||||
|
||||
- Create a sandbox with a single container, and then destroy everything:
|
||||
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --cmd CreateSandbox
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --bundle-dir {bundle:?} --cmd CreateContainer
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --cmd DestroySandbox
|
||||
$ {program} connect --server-address "{vsock_server_address}" --cmd CreateSandbox
|
||||
$ {program} connect --server-address "{vsock_server_address}" --bundle-dir {bundle:?} --cmd CreateContainer
|
||||
$ {program} connect --server-address "{vsock_server_address}" --cmd DestroySandbox
|
||||
|
||||
- Create a Container using a custom configuration file:
|
||||
|
||||
$ {program} connect --vsock-cid {cid} --vsock-port {port} --bundle-dir {bundle:?} --cmd 'CreateContainer spec={config_file_uri}'
|
||||
$ {program} connect --server-address "{vsock_server_address}" --bundle-dir {bundle:?} --cmd 'CreateContainer spec={config_file_uri}'
|
||||
"#,
|
||||
abstract_server_address = abstract_server_address,
|
||||
bundle = bundle,
|
||||
cid = cid,
|
||||
config_file_uri = config_file_uri,
|
||||
container_id = container_id,
|
||||
port = port,
|
||||
local_server_address = local_server_address,
|
||||
program = program_name,
|
||||
sandbox_id = sandbox_id,
|
||||
vsock_server_address = vsock_server_address,
|
||||
)
|
||||
}
|
||||
|
||||
@ -111,24 +121,11 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
|
||||
let interactive = args.is_present("interactive");
|
||||
let ignore_errors = args.is_present("ignore-errors");
|
||||
|
||||
let cid_str = args
|
||||
.value_of("vsock-cid")
|
||||
.ok_or("need VSOCK cid".to_string())
|
||||
let server_address = args
|
||||
.value_of("server-address")
|
||||
.ok_or("need server adddress".to_string())
|
||||
.map_err(|e| anyhow!(e))?;
|
||||
|
||||
let port_str = args
|
||||
.value_of("vsock-port")
|
||||
.ok_or("need VSOCK port number".to_string())
|
||||
.map_err(|e| anyhow!(e))?;
|
||||
|
||||
let cid: u32 = cid_str
|
||||
.parse::<u32>()
|
||||
.map_err(|e| anyhow!(format!("invalid VSOCK CID number: {}", e.to_string())))?;
|
||||
|
||||
let port: u32 = port_str
|
||||
.parse::<u32>()
|
||||
.map_err(|e| anyhow!(format!("invalid VSOCK port number: {}", e)))?;
|
||||
|
||||
let mut commands: Vec<&str> = Vec::new();
|
||||
|
||||
if !interactive {
|
||||
@ -156,8 +153,7 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
|
||||
|
||||
let result = rpc::run(
|
||||
&logger,
|
||||
cid,
|
||||
port,
|
||||
server_address,
|
||||
bundle_dir,
|
||||
interactive,
|
||||
ignore_errors,
|
||||
@ -200,13 +196,6 @@ fn real_main() -> Result<()> {
|
||||
.takes_value(true)
|
||||
.value_name("directory"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("vsock-cid")
|
||||
.long("vsock-cid")
|
||||
.help("VSOCK Context ID")
|
||||
.takes_value(true)
|
||||
.value_name("CID"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("cmd")
|
||||
.long("cmd")
|
||||
@ -227,11 +216,11 @@ fn real_main() -> Result<()> {
|
||||
.help("Allow interactive client"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("vsock-port")
|
||||
.long("vsock-port")
|
||||
.help("VSOCK Port number")
|
||||
Arg::with_name("server-address")
|
||||
.long("server-address")
|
||||
.help("server URI (vsock:// or unix://)")
|
||||
.takes_value(true)
|
||||
.value_name("port-number"),
|
||||
.value_name("URI"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("timeout")
|
||||
|
@ -13,8 +13,7 @@ use crate::types::Config;
|
||||
|
||||
pub fn run(
|
||||
logger: &Logger,
|
||||
cid: u32,
|
||||
port: u32,
|
||||
server_address: &str,
|
||||
bundle_dir: &str,
|
||||
interactive: bool,
|
||||
ignore_errors: bool,
|
||||
@ -22,8 +21,7 @@ pub fn run(
|
||||
commands: Vec<&str>,
|
||||
) -> Result<()> {
|
||||
let cfg = Config {
|
||||
cid: cid,
|
||||
port: port,
|
||||
server_address: server_address.to_string(),
|
||||
bundle_dir: bundle_dir.to_string(),
|
||||
timeout_nano: timeout_nano,
|
||||
interactive: interactive,
|
||||
|
@ -11,8 +11,7 @@ pub type Options = HashMap<String, String>;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
pub cid: u32,
|
||||
pub port: u32,
|
||||
pub server_address: String,
|
||||
pub bundle_dir: String,
|
||||
pub timeout_nano: i64,
|
||||
pub interactive: bool,
|
||||
|
@ -250,7 +250,7 @@ fn config_file_from_bundle_dir(bundle_dir: &str) -> Result<String> {
|
||||
config_path
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.map_err(|e| anyhow!(format!("failed to construct config file path: {:?}", e)))
|
||||
.map_err(|e| anyhow!("{:?}", e).context("failed to construct config file path"))
|
||||
}
|
||||
|
||||
fn root_oci_to_grpc(bundle_dir: &str, root: &ociRoot) -> Result<grpcRoot> {
|
||||
@ -265,7 +265,7 @@ fn root_oci_to_grpc(bundle_dir: &str, root: &ociRoot) -> Result<grpcRoot> {
|
||||
abs_root_dir
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.map_err(|e| anyhow!(format!("failed to construct bundle path: {:?}", e)))?
|
||||
.map_err(|e| anyhow!("{:?}", e).context("failed to construct bundle path"))?
|
||||
};
|
||||
|
||||
let grpc_root = grpcRoot {
|
||||
|
Loading…
Reference in New Issue
Block a user