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 }