debian-forge-composer/vendor/github.com/vmware/govmomi/property/collector.go
Achilleas Koutsou 3fd7092db5 go.mod: update osbuild/images to v0.156.0
tag v0.155.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.155.0

----------------
  * Fedora 43: add shadow-utils when LockRoot is enabled, update cloud-init service name (osbuild/images#1618)
    * Author: Achilleas Koutsou, Reviewers: Gianluca Zuccarelli, Michael Vogt
  * Update osbuild dependency commit ID to latest (osbuild/images#1609)
    * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger, Tomáš Hozza
  * Update snapshots to 20250626 (osbuild/images#1623)
    * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * distro/rhel9: xz compress azure-cvm image type [HMS-8587] (osbuild/images#1620)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro/rhel: introduce new image type: Azure SAP Apps [HMS-8738] (osbuild/images#1612)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro/rhel: move ansible-core to sap_extras_pkgset (osbuild/images#1624)
    * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Tomáš Hozza
  * github/create-tag: allow passing the version when run manually (osbuild/images#1621)
    * Author: Achilleas Koutsou, Reviewers: Lukáš Zapletal, Tomáš Hozza
  * rhel9: move image-config into pure YAML (HMS-8593) (osbuild/images#1616)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * test: split manifest checksums into separate files (osbuild/images#1625)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza

— Somewhere on the Internet, 2025-06-30

---

tag v0.156.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.156.0

----------------
  * Many: delete repositories for EOL distributions (HMS-7044) (osbuild/images#1607)
    * Author: Tomáš Hozza, Reviewers: Michael Vogt, Simon de Vlieger
  * RHSM/facts: add 'image-builder CLI' API type (osbuild/images#1640)
    * Author: Tomáš Hozza, Reviewers: Brian C. Lane, Simon de Vlieger
  * Update dependencies 2025-06-29 (osbuild/images#1628)
    * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza
  * Update osbuild dependency commit ID to latest (osbuild/images#1627)
    * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza
  * [RFC] image: drop `InstallWeakDeps` from image.DiskImage (osbuild/images#1642)
    * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger, Tomáš Hozza
  * build(deps): bump the go-deps group across 1 directory with 3 updates (osbuild/images#1632)
    * Author: dependabot[bot], Reviewers: SchutzBot, Tomáš Hozza
  * distro/rhel10: xz compress azure-cvm image type (osbuild/images#1638)
    * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Simon de Vlieger
  * distro: cleanup/refactor distro/{defs,generic} (HMS-8744) (osbuild/images#1570)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro: remove some hardcoded values from generic/images.go (osbuild/images#1636)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro: small tweaks for the YAML based imagetypes (osbuild/images#1622)
    * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger
  * fedora/wsl: packages and locale (osbuild/images#1635)
    * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza
  * image/many: make compression more generic (osbuild/images#1634)
    * Author: Simon de Vlieger, Reviewers: Brian C. Lane, Michael Vogt
  * manifest: handle content template name with spaces (osbuild/images#1641)
    * Author: Bryttanie, Reviewers: Brian C. Lane, Michael Vogt, Tomáš Hozza
  * many: implement gzip (osbuild/images#1633)
    * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza
  * rhel/azure: set GRUB_TERMINAL based on architecture [RHEL-91383] (osbuild/images#1626)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza

— Somewhere on the Internet, 2025-07-07

---
2025-07-14 13:13:20 +02:00

328 lines
8.4 KiB
Go

// © Broadcom. All Rights Reserved.
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
// SPDX-License-Identifier: Apache-2.0
package property
import (
"context"
"errors"
"fmt"
"sync"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
// ErrConcurrentCollector is returned from WaitForUpdates, WaitForUpdatesEx,
// or CheckForUpdates if any of those calls are unable to obtain an exclusive
// lock for the property collector.
var ErrConcurrentCollector = fmt.Errorf(
"only one goroutine may invoke WaitForUpdates, WaitForUpdatesEx, " +
"or CheckForUpdates on a given PropertyCollector")
// Collector models the PropertyCollector managed object.
//
// For more information, see:
// https://developer.broadcom.com/xapis/vsphere-web-services-api/latest/vmodl.query.PropertyCollector.html
type Collector struct {
mu sync.Mutex
roundTripper soap.RoundTripper
reference types.ManagedObjectReference
}
// DefaultCollector returns the session's default property collector.
func DefaultCollector(c *vim25.Client) *Collector {
p := Collector{
roundTripper: c,
reference: c.ServiceContent.PropertyCollector,
}
return &p
}
func (p *Collector) Reference() types.ManagedObjectReference {
return p.reference
}
// Create creates a new session-specific Collector that can be used to
// retrieve property updates independent of any other Collector.
func (p *Collector) Create(ctx context.Context) (*Collector, error) {
req := types.CreatePropertyCollector{
This: p.Reference(),
}
res, err := methods.CreatePropertyCollector(ctx, p.roundTripper, &req)
if err != nil {
return nil, err
}
newp := Collector{
roundTripper: p.roundTripper,
reference: res.Returnval,
}
return &newp, nil
}
// Destroy destroys this Collector.
func (p *Collector) Destroy(ctx context.Context) error {
req := types.DestroyPropertyCollector{
This: p.Reference(),
}
_, err := methods.DestroyPropertyCollector(ctx, p.roundTripper, &req)
if err != nil {
return err
}
p.reference = types.ManagedObjectReference{}
return nil
}
func (p *Collector) CreateFilter(ctx context.Context, req types.CreateFilter) (*Filter, error) {
req.This = p.Reference()
resp, err := methods.CreateFilter(ctx, p.roundTripper, &req)
if err != nil {
return nil, err
}
return &Filter{roundTripper: p.roundTripper, reference: resp.Returnval}, nil
}
// Deprecated: Please use WaitForUpdatesEx instead.
func (p *Collector) WaitForUpdates(
ctx context.Context,
version string,
opts ...*types.WaitOptions) (*types.UpdateSet, error) {
if !p.mu.TryLock() {
return nil, ErrConcurrentCollector
}
defer p.mu.Unlock()
req := types.WaitForUpdatesEx{
This: p.Reference(),
Version: version,
}
if len(opts) == 1 {
req.Options = opts[0]
} else if len(opts) > 1 {
panic("only one option may be specified")
}
res, err := methods.WaitForUpdatesEx(ctx, p.roundTripper, &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}
func (p *Collector) CancelWaitForUpdates(ctx context.Context) error {
req := &types.CancelWaitForUpdates{This: p.Reference()}
_, err := methods.CancelWaitForUpdates(ctx, p.roundTripper, req)
return err
}
// RetrieveProperties wraps RetrievePropertiesEx and ContinueRetrievePropertiesEx to collect properties in batches.
func (p *Collector) RetrieveProperties(
ctx context.Context,
req types.RetrieveProperties,
maxObjectsArgs ...int32) (*types.RetrievePropertiesResponse, error) {
var opts types.RetrieveOptions
if l := len(maxObjectsArgs); l > 1 {
return nil, fmt.Errorf("maxObjectsArgs accepts a single value")
} else if l == 1 {
opts.MaxObjects = maxObjectsArgs[0]
}
objects, err := mo.RetrievePropertiesEx(ctx, p.roundTripper, types.RetrievePropertiesEx{
This: p.Reference(),
SpecSet: req.SpecSet,
Options: opts,
})
if err != nil {
return nil, err
}
return &types.RetrievePropertiesResponse{Returnval: objects}, nil
}
// 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.
func (p *Collector) Retrieve(ctx context.Context, objs []types.ManagedObjectReference, ps []string, dst any) error {
if len(objs) == 0 {
return errors.New("object references is empty")
}
kinds := make(map[string]bool)
var propSet []types.PropertySpec
var objectSet []types.ObjectSpec
for _, obj := range objs {
if _, ok := kinds[obj.Type]; !ok {
spec := types.PropertySpec{
Type: obj.Type,
}
if len(ps) == 0 {
spec.All = types.NewBool(true)
} else {
spec.PathSet = ps
}
propSet = append(propSet, spec)
kinds[obj.Type] = true
}
objectSpec := types.ObjectSpec{
Obj: obj,
Skip: types.NewBool(false),
}
objectSet = append(objectSet, objectSpec)
}
req := types.RetrieveProperties{
SpecSet: []types.PropertyFilterSpec{
{
ObjectSet: objectSet,
PropSet: propSet,
},
},
}
res, err := p.RetrieveProperties(ctx, req)
if err != nil {
return err
}
if d, ok := dst.(*[]types.ObjectContent); ok {
*d = res.Returnval
return nil
}
return mo.LoadObjectContent(res.Returnval, dst)
}
// RetrieveWithFilter populates dst as Retrieve does, but only for entities
// that match the specified filter.
func (p *Collector) RetrieveWithFilter(
ctx context.Context,
objs []types.ManagedObjectReference,
ps []string,
dst any,
filter Match) error {
if len(filter) == 0 {
return p.Retrieve(ctx, objs, ps, dst)
}
var content []types.ObjectContent
err := p.Retrieve(ctx, objs, filter.Keys(), &content)
if err != nil {
return err
}
objs = filter.ObjectContent(content)
if len(objs) == 0 {
return nil
}
return p.Retrieve(ctx, objs, ps, dst)
}
// RetrieveOne calls Retrieve with a single managed object reference via Collector.Retrieve().
func (p *Collector) RetrieveOne(ctx context.Context, obj types.ManagedObjectReference, ps []string, dst any) error {
var objs = []types.ManagedObjectReference{obj}
return p.Retrieve(ctx, objs, ps, dst)
}
// 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 an update - including the empty filter set, which can occur if no
// objects are eligible for updates.
//
// If this function returns false, it continues waiting for
// subsequent updates. If this function returns true, it stops waiting and
// returns upon receiving the first non-empty filter set.
//
// 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.
func (p *Collector) WaitForUpdatesEx(
ctx context.Context,
opts *WaitOptions,
onUpdatesFn func([]types.ObjectUpdate) bool) error {
if !p.mu.TryLock() {
return ErrConcurrentCollector
}
defer p.mu.Unlock()
req := types.WaitForUpdatesEx{
This: p.Reference(),
Options: opts.Options,
}
for {
res, err := methods.WaitForUpdatesEx(ctx, p.roundTripper, &req)
if err != nil {
if ctx.Err() == context.Canceled {
return p.CancelWaitForUpdates(context.Background())
}
return err
}
set := res.Returnval
if set == nil {
if req.Options != nil && req.Options.MaxWaitSeconds != nil {
return nil // WaitOptions.MaxWaitSeconds exceeded
}
// Retry if the result came back empty
continue
}
req.Version = set.Version
opts.Truncated = false
if set.Truncated != nil {
opts.Truncated = *set.Truncated
}
if len(set.FilterSet) == 0 {
// Trigger callbacks in case callers need to be notified
// of the empty filter set.
_ = onUpdatesFn(make([]types.ObjectUpdate, 0))
}
for _, fs := range set.FilterSet {
if opts.PropagateMissing {
for i := range fs.ObjectSet {
for _, p := range fs.ObjectSet[i].MissingSet {
// Same behavior as mo.ObjectContentToType()
return soap.WrapVimFault(p.Fault.Fault)
}
}
}
if onUpdatesFn(fs.ObjectSet) {
return nil
}
}
}
}