github.com/vmware/govmomi@v0.51.0/object/task.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package object 6 7 import ( 8 "context" 9 "fmt" 10 11 "github.com/vmware/govmomi/property" 12 "github.com/vmware/govmomi/task" 13 "github.com/vmware/govmomi/vim25" 14 "github.com/vmware/govmomi/vim25/methods" 15 "github.com/vmware/govmomi/vim25/progress" 16 "github.com/vmware/govmomi/vim25/types" 17 ) 18 19 // Task is a convenience wrapper around task.Task that keeps a reference to 20 // the client that was used to create it. This allows users to call the Wait() 21 // function with only a context parameter, instead of a context parameter, a 22 // soap.RoundTripper, and reference to the root property collector. 23 type Task struct { 24 Common 25 } 26 27 func NewTask(c *vim25.Client, ref types.ManagedObjectReference) *Task { 28 t := Task{ 29 Common: NewCommon(c, ref), 30 } 31 32 return &t 33 } 34 35 // Wait waits for a task to complete. 36 // NOTE: This method create a thread-safe PropertyCollector instance per-call, so it is thread safe. 37 // The downside of this approach is the additional resource usage on the vCenter side for each call. 38 func (t *Task) Wait(ctx context.Context) error { 39 _, err := t.WaitForResult(ctx, nil) 40 return err 41 } 42 43 // WaitForResult wait for a task to complete. 44 // NOTE: This method create a thread-safe PropertyCollector instance per-call, so it is thread safe. 45 // The downside of this approach is the additional resource usage on the vCenter side for each call. 46 func (t *Task) WaitForResult(ctx context.Context, s ...progress.Sinker) (taskInfo *types.TaskInfo, result error) { 47 var pr progress.Sinker 48 if len(s) == 1 { 49 pr = s[0] 50 } 51 p, err := property.DefaultCollector(t.c).Create(ctx) 52 if err != nil { 53 return nil, err 54 } 55 56 // Attempt to destroy the collector using the background context, as the 57 // specified context may have timed out or have been canceled. 58 defer func() { 59 if err := p.Destroy(context.Background()); err != nil { 60 if result == nil { 61 result = err 62 } else { 63 result = fmt.Errorf( 64 "destroy property collector failed with %s after failing to wait for updates: %w", 65 err, 66 result) 67 } 68 } 69 }() 70 71 return task.WaitEx(ctx, t.Reference(), p, pr) 72 } 73 74 // WaitEx waits for a task to complete. 75 // NOTE: This method use the same PropertyCollector instance in each call, thus reducing resource usage on the vCenter side. 76 // The downside of this approach is that this method is not thread safe. 77 func (t *Task) WaitEx(ctx context.Context) error { 78 _, err := t.WaitForResultEx(ctx, nil) 79 return err 80 } 81 82 // WaitForResultEx waits for a task to complete. 83 // NOTE: This method use the same PropertyCollector instance in each call, thus reducing resource usage on the vCenter side. 84 // The downside of this approach is that this method is not thread safe. 85 func (t *Task) WaitForResultEx(ctx context.Context, s ...progress.Sinker) (*types.TaskInfo, error) { 86 var pr progress.Sinker 87 if len(s) == 1 { 88 pr = s[0] 89 } 90 p := property.DefaultCollector(t.c) 91 return task.WaitEx(ctx, t.Reference(), p, pr) 92 } 93 94 func (t *Task) Cancel(ctx context.Context) error { 95 _, err := methods.CancelTask(ctx, t.Client(), &types.CancelTask{ 96 This: t.Reference(), 97 }) 98 99 return err 100 } 101 102 // SetState sets task state and optionally sets results or fault, as appropriate for state. 103 func (t *Task) SetState(ctx context.Context, state types.TaskInfoState, result types.AnyType, fault *types.LocalizedMethodFault) error { 104 req := types.SetTaskState{ 105 This: t.Reference(), 106 State: state, 107 Result: result, 108 Fault: fault, 109 } 110 _, err := methods.SetTaskState(ctx, t.Common.Client(), &req) 111 return err 112 } 113 114 // SetDescription updates task description to describe the current phase of the task. 115 func (t *Task) SetDescription(ctx context.Context, description types.LocalizableMessage) error { 116 req := types.SetTaskDescription{ 117 This: t.Reference(), 118 Description: description, 119 } 120 _, err := methods.SetTaskDescription(ctx, t.Common.Client(), &req) 121 return err 122 } 123 124 // UpdateProgress Sets percentage done for this task and recalculates overall percentage done. 125 // If a percentDone value of less than zero or greater than 100 is specified, 126 // a value of zero or 100 respectively is used. 127 func (t *Task) UpdateProgress(ctx context.Context, percentDone int) error { 128 req := types.UpdateProgress{ 129 This: t.Reference(), 130 PercentDone: int32(percentDone), 131 } 132 _, err := methods.UpdateProgress(ctx, t.Common.Client(), &req) 133 return err 134 }