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}