123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- /*
- Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package nfc
- import (
- "context"
- "errors"
- "fmt"
- "io"
- "path"
- "github.com/vmware/govmomi/property"
- "github.com/vmware/govmomi/vim25"
- "github.com/vmware/govmomi/vim25/methods"
- "github.com/vmware/govmomi/vim25/mo"
- "github.com/vmware/govmomi/vim25/progress"
- "github.com/vmware/govmomi/vim25/soap"
- "github.com/vmware/govmomi/vim25/types"
- )
- type Lease struct {
- types.ManagedObjectReference
- c *vim25.Client
- }
- func NewLease(c *vim25.Client, ref types.ManagedObjectReference) *Lease {
- return &Lease{ref, c}
- }
- // Abort wraps methods.Abort
- func (l *Lease) Abort(ctx context.Context, fault *types.LocalizedMethodFault) error {
- req := types.HttpNfcLeaseAbort{
- This: l.Reference(),
- Fault: fault,
- }
- _, err := methods.HttpNfcLeaseAbort(ctx, l.c, &req)
- if err != nil {
- return err
- }
- return nil
- }
- // Complete wraps methods.Complete
- func (l *Lease) Complete(ctx context.Context) error {
- req := types.HttpNfcLeaseComplete{
- This: l.Reference(),
- }
- _, err := methods.HttpNfcLeaseComplete(ctx, l.c, &req)
- if err != nil {
- return err
- }
- return nil
- }
- // GetManifest wraps methods.GetManifest
- func (l *Lease) GetManifest(ctx context.Context) error {
- req := types.HttpNfcLeaseGetManifest{
- This: l.Reference(),
- }
- _, err := methods.HttpNfcLeaseGetManifest(ctx, l.c, &req)
- if err != nil {
- return err
- }
- return nil
- }
- // Progress wraps methods.Progress
- func (l *Lease) Progress(ctx context.Context, percent int32) error {
- req := types.HttpNfcLeaseProgress{
- This: l.Reference(),
- Percent: percent,
- }
- _, err := methods.HttpNfcLeaseProgress(ctx, l.c, &req)
- if err != nil {
- return err
- }
- return nil
- }
- type LeaseInfo struct {
- types.HttpNfcLeaseInfo
- Items []FileItem
- }
- func (l *Lease) newLeaseInfo(li *types.HttpNfcLeaseInfo, items []types.OvfFileItem) (*LeaseInfo, error) {
- info := &LeaseInfo{
- HttpNfcLeaseInfo: *li,
- }
- for _, device := range li.DeviceUrl {
- u, err := l.c.ParseURL(device.Url)
- if err != nil {
- return nil, err
- }
- if device.SslThumbprint != "" {
- // TODO: prefer host management IP
- l.c.SetThumbprint(u.Host, device.SslThumbprint)
- }
- if len(items) == 0 {
- // this is an export
- item := types.OvfFileItem{
- DeviceId: device.Key,
- Path: device.TargetId,
- Size: device.FileSize,
- }
- if item.Size == 0 {
- item.Size = li.TotalDiskCapacityInKB * 1024
- }
- if item.Path == "" {
- item.Path = path.Base(device.Url)
- }
- info.Items = append(info.Items, NewFileItem(u, item))
- continue
- }
- // this is an import
- for _, item := range items {
- if device.ImportKey == item.DeviceId {
- info.Items = append(info.Items, NewFileItem(u, item))
- break
- }
- }
- }
- return info, nil
- }
- func (l *Lease) Wait(ctx context.Context, items []types.OvfFileItem) (*LeaseInfo, error) {
- var lease mo.HttpNfcLease
- pc := property.DefaultCollector(l.c)
- err := property.Wait(ctx, pc, l.Reference(), []string{"state", "info", "error"}, func(pc []types.PropertyChange) bool {
- done := false
- for _, c := range pc {
- if c.Val == nil {
- continue
- }
- switch c.Name {
- case "error":
- val := c.Val.(types.LocalizedMethodFault)
- lease.Error = &val
- done = true
- case "info":
- val := c.Val.(types.HttpNfcLeaseInfo)
- lease.Info = &val
- case "state":
- lease.State = c.Val.(types.HttpNfcLeaseState)
- if lease.State != types.HttpNfcLeaseStateInitializing {
- done = true
- }
- }
- }
- return done
- })
- if err != nil {
- return nil, err
- }
- if lease.State == types.HttpNfcLeaseStateReady {
- return l.newLeaseInfo(lease.Info, items)
- }
- if lease.Error != nil {
- return nil, errors.New(lease.Error.LocalizedMessage)
- }
- return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State)
- }
- func (l *Lease) StartUpdater(ctx context.Context, info *LeaseInfo) *LeaseUpdater {
- return newLeaseUpdater(ctx, l, info)
- }
- func (l *Lease) Upload(ctx context.Context, item FileItem, f io.Reader, opts soap.Upload) error {
- if opts.Progress == nil {
- opts.Progress = item
- } else {
- opts.Progress = progress.Tee(item, opts.Progress)
- }
- // Non-disk files (such as .iso) use the PUT method.
- // Overwrite: t header is also required in this case (ovftool does the same)
- if item.Create {
- opts.Method = "PUT"
- opts.Headers = map[string]string{
- "Overwrite": "t",
- }
- } else {
- opts.Method = "POST"
- opts.Type = "application/x-vnd.vmware-streamVmdk"
- }
- return l.c.Upload(ctx, f, item.URL, &opts)
- }
- func (l *Lease) DownloadFile(ctx context.Context, file string, item FileItem, opts soap.Download) error {
- if opts.Progress == nil {
- opts.Progress = item
- } else {
- opts.Progress = progress.Tee(item, opts.Progress)
- }
- return l.c.DownloadFile(ctx, file, item.URL, &opts)
- }
|