github.com/vmware/govmomi@v0.51.0/cli/importx/vmdk.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 importx
     6  
     7  import (
     8  	"context"
     9  	"errors"
    10  	"flag"
    11  	"fmt"
    12  	"path"
    13  
    14  	"github.com/vmware/govmomi/cli"
    15  	"github.com/vmware/govmomi/cli/flags"
    16  	"github.com/vmware/govmomi/vmdk"
    17  )
    18  
    19  type disk struct {
    20  	*flags.DatastoreFlag
    21  	*flags.ResourcePoolFlag
    22  	*flags.FolderFlag
    23  	*flags.OutputFlag
    24  
    25  	force bool
    26  	info  bool
    27  }
    28  
    29  func init() {
    30  	cli.Register("import.vmdk", &disk{})
    31  }
    32  
    33  func (cmd *disk) Register(ctx context.Context, f *flag.FlagSet) {
    34  	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
    35  	cmd.DatastoreFlag.Register(ctx, f)
    36  	cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx)
    37  	cmd.ResourcePoolFlag.Register(ctx, f)
    38  	cmd.FolderFlag, ctx = flags.NewFolderFlag(ctx)
    39  	cmd.FolderFlag.Register(ctx, f)
    40  	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
    41  	cmd.OutputFlag.Register(ctx, f)
    42  
    43  	f.BoolVar(&cmd.force, "force", false, "Overwrite existing disk")
    44  	f.BoolVar(&cmd.info, "i", false, "Output vmdk info only")
    45  }
    46  
    47  func (cmd *disk) Process(ctx context.Context) error {
    48  	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
    49  		return err
    50  	}
    51  	if err := cmd.ResourcePoolFlag.Process(ctx); err != nil {
    52  		return err
    53  	}
    54  	if err := cmd.FolderFlag.Process(ctx); err != nil {
    55  		return err
    56  	}
    57  	if err := cmd.OutputFlag.Process(ctx); err != nil {
    58  		return err
    59  	}
    60  	return nil
    61  }
    62  
    63  func (cmd *disk) Usage() string {
    64  	return "PATH_TO_VMDK [REMOTE_DIRECTORY]"
    65  }
    66  
    67  func (cmd *disk) Description() string {
    68  	return `Import vmdk to datastore.
    69  
    70  The local vmdk must be in streamOptimized format.
    71  
    72  Examples:
    73    govc import.vmdk my.vmdk
    74    govc import.vmdk -i my.vmdk # output vmdk info only
    75    govc import.vmdk -json -i my.vmdk | jq .capacity | xargs numfmt --to=iec --suffix=B --format="%.1f"`
    76  }
    77  
    78  func (cmd *disk) Run(ctx context.Context, f *flag.FlagSet) error {
    79  	args := f.Args()
    80  	if len(args) < 1 {
    81  		return errors.New("no file to import")
    82  	}
    83  
    84  	src := f.Arg(0)
    85  
    86  	if cmd.info {
    87  		info, err := vmdk.Stat(src)
    88  		if err != nil {
    89  			if err == vmdk.ErrInvalidFormat {
    90  				return formatError(src, err)
    91  			}
    92  			return err
    93  		}
    94  		return cmd.WriteResult(info)
    95  	}
    96  
    97  	c, err := cmd.DatastoreFlag.Client()
    98  	if err != nil {
    99  		return err
   100  	}
   101  
   102  	dc, err := cmd.DatastoreFlag.Datacenter()
   103  	if err != nil {
   104  		return err
   105  	}
   106  
   107  	ds, err := cmd.DatastoreFlag.Datastore()
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	pool, err := cmd.ResourcePoolFlag.ResourcePool()
   113  	if err != nil {
   114  		return err
   115  	}
   116  
   117  	folder, err := cmd.FolderOrDefault("vm")
   118  	if err != nil {
   119  		return err
   120  	}
   121  
   122  	logger := cmd.ProgressLogger(fmt.Sprintf("Uploading %s... ", path.Base(src)))
   123  	defer logger.Wait()
   124  
   125  	p := vmdk.ImportParams{
   126  		Path:       f.Arg(1),
   127  		Logger:     logger,
   128  		Type:       "", // TODO: flag
   129  		Force:      cmd.force,
   130  		Datacenter: dc,
   131  		Pool:       pool,
   132  		Folder:     folder,
   133  	}
   134  
   135  	err = vmdk.Import(ctx, c, src, ds, p)
   136  	if err != nil && err == vmdk.ErrInvalidFormat {
   137  		return formatError(src, err)
   138  	}
   139  
   140  	return err
   141  }
   142  
   143  func formatError(src string, err error) error {
   144  	return fmt.Errorf(`%s
   145  The vmdk can be converted using one of:
   146    vmware-vdiskmanager -t 5 -r '%s' new.vmdk
   147    qemu-img convert -O vmdk -o subformat=streamOptimized '%s' new.vmdk`, err, src, src)
   148  }