file-restore: add namespace support to qemu part

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2022-05-12 13:27:16 +02:00
parent e30a2e9058
commit 8ca7cccf5f
4 changed files with 23 additions and 11 deletions

View File

@ -11,7 +11,7 @@ use serde_json::{json, Value};
use proxmox_router::cli::*; use proxmox_router::cli::*;
use proxmox_schema::api; use proxmox_schema::api;
use pbs_api_types::BackupDir; use pbs_api_types::{BackupDir, BackupNamespace};
use pbs_client::BackupRepository; use pbs_client::BackupRepository;
use pbs_datastore::catalog::ArchiveEntry; use pbs_datastore::catalog::ArchiveEntry;
use pbs_datastore::manifest::BackupManifest; use pbs_datastore::manifest::BackupManifest;
@ -21,6 +21,7 @@ use super::block_driver_qemu::QemuBlockDriver;
/// Contains details about a snapshot that is to be accessed by block file restore /// Contains details about a snapshot that is to be accessed by block file restore
pub struct SnapRestoreDetails { pub struct SnapRestoreDetails {
pub repo: BackupRepository, pub repo: BackupRepository,
pub namespace: BackupNamespace,
pub snapshot: BackupDir, pub snapshot: BackupDir,
pub manifest: BackupManifest, pub manifest: BackupManifest,
pub keyfile: Option<String>, pub keyfile: Option<String>,

View File

@ -10,7 +10,7 @@ use serde_json::json;
use proxmox_sys::fs::lock_file; use proxmox_sys::fs::lock_file;
use pbs_api_types::BackupDir; use pbs_api_types::{BackupDir, BackupNamespace};
use pbs_client::{BackupRepository, VsockClient, DEFAULT_VSOCK_PORT}; use pbs_client::{BackupRepository, VsockClient, DEFAULT_VSOCK_PORT};
use pbs_datastore::catalog::ArchiveEntry; use pbs_datastore::catalog::ArchiveEntry;
@ -78,8 +78,12 @@ impl VMStateMap {
} }
} }
fn make_name(repo: &BackupRepository, snap: &BackupDir) -> String { fn make_name(repo: &BackupRepository, ns: &BackupNamespace, snap: &BackupDir) -> String {
let full = format!("qemu_{}/{}", repo, snap); let full = if ns.is_root() {
format!("qemu_{}/{}", repo, snap)
} else {
format!("qemu_{}:{}/{}", repo, ns, snap)
};
proxmox_sys::systemd::escape_unit(&full, false) proxmox_sys::systemd::escape_unit(&full, false)
} }
@ -114,7 +118,7 @@ fn new_ticket() -> String {
} }
async fn ensure_running(details: &SnapRestoreDetails) -> Result<VsockClient, Error> { async fn ensure_running(details: &SnapRestoreDetails) -> Result<VsockClient, Error> {
let name = make_name(&details.repo, &details.snapshot); let name = make_name(&details.repo, &details.namespace, &details.snapshot);
let mut state = VMStateMap::load()?; let mut state = VMStateMap::load()?;
cleanup_map(&mut state.map).await; cleanup_map(&mut state.map).await;

View File

@ -95,7 +95,7 @@ fn keyfile_path(param: &Value) -> Option<String> {
async fn list_files( async fn list_files(
repo: BackupRepository, repo: BackupRepository,
ns: BackupNamespace, namespace: BackupNamespace,
snapshot: BackupDir, snapshot: BackupDir,
path: ExtractPath, path: ExtractPath,
crypt_config: Option<Arc<CryptConfig>>, crypt_config: Option<Arc<CryptConfig>>,
@ -107,7 +107,7 @@ async fn list_files(
client, client,
crypt_config.clone(), crypt_config.clone(),
repo.store(), repo.store(),
&ns, &namespace,
&snapshot, &snapshot,
true, true,
) )
@ -163,6 +163,7 @@ async fn list_files(
let details = SnapRestoreDetails { let details = SnapRestoreDetails {
manifest, manifest,
repo, repo,
namespace,
snapshot, snapshot,
keyfile, keyfile,
}; };
@ -395,7 +396,7 @@ async fn extract(
param: Value, param: Value,
) -> Result<(), Error> { ) -> Result<(), Error> {
let repo = extract_repository_from_value(&param)?; let repo = extract_repository_from_value(&param)?;
let ns = ns.unwrap_or_default(); let namespace = ns.unwrap_or_default();
let snapshot: BackupDir = snapshot.parse()?; let snapshot: BackupDir = snapshot.parse()?;
let orig_path = path; let orig_path = path;
let path = parse_path(orig_path.clone(), base64)?; let path = parse_path(orig_path.clone(), base64)?;
@ -425,7 +426,7 @@ async fn extract(
client, client,
crypt_config.clone(), crypt_config.clone(),
repo.store(), repo.store(),
&ns, &namespace,
&snapshot, &snapshot,
true, true,
) )
@ -456,6 +457,7 @@ async fn extract(
let details = SnapRestoreDetails { let details = SnapRestoreDetails {
manifest, manifest,
repo, repo,
namespace,
snapshot, snapshot,
keyfile, keyfile,
}; };

View File

@ -209,9 +209,14 @@ pub async fn start_vm(
} else { } else {
"".to_owned() "".to_owned()
}; };
let namespace = if details.namespace.is_root() {
String::new()
} else {
format!(",,namespace={}", details.namespace)
};
drives.push(format!( drives.push(format!(
"file=pbs:repository={},,snapshot={},,archive={}{},read-only=on,if=none,id=drive{}", "file=pbs:repository={}{},,snapshot={},,archive={}{},read-only=on,if=none,id=drive{}",
details.repo, details.snapshot, file, keyfile, id details.repo, namespace, details.snapshot, file, keyfile, id
)); ));
// a PCI bus can only support 32 devices, so add a new one every 32 // a PCI bus can only support 32 devices, so add a new one every 32