oasis_core_runtime/host/bundle_manager.rs
1use std::collections::BTreeMap;
2
3use async_trait::async_trait;
4
5use crate::{common::crypto::hash::Hash, protocol::Protocol};
6
7use super::{host_rpc_call, Error};
8
9/// Name of the local RPC endpoint for the bundle manager.
10pub const LOCAL_RPC_ENDPOINT_BUNDLE_MANAGER: &str = "bundle-manager";
11
12/// Name of the BundleWrite method.
13pub const METHOD_BUNDLE_WRITE: &str = "BundleWrite";
14/// Name of the BundleAdd method.
15pub const METHOD_BUNDLE_ADD: &str = "BundleAdd";
16/// Name of the BundleRemove method.
17pub const METHOD_BUNDLE_REMOVE: &str = "BundleRemove";
18/// Name of the BundleList method.
19pub const METHOD_BUNDLE_LIST: &str = "BundleList";
20
21/// Name of the special label that identifies the instance.
22pub const LABEL_INSTANCE_ID: &str = "net.oasis.instance_id";
23
24/// Bundle manager interface.
25#[async_trait]
26pub trait BundleManager: Send + Sync {
27 /// Request to host to write a chunk of the bundle to a temporary file.
28 ///
29 /// The `PermissionBundleAdd` permission is required to call this method.
30 async fn bundle_write(&self, args: BundleWriteRequest) -> Result<BundleWriteResponse, Error>;
31
32 /// Request to host to add a specific bundle to the host.
33 ///
34 /// The `PermissionBundleAdd` permission is required to call this method.
35 async fn bundle_add(&self, args: BundleAddRequest) -> Result<BundleAddResponse, Error>;
36
37 /// Request to host to remove a specific component. Only components added by this component
38 /// can be removed.
39 ///
40 /// The `PermissionBundleRemove` permission is required to call this method.
41 async fn bundle_remove(&self, args: BundleRemoveRequest)
42 -> Result<BundleRemoveResponse, Error>;
43
44 /// Request to host to list all bundles.
45 ///
46 /// The `PermissionBundleAdd` permission is required to call this method.
47 async fn bundle_list(&self, args: BundleListRequest) -> Result<BundleListResponse, Error>;
48}
49
50#[async_trait]
51impl BundleManager for Protocol {
52 async fn bundle_write(&self, args: BundleWriteRequest) -> Result<BundleWriteResponse, Error> {
53 host_rpc_call(
54 self,
55 LOCAL_RPC_ENDPOINT_BUNDLE_MANAGER,
56 METHOD_BUNDLE_WRITE,
57 args,
58 )
59 .await
60 }
61
62 async fn bundle_add(&self, args: BundleAddRequest) -> Result<BundleAddResponse, Error> {
63 host_rpc_call(
64 self,
65 LOCAL_RPC_ENDPOINT_BUNDLE_MANAGER,
66 METHOD_BUNDLE_ADD,
67 args,
68 )
69 .await
70 }
71
72 async fn bundle_remove(
73 &self,
74 args: BundleRemoveRequest,
75 ) -> Result<BundleRemoveResponse, Error> {
76 host_rpc_call(
77 self,
78 LOCAL_RPC_ENDPOINT_BUNDLE_MANAGER,
79 METHOD_BUNDLE_REMOVE,
80 args,
81 )
82 .await
83 }
84
85 async fn bundle_list(&self, args: BundleListRequest) -> Result<BundleListResponse, Error> {
86 host_rpc_call(
87 self,
88 LOCAL_RPC_ENDPOINT_BUNDLE_MANAGER,
89 METHOD_BUNDLE_LIST,
90 args,
91 )
92 .await
93 }
94}
95
96/// Request to host to write a chunk of the bundle to a temporary file.
97///
98/// The `PermissionBundleAdd` permission is required to call this method.
99#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
100pub struct BundleWriteRequest {
101 /// Temporary file name to use on the host while writing the bundle.
102 pub temporary_name: String,
103 /// Optional flag which specifies that the temporary file should be recreated. If the file
104 /// exists and this flag is set to true, it will be truncated. If the flag is set to false, any
105 /// content will be appended to the existing file.
106 pub create: bool,
107 /// Data that should be appended to the temporary file.
108 pub data: Vec<u8>,
109}
110
111/// Response form the BundleWrite method.
112#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
113pub struct BundleWriteResponse {}
114
115/// Request to host to add a specific bundle to the host.
116///
117/// The `PermissionBundleAdd` permission is required to call this method.
118#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
119pub struct BundleAddRequest {
120 /// Temporary file name to read the bundle from. The file must have previously been created by
121 /// using `BundleWriteRequest`.
122 ///
123 /// The file must be a valid bundle.
124 pub temporary_name: String,
125 /// Expected hash of the manifest contained inside the bundle.
126 pub manifest_hash: Hash,
127 /// Labels to tag the bundle with.
128 ///
129 /// Note that the host will assign a random component identifier to these components, so one
130 /// should use labels to later be able to find them.
131 ///
132 /// Use the special `LABEL_INSTANCE_ID` label to specify a deterministic instance ID.
133 pub labels: BTreeMap<String, String>,
134 /// Volumes to attach to the bundle.
135 pub volumes: BTreeMap<String, String>,
136}
137
138/// Response form the BundleAdd method.
139#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
140pub struct BundleAddResponse {}
141
142/// Request to host to remove a specific component. Only components added by this component can be
143/// removed.
144///
145/// The `PermissionBundleRemove` permission is required to call this method.
146#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
147pub struct BundleRemoveRequest {
148 /// Labels to filter the components by.
149 pub labels: BTreeMap<String, String>,
150}
151
152/// Response form the BundleRemove method.
153#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
154pub struct BundleRemoveResponse {}
155
156/// Request to host to list all bundles.
157///
158/// The `PermissionBundleAdd` permission is required to call this method.
159#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
160pub struct BundleListRequest {
161 /// Labels to filter the components by.
162 pub labels: BTreeMap<String, String>,
163}
164
165/// Response from host to list all bundles.
166#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
167pub struct BundleListResponse {
168 /// The resulting bundles.
169 #[cbor(optional)]
170 pub bundles: Vec<BundleInfo>,
171}
172
173/// Bundle information.
174#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
175pub struct BundleInfo {
176 /// Hash of the manifest.
177 pub manifest_hash: Hash,
178 /// List of all components in this bundle.
179 pub components: Vec<ComponentInfo>,
180 /// Labels assigned to this bundle.
181 pub labels: BTreeMap<String, String>,
182}
183
184/// Component information.
185#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
186pub struct ComponentInfo {
187 /// Component name.
188 pub name: String,
189}