1#![deny(missing_docs)]
6
7mod board;
10mod epoch;
11mod hash;
12mod image;
13pub mod images;
14pub mod manifest;
15mod name;
16mod packages;
17pub mod signed_manifest;
18mod update_mode;
19mod version;
20
21pub use crate::board::VerifyBoardError;
22pub use crate::epoch::ParseEpochError;
23pub use crate::hash::HashError;
24pub use crate::image::OpenImageError;
25pub use crate::images::{
26 ImageMetadata, ImageMetadataError, ImagePackagesError, ImagePackagesManifest,
27 ImagePackagesManifestBuilder, ImagesMetadata, ResolveImagesError, VerifyError,
28 VersionedImagePackagesManifest, ZbiAndOptionalVbmetaMetadata, parse_image_packages_json,
29};
30pub use crate::name::VerifyNameError;
31pub use crate::packages::{
32 ParsePackageError, SerializePackageError, parse_packages_json, serialize_packages_json,
33};
34pub use crate::update_mode::{ParseUpdateModeError, UpdateMode};
35pub use crate::version::{ReadVersionError, SystemVersion};
36
37use fidl_fuchsia_io as fio;
38use fuchsia_hash::Hash;
39use fuchsia_url::fuchsia_pkg::PinnedAbsolutePackageUrl;
40
41#[cfg(target_os = "fuchsia")]
43pub struct UpdateImagePackage {
44 proxy: fio::DirectoryProxy,
45}
46
47#[cfg(target_os = "fuchsia")]
48impl UpdateImagePackage {
49 pub fn new(proxy: fio::DirectoryProxy) -> Self {
51 Self { proxy }
52 }
53
54 pub async fn open_image(&self, path: &str) -> Result<fidl_fuchsia_mem::Buffer, OpenImageError> {
56 image::open_from_path(&self.proxy, path).await
57 }
58}
59
60#[derive(Debug)]
62pub struct UpdatePackage {
63 proxy: fio::DirectoryProxy,
64}
65
66impl UpdatePackage {
67 pub fn new(proxy: fio::DirectoryProxy) -> Self {
69 Self { proxy }
70 }
71
72 pub async fn verify_name(&self) -> Result<(), VerifyNameError> {
74 name::verify(&self.proxy).await
75 }
76
77 pub async fn images_metadata(&self) -> Result<ImagesMetadata, ImagePackagesError> {
79 images::images_metadata(&self.proxy).await
80 }
81
82 pub async fn verify_board(&self, contents: &str) -> Result<(), VerifyBoardError> {
84 board::verify_board(&self.proxy, contents).await
85 }
86
87 pub async fn update_mode(&self) -> Result<Option<UpdateMode>, ParseUpdateModeError> {
90 update_mode::update_mode(&self.proxy).await
91 }
92
93 pub async fn packages(&self) -> Result<Vec<PinnedAbsolutePackageUrl>, ParsePackageError> {
95 packages::packages(&self.proxy).await
96 }
97
98 pub async fn hash(&self) -> Result<Hash, HashError> {
100 hash::hash(&self.proxy).await
101 }
102
103 pub async fn version(&self) -> Result<SystemVersion, ReadVersionError> {
105 version::read_version(&self.proxy).await
106 }
107
108 pub async fn epoch(&self) -> Result<Option<u64>, ParseEpochError> {
111 epoch::epoch(&self.proxy).await
112 }
113}
114
115#[cfg(test)]
116struct TestUpdatePackage {
117 update_pkg: UpdatePackage,
118 temp_dir: tempfile::TempDir,
119}
120
121#[cfg(test)]
122impl TestUpdatePackage {
123 #[cfg(not(target_os = "fuchsia"))]
124 compile_error!(
125 "Building tests for non-fuchsia targets requires a library to serve a temp dir using the fidl_fuchsia_io::Directory protocol"
126 );
127
128 fn new() -> Self {
129 let temp_dir = tempfile::tempdir().expect("/tmp to exist");
130 let update_pkg_proxy = fuchsia_fs::directory::open_in_namespace(
131 temp_dir.path().to_str().unwrap(),
132 fio::PERM_READABLE,
133 )
134 .expect("temp dir to open");
135 Self { temp_dir, update_pkg: UpdatePackage::new(update_pkg_proxy) }
136 }
137
138 fn proxy(&self) -> &fio::DirectoryProxy {
139 &self.update_pkg.proxy
140 }
141
142 async fn add_file(self, path: impl AsRef<std::path::Path>, contents: impl AsRef<[u8]>) -> Self {
143 let path = path.as_ref();
144 match path.parent() {
145 Some(empty) if empty == std::path::Path::new("") => {}
146 None => {}
147 Some(parent) => std::fs::create_dir_all(self.temp_dir.path().join(parent)).unwrap(),
148 }
149 fuchsia_fs::file::write_in_namespace(
150 self.temp_dir.path().join(path).to_str().unwrap(),
151 contents,
152 )
153 .await
154 .expect("create test update package file");
155 self
156 }
157}
158
159#[cfg(test)]
160impl std::ops::Deref for TestUpdatePackage {
161 type Target = UpdatePackage;
162
163 fn deref(&self) -> &Self::Target {
164 &self.update_pkg
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171
172 #[fuchsia_async::run_singlethreaded(test)]
173 async fn lifecycle() {
174 let (proxy, _server_end) = fidl::endpoints::create_proxy::<fio::DirectoryMarker>();
175 UpdatePackage::new(proxy);
176 }
177}