1/*
2Copyright (c) 2014-2017 VMware, Inc. All Rights Reserved.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package importx
18
19import (
20	"context"
21	"errors"
22	"flag"
23	"fmt"
24	"path"
25
26	"github.com/vmware/govmomi/govc/cli"
27	"github.com/vmware/govmomi/govc/flags"
28	"github.com/vmware/govmomi/vmdk"
29)
30
31type disk struct {
32	*flags.DatastoreFlag
33	*flags.ResourcePoolFlag
34	*flags.FolderFlag
35	*flags.OutputFlag
36
37	force bool
38}
39
40func init() {
41	cli.Register("import.vmdk", &disk{})
42}
43
44func (cmd *disk) Register(ctx context.Context, f *flag.FlagSet) {
45	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
46	cmd.DatastoreFlag.Register(ctx, f)
47	cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx)
48	cmd.ResourcePoolFlag.Register(ctx, f)
49	cmd.FolderFlag, ctx = flags.NewFolderFlag(ctx)
50	cmd.FolderFlag.Register(ctx, f)
51	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
52	cmd.OutputFlag.Register(ctx, f)
53
54	f.BoolVar(&cmd.force, "force", false, "Overwrite existing disk")
55}
56
57func (cmd *disk) Process(ctx context.Context) error {
58	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
59		return err
60	}
61	if err := cmd.ResourcePoolFlag.Process(ctx); err != nil {
62		return err
63	}
64	if err := cmd.FolderFlag.Process(ctx); err != nil {
65		return err
66	}
67	if err := cmd.OutputFlag.Process(ctx); err != nil {
68		return err
69	}
70	return nil
71}
72
73func (cmd *disk) Usage() string {
74	return "PATH_TO_VMDK [REMOTE_DIRECTORY]"
75}
76
77func (cmd *disk) Run(ctx context.Context, f *flag.FlagSet) error {
78	args := f.Args()
79	if len(args) < 1 {
80		return errors.New("no file to import")
81	}
82
83	src := f.Arg(0)
84
85	c, err := cmd.DatastoreFlag.Client()
86	if err != nil {
87		return err
88	}
89
90	dc, err := cmd.DatastoreFlag.Datacenter()
91	if err != nil {
92		return err
93	}
94
95	ds, err := cmd.DatastoreFlag.Datastore()
96	if err != nil {
97		return err
98	}
99
100	pool, err := cmd.ResourcePoolFlag.ResourcePool()
101	if err != nil {
102		return err
103	}
104
105	folder, err := cmd.FolderOrDefault("vm")
106	if err != nil {
107		return err
108	}
109
110	logger := cmd.ProgressLogger(fmt.Sprintf("Uploading %s... ", path.Base(src)))
111	defer logger.Wait()
112
113	p := vmdk.ImportParams{
114		Path:       f.Arg(1),
115		Logger:     logger,
116		Type:       "", // TODO: flag
117		Force:      cmd.force,
118		Datacenter: dc,
119		Pool:       pool,
120		Folder:     folder,
121	}
122
123	err = vmdk.Import(ctx, c, src, ds, p)
124	if err != nil && err == vmdk.ErrInvalidFormat {
125		return fmt.Errorf(`%s
126The vmdk can be converted using one of:
127  vmware-vdiskmanager -t 5 -r '%s' new.vmdk
128  qemu-img convert -O vmdk -o subformat=streamOptimized '%s' new.vmdk`, err, src, src)
129	}
130
131	return err
132}
133