#![deny(missing_docs)]
mod board;
mod epoch;
mod hash;
mod image;
pub mod images;
mod name;
mod packages;
mod update_mode;
mod version;
pub use crate::board::VerifyBoardError;
pub use crate::epoch::ParseEpochError;
pub use crate::hash::HashError;
pub use crate::image::OpenImageError;
pub use crate::images::{
parse_image_packages_json, ImageMetadata, ImageMetadataError, ImagePackagesError,
ImagePackagesManifest, ImagePackagesManifestBuilder, ImagesMetadata, ResolveImagesError,
VerifyError, VersionedImagePackagesManifest, ZbiAndOptionalVbmetaMetadata,
};
pub use crate::name::VerifyNameError;
pub use crate::packages::{
parse_packages_json, serialize_packages_json, ParsePackageError, SerializePackageError,
};
pub use crate::update_mode::{ParseUpdateModeError, UpdateMode};
pub use crate::version::{ReadVersionError, SystemVersion};
use fidl_fuchsia_io as fio;
use fuchsia_hash::Hash;
use fuchsia_url::PinnedAbsolutePackageUrl;
#[cfg(target_os = "fuchsia")]
pub struct UpdateImagePackage {
proxy: fio::DirectoryProxy,
}
#[cfg(target_os = "fuchsia")]
impl UpdateImagePackage {
pub fn new(proxy: fio::DirectoryProxy) -> Self {
Self { proxy }
}
pub async fn open_image(&self, path: &str) -> Result<fidl_fuchsia_mem::Buffer, OpenImageError> {
image::open_from_path(&self.proxy, path).await
}
}
#[derive(Debug)]
pub struct UpdatePackage {
proxy: fio::DirectoryProxy,
}
impl UpdatePackage {
pub fn new(proxy: fio::DirectoryProxy) -> Self {
Self { proxy }
}
pub async fn verify_name(&self) -> Result<(), VerifyNameError> {
name::verify(&self.proxy).await
}
pub async fn images_metadata(&self) -> Result<ImagesMetadata, ImagePackagesError> {
images::images_metadata(&self.proxy).await
}
pub async fn verify_board(&self, contents: &str) -> Result<(), VerifyBoardError> {
board::verify_board(&self.proxy, contents).await
}
pub async fn update_mode(&self) -> Result<Option<UpdateMode>, ParseUpdateModeError> {
update_mode::update_mode(&self.proxy).await
}
pub async fn packages(&self) -> Result<Vec<PinnedAbsolutePackageUrl>, ParsePackageError> {
packages::packages(&self.proxy).await
}
pub async fn hash(&self) -> Result<Hash, HashError> {
hash::hash(&self.proxy).await
}
pub async fn version(&self) -> Result<SystemVersion, ReadVersionError> {
version::read_version(&self.proxy).await
}
pub async fn epoch(&self) -> Result<Option<u64>, ParseEpochError> {
epoch::epoch(&self.proxy).await
}
}
#[cfg(test)]
struct TestUpdatePackage {
update_pkg: UpdatePackage,
temp_dir: tempfile::TempDir,
}
#[cfg(test)]
impl TestUpdatePackage {
#[cfg(not(target_os = "fuchsia"))]
compile_error!("Building tests for non-fuchsia targets requires a library to serve a temp dir using the fidl_fuchsia_io::Directory protocol");
fn new() -> Self {
let temp_dir = tempfile::tempdir().expect("/tmp to exist");
let update_pkg_proxy = fuchsia_fs::directory::open_in_namespace(
temp_dir.path().to_str().unwrap(),
fio::PERM_READABLE,
)
.expect("temp dir to open");
Self { temp_dir, update_pkg: UpdatePackage::new(update_pkg_proxy) }
}
fn proxy(&self) -> &fio::DirectoryProxy {
&self.update_pkg.proxy
}
async fn add_file(self, path: impl AsRef<std::path::Path>, contents: impl AsRef<[u8]>) -> Self {
let path = path.as_ref();
match path.parent() {
Some(empty) if empty == std::path::Path::new("") => {}
None => {}
Some(parent) => std::fs::create_dir_all(self.temp_dir.path().join(parent)).unwrap(),
}
fuchsia_fs::file::write_in_namespace(
self.temp_dir.path().join(path).to_str().unwrap(),
contents,
)
.await
.expect("create test update package file");
self
}
}
#[cfg(test)]
impl std::ops::Deref for TestUpdatePackage {
type Target = UpdatePackage;
fn deref(&self) -> &Self::Target {
&self.update_pkg
}
}
#[cfg(test)]
mod tests {
use super::*;
#[fuchsia_async::run_singlethreaded(test)]
async fn lifecycle() {
let (proxy, _server_end) = fidl::endpoints::create_proxy::<fio::DirectoryMarker>();
UpdatePackage::new(proxy);
}
}