// GetVM returns a working blank VM created by the factory.
GetVM returns a working blank VM created by the factory.
// GetVM returns a working blank VM created by the factory .
func (f *factory) GetVM(ctx context.Context, config vc.VMConfig) (*vc.VM, error) {
	span, _ := trace(ctx, "GetVM")
	defer span.Finish()
	hypervisorConfig := config.HypervisorConfig
	err := f.validateNewVMConfig(config)
	if err != nil {
		f.log().WithError(err).Error("invalid hypervisor config")
		return nil, err
	}
	err = f.checkConfig(config)
	if err != nil {
		f.log().WithError(err).Info("fallback to direct factory vm")
		return direct.New(ctx, config).GetBaseVM(ctx, config)
	}
	f.log().Info("get base VM")
	vm, err := f.base.GetBaseVM(ctx, config)
	if err != nil {
		f.log().WithError(err).Error("failed to get base VM")
		return nil, err
	}
	defer func() {
		if err != nil {
			f.log().WithError(err).Error("clean up vm")
			vm.Stop()
		}
	}()
	err = vm.Resume()
	if err != nil {
		return nil, err
	}
	err = vm.ReseedRNG()
	if err != nil {
		return nil, err
	}
	err = vm.SyncTime()
	if err != nil {
		return nil, err
	}
	online := false
	baseConfig := f.base.Config().HypervisorConfig
	if baseConfig.NumVCPUs < hypervisorConfig.NumVCPUs {
		err = vm.AddCPUs(hypervisorConfig.NumVCPUs - baseConfig.NumVCPUs)
		if err != nil {
			return nil, err
		}
		online = true
	}
	if baseConfig.MemorySize < hypervisorConfig.MemorySize {
		err = vm.AddMemory(hypervisorConfig.MemorySize - baseConfig.MemorySize)
		if err != nil {
			return nil, err
		}
		online = true
	}
	if online {
		err = vm.OnlineCPUMemory()
		if err != nil {
			return nil, err
		}
	}
	return vm, nil
}
func ( f * factory ) GetVM ( ctx context . Context , config vc . VMConfig ) ( * vc . VM , error ) { span , _ := trace ( ctx , " " ) defer span . Finish ( ) hypervisorConfig := config . HypervisorConfig err := f . validateNewVMConfig ( config ) if err != nil { f . log ( ) . WithError ( err ) . Error ( " " ) return nil , err } err = f . checkConfig ( config ) if err != nil { f . log ( ) . WithError ( err ) . Info ( " " ) return direct . New ( ctx , config ) . GetBaseVM ( ctx , config ) } f . log ( ) . Info ( " " ) vm , err := f . base . GetBaseVM ( ctx , config ) if err != nil { f . log ( ) . WithError ( err ) . Error ( " " ) return nil , err } defer func ( ) { if err != nil { f . log ( ) . WithError ( err ) . Error ( " " ) vm . Stop ( ) } } ( ) err = vm . Resume ( ) if err != nil { return nil , err } err = vm . ReseedRNG ( ) if err != nil { return nil , err } err = vm . SyncTime ( ) if err != nil { return nil , err } online := false baseConfig := f . base . Config ( ) . HypervisorConfig if baseConfig . NumVCPUs < hypervisorConfig . NumVCPUs { err = vm . AddCPUs ( hypervisorConfig . NumVCPUs - baseConfig . NumVCPUs ) if err != nil { return nil , err } online = true } if baseConfig . MemorySize < hypervisorConfig . MemorySize { err = vm . AddMemory ( hypervisorConfig . MemorySize - baseConfig . MemorySize ) if err != nil { return nil , err } online = true } if online { err = vm . OnlineCPUMemory ( ) if err != nil { return nil , err } } return vm , nil }
GetVM returns a working blank VM created by the factory.
GetVM returns a working blank VM created by the factory .
// cleanup upon error // reseed RNG so that shared memory VMs do not generate same random numbers. // sync guest time since we might have paused it for a long time.