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