mirror of
https://github.com/marcoallegretti/WEFT_OS.git
synced 2026-03-27 01:13:09 +00:00
feat(appd,pack): capability dispatch -- map wapp.toml capabilities to --preopen args
Add capabilities field to weft-pack PackageMeta (optional Vec<String>).
Print cap: lines in weft-pack info output when capabilities are declared.
In weft-appd:
- Make app_store_roots pub(crate) so runtime.rs can use it.
- Add resolve_preopens(app_id) in runtime.rs: reads wapp.toml from the
package store, extracts capabilities, maps each to a (host, guest) pair:
fs:rw:app-data / fs:read:app-data -> ~/.local/share/weft/apps/<id>/data :: /data
fs:rw:xdg-documents / fs:read:xdg-documents -> ~/Documents :: /xdg/documents
Unknown capabilities are logged at debug level and skipped.
- supervise() calls resolve_preopens() and appends --preopen HOST::GUEST
flags before spawning the runtime binary.
This commit is contained in:
parent
84eb39db96
commit
c5a47a05b4
3 changed files with 77 additions and 1 deletions
|
|
@ -286,7 +286,7 @@ pub(crate) async fn dispatch(req: Request, registry: &Registry) -> Response {
|
|||
}
|
||||
}
|
||||
|
||||
fn app_store_roots() -> Vec<std::path::PathBuf> {
|
||||
pub(crate) fn app_store_roots() -> Vec<std::path::PathBuf> {
|
||||
if let Ok(explicit) = std::env::var("WEFT_APP_STORE") {
|
||||
return vec![std::path::PathBuf::from(explicit)];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||
|
|
@ -9,6 +10,71 @@ use crate::ipc::{AppStateKind, Response};
|
|||
|
||||
const READY_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
fn resolve_preopens(app_id: &str) -> Vec<(String, String)> {
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Pkg {
|
||||
capabilities: Option<Vec<String>>,
|
||||
}
|
||||
#[derive(serde::Deserialize)]
|
||||
struct M {
|
||||
package: Pkg,
|
||||
}
|
||||
|
||||
let pkg_dir = crate::app_store_roots().into_iter().find_map(|root| {
|
||||
let dir = root.join(app_id);
|
||||
if dir.join("wapp.toml").exists() {
|
||||
Some(dir)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
let caps = match pkg_dir {
|
||||
None => return Vec::new(),
|
||||
Some(dir) => {
|
||||
let Ok(text) = std::fs::read_to_string(dir.join("wapp.toml")) else {
|
||||
return Vec::new();
|
||||
};
|
||||
match toml::from_str::<M>(&text) {
|
||||
Ok(m) => m.package.capabilities.unwrap_or_default(),
|
||||
Err(_) => return Vec::new(),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let home = match std::env::var("HOME") {
|
||||
Ok(h) => PathBuf::from(h),
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
|
||||
let mut preopens = Vec::new();
|
||||
for cap in &caps {
|
||||
match cap.as_str() {
|
||||
"fs:rw:app-data" | "fs:read:app-data" => {
|
||||
let data_dir = home
|
||||
.join(".local/share/weft/apps")
|
||||
.join(app_id)
|
||||
.join("data");
|
||||
let _ = std::fs::create_dir_all(&data_dir);
|
||||
preopens.push((data_dir.to_string_lossy().into_owned(), "/data".to_string()));
|
||||
}
|
||||
"fs:rw:xdg-documents" | "fs:read:xdg-documents" => {
|
||||
let docs = home.join("Documents");
|
||||
if docs.exists() {
|
||||
preopens.push((
|
||||
docs.to_string_lossy().into_owned(),
|
||||
"/xdg/documents".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
other => {
|
||||
tracing::debug!(capability = other, "not mapped to preopen; skipped");
|
||||
}
|
||||
}
|
||||
}
|
||||
preopens
|
||||
}
|
||||
|
||||
pub(crate) async fn supervise(
|
||||
session_id: u64,
|
||||
app_id: &str,
|
||||
|
|
@ -37,6 +103,10 @@ pub(crate) async fn supervise(
|
|||
cmd.arg("--ipc-socket").arg(sock);
|
||||
}
|
||||
|
||||
for (host, guest) in resolve_preopens(app_id) {
|
||||
cmd.arg("--preopen").arg(format!("{host}::{guest}"));
|
||||
}
|
||||
|
||||
let mut child = match cmd.spawn() {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ struct PackageMeta {
|
|||
version: String,
|
||||
description: Option<String>,
|
||||
author: Option<String>,
|
||||
capabilities: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
|
@ -141,6 +142,11 @@ fn print_info(m: &Manifest) {
|
|||
}
|
||||
println!("module: {}", m.runtime.module);
|
||||
println!("ui: {}", m.ui.entry);
|
||||
if let Some(ref caps) = m.package.capabilities {
|
||||
for cap in caps {
|
||||
println!("cap: {cap}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_valid_app_id(id: &str) -> bool {
|
||||
|
|
|
|||
Loading…
Reference in a new issue