//go:build windows // +build windows package hypervctl import ( "fmt" "time" "github.com/containers/libhvee/pkg/wmiext" ) type SystemSettings struct { S__PATH string InstanceID string Caption string // = "Virtual Machine Settings" Description string ElementName string VirtualSystemIdentifier string VirtualSystemType string Notes []string CreationTime time.Time ConfigurationID string ConfigurationDataRoot string ConfigurationFile string SnapshotDataRoot string SuspendDataRoot string SwapFileDataRoot string LogDataRoot string AutomaticStartupAction uint16 // non-zero AutomaticStartupActionDelay time.Duration AutomaticStartupActionSequenceNumber uint16 AutomaticShutdownAction uint16 // non-zero AutomaticRecoveryAction uint16 // non-zero RecoveryFile string BIOSGUID string BIOSSerialNumber string BaseBoardSerialNumber string ChassisSerialNumber string Architecture string ChassisAssetTag string BIOSNumLock bool BootOrder []uint16 Parent string UserSnapshotType uint16 // non-zero IsSaved bool AdditionalRecoveryInformation string AllowFullSCSICommandSet bool DebugChannelId uint32 DebugPortEnabled uint16 DebugPort uint32 Version string IncrementalBackupEnabled bool VirtualNumaEnabled bool AllowReducedFcRedundancy bool // = False VirtualSystemSubType string BootSourceOrder []string PauseAfterBootFailure bool NetworkBootPreferredProtocol uint16 // non-zero GuestControlledCacheTypes bool AutomaticSnapshotsEnabled bool IsAutomaticSnapshot bool GuestStateFile string GuestStateDataRoot string LockOnDisconnect bool ParentPackage string AutomaticCriticalErrorActionTimeout time.Duration AutomaticCriticalErrorAction uint16 ConsoleMode uint16 SecureBootEnabled bool SecureBootTemplateId string LowMmioGapSize uint64 HighMmioGapSize uint64 EnhancedSessionTransportType uint16 } func DefaultSystemSettings() *SystemSettings { return &SystemSettings{ // setup all non-zero settings AutomaticStartupAction: 2, // no auto-start AutomaticShutdownAction: 4, // shutdown AutomaticRecoveryAction: 3, // restart UserSnapshotType: 2, // no snapshotting NetworkBootPreferredProtocol: 4096, // ipv4 for pxe VirtualSystemSubType: "Microsoft:Hyper-V:SubType:2", } } func (s *SystemSettings) Path() string { return s.S__PATH } func (s *SystemSettings) AddScsiController() (*ScsiControllerSettings, error) { const scsiControllerType = "Microsoft:Hyper-V:Synthetic SCSI Controller" controller := &ScsiControllerSettings{} if err := s.createSystemResourceInternal(controller, scsiControllerType, nil); err != nil { return nil, err } controller.systemSettings = s return controller, nil } func (s *SystemSettings) createSystemResourceInternal(settings interface{}, resourceType string, cb func()) error { var service *wmiext.Service var err error if service, err = NewLocalHyperVService(); err != nil { return err } defer service.Close() if err = populateDefaults(resourceType, settings); err != nil { return err } if cb != nil { cb() } resourceStr, err := createResourceSettingGeneric(settings, resourceType) if err != nil { return err } path, err := addResource(service, s.Path(), resourceStr) if err != nil { return err } err = service.GetObjectAsObject(path, settings) return err } func (s *SystemSettings) AddSyntheticEthernetPort(beforeAdd func(*SyntheticEthernetPortSettings)) (*SyntheticEthernetPortSettings, error) { const networkAdapterType = SyntheticEthernetPortResourceType port := &SyntheticEthernetPortSettings{} var cb func() if beforeAdd != nil { cb = func() { beforeAdd(port) } } if err := s.createSystemResourceInternal(port, networkAdapterType, cb); err != nil { return nil, err } port.systemSettings = s return port, nil } func addResource(service *wmiext.Service, systemSettingPath string, resourceSettings string) (string, error) { vsms, err := service.GetSingletonInstance(VirtualSystemManagementService) if err != nil { return "", err } defer vsms.Close() var res int32 var resultingSettings []string var job *wmiext.Instance err = vsms.BeginInvoke("AddResourceSettings"). In("AffectedConfiguration", systemSettingPath). In("ResourceSettings", []string{resourceSettings}). Execute(). Out("Job", &job). Out("ResultingResourceSettings", &resultingSettings). Out("ReturnValue", &res).End() if err != nil { return "", fmt.Errorf("AddResourceSettings failed: %w", err) } err = waitVMResult(res, service, job, "failed to add resource", nil) if len(resultingSettings) > 0 { return resultingSettings[0], err } return "", err } func (s *SystemSettings) GetVM() (*VirtualMachine, error) { var service *wmiext.Service var err error if service, err = NewLocalHyperVService(); err != nil { return nil, err } defer service.Close() inst, err := service.FindFirstRelatedInstance(s.Path(), "Msvm_ComputerSystem") if err != nil { return nil, err } defer inst.Close() vm := &VirtualMachine{} if err = inst.GetAll(vm); err != nil { return nil, err } return vm, nil }