switch installed flag mechanism

This commit is contained in:
dr-frmr 2024-02-06 14:39:44 -03:00
parent 785e145653
commit ec22e77161
No known key found for this signature in database
3 changed files with 57 additions and 75 deletions

View File

@ -64,7 +64,7 @@ fn gen_package_info(
"package": id.package().to_string(), "package": id.package().to_string(),
"publisher": id.publisher(), "publisher": id.publisher(),
"installed": match &state { "installed": match &state {
Some(state) => !state.source_zip.is_some(), Some(state) => state.installed,
None => false, None => false,
}, },
"metadata_hash": match &listing { "metadata_hash": match &listing {

View File

@ -227,12 +227,6 @@ fn handle_remote_request(
} }
} }
let file_name = format!("/{}.zip", package_id); let file_name = format!("/{}.zip", package_id);
if let Some(zip_bytes) = package_state.source_zip {
match spawn_transfer(&our, &file_name, Some(zip_bytes), 60, &source) {
Ok(()) => return Resp::RemoteResponse(RemoteResponse::DownloadApproved),
Err(_e) => return Resp::RemoteResponse(RemoteResponse::DownloadDenied),
}
}
// get the .zip from VFS and attach as blob to response // get the .zip from VFS and attach as blob to response
let file_path = format!("/{}/pkg/{}.zip", package_id, package_id); let file_path = format!("/{}/pkg/{}.zip", package_id, package_id);
let Ok(Ok(_)) = Request::to(("our", "vfs", "distro", "sys")) let Ok(Ok(_)) = Request::to(("our", "vfs", "distro", "sys"))
@ -274,13 +268,14 @@ fn handle_local_request(
let package_state = PackageState { let package_state = PackageState {
mirrored_from: Some(our.node.clone()), mirrored_from: Some(our.node.clone()),
our_version, our_version,
source_zip: Some(blob.bytes), installed: false,
caps_approved: true, // TODO see if we want to auto-approve local installs caps_approved: true, // TODO see if we want to auto-approve local installs
mirroring: *mirror, mirroring: *mirror,
auto_update: false, // can't auto-update a local package auto_update: false, // can't auto-update a local package
metadata: None, // TODO metadata: None, // TODO
}; };
let Ok(()) = state.add_downloaded_package(package, package_state, true) else { let Ok(()) = state.add_downloaded_package(package, package_state, Some(blob.bytes))
else {
return LocalResponse::NewPackageResponse(NewPackageResponse::Failure); return LocalResponse::NewPackageResponse(NewPackageResponse::Failure);
}; };
LocalResponse::NewPackageResponse(NewPackageResponse::Success) LocalResponse::NewPackageResponse(NewPackageResponse::Success)
@ -447,13 +442,13 @@ fn handle_receive_download(
PackageState { PackageState {
mirrored_from: Some(requested_package.from), mirrored_from: Some(requested_package.from),
our_version: download_hash, our_version: download_hash,
source_zip: Some(blob.bytes), installed: false,
caps_approved: false, caps_approved: false,
mirroring: requested_package.mirror, mirroring: requested_package.mirror,
auto_update: requested_package.auto_update, auto_update: requested_package.auto_update,
metadata: None, // TODO metadata: None, // TODO
}, },
true, Some(blob.bytes),
) )
} }
@ -693,5 +688,9 @@ pub fn handle_install(
))?) ))?)
.send_and_await_response(5)??; .send_and_await_response(5)??;
} }
// finally set the package as installed
state.update_downloaded_package(package_id, |package_state| {
package_state.installed = true;
});
Ok(()) Ok(())
} }

View File

@ -85,8 +85,7 @@ pub struct PackageState {
pub mirrored_from: Option<NodeId>, pub mirrored_from: Option<NodeId>,
/// the version of the package we have downloaded /// the version of the package we have downloaded
pub our_version: String, pub our_version: String,
/// if None, package already installed. if Some, the source file pub installed: bool,
pub source_zip: Option<Vec<u8>>,
pub caps_approved: bool, pub caps_approved: bool,
/// are we serving this package to others? /// are we serving this package to others?
pub mirroring: bool, pub mirroring: bool,
@ -173,14 +172,53 @@ impl State {
pub fn add_downloaded_package( pub fn add_downloaded_package(
&mut self, &mut self,
package_id: &PackageId, package_id: &PackageId,
package_state: PackageState, mut package_state: PackageState,
save_to_vfs: bool, package_bytes: Option<Vec<u8>>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
if let Some(package_bytes) = package_bytes {
let drive_name = format!("/{package_id}/pkg");
let blob = LazyLoadBlob {
mime: Some("application/zip".to_string()),
bytes: package_bytes,
};
// create a new drive for this package in VFS
// this is possible because we have root access
Request::to(("our", "vfs", "distro", "sys"))
.body(serde_json::to_vec(&vfs::VfsRequest {
path: drive_name.clone(),
action: vfs::VfsAction::CreateDrive,
})?)
.send_and_await_response(5)??;
// convert the zip to a new package drive
let response = Request::to(("our", "vfs", "distro", "sys"))
.body(serde_json::to_vec(&vfs::VfsRequest {
path: drive_name.clone(),
action: vfs::VfsAction::AddZip,
})?)
.blob(blob.clone())
.send_and_await_response(5)??;
let vfs::VfsResponse::Ok = serde_json::from_slice::<vfs::VfsResponse>(response.body())?
else {
return Err(anyhow::anyhow!(
"cannot add NewPackage: do not have capability to access vfs"
));
};
// save the zip file itself in VFS for sharing with other nodes
// call it <package_id>.zip
let zip_path = format!("{}/{}.zip", drive_name, package_id);
Request::to(("our", "vfs", "distro", "sys"))
.body(serde_json::to_vec(&vfs::VfsRequest {
path: zip_path,
action: vfs::VfsAction::Write,
})?)
.blob(blob)
.send_and_await_response(5)??;
}
self.downloaded_packages self.downloaded_packages
.insert(package_id.to_owned(), package_state); .insert(package_id.to_owned(), package_state);
if save_to_vfs {
self.save_downloaded_package_in_vfs(package_id)?;
}
crate::set_state(&bincode::serialize(self)?); crate::set_state(&bincode::serialize(self)?);
Ok(()) Ok(())
} }
@ -267,74 +305,19 @@ impl State {
PackageState { PackageState {
mirrored_from: None, mirrored_from: None,
our_version, our_version,
source_zip: None, // since it's already installed installed: true,
caps_approved: true, // since it's already installed this must be true caps_approved: true, // since it's already installed this must be true
mirroring: false, mirroring: false,
auto_update: false, auto_update: false,
metadata: None, metadata: None,
}, },
false, None,
)? )?
} }
} }
Ok(()) Ok(())
} }
/// saves state
fn save_downloaded_package_in_vfs(&mut self, package_id: &PackageId) -> anyhow::Result<()> {
let Some(mut package_state) = self.get_downloaded_package(package_id) else {
return Err(anyhow::anyhow!("no package state"));
};
let Some(zip_bytes) = package_state.source_zip else {
return Err(anyhow::anyhow!("no source zip"));
};
let drive_name = format!("/{package_id}/pkg");
let blob = LazyLoadBlob {
mime: Some("application/zip".to_string()),
bytes: zip_bytes,
};
// create a new drive for this package in VFS
// this is possible because we have root access
Request::to(("our", "vfs", "distro", "sys"))
.body(serde_json::to_vec(&vfs::VfsRequest {
path: drive_name.clone(),
action: vfs::VfsAction::CreateDrive,
})?)
.send_and_await_response(5)??;
// convert the zip to a new package drive
let response = Request::to(("our", "vfs", "distro", "sys"))
.body(serde_json::to_vec(&vfs::VfsRequest {
path: drive_name.clone(),
action: vfs::VfsAction::AddZip,
})?)
.blob(blob.clone())
.send_and_await_response(5)??;
let vfs::VfsResponse::Ok = serde_json::from_slice::<vfs::VfsResponse>(response.body())?
else {
return Err(anyhow::anyhow!(
"cannot add NewPackage: do not have capability to access vfs"
));
};
// save the zip file itself in VFS for sharing with other nodes
// call it <package_id>.zip
let zip_path = format!("{}/{}.zip", drive_name, package_id);
Request::to(("our", "vfs", "distro", "sys"))
// .inherit(true) is this needed?
.body(serde_json::to_vec(&vfs::VfsRequest {
path: zip_path,
action: vfs::VfsAction::Write,
})?)
.blob(blob)
.send_and_await_response(5)??;
package_state.source_zip = None;
crate::set_state(&bincode::serialize(self)?);
Ok(())
}
pub fn uninstall(&mut self, package_id: &PackageId) -> anyhow::Result<()> { pub fn uninstall(&mut self, package_id: &PackageId) -> anyhow::Result<()> {
let drive_path = format!("/{package_id}/pkg"); let drive_path = format!("/{package_id}/pkg");
Request::new() Request::new()