From d7796e14594cc616e761c0bf9027863c639d3318 Mon Sep 17 00:00:00 2001
From: Pierre HUBERT <pierre.git@communiquons.org>
Date: Mon, 9 Jun 2025 17:04:35 +0200
Subject: [PATCH] Can decompress XZ files
---
virtweb_backend/src/utils/file_disks_utils.rs | 30 +++++++++++++++++--
virtweb_frontend/src/api/DiskImageApi.ts | 4 ++-
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/virtweb_backend/src/utils/file_disks_utils.rs b/virtweb_backend/src/utils/file_disks_utils.rs
index 012f894..98a2ced 100644
--- a/virtweb_backend/src/utils/file_disks_utils.rs
+++ b/virtweb_backend/src/utils/file_disks_utils.rs
@@ -284,7 +284,7 @@ impl DiskFileInfo {
cmd
}
- // Decompress Raw to not sparse file
+ // Decompress Raw (Gz) to not sparse file
(DiskFileFormat::GzCompressedRaw, DiskFileFormat::Raw { is_sparse: false }) => {
let mut cmd = Command::new(constants::PROGRAM_GZIP);
cmd.arg("--keep")
@@ -294,13 +294,23 @@ impl DiskFileInfo {
.stdout(File::create(&temp_file)?);
cmd
}
+ // Decompress Raw (Xz) to not sparse file
+ (DiskFileFormat::XzCompressedRaw, DiskFileFormat::Raw { is_sparse: false }) => {
+ let mut cmd = Command::new(constants::PROGRAM_XZ);
+ cmd.arg("--keep")
+ .arg("--decompress")
+ .arg("--to-stdout")
+ .arg(&self.file_path)
+ .stdout(File::create(&temp_file)?);
+ cmd
+ }
- // Decompress Raw to sparse file
+ // Decompress Raw (Gz) to sparse file
// https://benou.fr/www/ben/decompressing-sparse-files.html
(DiskFileFormat::GzCompressedRaw, DiskFileFormat::Raw { is_sparse: true }) => {
let mut cmd = Command::new(constants::PROGRAM_BASH);
cmd.arg("-c").arg(format!(
- "{} -d -c {} | {} conv=sparse of={}",
+ "{} --decompress --to-stdout {} | {} conv=sparse of={}",
constants::PROGRAM_GZIP,
self.file_path.display(),
constants::PROGRAM_DD,
@@ -309,6 +319,20 @@ impl DiskFileInfo {
cmd
}
+ // Decompress Raw (XZ) to sparse file
+ // https://benou.fr/www/ben/decompressing-sparse-files.html
+ (DiskFileFormat::XzCompressedRaw, DiskFileFormat::Raw { is_sparse: true }) => {
+ let mut cmd = Command::new(constants::PROGRAM_BASH);
+ cmd.arg("-c").arg(format!(
+ "{} --decompress --to-stdout {} | {} conv=sparse of={}",
+ constants::PROGRAM_XZ,
+ self.file_path.display(),
+ constants::PROGRAM_DD,
+ temp_file.display()
+ ));
+ cmd
+ }
+
// Dumb copy of file
(a, b) if a == b => {
let mut cmd = Command::new(constants::PROGRAM_COPY);
diff --git a/virtweb_frontend/src/api/DiskImageApi.ts b/virtweb_frontend/src/api/DiskImageApi.ts
index bcca6c4..d07c359 100644
--- a/virtweb_frontend/src/api/DiskImageApi.ts
+++ b/virtweb_frontend/src/api/DiskImageApi.ts
@@ -5,7 +5,9 @@ export type DiskImageFormat =
| { format: "Raw"; is_sparse: boolean }
| { format: "QCow2"; virtual_size?: number }
| { format: "GzCompressedQCow2" }
- | { format: "GzCompressedRaw" };
+ | { format: "GzCompressedRaw" }
+ | { format: "XzCompressedQCow2" }
+ | { format: "XzCompressedRaw" };
export type DiskImage = {
file_size: number;