### new features
+* in Linux guests, exits early with better diagnostic when not
+ running under Xen
* the RPM now enables and starts the service on first install
* the RPM now causes xe-guest-utilities to be uninstalled
automatically
--- /dev/null
+use std::error::Error;
+use std::fmt::{Debug, Formatter, Result, Display};
+
+pub enum XenError {
+ NotInGuest,
+ HypervisorNotXen,
+}
+
+impl Error for XenError {}
+
+impl Debug for XenError {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ write!(f, "{}", self)
+ }
+}
+
+impl Display for XenError {
+ fn fmt(&self, f: &mut Formatter) -> Result {
+ match *self {
+ XenError::NotInGuest => write!(f, "Cannot identify hypervisor"),
+ XenError::HypervisorNotXen => write!(f, "Hypervisor is not Xen"),
+ }
+ }
+}
--- /dev/null
+use crate::error::XenError;
+
+pub fn check_is_in_xen_guest() -> Result<(), XenError> {
+ // NOTE: 'Ok' here implies that we do not know how to check for the hypervisor,
+ // so we assume the users are aware of their actions.
+ Ok(())
+}
--- /dev/null
+use std::fs;
+use crate::error::XenError;
+
+pub fn check_is_in_xen_guest() -> Result<(), XenError> {
+ match fs::read_to_string("/sys/hypervisor/type") {
+ Ok(hypervisor_type) => {
+ let hypervisor_type = hypervisor_type.trim();
+ log::debug!("hypervisor_type {hypervisor_type}");
+ if hypervisor_type.eq("xen") { Ok(()) } else { Err(XenError::HypervisorNotXen) }
+ },
+ Err(err) => {
+ log::error!("could not identify hypervisor type, {err}");
+ Err(XenError::NotInGuest)
+ }
+ }
+}
#[cfg_attr(target_os = "freebsd", path = "vif_detect_freebsd.rs")]
mod vif_detect;
+#[cfg_attr(target_os = "linux", path = "hypervisor_linux.rs")]
+mod hypervisor;
+
+mod error;
+
use clap::Parser;
use crate::collector_memory::MemorySource;
use crate::collector_net::NetworkSource;
use crate::datastructs::KernelInfo;
+use crate::hypervisor::check_is_in_xen_guest;
use crate::publisher::Publisher;
use futures::{pin_mut, select, FutureExt, TryStreamExt};
const MEM_PERIOD_SECONDS: u64 = 60;
const DEFAULT_LOGLEVEL: &str = "info";
+
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let cli = Cli::parse();
setup_logger(cli.stderr, &cli.loglevel)?;
+ if let Err(err) = check_is_in_xen_guest() {
+ log::error!("not starting xen-guest-agent, {err}");
+ return Err(err.into())
+ }
+
let mut publisher = Publisher::new()?;
let mut collector_memory = MemorySource::new()?;