1use crate::CryptDisk;
7use async_trait::async_trait;
8use disk_backend::resolve::ResolveDiskParameters;
9use disk_backend::resolve::ResolvedDisk;
10use disk_crypt_resources::DiskCryptHandle;
11use thiserror::Error;
12use vm_resource::AsyncResolveResource;
13use vm_resource::ResolveError;
14use vm_resource::ResourceResolver;
15use vm_resource::declare_static_async_resolver;
16use vm_resource::kind::DiskHandleKind;
17
18declare_static_async_resolver! {
19 DiskCryptResolver,
20 (DiskHandleKind, DiskCryptHandle),
21}
22
23pub struct DiskCryptResolver;
25
26#[derive(Debug, Error)]
28pub enum DiskResolveError {
29 #[error("failed to resolve inner disk")]
31 ResolveInner(#[source] ResolveError),
32 #[error("failed to create disk")]
34 NewDisk(#[source] crate::NewDiskError),
35 #[error("invalid disk")]
37 InvalidDisk(#[source] disk_backend::InvalidDisk),
38}
39
40#[async_trait]
41impl AsyncResolveResource<DiskHandleKind, DiskCryptHandle> for DiskCryptResolver {
42 type Output = ResolvedDisk;
43 type Error = DiskResolveError;
44
45 async fn resolve(
46 &self,
47 resolver: &ResourceResolver,
48 resource: DiskCryptHandle,
49 input: ResolveDiskParameters<'_>,
50 ) -> Result<Self::Output, Self::Error> {
51 let inner = resolver
52 .resolve(
53 resource.disk,
54 ResolveDiskParameters {
55 read_only: input.read_only,
56 _async_trait_workaround: &(),
57 },
58 )
59 .await
60 .map_err(DiskResolveError::ResolveInner)?;
61
62 let disk = CryptDisk::new(resource.cipher, &resource.key, inner.0)
63 .map_err(DiskResolveError::NewDisk)?;
64 ResolvedDisk::new(disk).map_err(DiskResolveError::InvalidDisk)
65 }
66}