-
Notifications
You must be signed in to change notification settings - Fork 16
Use PowerShell commands instead of WMI calls #258
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
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: evidolob The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
d04a4bc to
7a7d879
Compare
|
I didn't dig into the code but at first sight the question i have is, can your split it in smaller commits? Reviewing the first one would be hard otherwise. |
|
@lstocchi I not sure, this PR is basically rewrite all project, I could split first commit in to several smaller, but it would be very hard to keep project buildable. |
|
@n1hility could you please spend at least a minute or two and review this PR because it fundamentally is a switch in how we originally wrote this. |
pkg/hypervctl/vm.go
Outdated
| err = wmiext.WaitJob(service, job) | ||
| } else { | ||
| err = &wmiext.JobError{ErrorCode: int(ret)} | ||
| func getKvpSctipt(vmName string, op string, key string, value string) []string { |
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.
I tried with podman and the ignition fails. You can replicate by init/start a new machine.
I did some changes to make it work but this requires more investigation, i just wanted to track where the issue was.
Summarizing what i tried, I escaped value to be sure it did not break the quotes in the script, removed comments, changed the arg of the -Command flag in Execute as this should expect a string.
Another thing i noticed is that removing a machine was really slow. Maybe it was my fault but worth mentioning to give it a deeper look
There is a typo in the func name, it should be getKvpScript
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.
It can also be simplified by removing the Write-Host ... as they are never printed or update the code to print them when using --log-level debug
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.
Write-Host is to write text in to stdout from powershell, I could add re-output from go code if debug logging is enabled
| // parameter. | ||
| func (vmm *VirtualMachineManager) GetSummaryInformation(requestedFields SummaryRequestSet) ([]SummaryInformation, error) { | ||
| return vmm.getSummaryInformation("", requestedFields) | ||
| func (vmm *VirtualMachineManager) GetSummaryInformation() ([]PowerShellVM, error) { |
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.
is this the only alternative we have? I saw that the old SummaryInformation is completely different from PowerShellVM, not sure if someone is using it. The thing that caught my eye is the old allocatedGPU which is not present now. This could be used for AI stuff
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.
We could add GPU for vm with Set-VMGpuPartitionAdapter command, but I thing it may be a separate PR, as it involves in more changes, and introducing new API, as passing GPU is requiring modification(partitioning) on host system.
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.
my concern was more if someone is using this. It's ok to change wmi calls to powershell commands but here we're completely changing the output. So not sure if we break up something. I'll investigate a bit, maybe @gbraad have more knowledge
7a7d879 to
0a99894
Compare
0a99894 to
2aa6ad5
Compare
lstocchi
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.
have you tried it with podman? It fails for me
pkg/hypervctl/system_settings.go
Outdated
| NewVMName string | ||
|
|
||
| // ProcessorCount specifies the number of virtual processors for the virtual machine. | ||
| ProcessorCount uint32 |
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.
pkg/hypervctl/system_settings.go
Outdated
| if val, ok := vmData["AutomaticStopAction"].(string); ok { | ||
| settings.AutomaticStopAction = AutomaticStopActionType(val) |
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.
Same as above
| args := []string{"Hyper-V\\Stop-VM", "-Name", vm.Name, "-Force"} | ||
| if force { | ||
| args = append(args, "-TurnOff") |
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.
this looks weird. If force is true i expect -Force to be added.
Maybe we could change the variable name here? Or provide 3 different stop actions (stop, force stop, turn off)
Based on the example it looks like when -TurnOff is used -Force is not needed -> https://learn.microsoft.com/en-us/powershell/module/hyper-v/stop-vm?view=windowsserver2025-ps#examples
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 problem with plain stop-vm is work like Shuts down virtual machine TestVM through the guest operating system. which means guest OS need to have vm addons integrated to allow stop. In case if gest os doesn't have such integrations and you call stop-vm without -Force, the command will hung for 5-10m and fail, and VM will stuck in transition period, you cannot do anything with VM until that timeout is over, and after that VM will still continue to run.
So that is a question does we always run guest OS with hyper-v integrations to relay on stop without forcing?
cc @gbraad
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.
This is a library so i expect the caller to decide what to do. It's their choice to try a graceful stop (call Stop()), force it (call StopWithForce()) or turn it off (call TurnOff()).
I expect new OS image specific to Hyperv to have the addon enabled tbh. At least for the images used with macadam and podman i see they have the Shutdown service running. We could also verify if the service is disabled and directly returns an error to the caller (if they call Stop()) to inform they must use StopWithforce/turnoff so they do not wait 5+ mins ??
Something like
func (vm *VirtualMachine) TurnOff() error {
return vm.stop("-TurnOff")
}
func (vm *VirtualMachine) StopWithForce() error {
return vm.stop("-Force")
}
func (vm *VirtualMachine) Stop() error {
return vm.stop("")
}
func (vm *VirtualMachine) stop(flag string) error {
if !Enabled.equal(uint16(vm.State)) {
return ErrMachineNotRunning
}
args := []string{"Stop-VM", "-Name", vm.Name}
if flag != "" {
args = append(args, flag)
}
_, stderr, err := powershell.Execute(args...)
if err != nil {
return NewPSError(stderr)
}
return nil
}
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.
as long as you dont change functionally the library call for folks, i'm cool with this.
|
this PR makes me super nervous but lets see it through. once you have tests passing here, id lke to ask you to vendor this into github.com/containers/podman and create a draft PR and ensure that PR passes the entire test quite. This might be tricky so ask for help if needed. would you be willing to do this ? |
2aa6ad5 to
95ea80c
Compare
|
@baude Sure, I make draft PR for podman, and ensure that this changes doesn't brake anything on podman. |
Same for me. I also tried to look at successful builds and i don't see any logs. |
There might be something going on with the CI; in the meanwhile, do all tests pass locally ? |
|
@baude Local test are passing fine |
95ea80c to
76f5842
Compare
76f5842 to
3d4b46a
Compare
597b093 to
76bd5ac
Compare
Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
1ab63e2 to
bf5e121
Compare
bf5e121 to
6a3eab3
Compare
|
@baude I made a PR with this changes in podman containers/podman#27819 |
|
I apologize for commenting late, but I am trying to understand how this PR improves the current situation from a Podman perspective. I assume the main point of this PR is to eliminate the need to run commands in elevated mode. However, after @lstocchi's work, we currently don't require elevated mode for managing Hyper-V machines. While elevated permissions are still necessary for making changes to the Windows HKLM registry entries, they are not needed for VM management. The only requirement now is to be a member of the Hyper-V admins group. How does this PR enhance this situation? Apart from that, I believe that using PowerShell commands instead of the WMI API is not ideal. Spawning a new process can negatively impact performances, and it is less robust because we rely on the local version of PowerShell, which we cannot predict. I also have concerns related to output parsing that can be impacted by the internationalization and encoding. And we are loosing type checking on the handled objects. We should avoid this approach unless there is a critical reason to use it. |
Yes and no. Elevation is a non-issue if you are part of the Hyper-V Admin group, which we enforce during our installation process. See: #216 as now any error for permission error, no disk space, no physical memory or anything, will lead to
In CRC we resolved this before by having a persistent session available. These are optimizations, as in normal use will not have many calls happening. This might happen during bring up, and in this case, during the tests. We adopted libhvee as part od convergencing implementations, but all those issues you brought up had been resolved by us; internationalization, session persistence, permission needs, so this is already a lesson learned on our end. |
1 similar comment
Yes and no. Elevation is a non-issue if you are part of the Hyper-V Admin group, which we enforce during our installation process. See: #216 as now any error for permission error, no disk space, no physical memory or anything, will lead to
In CRC we resolved this before by having a persistent session available. These are optimizations, as in normal use will not have many calls happening. This might happen during bring up, and in this case, during the tests. We adopted libhvee as part od convergencing implementations, but all those issues you brought up had been resolved by us; internationalization, session persistence, permission needs, so this is already a lesson learned on our end. |
Replace wmi calls with powershell commands. This should improve error messages and remove need of executing this code with escalating privileges. The workflow should be the same, the most changes is in 'MemorySettings' memory field names and types, it should be set in bytes. And 'ProcessorSettings' has other name for processors count field. Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>


Replace wmi calls with powershell commands. This should improve error messages and remove need of executing this code with escalating privileges. The workflow should be the same, the most changes is in 'MemorySettings' memory field names and types, it should be set in bytes. And 'ProcessorSettings' has other name for processors count field.
Also this PR adds new sample cli 'managevm' which allow to start, stop, delete VM