Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.9 kB · 132 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133mod config;mod service;mod stratis;
use std::{ fs::{File, Permissions}, os::unix::fs::PermissionsExt,};
use bpaf::Bpaf;use camino::Utf8PathBuf;use tokio::net::UnixListener;use tokio_stream::wrappers::UnixListenerStream;use tonic::transport::Server;use tonic_health::pb::{HealthCheckRequest, health_client::HealthClient};use tracing::{info, warn};use tracing_subscriber::{EnvFilter, prelude::*};
use crate::{ config::Config, service::{ Service, lvmd::{lv_service_server::LvServiceServer, vg_service_server::VgServiceServer}, },};
#[derive(Default, Debug, Clone, Bpaf)]struct OptionsServe { #[bpaf(hide)] unsafe_world_writable_socket: bool,}
#[derive(Debug, Clone, Bpaf)]enum OptionsCommand { #[bpaf(hide, command)] Serve(#[bpaf(external(options_serve))] OptionsServe), #[bpaf(command)] Health,}
impl Default for OptionsCommand { fn default() -> Self { Self::Serve(Default::default()) }}
#[derive(Debug, Clone, Bpaf)]#[bpaf(options)]struct Options { #[bpaf(fallback("/etc/topolvm/lvmd.yaml".into()))] config: Utf8PathBuf, #[bpaf(external(options_command), fallback(OptionsCommand::default()))] command: OptionsCommand,}
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let opts = options().run();
tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().json()) .with(EnvFilter::from_default_env()) .init();
info!(config = %opts.config, "loading config");
let mut config_file = File::open(&opts.config)?; let config: Config = serde_norway::from_reader(&mut config_file)?;
match opts.command { OptionsCommand::Health => { info!(socket = %config.socket_name, "connecting to socket"); let chan = tonic::transport::Endpoint::try_from(format!("unix://{}", config.socket_name))? .connect() .await?;
info!("performing health check"); let mut client = HealthClient::new(chan); client .check(HealthCheckRequest { service: "".to_owned(), }) .await?; } OptionsCommand::Serve(opts) => { info!(socket = %config.socket_name, "binding to socket");
if let Some(parent) = config.socket_name.parent() { std::fs::create_dir_all(parent)?; }
std::fs::remove_file(&config.socket_name).or_else(|err| { if err.kind() == std::io::ErrorKind::NotFound { Ok(()) } else { Err(err) } })?; let sock = UnixListener::bind(&config.socket_name)?;
if opts.unsafe_world_writable_socket { warn!("setting socket to be WORLD-WRITABLE for tests!"); std::fs::set_permissions(&config.socket_name, Permissions::from_mode(0o666))?; }
info!("connecting to system bus"); let conn = zbus::Connection::system().await?;
let service = Service::start(config, conn).await?;
let (health_reporter, health_service) = tonic_health::server::health_reporter(); health_reporter .set_serving::<LvServiceServer<Service>>() .await; health_reporter .set_serving::<VgServiceServer<Service>>() .await;
info!("serving!");
Server::builder() .add_service(LvServiceServer::from_arc(service.clone())) .add_service(VgServiceServer::from_arc(service)) .add_service(health_service) .serve_with_incoming(UnixListenerStream::new(sock)) .await?; } }
Ok(())}