diff --git a/appmgr/src/manager/mod.rs b/appmgr/src/manager/mod.rs index a8611da63..d45ca0462 100644 --- a/appmgr/src/manager/mod.rs +++ b/appmgr/src/manager/mod.rs @@ -23,6 +23,7 @@ use crate::action::{ActionImplementation, NoOutput}; use crate::context::RpcContext; use crate::manager::sync::synchronizer; use crate::net::interface::InterfaceId; +use crate::net::GeneratedCertificateMountPoint; use crate::notifications::NotificationLevel; use crate::s9pk::manifest::{Manifest, PackageId}; use crate::util::{Container, NonDetachingJoinHandle, Version}; @@ -176,22 +177,32 @@ async fn run_main( state: &Arc, ) -> Result, Error> { let rt_state = state.clone(); - let mut runtime = tokio::spawn(async move { - rt_state - .manifest - .main - .execute::<(), NoOutput>( - &rt_state.ctx, - &rt_state.manifest.id, - &rt_state.manifest.version, - None, - &rt_state.manifest.volumes, - None, - false, - None, - ) - .await - }); + let interfaces = state + .manifest + .interfaces + .0 + .iter() + .map(|(id, info)| { + Ok(( + id.clone(), + info, + state + .tor_keys + .get(id) + .ok_or_else(|| { + Error::new(eyre!("interface {} missing key", id), crate::ErrorKind::Tor) + })? + .clone(), + )) + }) + .collect::, Error>>()?; + let generated_certificate = state + .ctx + .net_controller + .generate_certificate_mountpoint(&state.manifest.id, &interfaces) + .await?; + let mut runtime = + tokio::spawn(async move { start_up_image(rt_state, generated_certificate).await }); let ip; loop { match state @@ -232,32 +243,7 @@ async fn run_main( state .ctx .net_controller - .add( - &state.manifest.id, - ip, - state - .manifest - .interfaces - .0 - .iter() - .map(|(id, info)| { - Ok(( - id.clone(), - info, - state - .tor_keys - .get(id) - .ok_or_else(|| { - Error::new( - eyre!("interface {} missing key", id), - crate::ErrorKind::Tor, - ) - })? - .clone(), - )) - }) - .collect::, Error>>()?, - ) + .add(&state.manifest.id, ip, interfaces, generated_certificate) .await?; state @@ -309,6 +295,28 @@ async fn run_main( res } +/// We want to start up the manifest, but in this case we want to know that we have generated the certificates. +/// Note for _generated_certificate: Needed to know that before we start the state we have generated the certificate +async fn start_up_image( + rt_state: Arc, + _generated_certificate: GeneratedCertificateMountPoint, +) -> Result, Error> { + rt_state + .manifest + .main + .execute::<(), NoOutput>( + &rt_state.ctx, + &rt_state.manifest.id, + &rt_state.manifest.version, + None, + &rt_state.manifest.volumes, + None, + false, + None, + ) + .await +} + impl Manager { #[instrument(skip(ctx))] async fn create( diff --git a/appmgr/src/net/mod.rs b/appmgr/src/net/mod.rs index b6505f3a8..d7296df98 100644 --- a/appmgr/src/net/mod.rs +++ b/appmgr/src/net/mod.rs @@ -34,6 +34,11 @@ pub fn net() -> Result<(), Error> { Ok(()) } +/// Indicates that the net controller has created the +/// SSL keys +#[derive(Clone, Copy)] +pub struct GeneratedCertificateMountPoint(()); + pub struct NetController { pub tor: TorController, #[cfg(feature = "avahi")] @@ -67,20 +72,18 @@ impl NetController { PathBuf::from(format!("{}/{}", PACKAGE_CERT_PATH, pkg_id)) } - #[instrument(skip(self, interfaces))] + #[instrument(skip(self, interfaces, _generated_certificate))] pub async fn add<'a, I>( &self, pkg_id: &PackageId, ip: Ipv4Addr, interfaces: I, + _generated_certificate: GeneratedCertificateMountPoint, ) -> Result<(), Error> where I: IntoIterator + Clone, for<'b> &'b I: IntoIterator, { - self.generate_certificate_mountpoint(pkg_id, &interfaces) - .await?; - let interfaces_tor = interfaces .clone() .into_iter() @@ -150,11 +153,11 @@ impl NetController { Ok(()) } - async fn generate_certificate_mountpoint<'a, I>( + pub async fn generate_certificate_mountpoint<'a, I>( &self, pkg_id: &PackageId, interfaces: &I, - ) -> Result<(), Error> + ) -> Result where I: IntoIterator + Clone, for<'b> &'b I: IntoIterator, @@ -162,7 +165,7 @@ impl NetController { tracing::info!("Generating SSL Certificate mountpoints for {}", pkg_id); let package_path = PathBuf::from(PACKAGE_CERT_PATH).join(pkg_id); tokio::fs::create_dir_all(&package_path).await?; - Ok(for (id, _, key) in interfaces { + for (id, _, key) in interfaces { let dns_base = OnionAddressV3::from(&key.public()).get_address_without_dot_onion(); let ssl_path_key = package_path.join(format!("{}.key.pem", id)); let ssl_path_cert = package_path.join(format!("{}.cert.pem", id)); @@ -171,7 +174,8 @@ impl NetController { crate::net::ssl::export_key(&key, &ssl_path_key), crate::net::ssl::export_cert(&chain, &ssl_path_cert) )?; - }) + } + Ok(GeneratedCertificateMountPoint(())) } pub async fn export_root_ca(&self) -> Result<(PKey, X509), Error> {