func (w *virtualMachineCustomizationWaiter) wait(client *govmomi.Client, vm *object.VirtualMachine, timeout int) error {
	// A timeout of less than 1 minute (zero or negative value) skips the waiter,
	// so we return immediately.
	if timeout < 1 {
		return nil
	}

	// Our listener loop callback.
	cbErr := make(chan error, 1)
	cb := func(obj types.ManagedObjectReference, page []types.BaseEvent) error {
		for _, be := range page {
			switch e := be.(type) {
			case types.BaseCustomizationFailed:
				cbErr <- errors.New(e.GetCustomizationFailed().GetEvent().FullFormattedMessage)
			case *types.CustomizationSucceeded:
				close(cbErr)
			}
		}
		return nil
	}

	mgr := event.NewManager(client.Client)
	mgrErr := make(chan error, 1)
	// Make a proper background context so that we can gracefully cancel the
	// subscriber when we are done with it. This eventually gets passed down to
	// the property collector SOAP calls.
	pctx, pcancel := context.WithCancel(context.Background())
	defer pcancel()
	go func() {
		mgrErr <- mgr.Events(pctx, []types.ManagedObjectReference{vm.Reference()}, 10, true, false, cb)
	}()

	// Wait for any error condition (including nil from the closure of the
	// callback error channel on success). We also use a different context so
	// that we can give a better error message on timeout without interfering
	// with the subscriber's context.
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Minute)
	defer cancel()
	var err error
	select {
	case <-ctx.Done():
		if ctx.Err() == context.DeadlineExceeded {
			err = fmt.Errorf("timeout waiting for customization to complete")
		}
	case err = <-mgrErr:
	case err = <-cbErr:
	}
	return err
}
func (w *virtualMachineCustomizationWaiter) wait(client *govmomi.Client, vm *object.VirtualMachine, timeout int) error {
	
	
	if timeout < 1 {
		return nil
	}

	
	cbErr := make(chan error, 1)
	cb := func(obj types.ManagedObjectReference, page []types.BaseEvent) error {
		for _, be := range page {
			switch e := be.(type) {
			case types.BaseCustomizationFailed:
				cbErr <- errors.New(e.GetCustomizationFailed().GetEvent().FullFormattedMessage)
			case *types.CustomizationSucceeded:
				close(cbErr)
			}
		}
		return nil
	}

	mgr := event.NewManager(client.Client)
	mgrErr := make(chan error, 1)
	
	
	
	pctx, pcancel := context.WithCancel(context.Background())
	defer pcancel()
	go func() {
		mgrErr <- mgr.Events(pctx, []types.ManagedObjectReference{vm.Reference()}, 10, true, false, cb)
	}()

	
	
	
	
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Minute)
	defer cancel()
	var err error
	select {
	case <-ctx.Done():
		if ctx.Err() == context.DeadlineExceeded {
			err = fmt.Errorf("timeout waiting for customization to complete")
		}
	case err = <-mgrErr:
	case err = <-cbErr:
	}
	return err
}
func ( w * virtualMachineCustomizationWaiter ) wait ( client * govmomi . Client , vm * object . VirtualMachine , timeout int ) error { // A timeout of less than 1 minute (zero or negative value) skips the waiter, // so we return immediately. if timeout < 1 { return nil } // Our listener loop callback. cbErr := make ( chan error , 1 ) cb := func ( obj types . ManagedObjectReference , page [ ] types . BaseEvent ) error { for _ , be := range page { switch e := be . ( type ) { case types . BaseCustomizationFailed : cbErr <- errors . New ( e . GetCustomizationFailed ( ) . GetEvent ( ) . FullFormattedMessage ) case * types . CustomizationSucceeded : close ( cbErr ) } } return nil } mgr := event . NewManager ( client . Client ) mgrErr := make ( chan error , 1 ) // Make a proper background context so that we can gracefully cancel the // subscriber when we are done with it. This eventually gets passed down to // the property collector SOAP calls. pctx , pcancel := context . WithCancel ( context . Background ( ) ) defer pcancel ( ) go func ( ) { mgrErr <- mgr . Events ( pctx , [ ] types . ManagedObjectReference { vm . Reference ( ) } , 10 , true , false , cb ) } ( ) // Wait for any error condition (including nil from the closure of the // callback error channel on success). We also use a different context so // that we can give a better error message on timeout without interfering // with the subscriber's context. ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Duration ( timeout ) * time . Minute ) defer cancel ( ) var err error select { case <- ctx . Done ( ) : if ctx . Err ( ) == context . DeadlineExceeded { err = fmt . Errorf ( " " ) } case err = <- mgrErr : case err = <- cbErr : } return err }
// wait waits for the customization of a supplied VirtualMachine to complete,
// either due to success or error. It does this by watching specifically for
// CustomizationSucceeded and CustomizationFailed events. If the customization
// failed due to some sort of error, the full formatted message is returned as
// an error.
wait waits for the customization of a supplied VirtualMachine to complete either due to success or error . It does this by watching specifically for CustomizationSucceeded and CustomizationFailed events . If the customization failed due to some sort of error the full formatted message is returned as an error .