Can decompress QCow2
This commit is contained in:
		@@ -126,3 +126,6 @@ pub const IP_PROGRAM: &str = "/usr/sbin/ip";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Copy program path
 | 
					/// Copy program path
 | 
				
			||||||
pub const COPY_PROGRAM: &str = "/bin/cp";
 | 
					pub const COPY_PROGRAM: &str = "/bin/cp";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Gzip program path
 | 
				
			||||||
 | 
					pub const GZIP_PROGRAM: &str = "/usr/bin/gzip";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
use crate::app_config::AppConfig;
 | 
					use crate::app_config::AppConfig;
 | 
				
			||||||
use crate::constants;
 | 
					use crate::constants;
 | 
				
			||||||
use crate::utils::file_size_utils::FileSize;
 | 
					use crate::utils::file_size_utils::FileSize;
 | 
				
			||||||
 | 
					use std::fs::File;
 | 
				
			||||||
use std::os::linux::fs::MetadataExt;
 | 
					use std::os::linux::fs::MetadataExt;
 | 
				
			||||||
use std::path::{Path, PathBuf};
 | 
					use std::path::{Path, PathBuf};
 | 
				
			||||||
use std::process::Command;
 | 
					use std::process::Command;
 | 
				
			||||||
@@ -156,6 +157,17 @@ impl DiskFileInfo {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Prepare the conversion
 | 
					        // Prepare the conversion
 | 
				
			||||||
        let mut cmd = match (self.format, dest_format) {
 | 
					        let mut cmd = match (self.format, dest_format) {
 | 
				
			||||||
 | 
					            // Decompress QCow2
 | 
				
			||||||
 | 
					            (DiskFileFormat::CompressedQCow2, DiskFileFormat::QCow2 { .. }) => {
 | 
				
			||||||
 | 
					                let mut cmd = Command::new(constants::GZIP_PROGRAM);
 | 
				
			||||||
 | 
					                cmd.arg("--keep")
 | 
				
			||||||
 | 
					                    .arg("--decompress")
 | 
				
			||||||
 | 
					                    .arg("--to-stdout")
 | 
				
			||||||
 | 
					                    .arg(&self.file_path)
 | 
				
			||||||
 | 
					                    .stdout(File::create(&temp_file)?);
 | 
				
			||||||
 | 
					                cmd
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Dumb copy of file
 | 
					            // Dumb copy of file
 | 
				
			||||||
            (a, b) if a == b => {
 | 
					            (a, b) if a == b => {
 | 
				
			||||||
                let mut cmd = Command::new(constants::COPY_PROGRAM);
 | 
					                let mut cmd = Command::new(constants::COPY_PROGRAM);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import DeleteIcon from "@mui/icons-material/Delete";
 | 
					import DeleteIcon from "@mui/icons-material/Delete";
 | 
				
			||||||
import DownloadIcon from "@mui/icons-material/Download";
 | 
					import DownloadIcon from "@mui/icons-material/Download";
 | 
				
			||||||
import RefreshIcon from "@mui/icons-material/Refresh";
 | 
					 | 
				
			||||||
import LoopIcon from "@mui/icons-material/Loop";
 | 
					import LoopIcon from "@mui/icons-material/Loop";
 | 
				
			||||||
 | 
					import RefreshIcon from "@mui/icons-material/Refresh";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Alert,
 | 
					  Alert,
 | 
				
			||||||
  Button,
 | 
					  Button,
 | 
				
			||||||
@@ -16,17 +16,17 @@ import { filesize } from "filesize";
 | 
				
			|||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import { DiskImage, DiskImageApi } from "../api/DiskImageApi";
 | 
					import { DiskImage, DiskImageApi } from "../api/DiskImageApi";
 | 
				
			||||||
import { ServerApi } from "../api/ServerApi";
 | 
					import { ServerApi } from "../api/ServerApi";
 | 
				
			||||||
 | 
					import { ConvertDiskImageDialog } from "../dialogs/ConvertDiskImageDialog";
 | 
				
			||||||
import { useAlert } from "../hooks/providers/AlertDialogProvider";
 | 
					import { useAlert } from "../hooks/providers/AlertDialogProvider";
 | 
				
			||||||
import { useConfirm } from "../hooks/providers/ConfirmDialogProvider";
 | 
					import { useConfirm } from "../hooks/providers/ConfirmDialogProvider";
 | 
				
			||||||
import { useLoadingMessage } from "../hooks/providers/LoadingMessageProvider";
 | 
					import { useLoadingMessage } from "../hooks/providers/LoadingMessageProvider";
 | 
				
			||||||
import { useSnackbar } from "../hooks/providers/SnackbarProvider";
 | 
					import { useSnackbar } from "../hooks/providers/SnackbarProvider";
 | 
				
			||||||
 | 
					import { downloadBlob } from "../utils/FilesUtils";
 | 
				
			||||||
import { AsyncWidget } from "../widgets/AsyncWidget";
 | 
					import { AsyncWidget } from "../widgets/AsyncWidget";
 | 
				
			||||||
import { DateWidget } from "../widgets/DateWidget";
 | 
					import { DateWidget } from "../widgets/DateWidget";
 | 
				
			||||||
import { FileInput } from "../widgets/forms/FileInput";
 | 
					import { FileInput } from "../widgets/forms/FileInput";
 | 
				
			||||||
import { VirtWebPaper } from "../widgets/VirtWebPaper";
 | 
					import { VirtWebPaper } from "../widgets/VirtWebPaper";
 | 
				
			||||||
import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
 | 
					import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
 | 
				
			||||||
import { downloadBlob } from "../utils/FilesUtils";
 | 
					 | 
				
			||||||
import { ConvertDiskImageDialog } from "../dialogs/ConvertDiskImageDialog";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function DiskImagesRoute(): React.ReactElement {
 | 
					export function DiskImagesRoute(): React.ReactElement {
 | 
				
			||||||
  const [list, setList] = React.useState<DiskImage[] | undefined>();
 | 
					  const [list, setList] = React.useState<DiskImage[] | undefined>();
 | 
				
			||||||
@@ -232,7 +232,13 @@ function DiskImageList(p: {
 | 
				
			|||||||
      headerName: "File size",
 | 
					      headerName: "File size",
 | 
				
			||||||
      flex: 1,
 | 
					      flex: 1,
 | 
				
			||||||
      renderCell(params) {
 | 
					      renderCell(params) {
 | 
				
			||||||
        return filesize(params.row.file_size);
 | 
					        let res = filesize(params.row.file_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (params.row.format === "QCow2") {
 | 
				
			||||||
 | 
					          res += ` (${filesize(params.row.virtual_size!)})`;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return res;
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user