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