file-restore(-daemon): implement list API

Allows listing files and directories on a block device snapshot.
Hierarchy displayed is:

/archive.img.fidx/bucket/component/<path>
e.g.
/drive-scsi0.img.fidx/part/2/etc/passwd
(corresponding to /etc/passwd on the second partition of drive-scsi0)

Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Stefan Reiter
2021-03-31 12:21:59 +02:00
committed by Thomas Lamprecht
parent 34ac5cd889
commit 801ec1dbf9
4 changed files with 187 additions and 3 deletions

View File

@ -9,6 +9,7 @@ use std::hash::BuildHasher;
use std::pin::Pin;
use proxmox_backup::backup::{BackupDir, BackupManifest};
use proxmox_backup::api2::types::ArchiveEntry;
use proxmox_backup::client::BackupRepository;
use proxmox::api::{api, cli::*};
@ -32,6 +33,14 @@ pub type Async<R> = Pin<Box<dyn Future<Output = R> + Send>>;
/// An abstract implementation for retrieving data out of a block file backup
pub trait BlockRestoreDriver {
/// List ArchiveEntrys for the given image file and path
fn data_list(
&self,
details: SnapRestoreDetails,
img_file: String,
path: Vec<u8>,
) -> Async<Result<Vec<ArchiveEntry>, Error>>;
/// Return status of all running/mapped images, result value is (id, extra data), where id must
/// match with the ones returned from list()
fn status(&self) -> Async<Result<Vec<DriverStatus>, Error>>;
@ -60,6 +69,16 @@ impl BlockDriverType {
const DEFAULT_DRIVER: BlockDriverType = BlockDriverType::Qemu;
const ALL_DRIVERS: &[BlockDriverType] = &[BlockDriverType::Qemu];
pub async fn data_list(
driver: Option<BlockDriverType>,
details: SnapRestoreDetails,
img_file: String,
path: Vec<u8>,
) -> Result<Vec<ArchiveEntry>, Error> {
let driver = driver.unwrap_or(DEFAULT_DRIVER).resolve();
driver.data_list(details, img_file, path).await
}
#[api(
input: {
properties: {

View File

@ -9,6 +9,7 @@ use std::fs::{File, OpenOptions};
use std::io::{prelude::*, SeekFrom};
use proxmox::tools::fs::lock_file;
use proxmox_backup::api2::types::ArchiveEntry;
use proxmox_backup::backup::BackupDir;
use proxmox_backup::client::*;
use proxmox_backup::tools;
@ -183,6 +184,26 @@ async fn start_vm(cid_request: i32, details: &SnapRestoreDetails) -> Result<VMSt
}
impl BlockRestoreDriver for QemuBlockDriver {
fn data_list(
&self,
details: SnapRestoreDetails,
img_file: String,
mut path: Vec<u8>,
) -> Async<Result<Vec<ArchiveEntry>, Error>> {
async move {
let client = ensure_running(&details).await?;
if !path.is_empty() && path[0] != b'/' {
path.insert(0, b'/');
}
let path = base64::encode(img_file.bytes().chain(path).collect::<Vec<u8>>());
let mut result = client
.get("api2/json/list", Some(json!({ "path": path })))
.await?;
serde_json::from_value(result["data"].take()).map_err(|err| err.into())
}
.boxed()
}
fn status(&self) -> Async<Result<Vec<DriverStatus>, Error>> {
async move {
let mut state_map = VMStateMap::load()?;