fuchsia_pkg_testing/
system_image.rs1use crate::{Package, PackageBuilder};
6use fuchsia_merkle::Hash;
7use fuchsia_pkg::PackagePath;
8use fuchsia_pkg::package_sets::AnchoredPackageSetType;
9use fuchsia_url::fuchsia_pkg::PinnedAbsolutePackageUrl;
10use std::future::Future;
11use system_image::{AnchoredPackages, CachePackages, StaticPackages};
12
13const DEFAULT_PACKAGE_REPO_URL: &str = "fuchsia-pkg://fuchsia.com";
14
15#[derive(Default)]
17pub struct SystemImageBuilder {
18 static_packages: Option<Vec<(PackagePath, Hash)>>,
19 cache_packages: Option<Vec<PinnedAbsolutePackageUrl>>,
20 anchored_packages: Option<AnchoredPackages>,
21 pkgfs_disable_executability_restrictions: bool,
22}
23
24impl SystemImageBuilder {
25 pub fn new() -> Self {
27 Self::default()
28 }
29
30 pub fn static_package(mut self, path: PackagePath, hash: Hash) -> Self {
32 self.static_packages.get_or_insert_with(Vec::new).push((path, hash));
33 self
34 }
35
36 pub fn static_packages(mut self, static_packages: &[&Package]) -> Self {
39 assert_eq!(self.static_packages, None);
40 self.static_packages = Some(Self::packages_to_entries(static_packages));
41 self
42 }
43
44 pub fn cache_package(mut self, path: PackagePath, hash: Hash) -> Self {
47 let (name, variant) = path.into_name_and_variant();
48 let pinned_url = PinnedAbsolutePackageUrl::new(
49 DEFAULT_PACKAGE_REPO_URL.parse().unwrap(),
50 name,
51 Some(variant),
52 hash,
53 );
54 self.cache_packages.get_or_insert_with(Vec::new).push(pinned_url);
55 self
56 }
57
58 pub fn cache_packages(mut self, cache_packages: &[&Package]) -> Self {
61 assert_eq!(self.cache_packages, None);
62 self.cache_packages =
63 Some(cache_packages.iter().map(|pkg| pkg.pinned_fuchsia_url()).collect());
64 self
65 }
66
67 pub fn anchored_package(
70 mut self,
71 package_set_type: AnchoredPackageSetType,
72 path: PackagePath,
73 hash: Hash,
74 ) -> Self {
75 let (name, variant) = path.into_name_and_variant();
76 let pinned_url = PinnedAbsolutePackageUrl::new(
77 DEFAULT_PACKAGE_REPO_URL.parse().unwrap(),
78 name,
79 Some(variant),
80 hash,
81 );
82 self.anchored_packages
83 .get_or_insert_default()
84 .insert(package_set_type, pinned_url)
85 .unwrap();
86 self
87 }
88
89 pub fn pkgfs_disable_executability_restrictions(mut self) -> Self {
92 self.pkgfs_disable_executability_restrictions = true;
93 self
94 }
95
96 fn packages_to_entries(pkgs: &[&Package]) -> Vec<(PackagePath, Hash)> {
97 pkgs.iter()
98 .map(|pkg| {
99 (
100 PackagePath::from_name_and_variant(pkg.name().to_owned(), "0".parse().unwrap()),
101 *pkg.hash(),
102 )
103 })
104 .collect()
105 }
106
107 pub fn build(&self) -> impl Future<Output = Package> {
109 let mut builder = PackageBuilder::new("system_image");
110 let mut bytes = vec![];
111
112 StaticPackages::from_iter(self.static_packages.clone().unwrap_or_default())
113 .serialize(&mut bytes)
114 .unwrap();
115 builder = builder.add_resource_at("data/static_packages", bytes.as_slice());
116
117 if let Some(cache_packages) = &self.cache_packages {
118 bytes.clear();
119 let cache_packages = CachePackages::from_entries(cache_packages.clone());
120 cache_packages.serialize(&mut bytes).unwrap();
121 builder = builder.add_resource_at("data/cache_packages.json", bytes.as_slice());
122 }
123
124 if let Some(anchored_packages) = &self.anchored_packages {
125 bytes.clear();
126 anchored_packages.serialize(&mut bytes).unwrap();
127 builder = builder.add_resource_at("data/anchored_packages.json", bytes.as_slice());
128 }
129
130 if self.pkgfs_disable_executability_restrictions {
131 builder = builder
132 .add_resource_at("data/pkgfs_disable_executability_restrictions", &[] as &[u8]);
133 }
134
135 async move { builder.build().await.unwrap() }
136 }
137}