|
13 | 13 | //! xtask image ls |
14 | 14 | //! // Download a specific image and automatically extract it |
15 | 15 | //! xtask image download evm3588_arceos --output-dir ./images |
16 | | -//! // Pull a specific image (alias for download) and automatically extract it |
17 | | -//! xtask image pull evm3588_arceos --output-dir ./images |
| 16 | +//! // Download a specific image without extracting |
| 17 | +//! xtask image download evm3588_arceos --output-dir ./images --no-extract |
18 | 18 | //! // Remove a specific image from temp directory |
19 | 19 | //! xtask image rm evm3588_arceos |
20 | 20 | //! ``` |
21 | 21 |
|
22 | 22 | use anyhow::{Result, anyhow}; |
23 | 23 | use clap::{Parser, Subcommand}; |
| 24 | +use sha2::{Sha256, Digest}; |
24 | 25 | use std::path::{Path}; |
25 | 26 | use std::process::Command; |
26 | 27 | use std::fs; |
27 | 28 | use std::env; |
| 29 | +use std::io::Read; |
| 30 | +use tokio::fs::File; |
| 31 | +use tokio::io::AsyncWriteExt; |
28 | 32 |
|
29 | 33 | /// Base URL for downloading images |
30 | 34 | const IMAGE_URL_BASE: &str = "https://github.com/arceos-hypervisor/axvisor-guest/releases/download/v0.0.16/"; |
@@ -216,17 +220,20 @@ impl Image { |
216 | 220 | /// # Errors |
217 | 221 | /// * `anyhow::Error` - If any error occurs during the verification process |
218 | 222 | fn image_verify_sha256(file_path: &Path, expected_sha256: &str) -> Result<bool> { |
219 | | - let output = Command::new("sha256sum") |
220 | | - .arg(file_path) |
221 | | - .output()?; |
222 | | - |
223 | | - if !output.status.success() { |
224 | | - return Err(anyhow!("Failed to calculate SHA256")); |
| 223 | + let mut file = fs::File::open(file_path)?; |
| 224 | + let mut hasher = Sha256::new(); |
| 225 | + let mut buffer = [0; 8192]; |
| 226 | + |
| 227 | + loop { |
| 228 | + let bytes_read = file.read(&mut buffer)?; |
| 229 | + if bytes_read == 0 { |
| 230 | + break; |
| 231 | + } |
| 232 | + hasher.update(&buffer[..bytes_read]); |
225 | 233 | } |
226 | 234 |
|
227 | | - let stdout = String::from_utf8(output.stdout)?; |
228 | | - let actual_sha256 = stdout.split_whitespace().next() |
229 | | - .ok_or_else(|| anyhow!("Unable to parse SHA256 output"))?; |
| 235 | + let result = hasher.finalize(); |
| 236 | + let actual_sha256 = format!("{:x}", result); |
230 | 237 |
|
231 | 238 | Ok(actual_sha256 == expected_sha256) |
232 | 239 | } |
@@ -281,7 +288,7 @@ fn image_list() -> Result<()> { |
281 | 288 | /// // Or use the pull alias |
282 | 289 | /// xtask image pull evm3588_arceos --output-dir ./images |
283 | 290 | /// ``` |
284 | | -fn image_download(image_name: &str, output_dir: Option<String>, extract: bool) -> Result<()> { |
| 291 | +async fn image_download(image_name: &str, output_dir: Option<String>, extract: bool) -> Result<()> { |
285 | 292 | let image = Image::find_by_name(image_name) |
286 | 293 | .ok_or_else(|| anyhow!("Image not found: {}. Use 'xtask image ls' to view available images", image_name))?; |
287 | 294 |
|
@@ -339,19 +346,19 @@ fn image_download(image_name: &str, output_dir: Option<String>, extract: bool) - |
339 | 346 |
|
340 | 347 | println!("Downloading file from {}...", download_url); |
341 | 348 |
|
342 | | - let mut child = Command::new("curl") |
343 | | - .arg("-L") // Follow redirects |
344 | | - .arg("-o") |
345 | | - .arg(&output_path) |
346 | | - .arg(&download_url) |
347 | | - .spawn()?; |
348 | | - |
349 | | - let status = child.wait()?; |
350 | | - if !status.success() { |
351 | | - return Err(anyhow!("Download failed, curl exit code: {}", status)); |
| 349 | + // Use reqwest to download the file |
| 350 | + let response = reqwest::get(&download_url).await?; |
| 351 | + if !response.status().is_success() { |
| 352 | + return Err(anyhow!("Failed to download file: HTTP {}", response.status())); |
352 | 353 | } |
353 | 354 |
|
354 | | - println!("Download completed"); |
| 355 | + let bytes = response.bytes().await?; |
| 356 | + |
| 357 | + // Write all bytes at once |
| 358 | + let mut file = File::create(&output_path).await?; |
| 359 | + file.write_all(&bytes).await?; |
| 360 | + |
| 361 | + println!("Download completed ({} bytes)", bytes.len()); |
355 | 362 |
|
356 | 363 | // Verify downloaded file |
357 | 364 | println!("Verifying SHA256 of downloaded file..."); |
@@ -463,13 +470,13 @@ fn image_remove(image_name: &str) -> Result<()> { |
463 | 470 | /// xtask image pull evm3588_arceos --output-dir ./images |
464 | 471 | /// xtask image rm evm3588_arceos |
465 | 472 | /// ``` |
466 | | -pub fn run_image(args: ImageArgs) -> Result<()> { |
| 473 | +pub async fn run_image(args: ImageArgs) -> Result<()> { |
467 | 474 | match args.command { |
468 | 475 | ImageCommands::Ls => { |
469 | 476 | image_list()?; |
470 | 477 | } |
471 | 478 | ImageCommands::Download { image_name, output_dir, extract } => { |
472 | | - image_download(&image_name, output_dir, extract.unwrap_or(true))?; |
| 479 | + image_download(&image_name, output_dir, extract.unwrap_or(true)).await?; |
473 | 480 | } |
474 | 481 | ImageCommands::Rm { image_name } => { |
475 | 482 | image_remove(&image_name)?; |
|
0 commit comments