BIG change:

- add `inherit` to Response
- refactor repo to match
- make remote app distribution work
This commit is contained in:
dr-frmr 2023-10-16 17:39:00 -04:00
parent ae766b4e9a
commit 114def40fc
No known key found for this signature in database
22 changed files with 121 additions and 34 deletions

View File

@ -38,7 +38,7 @@ struct AppTrackerState {
#[derive(Debug, Serialize, Deserialize)]
pub enum AppTrackerRequest {
New {
package: String,
package: PackageId,
mirror: bool,
},
NewFromRemote {
@ -46,7 +46,7 @@ pub enum AppTrackerRequest {
install_from: NodeId,
},
Install {
package: String,
package: PackageId,
},
}
@ -87,7 +87,7 @@ fn parse_command(
if our.node != source.node {
return Err(anyhow::anyhow!("new package request from non-local node"));
}
let Some(payload) = get_payload() else {
let Some(mut payload) = get_payload() else {
return Err(anyhow::anyhow!("no payload"));
};
@ -100,7 +100,7 @@ fn parse_command(
&vfs_address,
false,
Some(serde_json::to_string(&kt::VfsRequest {
drive: package.clone(),
drive: package.to_string(),
action: kt::VfsAction::New,
})?),
None,
@ -109,13 +109,14 @@ fn parse_command(
)?;
// add zip bytes
payload.mime = Some("application/zip".to_string());
let _ = process_lib::send_and_await_response(
&vfs_address,
true,
Some(serde_json::to_string(&kt::VfsRequest {
drive: package.clone(),
drive: package.to_string(),
action: kt::VfsAction::Add {
full_path: package.clone().into(),
full_path: package.to_string(),
entry_type: kt::AddEntryType::ZipArchive,
},
})?),
@ -130,9 +131,9 @@ fn parse_command(
&vfs_address,
true,
Some(serde_json::to_string(&kt::VfsRequest {
drive: package.clone(),
drive: package.to_string(),
action: kt::VfsAction::Add {
full_path: format!("/{}.zip", package),
full_path: format!("/{}.zip", package.to_string()),
entry_type: kt::AddEntryType::NewFile,
},
})?),
@ -147,7 +148,7 @@ fn parse_command(
&vfs_address,
false,
Some(serde_json::to_string(&kt::VfsRequest {
drive: package.clone(),
drive: package.to_string(),
action: kt::VfsAction::GetEntry("/metadata.json".into()),
})?),
None,
@ -165,7 +166,7 @@ fn parse_command(
process_lib::set_state::<AppTrackerState>(&state);
}
Ok(Some(AppTrackerResponse::New { package }))
Ok(Some(AppTrackerResponse::New { package: package.to_string() }))
}
// if we are the source, forward to install_from target.
// if we install_from, respond with package if we have it
@ -183,16 +184,20 @@ fn parse_command(
inherit: true,
expects_response: Some(5), // TODO
ipc: Some(serde_json::to_string(&AppTrackerRequest::NewFromRemote {
package_id,
install_from,
package_id: package_id.clone(),
install_from: install_from.clone(),
})?),
metadata: None,
},
None,
None,
);
state.requested_packages.insert(package_id, install_from);
process_lib::set_state::<AppTrackerState>(&state);
Ok(None)
} else if our.node == install_from {
print_to_terminal(0, &format!("app-store: got new from remote for {}", package_id.to_string()));
print_to_terminal(0, &format!("{:?}", state.mirrored_packages));
let Some(_mirror) = state.mirrored_packages.get(&package_id) else {
return Ok(Some(AppTrackerResponse::Error { error: "package not mirrored here!".into() }))
};
@ -231,7 +236,7 @@ fn parse_command(
&vfs_address,
false,
Some(serde_json::to_string(&kt::VfsRequest {
drive: package.clone(),
drive: package.to_string(),
action: kt::VfsAction::GetEntry("/manifest.json".into()),
})?),
None,
@ -255,7 +260,7 @@ fn parse_command(
&vfs_address,
false,
Some(serde_json::to_string(&kt::VfsRequest {
drive: package.clone(),
drive: package.to_string(),
action: kt::VfsAction::GetHash(path.clone()),
})?),
None,
@ -288,7 +293,7 @@ fn parse_command(
&vfs_address.clone(),
&serde_json::to_string(&serde_json::json!({
"kind": "read",
"drive": package,
"drive": package.to_string(),
}))?,
) else {
return Err(anyhow::anyhow!("app-store: no read cap"));
@ -298,7 +303,7 @@ fn parse_command(
&vfs_address.clone(),
&serde_json::to_string(&serde_json::json!({
"kind": "write",
"drive": package,
"drive": package.to_string(),
}))?,
) else {
return Err(anyhow::anyhow!("app-store: no write cap"));
@ -323,7 +328,7 @@ fn parse_command(
initial_capabilities.insert(kt::de_wit_signed_capability(messaging_cap));
}
let process_id = format!("{}:{}", entry.process_name, package.clone());
let process_id = format!("{}:{}", entry.process_name, package.to_string());
let Ok(parsed_new_process_id) = ProcessId::from_str(&process_id) else {
return Err(anyhow::anyhow!("app-store: invalid process id!"));
};
@ -347,7 +352,7 @@ fn parse_command(
&vfs_address,
false,
Some(serde_json::to_string(&kt::VfsRequest {
drive: package.clone(),
drive: package.to_string(),
action: kt::VfsAction::GetEntry(path),
})?),
None,
@ -377,7 +382,7 @@ fn parse_command(
5,
)?;
}
Ok(Some(AppTrackerResponse::Install { package }))
Ok(Some(AppTrackerResponse::Install { package: package.to_string() }))
}
}
}
@ -385,6 +390,23 @@ fn parse_command(
impl Guest for Component {
fn init(our: Address) {
assert_eq!(our.process.to_string(), "main:app_store:uqbar");
// grant messaging caps to http_bindings and terminal
let Some(our_messaging_cap) = bindings::get_capability(
&our,
&"\"messaging\"".into()
) else {
panic!("missing self-messaging cap!")
};
bindings::share_capability(
&ProcessId::from_str("http_bindings:http_bindings:uqbar").unwrap(),
&our_messaging_cap,
);
bindings::share_capability(
&ProcessId::from_str("terminal:terminal:uqbar").unwrap(),
&our_messaging_cap,
);
print_to_terminal(0, &format!("app_store main proc: start"));
let mut state = process_lib::get_state::<AppTrackerState>().unwrap_or(AppTrackerState {
@ -413,8 +435,10 @@ impl Guest for Component {
match parse_command(&our, &source, command, &mut state) {
Ok(response) => {
if let Some(_) = expects_response {
print_to_terminal(0, &format!("app-store: sending response {:?}", response));
let _ = send_response(
&Response {
inherit: true,
ipc: Some(serde_json::to_string(&response).unwrap()),
metadata,
},
@ -430,6 +454,7 @@ impl Guest for Component {
};
let _ = send_response(
&Response {
inherit: false,
ipc: Some(serde_json::to_string(&error).unwrap()),
metadata,
},
@ -440,12 +465,14 @@ impl Guest for Component {
}
}
Message::Response((response, _)) => {
print_to_terminal(0, &format!("app-store: got response {:?}", response));
// only expecting NewFromRemote for apps we've requested
match serde_json::from_str(&response.ipc.unwrap_or_default()) {
Ok(AppTrackerResponse::NewFromRemote { package_id }) => {
if let Some(install_from) = state.requested_packages.remove(&package_id)
{
if install_from == source.node {
print_to_terminal(0, "got install");
// auto-take zip from payload and request ourself with New
let _ = send_request(
&our,
@ -454,7 +481,7 @@ impl Guest for Component {
expects_response: None,
ipc: Some(
serde_json::to_string(&AppTrackerRequest::New {
package: package_id.package().into(),
package: package_id,
mirror: true,
})
.unwrap(),

View File

@ -162,6 +162,7 @@ pub fn receive_transfer(
// respond to first request
send_response(
&Response {
inherit: false,
ipc: None,
metadata: Some(1.to_string()),
},
@ -201,6 +202,7 @@ pub fn receive_transfer(
file.extend(payload.bytes);
send_response(
&Response {
inherit: false,
ipc: None,
metadata: Some(chunk_num.to_string()),
},

View File

@ -85,6 +85,7 @@ fn json_game(game: &Game) -> serde_json::Value {
fn send_http_response(status: u16, headers: HashMap<String, String>, payload_bytes: Vec<u8>) {
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"status": status,
@ -298,6 +299,7 @@ impl Guest for Component {
if !game.ended {
send_response(
&Response {
inherit: false,
ipc: None,
metadata: None,
},
@ -331,6 +333,7 @@ impl Guest for Component {
send_response(
&Response {
inherit: false,
ipc: None,
metadata: None,
},
@ -346,6 +349,7 @@ impl Guest for Component {
let Some(game) = state.games.get_mut(&game_id) else {
send_response(
&Response {
inherit: false,
ipc: None,
metadata: None,
},
@ -405,6 +409,7 @@ impl Guest for Component {
send_response(
&Response {
inherit: false,
ipc: None,
metadata: None,
},
@ -417,6 +422,7 @@ impl Guest for Component {
} else {
send_response(
&Response {
inherit: false,
ipc: None,
metadata: None,
},
@ -433,6 +439,7 @@ impl Guest for Component {
let Some(game) = state.games.get_mut(&game_id) else {
send_response(
&Response {
inherit: false,
ipc: None,
metadata: None,
},
@ -457,6 +464,7 @@ impl Guest for Component {
send_response(
&Response {
inherit: false,
ipc: None,
metadata: None,
},

View File

@ -72,6 +72,7 @@ impl Guest for Component {
send_response(
&Response {
inherit: false,
ipc: Some(serde_json::json!({
"action": "response",
"status": 200,
@ -89,6 +90,7 @@ impl Guest for Component {
} else if message_json["path"].is_string() {
send_response(
&Response {
inherit: false,
ipc: Some(json!({
"action": "response",
"status": 404,
@ -109,6 +111,7 @@ impl Guest for Component {
} else if message_json["hello"] == "world" {
send_response(
&Response {
inherit: false,
ipc: Some(serde_json::json!({
"hello": "to you too"
}).to_string()),

View File

@ -87,6 +87,7 @@ fn auth_cookie_valid(our_node: String, cookie: &str, secret: Hmac<Sha256>) -> bo
fn send_http_response(status: u16, headers: HashMap<String, String>, payload_bytes: Vec<u8>) {
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"status": status,
@ -180,6 +181,7 @@ impl Guest for Component {
};
send_response(
&Response {
inherit: false,
ipc: None,
metadata: None,
},

View File

@ -30,6 +30,7 @@ pub struct FileSystemRequest {
fn send_http_response(status: u16, headers: HashMap<String, String>, payload_bytes: Vec<u8>) {
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"status": status,
@ -197,6 +198,7 @@ impl Guest for Component {
if message_json["path"] == "/http-proxy" && message_json["method"] == "GET" {
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"action": "response",
@ -221,6 +223,7 @@ impl Guest for Component {
{
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"action": "response",
@ -271,6 +274,7 @@ impl Guest for Component {
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"action": "response",
@ -313,6 +317,7 @@ impl Guest for Component {
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"action": "response",
@ -349,6 +354,7 @@ impl Guest for Component {
} else if !registrations.contains_key(username) {
send_response(
&Response {
inherit: false,
ipc: Some(
json!({
"action": "response",

View File

@ -121,6 +121,7 @@ fn get_http_request_info(
fn send_http_response(status: u16, headers: HashMap<String, String>, payload_bytes: Vec<u8>) {
send_response(
&Response {
inherit: false,
ipc: Some(
json!({
"status": status,
@ -735,6 +736,7 @@ impl Guest for Component {
print_to_terminal(1, "orgs: get_contact_info");
send_response(
&Response {
inherit: false,
ipc: Some(
json!({
"action": "get_contact_info",
@ -758,6 +760,7 @@ impl Guest for Component {
bindings::set_state(&to_vec(&state).unwrap());
send_response(
&Response {
inherit: false,
ipc: Some(
json!({
"action": "update_contact_info",
@ -777,6 +780,7 @@ impl Guest for Component {
state.orgs.insert(org.id, org);
send_response(
&Response {
inherit: false,
ipc: Some(
json!({
"action": "update_orgs",

View File

@ -201,6 +201,7 @@ impl UqProcess for Component {
if let Some(node) = state.nodes.get(name) {
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"status": 200,
@ -227,6 +228,7 @@ impl UqProcess for Component {
}
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"status": 404,

View File

@ -64,6 +64,7 @@ struct WriteFileResult {
fn send_http_response(status: u16, headers: HashMap<String, String>, payload_bytes: Vec<u8>) {
send_response(
&Response {
inherit: false,
ipc: Some(
json!({
"status": status,
@ -207,6 +208,7 @@ impl Guest for Component {
"/rpc" => {
send_response(
&Response {
inherit: false,
ipc: Some(
json!({
"action": "response",

View File

@ -108,7 +108,7 @@ impl Guest for Component {
};
parse_command(&our.node, command);
}
Message::Response((Response { ipc, metadata }, _)) => {
Message::Response((Response { ipc, metadata, .. }, _)) => {
if let Some(txt) = &ipc {
print_to_terminal(0, &format!("net response: {}", txt));
}

View File

@ -159,6 +159,7 @@ pub async fn encryptor(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some(serde_json::json!({
"status": 201,
"headers": headers,
@ -340,6 +341,7 @@ pub async fn encryptor(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: None,
metadata: None,
},
@ -395,6 +397,7 @@ pub async fn encryptor(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: None,
metadata: None,
},

View File

@ -134,6 +134,7 @@ pub async fn eth_rpc(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some(
serde_json::to_string::<Result<u64, EthRpcError>>(&Ok(
message.id
@ -301,6 +302,7 @@ fn make_error_message(our_name: String, km: &KernelMessage, error: EthRpcError)
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some(serde_json::to_string::<Result<u64, EthRpcError>>(&Err(error)).unwrap()),
metadata: None,
},

View File

@ -757,6 +757,7 @@ async fn handle_request(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some(
serde_json::to_string::<Result<FsResponse, FsError>>(&Ok(ipc)).unwrap(),
),
@ -804,6 +805,7 @@ fn make_error_message(our_name: String, km: &KernelMessage, error: FsError) -> K
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some(
serde_json::to_string::<Result<FsResponse, FsError>>(&Err(error)).unwrap(),
),

View File

@ -144,6 +144,7 @@ async fn handle_message(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some(
serde_json::to_string::<Result<HttpClientResponse, HttpClientError>>(&Ok(
http_client_response,
@ -219,6 +220,7 @@ fn make_error_message(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some(
serde_json::to_string::<Result<HttpClientResponse, HttpClientError>>(&Err(
error,

View File

@ -457,6 +457,7 @@ pub fn make_error_message(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some(serde_json::to_string(&error).unwrap()),
metadata: None,
},

View File

@ -993,7 +993,10 @@ impl Process {
mime: p.mime,
bytes: p.bytes,
}),
None => None,
None => match request.inherit {
true => self.last_payload.clone(),
false => None,
},
};
// rsvp is set if there was a Request expecting Response
@ -1076,6 +1079,11 @@ impl Process {
}
};
let payload = match response.inherit {
true => self.last_payload.clone(),
false => de_wit_payload(payload),
};
self.send_to_loop
.send(t::KernelMessage {
id,
@ -1087,7 +1095,7 @@ impl Process {
// the context will be set by the process receiving this Response.
None,
)),
payload: de_wit_payload(payload),
payload,
signed_capabilities: None,
})
.await
@ -1419,6 +1427,7 @@ async fn handle_kernel_request(
rsvp: None,
message: t::Message::Response((
t::Response {
inherit: false,
ipc: Some(
serde_json::to_string(&t::KernelResponse::StartProcessError)
.unwrap(),
@ -1584,6 +1593,7 @@ async fn handle_kernel_request(
rsvp: None,
message: t::Message::Response((
t::Response {
inherit: false,
ipc: Some(
serde_json::to_string(&t::KernelResponse::KilledProcess(
process_id,
@ -1778,6 +1788,7 @@ async fn start_process(
rsvp: None,
message: t::Message::Response((
t::Response {
inherit: false,
ipc: Some(serde_json::to_string(&t::KernelResponse::StartedProcess).unwrap()),
metadata: None,
},

View File

@ -34,6 +34,7 @@ pub fn en_wit_request(request: t::Request) -> wit::Request {
pub fn de_wit_response(wit: wit::Response) -> t::Response {
t::Response {
inherit: wit.inherit,
ipc: wit.ipc,
metadata: wit.metadata,
}
@ -41,6 +42,7 @@ pub fn de_wit_response(wit: wit::Response) -> t::Response {
pub fn en_wit_response(response: t::Response) -> wit::Response {
wit::Response {
inherit: response.inherit,
ipc: response.ipc,
metadata: response.metadata,
}

View File

@ -137,6 +137,7 @@ pub struct Request {
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Response {
pub inherit: bool,
pub ipc: Option<String>, // JSON-string
pub metadata: Option<String>, // JSON-string
}
@ -334,6 +335,7 @@ pub fn en_wit_request(request: Request) -> wit::Request {
pub fn de_wit_response(wit: wit::Response) -> Response {
Response {
inherit: wit.inherit,
ipc: wit.ipc,
metadata: wit.metadata,
}
@ -341,6 +343,7 @@ pub fn de_wit_response(wit: wit::Response) -> Response {
pub fn en_wit_response(response: Response) -> wit::Response {
wit::Response {
inherit: response.inherit,
ipc: response.ipc,
metadata: response.metadata,
}

View File

@ -718,6 +718,7 @@ async fn handle_incoming_message(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some("delivered".into()),
metadata: None,
},
@ -781,7 +782,7 @@ async fn handle_incoming_message(
NetActions::QnsUpdate(log) => {
let _ = print_tx
.send(Printout {
verbosity: 0, // TODO 1
verbosity: 1, // TODO 1
content: format!("net: got QNS update for {}", log.name),
})
.await;

View File

@ -207,6 +207,7 @@ pub struct Request {
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Response {
pub inherit: bool,
pub ipc: Option<String>, // JSON-string
pub metadata: Option<String>, // JSON-string
}
@ -672,8 +673,8 @@ impl std::fmt::Display for KernelMessage {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"{{\n id: {},\n source: {},\n target: {},\n rsvp: {:?},\n message: {}\n}}",
self.id, self.source, self.target, self.rsvp, self.message,
"{{\n id: {},\n source: {},\n target: {},\n rsvp: {:?},\n message: {},\n payload: {}\n}}",
self.id, self.source, self.target, self.rsvp, self.message, self.payload.is_some()
)
}
}
@ -691,7 +692,8 @@ impl std::fmt::Display for Message {
),
Message::Response((response, context)) => write!(
f,
"Response(\n ipc: {},\n metadata: {},\n context: {}\n )",
"Response(\n inherit: {},\n ipc: {},\n metadata: {},\n context: {}\n )",
response.inherit,
&response.ipc.as_ref().unwrap_or(&"None".into()),
&response.metadata.as_ref().unwrap_or(&"None".into()),
&context.as_ref().unwrap_or(&"None".into()),

View File

@ -113,6 +113,7 @@ fn make_error_message(
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: Some(serde_json::to_string(&VfsResponse::Err(error)).unwrap()), // TODO: handle error?
metadata: None,
},
@ -638,7 +639,7 @@ async fn handle_request(
process: source.process.clone(),
},
rsvp,
message: Message::Response((Response { ipc, metadata }, None)),
message: Message::Response((Response { inherit: false, ipc, metadata, }, None)),
payload: match bytes {
Some(bytes) => Some(Payload {
mime: Some("application/octet-stream".into()),
@ -986,7 +987,7 @@ async fn match_request(
}
};
let KernelMessage { message, .. } = write_response;
let Message::Response((Response { ipc, metadata: _ }, None)) = message
let Message::Response((Response { ipc, .. }, None)) = message
else {
panic!("")
};
@ -1220,7 +1221,7 @@ async fn match_request(
.await;
let write_response = recv_response.recv().await.unwrap();
let KernelMessage { message, .. } = write_response;
let Message::Response((Response { ipc, metadata: _ }, None)) = message else {
let Message::Response((Response { ipc, .. }, None)) = message else {
panic!("")
};
let Some(ipc) = ipc else {
@ -1275,7 +1276,7 @@ async fn match_request(
.await;
let write_response = recv_response.recv().await.unwrap();
let KernelMessage { message, .. } = write_response;
let Message::Response((Response { ipc, metadata: _ }, None)) = message else {
let Message::Response((Response { ipc, .. }, None)) = message else {
panic!("")
};
let Some(ipc) = ipc else {
@ -1419,7 +1420,7 @@ async fn match_request(
let KernelMessage {
message, payload, ..
} = read_response;
let Message::Response((Response { ipc, metadata: _ }, None)) = message
let Message::Response((Response { ipc, .. }, None)) = message
else {
panic!("");
};
@ -1503,7 +1504,7 @@ async fn match_request(
let KernelMessage {
message, payload, ..
} = read_response;
let Message::Response((Response { ipc, metadata: _ }, None)) = message else {
let Message::Response((Response { ipc, .. }, None)) = message else {
panic!("")
};
let Some(ipc) = ipc else {
@ -1568,7 +1569,7 @@ async fn match_request(
.await;
let length_response = recv_response.recv().await.unwrap();
let KernelMessage { message, .. } = length_response;
let Message::Response((Response { ipc, metadata: _ }, None)) = message else {
let Message::Response((Response { ipc, .. }, None)) = message else {
panic!("")
};
let Some(ipc) = ipc else {

View File

@ -41,6 +41,7 @@ interface types {
}
record response {
inherit: bool,
ipc: option<json>,
metadata: option<json>,
// to grab payload, use get_payload()