mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 04:01:58 +00:00
Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major
This commit is contained in:
@@ -1034,6 +1034,15 @@ impl ListenerMap {
|
||||
fn poll_accept(&self, cx: &mut std::task::Context<'_>) -> Poll<Result<Accepted, Error>> {
|
||||
for (bind_addr, listener) in self.listeners.iter() {
|
||||
if let Poll::Ready((stream, addr)) = listener.0.poll_accept(cx)? {
|
||||
if let Err(e) = socket2::SockRef::from(&stream).set_tcp_keepalive(
|
||||
&socket2::TcpKeepalive::new()
|
||||
.with_time(Duration::from_secs(900))
|
||||
.with_interval(Duration::from_secs(60))
|
||||
.with_retries(5),
|
||||
) {
|
||||
tracing::error!("Failed to set tcp keepalive: {e}");
|
||||
tracing::debug!("{e:?}");
|
||||
}
|
||||
return Poll::Ready(Ok(Accepted {
|
||||
stream,
|
||||
peer: addr,
|
||||
|
||||
@@ -258,16 +258,6 @@ impl VHostServer {
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = socket2::SockRef::from(&accepted.stream).set_tcp_keepalive(
|
||||
&socket2::TcpKeepalive::new()
|
||||
.with_time(Duration::from_secs(900))
|
||||
.with_interval(Duration::from_secs(60))
|
||||
.with_retries(5),
|
||||
) {
|
||||
tracing::error!("Failed to set tcp keepalive: {e}");
|
||||
tracing::debug!("{e:?}");
|
||||
}
|
||||
|
||||
tokio::spawn(async move {
|
||||
let bind = accepted.bind;
|
||||
if let Err(e) =
|
||||
|
||||
@@ -36,6 +36,25 @@ impl<'a, T: Clone> Expected<'a, T> {
|
||||
))
|
||||
}
|
||||
}
|
||||
pub fn check_dir(&mut self, path: impl AsRef<Path>) -> Result<(), Error> {
|
||||
if let Some(dir) = self
|
||||
.dir
|
||||
.get_path(path.as_ref())
|
||||
.and_then(|e| e.as_directory())
|
||||
{
|
||||
for entry in dir.file_paths(path.as_ref()) {
|
||||
if !entry.to_string_lossy().ends_with("/") {
|
||||
self.keep.insert_path(entry, Entry::file(()))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(
|
||||
eyre!("directory {} missing from archive", path.as_ref().display()),
|
||||
ErrorKind::ParseS9pk,
|
||||
))
|
||||
}
|
||||
}
|
||||
pub fn check_stem(
|
||||
&mut self,
|
||||
path: impl AsRef<Path>,
|
||||
|
||||
@@ -129,25 +129,16 @@ impl S9pk<TmpSource<PackSource>> {
|
||||
tokio_tar::Archive::new(reader.assets().await?)
|
||||
.unpack(&asset_dir)
|
||||
.await?;
|
||||
for (asset_id, _) in manifest
|
||||
.volumes
|
||||
.iter()
|
||||
.filter(|(_, v)| v.get("type").and_then(|v| v.as_str()) == Some("assets"))
|
||||
{
|
||||
let assets_path = asset_dir.join(&asset_id);
|
||||
let sqfs_path = assets_path.with_extension("squashfs");
|
||||
Command::new("mksquashfs")
|
||||
.arg(&assets_path)
|
||||
.arg(&sqfs_path)
|
||||
.invoke(ErrorKind::Filesystem)
|
||||
.await?;
|
||||
archive.insert_path(
|
||||
Path::new("assets")
|
||||
.join(&asset_id)
|
||||
.with_extension("squashfs"),
|
||||
Entry::file(TmpSource::new(tmp_dir.clone(), PackSource::File(sqfs_path))),
|
||||
)?;
|
||||
}
|
||||
let sqfs_path = asset_dir.with_extension("squashfs");
|
||||
Command::new("mksquashfs")
|
||||
.arg(&asset_dir)
|
||||
.arg(&sqfs_path)
|
||||
.invoke(ErrorKind::Filesystem)
|
||||
.await?;
|
||||
archive.insert_path(
|
||||
"assets.squashfs",
|
||||
Entry::file(TmpSource::new(tmp_dir.clone(), PackSource::File(sqfs_path))),
|
||||
)?;
|
||||
|
||||
// javascript
|
||||
let js_dir = tmp_dir.join("javascript");
|
||||
@@ -217,12 +208,6 @@ impl TryFrom<ManifestV1> for Manifest {
|
||||
donation_url: value.donation_url,
|
||||
description: value.description,
|
||||
images: BTreeMap::new(),
|
||||
assets: value
|
||||
.volumes
|
||||
.iter()
|
||||
.filter(|(_, v)| v.get("type").and_then(|v| v.as_str()) == Some("assets"))
|
||||
.map(|(id, _)| id.clone())
|
||||
.collect(),
|
||||
volumes: value
|
||||
.volumes
|
||||
.iter()
|
||||
|
||||
@@ -53,7 +53,6 @@ pub struct Manifest {
|
||||
pub donation_url: Option<Url>,
|
||||
pub description: Description,
|
||||
pub images: BTreeMap<ImageId, ImageConfig>,
|
||||
pub assets: BTreeSet<VolumeId>, // TODO: AssetsId
|
||||
pub volumes: BTreeSet<VolumeId>,
|
||||
#[serde(default)]
|
||||
pub alerts: Alerts,
|
||||
@@ -93,8 +92,11 @@ impl Manifest {
|
||||
.map_or(false, |mime| mime.starts_with("image/"))
|
||||
});
|
||||
}
|
||||
for assets in &self.assets {
|
||||
expected.check_file(Path::new("assets").join(assets).with_extension("squashfs"))?;
|
||||
if let Err(e) = expected.check_file(Path::new("assets.squashfs")) {
|
||||
// backwards compatibility for alpha s9pks - remove eventually
|
||||
if expected.check_dir("assets").is_err() {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
for (image_id, config) in &self.images {
|
||||
let mut check_arch = |arch: &str| {
|
||||
|
||||
@@ -60,7 +60,7 @@ fn priority(s: &str) -> Option<usize> {
|
||||
"instructions.md" => Some(3),
|
||||
"dependencies" => Some(4),
|
||||
"javascript.squashfs" => Some(5),
|
||||
"assets" => Some(6),
|
||||
"assets.squashfs" => Some(6),
|
||||
"images" => Some(7),
|
||||
_ => None,
|
||||
}
|
||||
|
||||
@@ -694,18 +694,13 @@ pub async fn pack(ctx: CliContext, params: PackParams) -> Result<(), Error> {
|
||||
.await?;
|
||||
|
||||
let assets_dir = params.assets();
|
||||
for assets in s9pk.as_manifest().assets.clone() {
|
||||
s9pk.as_archive_mut().contents_mut().insert_path(
|
||||
Path::new("assets").join(&assets).with_extension("squashfs"),
|
||||
Entry::file(TmpSource::new(
|
||||
tmp_dir.clone(),
|
||||
PackSource::Squashfs(Arc::new(SqfsDir::new(
|
||||
assets_dir.join(&assets),
|
||||
tmp_dir.clone(),
|
||||
))),
|
||||
)),
|
||||
)?;
|
||||
}
|
||||
s9pk.as_archive_mut().contents_mut().insert_path(
|
||||
"assets.squashfs",
|
||||
Entry::file(TmpSource::new(
|
||||
tmp_dir.clone(),
|
||||
PackSource::Squashfs(Arc::new(SqfsDir::new(assets_dir, tmp_dir.clone()))),
|
||||
)),
|
||||
)?;
|
||||
|
||||
s9pk.load_images(tmp_dir.clone()).await?;
|
||||
|
||||
@@ -816,9 +811,7 @@ pub async fn list_ingredients(_: CliContext, params: PackParams) -> Result<Vec<P
|
||||
}
|
||||
|
||||
let assets_dir = params.assets();
|
||||
for assets in manifest.assets {
|
||||
ingredients.push(assets_dir.join(assets));
|
||||
}
|
||||
ingredients.push(assets_dir);
|
||||
|
||||
for image in manifest.images.values() {
|
||||
ingredients.extend(image.source.ingredients());
|
||||
|
||||
@@ -106,7 +106,7 @@ pub struct PersistentContainer {
|
||||
// procedures: Mutex<Vec<(ProcedureName, ProcedureId)>>,
|
||||
js_mount: MountGuard,
|
||||
volumes: BTreeMap<VolumeId, MountGuard>,
|
||||
assets: BTreeMap<VolumeId, MountGuard>,
|
||||
assets: Vec<MountGuard>,
|
||||
pub(super) images: BTreeMap<ImageId, Arc<MountGuard>>,
|
||||
pub(super) subcontainers: Arc<Mutex<BTreeMap<Guid, Subcontainer>>>,
|
||||
pub(super) state: Arc<watch::Sender<ServiceState>>,
|
||||
@@ -168,35 +168,63 @@ impl PersistentContainer {
|
||||
.await?;
|
||||
volumes.insert(volume.clone(), mount);
|
||||
}
|
||||
let mut assets = BTreeMap::new();
|
||||
for asset in &s9pk.as_manifest().assets {
|
||||
let mountpoint = lxc_container
|
||||
.rootfs_dir()
|
||||
.join("media/startos/assets")
|
||||
.join(asset);
|
||||
tokio::fs::create_dir_all(&mountpoint).await?;
|
||||
Command::new("chown")
|
||||
.arg("100000:100000")
|
||||
.arg(&mountpoint)
|
||||
.invoke(crate::ErrorKind::Filesystem)
|
||||
.await?;
|
||||
let s9pk_asset_path = Path::new("assets").join(asset).with_extension("squashfs");
|
||||
let sqfs = s9pk
|
||||
.as_archive()
|
||||
.contents()
|
||||
.get_path(&s9pk_asset_path)
|
||||
.and_then(|e| e.as_file())
|
||||
.or_not_found(s9pk_asset_path.display())?;
|
||||
assets.insert(
|
||||
asset.clone(),
|
||||
|
||||
let mountpoint = lxc_container.rootfs_dir().join("media/startos/assets");
|
||||
tokio::fs::create_dir_all(&mountpoint).await?;
|
||||
Command::new("chown")
|
||||
.arg("100000:100000")
|
||||
.arg(&mountpoint)
|
||||
.invoke(crate::ErrorKind::Filesystem)
|
||||
.await?;
|
||||
let assets = if let Some(sqfs) = s9pk
|
||||
.as_archive()
|
||||
.contents()
|
||||
.get_path("assets.squashfs")
|
||||
.and_then(|e| e.as_file())
|
||||
{
|
||||
vec![
|
||||
MountGuard::mount(
|
||||
&IdMapped::new(LoopDev::from(&**sqfs), 0, 100000, 65536),
|
||||
mountpoint,
|
||||
MountType::ReadWrite,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
}
|
||||
]
|
||||
} else if let Some(dir) = s9pk
|
||||
.as_archive()
|
||||
.contents()
|
||||
.get_path("assets")
|
||||
.and_then(|e| e.as_directory())
|
||||
{
|
||||
// backwards compatibility for alpha s9pks - remove eventually
|
||||
let mut assets = Vec::new();
|
||||
for (asset, entry) in &**dir {
|
||||
let mountpoint = lxc_container
|
||||
.rootfs_dir()
|
||||
.join("media/startos/assets")
|
||||
.join(Path::new(asset).with_extension(""));
|
||||
tokio::fs::create_dir_all(&mountpoint).await?;
|
||||
Command::new("chown")
|
||||
.arg("100000:100000")
|
||||
.arg(&mountpoint)
|
||||
.invoke(crate::ErrorKind::Filesystem)
|
||||
.await?;
|
||||
let Some(sqfs) = entry.as_file() else {
|
||||
continue;
|
||||
};
|
||||
assets.push(
|
||||
MountGuard::mount(
|
||||
&IdMapped::new(LoopDev::from(&**sqfs), 0, 100000, 65536),
|
||||
mountpoint,
|
||||
MountType::ReadWrite,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
}
|
||||
assets
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let mut images = BTreeMap::new();
|
||||
let image_path = lxc_container.rootfs_dir().join("media/startos/images");
|
||||
@@ -432,7 +460,7 @@ impl PersistentContainer {
|
||||
for (_, volume) in volumes {
|
||||
errs.handle(volume.unmount(true).await);
|
||||
}
|
||||
for (_, assets) in assets {
|
||||
for assets in assets {
|
||||
errs.handle(assets.unmount(true).await);
|
||||
}
|
||||
for (_, overlay) in std::mem::take(&mut *subcontainers.lock().await) {
|
||||
|
||||
@@ -35,6 +35,7 @@ mod v0_3_6_alpha_12;
|
||||
mod v0_3_6_alpha_13;
|
||||
mod v0_3_6_alpha_14;
|
||||
mod v0_3_6_alpha_15;
|
||||
mod v0_3_6_alpha_16;
|
||||
|
||||
mod v0_4_0_alpha_0;
|
||||
|
||||
@@ -136,6 +137,7 @@ enum Version {
|
||||
V0_3_6_alpha_13(Wrapper<v0_3_6_alpha_13::Version>),
|
||||
V0_3_6_alpha_14(Wrapper<v0_3_6_alpha_14::Version>),
|
||||
V0_3_6_alpha_15(Wrapper<v0_3_6_alpha_15::Version>),
|
||||
V0_3_6_alpha_16(Wrapper<v0_3_6_alpha_16::Version>),
|
||||
V0_4_0_alpha_0(Wrapper<v0_4_0_alpha_0::Version>), // VERSION_BUMP
|
||||
Other(exver::Version),
|
||||
}
|
||||
@@ -176,6 +178,7 @@ impl Version {
|
||||
Self::V0_3_6_alpha_13(v) => DynVersion(Box::new(v.0)),
|
||||
Self::V0_3_6_alpha_14(v) => DynVersion(Box::new(v.0)),
|
||||
Self::V0_3_6_alpha_15(v) => DynVersion(Box::new(v.0)),
|
||||
Self::V0_3_6_alpha_16(v) => DynVersion(Box::new(v.0)),
|
||||
Self::V0_4_0_alpha_0(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP
|
||||
Self::Other(v) => {
|
||||
return Err(Error::new(
|
||||
@@ -208,6 +211,7 @@ impl Version {
|
||||
Version::V0_3_6_alpha_13(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_6_alpha_14(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_6_alpha_15(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_6_alpha_16(Wrapper(x)) => x.semver(),
|
||||
Version::V0_4_0_alpha_0(Wrapper(x)) => x.semver(), // VERSION_BUMP
|
||||
Version::Other(x) => x.clone(),
|
||||
}
|
||||
|
||||
36
core/startos/src/version/v0_3_6_alpha_16.rs
Normal file
36
core/startos/src/version/v0_3_6_alpha_16.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use exver::{PreReleaseSegment, VersionRange};
|
||||
|
||||
use super::v0_3_5::V0_3_0_COMPAT;
|
||||
use super::{v0_3_6_alpha_15, VersionT};
|
||||
use crate::prelude::*;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref V0_3_6_alpha_16: exver::Version = exver::Version::new(
|
||||
[0, 3, 6],
|
||||
[PreReleaseSegment::String("alpha".into()), 16.into()]
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct Version;
|
||||
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_6_alpha_15::Version;
|
||||
type PreUpRes = ();
|
||||
|
||||
async fn pre_up(self) -> Result<Self::PreUpRes, Error> {
|
||||
Ok(())
|
||||
}
|
||||
fn semver(self) -> exver::Version {
|
||||
V0_3_6_alpha_16.clone()
|
||||
}
|
||||
fn compat(self) -> &'static VersionRange {
|
||||
&V0_3_0_COMPAT
|
||||
}
|
||||
fn up(self, _db: &mut Value, _: Self::PreUpRes) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
fn down(self, _db: &mut Value) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ use exver::{PreReleaseSegment, VersionRange};
|
||||
use imbl_value::json;
|
||||
|
||||
use super::v0_3_5::V0_3_0_COMPAT;
|
||||
use super::{v0_3_6_alpha_15, VersionT};
|
||||
use super::{v0_3_6_alpha_16, VersionT};
|
||||
use crate::prelude::*;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
@@ -16,7 +16,7 @@ lazy_static::lazy_static! {
|
||||
pub struct Version;
|
||||
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_6_alpha_15::Version;
|
||||
type Previous = v0_3_6_alpha_16::Version;
|
||||
type PreUpRes = ();
|
||||
|
||||
async fn pre_up(self) -> Result<Self::PreUpRes, Error> {
|
||||
|
||||
Reference in New Issue
Block a user