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::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 = Some(cache_packages.iter().map(|pkg| pkg.fuchsia_url()).collect());
63 self
64 }
65
66 pub fn anchored_package(
69 mut self,
70 package_set_type: AnchoredPackageSetType,
71 path: PackagePath,
72 hash: Hash,
73 ) -> Self {
74 let (name, variant) = path.into_name_and_variant();
75 let pinned_url = PinnedAbsolutePackageUrl::new(
76 DEFAULT_PACKAGE_REPO_URL.parse().unwrap(),
77 name,
78 Some(variant),
79 hash,
80 );
81 self.anchored_packages
82 .get_or_insert_default()
83 .insert(package_set_type, pinned_url)
84 .unwrap();
85 self
86 }
87
88 pub fn pkgfs_disable_executability_restrictions(mut self) -> Self {
91 self.pkgfs_disable_executability_restrictions = true;
92 self
93 }
94
95 fn packages_to_entries(pkgs: &[&Package]) -> Vec<(PackagePath, Hash)> {
96 pkgs.iter()
97 .map(|pkg| {
98 (
99 PackagePath::from_name_and_variant(pkg.name().to_owned(), "0".parse().unwrap()),
100 *pkg.hash(),
101 )
102 })
103 .collect()
104 }
105
106 pub fn build(&self) -> impl Future<Output = Package> {
108 let mut builder = PackageBuilder::new("system_image");
109 let mut bytes = vec![];
110
111 StaticPackages::from_entries(self.static_packages.clone().unwrap_or_default())
112 .serialize(&mut bytes)
113 .unwrap();
114 builder = builder.add_resource_at("data/static_packages", bytes.as_slice());
115
116 if let Some(cache_packages) = &self.cache_packages {
117 bytes.clear();
118 let cache_packages = CachePackages::from_entries(cache_packages.clone());
119 cache_packages.serialize(&mut bytes).unwrap();
120 builder = builder.add_resource_at("data/cache_packages.json", bytes.as_slice());
121 }
122
123 if let Some(anchored_packages) = &self.anchored_packages {
124 bytes.clear();
125 anchored_packages.serialize(&mut bytes).unwrap();
126 builder = builder.add_resource_at("data/anchored_packages.json", bytes.as_slice());
127 }
128
129 if self.pkgfs_disable_executability_restrictions {
130 builder = builder
131 .add_resource_at("data/pkgfs_disable_executability_restrictions", &[] as &[u8]);
132 }
133
134 async move { builder.build().await.unwrap() }
135 }
136}