task.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. Copyright (c) 2017 VMware, Inc. All Rights Reserved.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package simulator
  14. import (
  15. "fmt"
  16. "reflect"
  17. "strings"
  18. "time"
  19. "github.com/vmware/govmomi/vim25/mo"
  20. "github.com/vmware/govmomi/vim25/types"
  21. )
  22. const vTaskSuffix = "_Task" // vmomi suffix
  23. const sTaskSuffix = "Task" // simulator suffix (avoiding golint warning)
  24. type Task struct {
  25. mo.Task
  26. Execute func(*Task) (types.AnyType, types.BaseMethodFault)
  27. }
  28. func NewTask(runner TaskRunner) *Task {
  29. ref := runner.Reference()
  30. name := reflect.TypeOf(runner).Elem().Name()
  31. name = strings.Replace(name, "VM", "Vm", 1) // "VM" for the type to make go-lint happy, but "Vm" for the vmodl ID
  32. return CreateTask(ref, name, runner.Run)
  33. }
  34. func CreateTask(e mo.Reference, name string, run func(*Task) (types.AnyType, types.BaseMethodFault)) *Task {
  35. ref := e.Reference()
  36. id := name
  37. if strings.HasSuffix(id, sTaskSuffix) {
  38. id = id[:len(id)-len(sTaskSuffix)]
  39. name = id + vTaskSuffix
  40. }
  41. task := &Task{
  42. Execute: run,
  43. }
  44. task.Self = Map.newReference(task)
  45. task.Info.Key = task.Self.Value
  46. task.Info.Task = task.Self
  47. task.Info.Name = ucFirst(name)
  48. task.Info.DescriptionId = fmt.Sprintf("%s.%s", ref.Type, id)
  49. task.Info.Entity = &ref
  50. task.Info.EntityName = ref.Value
  51. task.Info.Reason = &types.TaskReasonUser{UserName: "vcsim"} // TODO: Context.Session.User
  52. task.Info.QueueTime = time.Now()
  53. task.Info.State = types.TaskInfoStateQueued
  54. Map.Put(task)
  55. return task
  56. }
  57. type TaskRunner interface {
  58. mo.Reference
  59. Run(*Task) (types.AnyType, types.BaseMethodFault)
  60. }
  61. func (t *Task) Run() types.ManagedObjectReference {
  62. now := time.Now()
  63. Map.Update(t, []types.PropertyChange{
  64. {Name: "info.startTime", Val: now},
  65. {Name: "info.state", Val: types.TaskInfoStateRunning},
  66. })
  67. res, err := t.Execute(t)
  68. state := types.TaskInfoStateSuccess
  69. var fault interface{}
  70. if err != nil {
  71. state = types.TaskInfoStateError
  72. fault = types.LocalizedMethodFault{
  73. Fault: err,
  74. LocalizedMessage: fmt.Sprintf("%T", err),
  75. }
  76. }
  77. now = time.Now()
  78. Map.Update(t, []types.PropertyChange{
  79. {Name: "info.completeTime", Val: now},
  80. {Name: "info.state", Val: state},
  81. {Name: "info.result", Val: res},
  82. {Name: "info.error", Val: fault},
  83. })
  84. return t.Self
  85. }