-
Notifications
You must be signed in to change notification settings - Fork 9
libvirt: Only inject STORAGE_OPTS when bind-storage-ro is enabled #122
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
Conversation
Previously, STORAGE_OPTS environment configuration was unconditionally injected into VMs via both tmpfiles.d and a systemd service unit. This caused VMs created without `--bind-storage-ro` to reference a non-existent `/run/host-container-storage` path in their environment. Change things to only inject when opts.bind_storage_ro is set. Additionally, refactor to use a single smbios_creds vector instead of separate mount_unit_smbios_creds and storage_opts_creds vectors, making the code cleaner and easier to follow. Assisted-by: Claude Code (Sonnet 4.5) Signed-off-by: Colin Walters <walters@verbum.org>
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 correctly fixes an issue where STORAGE_OPTS were unconditionally injected into VMs, even when not required. The change correctly scopes the injection to only occur when the --bind-storage-ro flag is used. A comprehensive integration test has been added to verify this fix, ensuring that VMs created without the flag do not contain the unnecessary configuration. Additionally, the code has been refactored to use a single smbios_creds vector, which improves clarity and maintainability by consolidating SMBIOS credential handling. The changes are well-implemented and improve both the correctness and readability of the code. I have one suggestion to make the code even more idiomatic.
| for cred in smbios_creds { | ||
| qemu_args.push("-smbios".to_string()); | ||
| qemu_args.push(format!("type=11,value={}", mount_cred)); | ||
| qemu_args.push(format!("type=11,value={}", cred)); | ||
| } |
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.
For better performance and more idiomatic Rust, you can replace this loop with a combination of flat_map and extend. This avoids repeated push calls which might cause reallocations and is generally more expressive.
| for cred in smbios_creds { | |
| qemu_args.push("-smbios".to_string()); | |
| qemu_args.push(format!("type=11,value={}", mount_cred)); | |
| qemu_args.push(format!("type=11,value={}", cred)); | |
| } | |
| qemu_args.extend(smbios_creds.into_iter().flat_map(|cred| { | |
| [ | |
| "-smbios".to_string(), | |
| format!("type=11,value={}", cred), | |
| ] | |
| })); |
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 correctly addresses the issue of unconditionally injecting STORAGE_OPTS by making the injection conditional on the --bind-storage-ro flag. The addition of the test_libvirt_run_no_storage_opts_without_bind_storage integration test is excellent, as it thoroughly verifies the fix by checking for the absence of the related configurations in the domain XML. The refactoring to use a single smbios_creds vector and consolidating the QEMU argument construction significantly improves code clarity and maintainability. I have one minor suggestion to further simplify the QEMU argument building logic.
| // Build QEMU args with all SMBIOS credentials | ||
| { | ||
| let encoded = data_encoding::BASE64.encode(tmpfiles_content.as_bytes()); | ||
| let smbios_cred = format!("io.systemd.credential.binary:tmpfiles.extra={encoded}"); | ||
| qemu_args.extend([ | ||
| "-smbios".to_string(), | ||
| format!("type=11,value={}", smbios_cred), | ||
| ]); | ||
| } | ||
|
|
||
| // Add SMBIOS credentials for mount units | ||
| for mount_cred in mount_unit_smbios_creds { | ||
| // Add all SMBIOS credentials (mount units, storage opts, etc.) | ||
| for cred in smbios_creds { | ||
| qemu_args.push("-smbios".to_string()); | ||
| qemu_args.push(format!("type=11,value={}", mount_cred)); | ||
| qemu_args.push(format!("type=11,value={}", cred)); | ||
| } |
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 logic for adding SMBIOS credentials to qemu_args is split into two parts (one for tmpfiles.extra and another for other credentials), which leads to some repetition. You could simplify this by combining all credentials into a single collection first and then iterating over it once to build the arguments. This would make the code more concise and easier to maintain.
For example:
// Collect all credentials into one vector
let mut all_creds = smbios_creds;
let encoded = data_encoding::BASE64.encode(tmpfiles_content.as_bytes());
all_creds.push(format!(
"io.systemd.credential.binary:tmpfiles.extra={}",
encoded
));
// Build QEMU args from the consolidated list
for cred in all_creds {
qemu_args.push("-smbios".to_string());
qemu_args.push(format!("type=11,value={}", cred));
}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 correctly fixes an issue where STORAGE_OPTS were unconditionally injected into VMs, and adds a new integration test to verify the behavior. The refactoring to consolidate SMBIOS credentials into a single vector is a great improvement for code clarity. I've added a couple of suggestions: one to further improve the credential handling logic for better maintainability, and another to make the new integration test more robust against potential name collisions.
| std::time::SystemTime::now() | ||
| .duration_since(std::time::UNIX_EPOCH) | ||
| .unwrap() | ||
| .as_secs() |
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.
Using the current time in seconds for unique names can lead to collisions if tests run in the same second. Using nanoseconds provides higher resolution and significantly reduces the chance of creating duplicate domain names, making the tests more robust.
| std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap() | |
| .as_secs() | |
| std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap() | |
| .as_nanos() |
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.
Yeah I'll try to get back to #78
jmarrero
left a comment
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.
lgtm
Previously, STORAGE_OPTS environment configuration was unconditionally injected into VMs via both tmpfiles.d and a systemd service unit. This caused VMs created without
--bind-storage-roto reference a non-existent/run/host-container-storagepath in their environment.Change things to only inject when opts.bind_storage_ro is set.
Additionally, refactor to use a single smbios_creds vector instead of separate mount_unit_smbios_creds and storage_opts_creds vectors, making the code cleaner and easier to follow.
Assisted-by: Claude Code (Sonnet 4.5)