-
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.
Needs 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 ? |
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 <[email protected]> Signed-off-by: Yevhen Vydolob <[email protected]>
Signed-off-by: Yevhen Vydolob <[email protected]>
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 |

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