- 
                Notifications
    You must be signed in to change notification settings 
- Fork 8
libvirt: Support qemu:///system #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| Summary of ChangesHello @cgwalters, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances  Highlights
 Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either  
 Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a  Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
 | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request adds significant functionality by supporting qemu:///system libvirt connections, which is crucial for environments where the user lacks direct write access to the libvirt storage pool. The approach of using virsh commands for all volume management and introducing a fallback path for disk creation via virsh vol-upload is robust and well-implemented. The refactoring to centralize virsh XML command execution is also a good improvement. I have identified some issues in the new integration tests regarding incorrect command argument ordering and a potential improvement for temporary file handling to enhance robustness. Overall, this is a solid and valuable contribution.
| let mut vm1_cmd = Command::new("timeout"); | ||
| vm1_cmd.args(["300s", &bck, "libvirt", "run"]); | ||
| for arg in &connect_args { | ||
| vm1_cmd.arg(arg); | ||
| } | ||
| vm1_cmd.args(["--name", &vm1_name, "--filesystem", "ext4", &test_image]); | ||
| let vm1_output = vm1_cmd.output().expect("Failed to create first VM"); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The --connect argument is a global option for the bcvk libvirt subcommand and should be placed before the run subcommand. The current argument order is incorrect and will cause the test to fail when LIBVIRT_DEFAULT_URI is set.
| let mut vm1_cmd = Command::new("timeout"); | |
| vm1_cmd.args(["300s", &bck, "libvirt", "run"]); | |
| for arg in &connect_args { | |
| vm1_cmd.arg(arg); | |
| } | |
| vm1_cmd.args(["--name", &vm1_name, "--filesystem", "ext4", &test_image]); | |
| let vm1_output = vm1_cmd.output().expect("Failed to create first VM"); | |
| let mut vm1_cmd = Command::new("timeout"); | |
| vm1_cmd.args(["300s", &bck, "libvirt"]); | |
| vm1_cmd.args(&connect_args); | |
| vm1_cmd.arg("run"); | |
| vm1_cmd.args(["--name", &vm1_name, "--filesystem", "ext4", &test_image]); | |
| let vm1_output = vm1_cmd.output().expect("Failed to create first VM"); | 
| let mut vm2_cmd = Command::new("timeout"); | ||
| vm2_cmd.args(["300s", &bck, "libvirt", "run"]); | ||
| for arg in &connect_args { | ||
| vm2_cmd.arg(arg); | ||
| } | ||
| vm2_cmd.args(["--name", &vm2_name, "--filesystem", "ext4", &test_image]); | ||
| let vm2_output = vm2_cmd.output().expect("Failed to create second VM"); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the previous command construction, the --connect argument for bcvk libvirt is misplaced. It should appear before the run subcommand to be parsed correctly as a global option for libvirt.
| let mut vm2_cmd = Command::new("timeout"); | |
| vm2_cmd.args(["300s", &bck, "libvirt", "run"]); | |
| for arg in &connect_args { | |
| vm2_cmd.arg(arg); | |
| } | |
| vm2_cmd.args(["--name", &vm2_name, "--filesystem", "ext4", &test_image]); | |
| let vm2_output = vm2_cmd.output().expect("Failed to create second VM"); | |
| let mut vm2_cmd = Command::new("timeout"); | |
| vm2_cmd.args(["300s", &bck, "libvirt"]); | |
| vm2_cmd.args(&connect_args); | |
| vm2_cmd.arg("run"); | |
| vm2_cmd.args(["--name", &vm2_name, "--filesystem", "ext4", &test_image]); | |
| let vm2_output = vm2_cmd.output().expect("Failed to create second VM"); | 
| let mut cmd = Command::new(&bck); | ||
| cmd.args(["libvirt", "base-disks", "list"]); | ||
| for arg in &connect_args { | ||
| cmd.arg(arg); | ||
| } | ||
| let output = cmd.output().expect("Failed to run base-disks list"); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The --connect argument should be provided before the base-disks subcommand for bcvk libvirt. The current ordering is incorrect.
| let mut cmd = Command::new(&bck); | |
| cmd.args(["libvirt", "base-disks", "list"]); | |
| for arg in &connect_args { | |
| cmd.arg(arg); | |
| } | |
| let output = cmd.output().expect("Failed to run base-disks list"); | |
| let mut cmd = Command::new(&bck); | |
| cmd.arg("libvirt"); | |
| cmd.args(&connect_args); | |
| cmd.args(["base-disks", "list"]); | |
| let output = cmd.output().expect("Failed to run base-disks list"); | 
| let mut cmd = Command::new(&bck); | ||
| cmd.args(["libvirt", "base-disks", "prune", "--dry-run"]); | ||
| for arg in &connect_args { | ||
| cmd.arg(arg); | ||
| } | ||
| let output = cmd | ||
| .output() | ||
| .expect("Failed to run base-disks prune --dry-run"); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The --connect argument is misplaced. It should be a global option for the libvirt subcommand, placed before the base-disks subcommand.
| let mut cmd = Command::new(&bck); | |
| cmd.args(["libvirt", "base-disks", "prune", "--dry-run"]); | |
| for arg in &connect_args { | |
| cmd.arg(arg); | |
| } | |
| let output = cmd | |
| .output() | |
| .expect("Failed to run base-disks prune --dry-run"); | |
| let mut cmd = Command::new(&bck); | |
| cmd.arg("libvirt"); | |
| cmd.args(&connect_args); | |
| cmd.args(["base-disks", "prune", "--dry-run"]); | |
| let output = cmd | |
| .output() | |
| .expect("Failed to run base-disks prune --dry-run"); | 
| let mut vm_cmd = Command::new("timeout"); | ||
| vm_cmd.args(["300s", &bck, "libvirt", "run"]); | ||
| for arg in &connect_args { | ||
| vm_cmd.arg(arg); | ||
| } | ||
| vm_cmd.args(["--name", &vm_name, "--filesystem", "ext4", &test_image]); | ||
| let output = vm_cmd.output().expect("Failed to create VM"); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The --connect argument for bcvk libvirt is a global option and should be placed before the run subcommand.
| let mut vm_cmd = Command::new("timeout"); | |
| vm_cmd.args(["300s", &bck, "libvirt", "run"]); | |
| for arg in &connect_args { | |
| vm_cmd.arg(arg); | |
| } | |
| vm_cmd.args(["--name", &vm_name, "--filesystem", "ext4", &test_image]); | |
| let output = vm_cmd.output().expect("Failed to create VM"); | |
| let mut vm_cmd = Command::new("timeout"); | |
| vm_cmd.args(["300s", &bck, "libvirt"]); | |
| vm_cmd.args(&connect_args); | |
| vm_cmd.arg("run"); | |
| vm_cmd.args(["--name", &vm_name, "--filesystem", "ext4", &test_image]); | |
| let output = vm_cmd.output().expect("Failed to create VM"); | 
| let mut cleanup_cmd = Command::new(&bck); | ||
| cleanup_cmd.args(&["libvirt", "rm", domain_name]); | ||
| for arg in &connect_args { | ||
| cleanup_cmd.arg(arg); | ||
| } | ||
| cleanup_cmd.args(&["--force", "--stop"]); | ||
| let cleanup_output = cleanup_cmd.output(); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The --connect argument for bcvk libvirt is misplaced. It should be provided before the rm subcommand.
| let mut cleanup_cmd = Command::new(&bck); | |
| cleanup_cmd.args(&["libvirt", "rm", domain_name]); | |
| for arg in &connect_args { | |
| cleanup_cmd.arg(arg); | |
| } | |
| cleanup_cmd.args(&["--force", "--stop"]); | |
| let cleanup_output = cleanup_cmd.output(); | |
| let mut cleanup_cmd = Command::new(&bck); | |
| cleanup_cmd.arg("libvirt"); | |
| cleanup_cmd.args(&connect_args); | |
| cleanup_cmd.args(&["rm", domain_name, "--force", "--stop"]); | |
| let cleanup_output = cleanup_cmd.output(); | 
        
          
                crates/kit/src/libvirt/base_disks.rs
              
                Outdated
          
        
      | let timestamp = std::time::SystemTime::now() | ||
| .duration_since(std::time::UNIX_EPOCH) | ||
| .map(|d| d.as_nanos()) | ||
| .unwrap_or(0); | ||
| let temp_disk_path = temp_dir.join(format!( | ||
| "bcvk-base-disk-{}-{}.qcow2", | ||
| std::process::id(), | ||
| timestamp | ||
| )); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The manual construction of a temporary file path using PID and timestamp is not fully robust against race conditions and is inconsistent with the create_base_disk function, which uses the tempfile crate. Using tempfile::Builder would be safer and also simplifies cleanup logic, as the temporary file would be automatically removed when it goes out of scope. This would allow removing the manual fs::remove_file calls elsewhere in this function.
| let timestamp = std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .map(|d| d.as_nanos()) | |
| .unwrap_or(0); | |
| let temp_disk_path = temp_dir.join(format!( | |
| "bcvk-base-disk-{}-{}.qcow2", | |
| std::process::id(), | |
| timestamp | |
| )); | |
| let temp_file = tempfile::Builder::new() | |
| .prefix("bcvk-base-disk-") | |
| .suffix(".qcow2") | |
| .tempfile_in(&temp_dir) | |
| .with_context(|| format!("Failed to create temp file in {:?}", temp_dir))?; | |
| let temp_disk_path = Utf8PathBuf::from_path_buf(temp_file.path().to_path_buf()) | |
| .map_err(|p| eyre!("temp path is not UTF-8: {:?}", p))?; | 
Closes: bootc-dev#61 Signed-off-by: Colin Walters <[email protected]>
With a helper fn. Signed-off-by: Colin Walters <[email protected]>
bf176ce    to
    b4ac4ce      
    Compare
  
    
Closes: #61