property

package
v0.0.0-...-5f55900 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2024 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrConcurrentCollector = fmt.Errorf(
	"only one goroutine may invoke WaitForUpdates, WaitForUpdatesEx, " +
		"or CheckForUpdates on a given PropertyCollector")

ErrConcurrentCollector is returned from WaitForUpdates, WaitForUpdatesEx, or CheckForUpdates if any of those calls are unable to obtain an exclusive lock for the property collector.

Functions

func Wait

Wait creates a new WaitFilter and calls the specified function for each ObjectUpdate via WaitForUpdates

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/vmware/govmomi/find"
	"github.com/vmware/govmomi/property"
	"github.com/vmware/govmomi/simulator"
	"github.com/vmware/govmomi/vim25"
	"github.com/vmware/govmomi/vim25/types"
)

func main() {
	simulator.Run(func(ctx context.Context, c *vim25.Client) error {
		pc := property.DefaultCollector(c)

		vm, err := find.NewFinder(c).VirtualMachine(ctx, "DC0_H0_VM0")
		if err != nil {
			return err
		}

		// power off VM after some time
		go func() {
			time.Sleep(time.Millisecond * 100)
			_, err := vm.PowerOff(ctx)
			if err != nil {
				panic(err)
			}
		}()

		return property.Wait(ctx, pc, vm.Reference(), []string{"runtime.powerState"}, func(changes []types.PropertyChange) bool {
			for _, change := range changes {
				state := change.Val.(types.VirtualMachinePowerState)
				fmt.Println(state)
				if state == types.VirtualMachinePowerStatePoweredOff {
					return true
				}
			}

			// continue polling
			return false
		})
	})
}
Output:

poweredOn
poweredOff

func WaitForUpdates

func WaitForUpdates(
	ctx context.Context,
	c *Collector,
	filter *WaitFilter,
	onUpdatesFn func([]types.ObjectUpdate) bool) (result error)

WaitForUpdates waits for any of the specified properties of the specified managed object to change. It calls the specified function for every update it receives. If this function returns false, it continues waiting for subsequent updates. If this function returns true, it stops waiting and returns.

To only receive updates for the specified managed object, the function creates a new property collector and calls CreateFilter. A new property collector is required because filters can only be added, not removed.

If the Context is canceled, a call to CancelWaitForUpdates() is made and its error value is returned. The newly created collector is destroyed before this function returns (both in case of success or error).

By default, ObjectUpdate.MissingSet faults are not propagated to the returned error, set WaitFilter.PropagateMissing=true to enable MissingSet fault propagation.

func WaitForUpdatesEx

func WaitForUpdatesEx(
	ctx context.Context,
	pc *Collector,
	filter *WaitFilter,
	onUpdatesFn func([]types.ObjectUpdate) bool) (result error)

WaitForUpdates waits for any of the specified properties of the specified managed object to change. It calls the specified function for every update it receives. If this function returns false, it continues waiting for subsequent updates. If this function returns true, it stops waiting and returns.

If the Context is canceled, a call to CancelWaitForUpdates() is made and its error value is returned.

By default, ObjectUpdate.MissingSet faults are not propagated to the returned error, set WaitFilter.PropagateMissing=true to enable MissingSet fault propagation.

Types

type Collector

type Collector struct {
	// contains filtered or unexported fields
}

Collector models the PropertyCollector managed object.

For more information, see: http://pubs.vmware.com/vsphere-60/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.query.PropertyCollector.html

func DefaultCollector

func DefaultCollector(c *vim25.Client) *Collector

DefaultCollector returns the session's default property collector.

func (*Collector) CancelWaitForUpdates

func (p *Collector) CancelWaitForUpdates(ctx context.Context) error

func (*Collector) Create

func (p *Collector) Create(ctx context.Context) (*Collector, error)

Create creates a new session-specific Collector that can be used to retrieve property updates independent of any other Collector.

func (*Collector) CreateFilter

func (p *Collector) CreateFilter(ctx context.Context, req types.CreateFilter) (*Filter, error)

func (*Collector) Destroy

func (p *Collector) Destroy(ctx context.Context) error

Destroy destroys this Collector.

func (*Collector) Reference

func (p *Collector) Reference() types.ManagedObjectReference

func (*Collector) Retrieve

func (p *Collector) Retrieve(ctx context.Context, objs []types.ManagedObjectReference, ps []string, dst interface{}) error

Retrieve loads properties for a slice of managed objects. The dst argument must be a pointer to a []interface{}, which is populated with the instances of the specified managed objects, with the relevant properties filled in. If the properties slice is nil, all properties are loaded. Note that pointer types are optional fields that may be left as a nil value. The caller should check such fields for a nil value before dereferencing.

Example
package main

import (
	"context"
	"fmt"

	"github.com/vmware/govmomi/find"
	"github.com/vmware/govmomi/property"
	"github.com/vmware/govmomi/simulator"
	"github.com/vmware/govmomi/vim25"
	"github.com/vmware/govmomi/vim25/mo"
)

func main() {
	simulator.Run(func(ctx context.Context, c *vim25.Client) error {
		pc := property.DefaultCollector(c)

		obj, err := find.NewFinder(c).HostSystem(ctx, "DC0_H0")
		if err != nil {
			return err
		}

		var host mo.HostSystem
		err = pc.RetrieveOne(ctx, obj.Reference(), []string{"vm"}, &host)
		if err != nil {
			return err
		}

		var vms []mo.VirtualMachine
		err = pc.Retrieve(ctx, host.Vm, []string{"name"}, &vms)
		if err != nil {
			return err
		}

		fmt.Printf("host has %d vms:", len(vms))
		for i := range vms {
			fmt.Print(" ", vms[i].Name)
		}

		return nil
	})
}
Output:

host has 2 vms: DC0_H0_VM0 DC0_H0_VM1

func (*Collector) RetrieveOne

func (p *Collector) RetrieveOne(ctx context.Context, obj types.ManagedObjectReference, ps []string, dst interface{}) error

RetrieveOne calls Retrieve with a single managed object reference via Collector.Retrieve().

Example

Example to retrieve properties from a single object

package main

import (
	"context"
	"fmt"

	"github.com/vmware/govmomi/find"
	"github.com/vmware/govmomi/property"
	"github.com/vmware/govmomi/simulator"
	"github.com/vmware/govmomi/vim25"
	"github.com/vmware/govmomi/vim25/mo"
)

func main() {
	simulator.Run(func(ctx context.Context, c *vim25.Client) error {
		pc := property.DefaultCollector(c)

		obj, err := find.NewFinder(c).VirtualMachine(ctx, "DC0_H0_VM0")
		if err != nil {
			return err
		}

		var vm mo.VirtualMachine
		err = pc.RetrieveOne(ctx, obj.Reference(), []string{"config.version"}, &vm)
		if err != nil {
			return err
		}

		fmt.Printf("hardware version %s", vm.Config.Version)
		return nil
	})
}
Output:

hardware version vmx-13

func (*Collector) RetrieveProperties

func (p *Collector) RetrieveProperties(
	ctx context.Context,
	req types.RetrieveProperties,
	maxObjectsArgs ...int32) (*types.RetrievePropertiesResponse, error)

RetrieveProperties wraps RetrievePropertiesEx and ContinueRetrievePropertiesEx to collect properties in batches.

func (*Collector) RetrieveWithFilter

func (p *Collector) RetrieveWithFilter(
	ctx context.Context,
	objs []types.ManagedObjectReference,
	ps []string,
	dst interface{},
	filter Match) error

RetrieveWithFilter populates dst as Retrieve does, but only for entities that match the specified filter.

func (*Collector) WaitForUpdates deprecated

func (p *Collector) WaitForUpdates(
	ctx context.Context,
	version string,
	opts ...*types.WaitOptions) (*types.UpdateSet, error)

Deprecated: Please use WaitForUpdatesEx instead.

func (*Collector) WaitForUpdatesEx

func (p *Collector) WaitForUpdatesEx(
	ctx context.Context,
	opts *WaitOptions,
	onUpdatesFn func([]types.ObjectUpdate) bool) error

WaitForUpdatesEx waits for any of the specified properties of the specified managed object to change. It calls the specified function for every update it receives. If this function returns false, it continues waiting for subsequent updates. If this function returns true, it stops waiting and returns.

If the Context is canceled, a call to CancelWaitForUpdates() is made and its error value is returned.

By default, ObjectUpdate.MissingSet faults are not propagated to the returned error, set WaitFilter.PropagateMissing=true to enable MissingSet fault propagation.

Example (AddingRemovingPropertyFilters)
model := simulator.VPX()
model.Datacenter = 1
model.Cluster = 0
model.Pool = 0
model.Machine = 1
model.Autostart = false

simulator.Run(func(ctx context.Context, c *vim25.Client) error {
	// Set up the finder and get a VM.
	finder := find.NewFinder(c, true)
	datacenter, err := finder.DefaultDatacenter(ctx)
	if err != nil {
		return fmt.Errorf("default datacenter not found: %w", err)
	}
	finder.SetDatacenter(datacenter)
	vmList, err := finder.VirtualMachineList(ctx, "*")
	if len(vmList) == 0 {
		return fmt.Errorf("vmList == 0")
	}
	vm := vmList[0]

	pc, err := property.DefaultCollector(c).Create(ctx)
	if err != nil {
		return fmt.Errorf("failed to create new property collector: %w", err)
	}

	// Start a goroutine to wait for power state changes to the VM. They
	// should not be triggered as there is no property filter yet defined.
	chanResult := make(chan any)
	cancelCtx, cancel := context.WithCancel(ctx)
	defer cancel()
	go func() {
		if err := pc.WaitForUpdatesEx(
			cancelCtx,
			&property.WaitOptions{},
			func(updates []types.ObjectUpdate) bool {
				return waitForPowerStateChanges(
					cancelCtx,
					vm,
					chanResult,
					updates,
					types.VirtualMachinePowerStatePoweredOff)
			}); err != nil {

			chanResult <- err
			return
		}
	}()

	// Power on the VM to cause a property change.
	if _, err := vm.PowerOn(ctx); err != nil {
		return fmt.Errorf("error while powering on vm: %w", err)
	}

	// The power change should be ignored.
	select {
	case <-time.After(3 * time.Second):
		fmt.Println("poweredOn event not received")
	case result := <-chanResult:
		switch tResult := result.(type) {
		case types.VirtualMachinePowerState:
			return fmt.Errorf("update should not have been received without a property filter")
		case error:
			return fmt.Errorf("error while waiting for updates: %v", tResult)
		}
	}

	// Now create a property filter that will catch the update.
	pf, err := pc.CreateFilter(
		ctx,
		types.CreateFilter{Spec: getDatacenterToVMFolderFilter(datacenter)},
	)
	if err != nil {
		return fmt.Errorf("failed to create dc2vm property filter: %w", err)
	}

	// Power off the VM to cause a property change.
	if _, err := vm.PowerOff(ctx); err != nil {
		return fmt.Errorf("error while powering off vm: %w", err)
	}

	// The power change should now be noticed.
	select {
	case <-time.After(3 * time.Second):
		return fmt.Errorf("timed out while waiting for property update")
	case result := <-chanResult:
		switch tResult := result.(type) {
		case types.VirtualMachinePowerState:
			if tResult != types.VirtualMachinePowerStatePoweredOff {
				return fmt.Errorf("unexpected power state: %v", tResult)
			}
			fmt.Println("poweredOff event received")
		case error:
			return fmt.Errorf("error while waiting for updates: %w", tResult)
		}
	}

	// Destroy the property filter and repeat, and the power change should
	// once again be ignored.
	if err := pf.Destroy(ctx); err != nil {
		return fmt.Errorf("failed to destroy property filter: %w", err)
	}

	// Power on the VM to cause a property change.
	if _, err := vm.PowerOn(ctx); err != nil {
		return fmt.Errorf("error while powering on vm: %w", err)
	}

	// The power change should be ignored.
	select {
	case <-time.After(3 * time.Second):
		fmt.Println("poweredOn event not received")
	case result := <-chanResult:
		switch tResult := result.(type) {
		case types.VirtualMachinePowerState:
			return fmt.Errorf("update should not have been received after property filter was destroyed")
		case error:
			return fmt.Errorf("error while waiting for updates: %v", tResult)
		}
	}

	return nil
}, model)
Output:

poweredOn event not received
poweredOff event received
poweredOn event not received
Example (ErrConcurrentCollector)
simulator.Run(func(ctx context.Context, c *vim25.Client) error {
	pc := property.DefaultCollector(c)

	waitOptions := property.WaitOptions{
		Options: &types.WaitOptions{
			MaxWaitSeconds: addrOf(int32(1)),
		},
	}

	onUpdatesFn := func(_ []types.ObjectUpdate) bool {
		return false
	}

	waitForChanges := func(chanErr chan error) {
		defer close(chanErr)
		chanErr <- pc.WaitForUpdatesEx(ctx, &waitOptions, onUpdatesFn)
	}

	// Start two goroutines that wait for changes, but only one will begin
	// waiting -- the other will return property.ErrConcurrentCollector.
	chanErr1, chanErr2 := make(chan error), make(chan error)
	go waitForChanges(chanErr1)
	go waitForChanges(chanErr2)

	err1 := <-chanErr1
	err2 := <-chanErr2

	if err1 == nil && err2 == nil {
		return fmt.Errorf(
			"one of the WaitForUpdate calls should have returned %s",
			property.ErrConcurrentCollector)
	}

	if err1 == property.ErrConcurrentCollector &&
		err2 == property.ErrConcurrentCollector {

		return fmt.Errorf(
			"both of the WaitForUpdate calls returned %s",
			property.ErrConcurrentCollector)
	}

	fmt.Println("WaitForUpdatesEx call succeeded")
	fmt.Println("WaitForUpdatesEx call returned ErrConcurrentCollector")

	// The third WaitForUpdatesEx call should be able to successfully obtain
	// the lock since the other two calls are completed.
	if err := pc.WaitForUpdatesEx(ctx, &waitOptions, onUpdatesFn); err != nil {
		return fmt.Errorf(
			"unexpected error from third call to WaitForUpdatesEx: %s", err)
	}

	fmt.Println("WaitForUpdatesEx call succeeded")

	return nil
})
Output:

WaitForUpdatesEx call succeeded
WaitForUpdatesEx call returned ErrConcurrentCollector
WaitForUpdatesEx call succeeded
Example (Pagination)
package main

import (
	"context"
	"fmt"

	"github.com/vmware/govmomi/property"
	"github.com/vmware/govmomi/simulator"
	"github.com/vmware/govmomi/view"
	"github.com/vmware/govmomi/vim25"
	"github.com/vmware/govmomi/vim25/types"
)

func main() {
	model := simulator.VPX()
	model.Cluster = 3
	model.Machine = 42

	simulator.Run(func(ctx context.Context, c *vim25.Client) error {
		pc := property.DefaultCollector(c)
		m := view.NewManager(c)

		// Note: both types can be collected with 1 ContainerView and 1 PropertyFilter,
		// but we are creating 2 PropertyFilter for example purposes.
		kinds := []string{"HostSystem", "VirtualMachine"}
		for _, kind := range kinds {
			v, err := m.CreateContainerView(ctx, c.ServiceContent.RootFolder, []string{kind}, true)
			if err != nil {
				return err
			}

			defer v.Destroy(ctx)

			filter := new(property.WaitFilter).Add(v.Reference(), kind, []string{"name"}, v.TraversalSpec())

			f, err := pc.CreateFilter(ctx, filter.CreateFilter)
			if err != nil {
				return err
			}

			defer f.Destroy(ctx)
		}

		options := &property.WaitOptions{
			Options: &types.WaitOptions{MaxObjectUpdates: 50},
		}

		// Callback is invoked once for each FilterSet:
		// 1st WaitForUpdatesEx call returns 2 FilterSet, 10 hosts + 40 vms
		// Next 4 calls are 1 FilterSet of 50, 50 and 28 vms
		callbacks := 0
		objects := make(map[string]int)

		err := pc.WaitForUpdatesEx(ctx, options, func(updates []types.ObjectUpdate) bool {
			for _, update := range updates {
				objects[update.Obj.Type]++
			}
			callbacks++
			return options.Truncated == false
		})
		if err != nil {
			return err
		}

		fmt.Printf("%d Callbacks\n", callbacks)
		for _, kind := range kinds {
			fmt.Printf("%d %s\n", objects[kind], kind)
		}
		return nil
	}, model)
}
Output:

5 Callbacks
10 HostSystem
168 VirtualMachine

type Filter

type Filter struct {
	// contains filtered or unexported fields
}

Filter models the Filter managed object.

For more information, see: https://vdc-download.vmware.com/vmwb-repository/dcr-public/184bb3ba-6fa8-4574-a767-d0c96e2a38f4/ba9422ef-405c-47dd-8553-e11b619185b2/SDK/vsphere-ws/docs/ReferenceGuide/vmodl.query.PropertyCollector.Filter.html.

func (*Filter) Destroy

func (f *Filter) Destroy(ctx context.Context) error

Destroy destroys this filter.

This operation can be called explicitly, or it can take place implicitly when the session that created the filter is closed.

func (Filter) Reference

func (f Filter) Reference() types.ManagedObjectReference

type Match

type Match map[string]types.AnyType

Match provides methods for matching against types.DynamicProperty

func (Match) AnyList

func (m Match) AnyList(props []types.DynamicProperty) bool

AnyList returns true if any given props match.

func (Match) AnyObjectContent

func (m Match) AnyObjectContent(objects []types.ObjectContent) []types.ManagedObjectReference

AnyObjectContent returns a list of ObjectContent.Obj where the ObjectContent.PropSet matches any property.

func (Match) Keys

func (m Match) Keys() []string

Keys returns the Match map keys as a []string

func (Match) List

func (m Match) List(props []types.DynamicProperty) bool

List returns true if all given props match.

func (Match) ObjectContent

func (m Match) ObjectContent(objects []types.ObjectContent) []types.ManagedObjectReference

ObjectContent returns a list of ObjectContent.Obj where the ObjectContent.PropSet matches all properties the Filter.

func (Match) Property

func (m Match) Property(prop types.DynamicProperty) bool

Property returns true if an entry matches the given prop.

type WaitFilter

type WaitFilter struct {
	types.CreateFilter
	WaitOptions
}

WaitFilter provides helpers to construct a types.CreateFilter for use with property.Wait

func (*WaitFilter) Add

Add a new ObjectSpec and PropertySpec to the WaitFilter

type WaitOptions

type WaitOptions struct {
	Options          *types.WaitOptions
	PropagateMissing bool
	Truncated        bool
}

WaitOptions defines options for a property collector's WaitForUpdatesEx method.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL