mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 14:29:45 +00:00
build multi-arch s9pks (#2601)
* build multi-arch s9pks * remove images incrementally * wip * prevent rebuild * fix sdk makefile * fix hanging on uninstall * fix build * fix build * fix build * fix build (for real this time) * fix git hash computation
This commit is contained in:
@@ -13,12 +13,14 @@ use start_stop::StartStop;
|
||||
use tokio::sync::Notify;
|
||||
use ts_rs::TS;
|
||||
|
||||
use crate::context::{CliContext, RpcContext};
|
||||
use crate::core::rpc_continuations::RequestGuid;
|
||||
use crate::db::model::package::{
|
||||
InstalledState, PackageDataEntry, PackageState, PackageStateMatchModelRef, UpdatingState,
|
||||
};
|
||||
use crate::disk::mount::guard::GenericMountGuard;
|
||||
use crate::install::PKG_ARCHIVE_DIR;
|
||||
use crate::lxc::ContainerId;
|
||||
use crate::prelude::*;
|
||||
use crate::progress::{NamedProgress, Progress};
|
||||
use crate::s9pk::S9pk;
|
||||
@@ -31,10 +33,6 @@ use crate::util::actor::concurrent::ConcurrentActor;
|
||||
use crate::util::actor::Actor;
|
||||
use crate::util::serde::Pem;
|
||||
use crate::volume::data_dir;
|
||||
use crate::{
|
||||
context::{CliContext, RpcContext},
|
||||
lxc::ContainerId,
|
||||
};
|
||||
|
||||
mod action;
|
||||
pub mod cli;
|
||||
@@ -138,7 +136,7 @@ impl Service {
|
||||
match entry.as_state_info().as_match() {
|
||||
PackageStateMatchModelRef::Installing(_) => {
|
||||
if disposition == LoadDisposition::Retry {
|
||||
if let Ok(s9pk) = S9pk::open(s9pk_path, Some(id)).await.map_err(|e| {
|
||||
if let Ok(s9pk) = S9pk::open(s9pk_path, Some(id), true).await.map_err(|e| {
|
||||
tracing::error!("Error opening s9pk for install: {e}");
|
||||
tracing::debug!("{e:?}")
|
||||
}) {
|
||||
@@ -171,7 +169,7 @@ impl Service {
|
||||
&& progress == &Progress::Complete(true)
|
||||
})
|
||||
{
|
||||
if let Ok(s9pk) = S9pk::open(&s9pk_path, Some(id)).await.map_err(|e| {
|
||||
if let Ok(s9pk) = S9pk::open(&s9pk_path, Some(id), true).await.map_err(|e| {
|
||||
tracing::error!("Error opening s9pk for update: {e}");
|
||||
tracing::debug!("{e:?}")
|
||||
}) {
|
||||
@@ -190,7 +188,7 @@ impl Service {
|
||||
}
|
||||
}
|
||||
}
|
||||
let s9pk = S9pk::open(s9pk_path, Some(id)).await?;
|
||||
let s9pk = S9pk::open(s9pk_path, Some(id), true).await?;
|
||||
ctx.db
|
||||
.mutate({
|
||||
|db| {
|
||||
@@ -215,7 +213,7 @@ impl Service {
|
||||
handle_installed(s9pk, entry).await
|
||||
}
|
||||
PackageStateMatchModelRef::Removing(_) | PackageStateMatchModelRef::Restoring(_) => {
|
||||
if let Ok(s9pk) = S9pk::open(s9pk_path, Some(id)).await.map_err(|e| {
|
||||
if let Ok(s9pk) = S9pk::open(s9pk_path, Some(id), true).await.map_err(|e| {
|
||||
tracing::error!("Error opening s9pk for removal: {e}");
|
||||
tracing::debug!("{e:?}")
|
||||
}) {
|
||||
@@ -243,7 +241,7 @@ impl Service {
|
||||
Ok(None)
|
||||
}
|
||||
PackageStateMatchModelRef::Installed(_) => {
|
||||
handle_installed(S9pk::open(s9pk_path, Some(id)).await?, entry).await
|
||||
handle_installed(S9pk::open(s9pk_path, Some(id), true).await?, entry).await
|
||||
}
|
||||
PackageStateMatchModelRef::Error(e) => Err(Error::new(
|
||||
eyre!("Failed to parse PackageDataEntry, found {e:?}"),
|
||||
@@ -349,6 +347,7 @@ impl Service {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn backup(&self, _guard: impl GenericMountGuard) -> Result<BackupReturn, Error> {
|
||||
// TODO
|
||||
Err(Error::new(eyre!("not yet implemented"), ErrorKind::Unknown))
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::sync::{Arc, Weak};
|
||||
use std::time::Duration;
|
||||
|
||||
use futures::future::ready;
|
||||
use futures::Future;
|
||||
use futures::{Future, FutureExt};
|
||||
use helpers::NonDetachingJoinHandle;
|
||||
use imbl_value::InternedString;
|
||||
use models::{ProcedureName, VolumeId};
|
||||
@@ -92,6 +92,7 @@ pub struct PersistentContainer {
|
||||
pub(super) overlays: Arc<Mutex<BTreeMap<InternedString, OverlayGuard>>>,
|
||||
pub(super) state: Arc<watch::Sender<ServiceState>>,
|
||||
pub(super) net_service: Mutex<NetService>,
|
||||
destroyed: bool,
|
||||
}
|
||||
|
||||
impl PersistentContainer {
|
||||
@@ -217,6 +218,7 @@ impl PersistentContainer {
|
||||
overlays: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
state: Arc::new(watch::channel(ServiceState::new(start)).0),
|
||||
net_service: Mutex::new(net_service),
|
||||
destroyed: false,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -285,7 +287,10 @@ impl PersistentContainer {
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
fn destroy(&mut self) -> impl Future<Output = Result<(), Error>> + 'static {
|
||||
fn destroy(&mut self) -> Option<impl Future<Output = Result<(), Error>> + 'static> {
|
||||
if self.destroyed {
|
||||
return None;
|
||||
}
|
||||
let rpc_client = self.rpc_client.clone();
|
||||
let rpc_server = self.rpc_server.send_replace(None);
|
||||
let js_mount = self.js_mount.take();
|
||||
@@ -293,33 +298,45 @@ impl PersistentContainer {
|
||||
let assets = std::mem::take(&mut self.assets);
|
||||
let overlays = self.overlays.clone();
|
||||
let lxc_container = self.lxc_container.take();
|
||||
async move {
|
||||
let mut errs = ErrorCollection::new();
|
||||
if let Some((hdl, shutdown)) = rpc_server {
|
||||
errs.handle(rpc_client.request(rpc::Exit, Empty {}).await);
|
||||
shutdown.shutdown();
|
||||
errs.handle(hdl.await.with_kind(ErrorKind::Cancelled));
|
||||
self.destroyed = true;
|
||||
Some(
|
||||
async move {
|
||||
dbg!(
|
||||
async move {
|
||||
let mut errs = ErrorCollection::new();
|
||||
if let Some((hdl, shutdown)) = rpc_server {
|
||||
errs.handle(rpc_client.request(rpc::Exit, Empty {}).await);
|
||||
shutdown.shutdown();
|
||||
errs.handle(hdl.await.with_kind(ErrorKind::Cancelled));
|
||||
}
|
||||
for (_, volume) in volumes {
|
||||
errs.handle(volume.unmount(true).await);
|
||||
}
|
||||
for (_, assets) in assets {
|
||||
errs.handle(assets.unmount(true).await);
|
||||
}
|
||||
for (_, overlay) in std::mem::take(&mut *overlays.lock().await) {
|
||||
errs.handle(overlay.unmount(true).await);
|
||||
}
|
||||
errs.handle(js_mount.unmount(true).await);
|
||||
if let Some(lxc_container) = lxc_container {
|
||||
errs.handle(lxc_container.exit().await);
|
||||
}
|
||||
dbg!(errs.into_result())
|
||||
}
|
||||
.await
|
||||
)
|
||||
}
|
||||
for (_, volume) in volumes {
|
||||
errs.handle(volume.unmount(true).await);
|
||||
}
|
||||
for (_, assets) in assets {
|
||||
errs.handle(assets.unmount(true).await);
|
||||
}
|
||||
for (_, overlay) in std::mem::take(&mut *overlays.lock().await) {
|
||||
errs.handle(overlay.unmount(true).await);
|
||||
}
|
||||
errs.handle(js_mount.unmount(true).await);
|
||||
if let Some(lxc_container) = lxc_container {
|
||||
errs.handle(lxc_container.exit().await);
|
||||
}
|
||||
errs.into_result()
|
||||
}
|
||||
.map(|a| dbg!(a)),
|
||||
)
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
pub async fn exit(mut self) -> Result<(), Error> {
|
||||
self.destroy().await?;
|
||||
if let Some(destroy) = self.destroy() {
|
||||
dbg!(destroy.await)?;
|
||||
}
|
||||
tracing::info!("Service for {} exited", self.s9pk.as_manifest().id);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -416,7 +433,8 @@ impl PersistentContainer {
|
||||
|
||||
impl Drop for PersistentContainer {
|
||||
fn drop(&mut self) {
|
||||
let destroy = self.destroy();
|
||||
tokio::spawn(async move { destroy.await.unwrap() });
|
||||
if let Some(destroy) = self.destroy() {
|
||||
tokio::spawn(async move { destroy.await.unwrap() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1165,6 +1165,7 @@ async fn set_dependencies(
|
||||
.join(&format!("package/v2/{}.s9pk?spec={}", dep_id, version_spec))?,
|
||||
)
|
||||
.await?,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -42,10 +42,9 @@ pub struct InstallProgressHandles {
|
||||
pub struct ServiceMap(Mutex<OrdMap<PackageId, Arc<RwLock<Option<Service>>>>>);
|
||||
impl ServiceMap {
|
||||
async fn entry(&self, id: &PackageId) -> Arc<RwLock<Option<Service>>> {
|
||||
self.0
|
||||
.lock()
|
||||
.await
|
||||
.entry(id.clone())
|
||||
let mut lock = self.0.lock().await;
|
||||
dbg!(lock.keys().collect::<Vec<_>>());
|
||||
lock.entry(id.clone())
|
||||
.or_insert_with(|| Arc::new(RwLock::new(None)))
|
||||
.clone()
|
||||
}
|
||||
@@ -230,7 +229,7 @@ impl ServiceMap {
|
||||
.await?;
|
||||
Ok(reload_guard
|
||||
.handle_last(async move {
|
||||
let s9pk = S9pk::open(&installed_path, Some(&id)).await?;
|
||||
let s9pk = S9pk::open(&installed_path, Some(&id), true).await?;
|
||||
let prev = if let Some(service) = service.take() {
|
||||
ensure_code!(
|
||||
recovery_source.is_none(),
|
||||
@@ -293,9 +292,14 @@ impl ServiceMap {
|
||||
/// This is ran during the cleanup, so when we are uninstalling the service
|
||||
#[instrument(skip_all)]
|
||||
pub async fn uninstall(&self, ctx: &RpcContext, id: &PackageId) -> Result<(), Error> {
|
||||
if let Some(service) = self.get_mut(id).await.take() {
|
||||
let mut guard = self.get_mut(id).await;
|
||||
if let Some(service) = guard.take() {
|
||||
ServiceReloadGuard::new(ctx.clone(), id.clone(), "Uninstall")
|
||||
.handle_last(service.uninstall(None))
|
||||
.handle_last(async move {
|
||||
let res = service.uninstall(None).await;
|
||||
drop(guard);
|
||||
res
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user