Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yield more information about services to client #30

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 4 additions & 0 deletions api/admin/admin.proto
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ message QueryListItem {
string Description = 2;
string VmStatus = 3;
string TrustLevel = 4;
string VmType = 5;
string ServiceType = 6;
optional string VmName = 7; // None for host running services
optional string AgentName = 8; // None for agents
}

message QueryListResponse {
Expand Down
69 changes: 57 additions & 12 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub use givc_common::query::{Event, QueryResult};
use givc_common::types::*;

use crate::endpoint::{EndpointConfig, TlsConfig};
use crate::error::rewrap_error;

type Client = pb::admin_service_client::AdminServiceClient<Channel>;

Expand Down Expand Up @@ -94,7 +95,12 @@ impl AdminClient {
vm_name,
args,
};
let _response = self.connect_to().await?.start_application(request).await?;
let _response = self
.connect_to()
.await?
.start_application(request)
.await
.map_err(rewrap_error)?;
Ok(())
}

Expand All @@ -104,7 +110,12 @@ impl AdminClient {
vm_name: None,
args: Vec::new(),
};
let _response = self.connect_to().await?.stop_application(request).await?;
let _response = self
.connect_to()
.await?
.stop_application(request)
.await
.map_err(rewrap_error)?;
Ok(())
}

Expand All @@ -114,7 +125,12 @@ impl AdminClient {
vm_name: None,
args: Vec::new(),
};
let _response = self.connect_to().await?.pause_application(request).await?;
let _response = self
.connect_to()
.await?
.pause_application(request)
.await
.map_err(rewrap_error)?;
Ok(())
}

Expand All @@ -124,31 +140,56 @@ impl AdminClient {
vm_name: None,
args: Vec::new(),
};
let _response = self.connect_to().await?.resume_application(request).await?;
let _response = self
.connect_to()
.await?
.resume_application(request)
.await
.map_err(rewrap_error)?;
Ok(())
}

pub async fn reboot(&self) -> anyhow::Result<()> {
let request = pb::admin::Empty {};
let _response = self.connect_to().await?.reboot(request).await?;
let _response = self
.connect_to()
.await?
.reboot(request)
.await
.map_err(rewrap_error)?;
Ok(())
}

pub async fn poweroff(&self) -> anyhow::Result<()> {
let request = pb::admin::Empty {};
let _response = self.connect_to().await?.poweroff(request).await?;
let _response = self
.connect_to()
.await?
.poweroff(request)
.await
.map_err(rewrap_error)?;
Ok(())
}

pub async fn suspend(&self) -> anyhow::Result<()> {
let request = pb::admin::Empty {};
let _response = self.connect_to().await?.suspend(request).await?;
let _response = self
.connect_to()
.await?
.suspend(request)
.await
.map_err(rewrap_error)?;
Ok(())
}

pub async fn wakeup(&self) -> anyhow::Result<()> {
let request = pb::admin::Empty {};
let _response = self.connect_to().await?.wakeup(request).await?;
let _response = self
.connect_to()
.await?
.wakeup(request)
.await
.map_err(rewrap_error)?;
Ok(())
}

Expand All @@ -165,7 +206,8 @@ impl AdminClient {
self.connect_to()
.await?
.query_list(pb::admin::Empty {})
.await?
.await
.map_err(rewrap_error)?
.into_inner()
.list
.into_iter()
Expand All @@ -177,15 +219,17 @@ impl AdminClient {
self.connect_to()
.await?
.set_locale(pb::admin::LocaleRequest { locale })
.await?;
.await
.map_err(rewrap_error)?;
Ok(())
}

pub async fn set_timezone(&self, timezone: String) -> anyhow::Result<()> {
self.connect_to()
.await?
.set_timezone(pb::admin::TimezoneRequest { timezone })
.await?;
.await
.map_err(rewrap_error)?;
Ok(())
}

Expand All @@ -199,7 +243,8 @@ impl AdminClient {
.connect_to()
.await?
.watch(pb::admin::Empty {})
.await?
.await
.map_err(rewrap_error)?
.into_inner();

let list = match watch.try_next().await? {
Expand Down
3 changes: 2 additions & 1 deletion client/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ impl EndpointConfig {
let url = transport_config_to_url(&self.transport.address, self.tls.is_some());
info!("Connecting to {url}, TLS name {:?}", &self.tls);
let mut endpoint = Endpoint::try_from(url.clone())?
.timeout(Duration::from_secs(5))
.timeout(Duration::from_millis(500))
.connect_timeout(Duration::from_millis(300))
.concurrency_limit(30);
if let Some(tls) = &self.tls {
endpoint = endpoint.tls_config(tls.client_config()?)?;
Expand Down
17 changes: 17 additions & 0 deletions client/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use anyhow::Error;
use tonic::Status;
use tonic_types::StatusExt;
use tracing::{debug, error};

pub fn rewrap_error(status: Status) -> Error {
let mut err = Error::msg(status.message().to_owned());
let details = status.get_error_details();
if let Some(debug_info) = details.debug_info() {
err = err.context(format!("Detail: {}", debug_info.detail));
err = debug_info
.stack_entries
.iter()
.fold(err, |err, each| err.context(format!("Stack: {}", each)))
};
err
}
1 change: 1 addition & 0 deletions client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod client;
pub mod endpoint;
pub mod error;
pub use crate::client::{AdminClient, QueryResult};
15 changes: 15 additions & 0 deletions common/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Types related to QueryList and Watch API
use super::types::{ServiceType, VmType};
use crate::pb;
use pb::admin::watch_item::Status;

Expand Down Expand Up @@ -33,6 +34,10 @@ pub struct QueryResult {
pub description: String, //App name, some details
pub status: VMStatus,
pub trust_level: TrustLevel,
pub vm_type: VmType,
pub service_type: ServiceType,
pub vm_name: Option<String>,
pub agent_name: Option<String>,
}

impl QueryResult {
Expand All @@ -51,6 +56,12 @@ impl TryFrom<pb::QueryListItem> for QueryResult {
.with_context(|| format!("While parsing vm_status {}", item.vm_status))?,
trust_level: TrustLevel::from_str(item.trust_level.as_str())
.with_context(|| format!("While parsing trust_level {}", item.trust_level))?,
vm_type: VmType::from_str(item.vm_type.as_str())
.with_context(|| format!("While parsing vm_type {}", item.vm_type))?,
service_type: ServiceType::from_str(item.service_type.as_str())
.with_context(|| format!("While parsing service_type {}", item.service_type))?,
agent_name: item.agent_name,
vm_name: item.vm_name,
})
}
}
Expand All @@ -62,6 +73,10 @@ impl From<QueryResult> for pb::QueryListItem {
description: val.description,
vm_status: val.status.to_string(),
trust_level: val.trust_level.to_string(),
vm_type: val.vm_type.to_string(),
service_type: val.service_type.to_string(),
agent_name: val.agent_name,
vm_name: val.vm_name,
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions common/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use crate::pb;
use std::convert::{Into, TryFrom};

use anyhow::bail;
use serde::Serialize;
use strum::{Display, EnumString};
use tokio_vsock::VsockAddr;

#[derive(Debug, Copy, Clone, PartialEq)]
Expand All @@ -13,15 +15,15 @@ pub struct UnitType {
pub service: ServiceType,
}

#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, EnumString, Display)]
pub enum VmType {
Host,
AdmVM,
SysVM,
AppVM,
}

#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, EnumString, Display)]
pub enum ServiceType {
Mgr,
Svc,
Expand Down
2 changes: 1 addition & 1 deletion nixos/modules/admin.nix
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ in
"HOST_KEY" = "${cfg.tls.keyPath}";
}
// attrsets.optionalAttrs cfg.debug {
"RUST_BACKTRACE" = "1";
# "RUST_BACKTRACE" = "1";
"GIVC_LOG" = "debug";
};
};
Expand Down
16 changes: 15 additions & 1 deletion nixos/tests/admin.nix
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,15 @@ in
];
tls = mkTls "ghaf-host";
};
systemd.services."microvm@foot-vm" = {
systemd.services."microvm@chromium-vm" = {
preStart = ''
expr $(cat /tmp/[email protected] 2>/dev/null || true) + 1 >/tmp/[email protected]
'';
script = ''
# Do nothing script, simulating microvm service
while true; do sleep 10; done
'';
wantedBy = [ "multi-user.target" ];
};
};
guivm =
Expand Down Expand Up @@ -321,6 +325,7 @@ in
with subtest("Clean run"):
print(hostvm.succeed("${cli} --addr ${nodes.adminvm.config.givc.admin.addr} --port ${nodes.adminvm.config.givc.admin.port} --cacert ${nodes.hostvm.givc.host.tls.caCertPath} --cert ${nodes.hostvm.givc.host.tls.certPath} --key ${nodes.hostvm.givc.host.tls.keyPath} ${if tls then "" else "--notls"} --name ${nodes.adminvm.config.givc.admin.name} start --vm chromium-vm foot"))
time.sleep(10) # Give few seconds to application to spin up
print(hostvm.succeed("cat /tmp/[email protected]"))
wait_for_window("ghaf@appvm")

with subtest("crash and restart"):
Expand Down Expand Up @@ -356,6 +361,15 @@ in
print(hostvm.succeed("${cli} --addr ${nodes.adminvm.config.givc.admin.addr} --port ${nodes.adminvm.config.givc.admin.port} --cacert ${nodes.hostvm.givc.host.tls.caCertPath} --cert ${nodes.hostvm.givc.host.tls.certPath} --key ${nodes.hostvm.givc.host.tls.keyPath} ${if tls then "" else "--notls"} --name ${nodes.adminvm.config.givc.admin.name} start --vm chromium-vm clearexit"))
time.sleep(20) # Give few seconds to application to spin up, exit, then start it again
print(hostvm.succeed("${cli} --addr ${nodes.adminvm.config.givc.admin.addr} --port ${nodes.adminvm.config.givc.admin.port} --cacert ${nodes.hostvm.givc.host.tls.caCertPath} --cert ${nodes.hostvm.givc.host.tls.certPath} --key ${nodes.hostvm.givc.host.tls.keyPath} ${if tls then "" else "--notls"} --name ${nodes.adminvm.config.givc.admin.name} start --vm chromium-vm clearexit"))
with subtest("VM restart"):
appvm.crash()
hostvm.succeed("systemctl stop [email protected]")
time.sleep(20)
appvm.start()
time.sleep(20)
print(hostvm.succeed("${cli} --addr ${nodes.adminvm.config.givc.admin.addr} --port ${nodes.adminvm.config.givc.admin.port} --cacert ${nodes.hostvm.givc.host.tls.caCertPath} --cert ${nodes.hostvm.givc.host.tls.certPath} --key ${nodes.hostvm.givc.host.tls.keyPath} ${if tls then "" else "--notls"} --name ${nodes.adminvm.config.givc.admin.name} start --vm chromium-vm foot"))
assert hostvm.succeed("cat /tmp/[email protected]") == "2"
wait_for_window("ghaf@appvm")
'';
};
};
Expand Down
Loading