github.com/vmware/govmomi@v0.37.2/govc/library/clone.go (about)

     1  /*
     2  Copyright (c) 2019 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package library
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"fmt"
    23  
    24  	"github.com/vmware/govmomi/govc/cli"
    25  	"github.com/vmware/govmomi/govc/flags"
    26  	"github.com/vmware/govmomi/vapi/vcenter"
    27  )
    28  
    29  type clone struct {
    30  	*flags.ClusterFlag
    31  	*flags.DatastoreFlag
    32  	*flags.FolderFlag
    33  	*flags.ResourcePoolFlag
    34  	*flags.HostSystemFlag
    35  	*flags.VirtualMachineFlag
    36  
    37  	profile string
    38  	ovf     bool
    39  	extra   bool
    40  	mac     bool
    41  }
    42  
    43  func init() {
    44  	cli.Register("library.clone", &clone{})
    45  }
    46  
    47  func (cmd *clone) Register(ctx context.Context, f *flag.FlagSet) {
    48  	cmd.ClusterFlag, ctx = flags.NewClusterFlag(ctx)
    49  	cmd.ClusterFlag.Register(ctx, f)
    50  
    51  	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
    52  	cmd.DatastoreFlag.Register(ctx, f)
    53  
    54  	cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx)
    55  	cmd.ResourcePoolFlag.Register(ctx, f)
    56  
    57  	cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
    58  	cmd.HostSystemFlag.Register(ctx, f)
    59  
    60  	cmd.FolderFlag, ctx = flags.NewFolderFlag(ctx)
    61  	cmd.FolderFlag.Register(ctx, f)
    62  
    63  	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
    64  	cmd.VirtualMachineFlag.Register(ctx, f)
    65  
    66  	f.BoolVar(&cmd.ovf, "ovf", false, "Clone as OVF (default is VM Template)")
    67  	f.BoolVar(&cmd.extra, "e", false, "Include extra configuration")
    68  	f.BoolVar(&cmd.mac, "m", false, "Preserve MAC-addresses on network adapters")
    69  	f.StringVar(&cmd.profile, "profile", "", "Storage profile")
    70  }
    71  
    72  func (cmd *clone) Process(ctx context.Context) error {
    73  	if err := cmd.ClusterFlag.Process(ctx); err != nil {
    74  		return err
    75  	}
    76  	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
    77  		return err
    78  	}
    79  	if err := cmd.ResourcePoolFlag.Process(ctx); err != nil {
    80  		return err
    81  	}
    82  	if err := cmd.HostSystemFlag.Process(ctx); err != nil {
    83  		return err
    84  	}
    85  	if err := cmd.FolderFlag.Process(ctx); err != nil {
    86  		return err
    87  	}
    88  	return cmd.VirtualMachineFlag.Process(ctx)
    89  }
    90  
    91  func (cmd *clone) Usage() string {
    92  	return "PATH NAME"
    93  }
    94  
    95  func (cmd *clone) Description() string {
    96  	return `Clone VM to Content Library PATH.
    97  
    98  By default, clone as a VM template (requires vCenter version 6.7U1 or higher).
    99  Clone as an OVF when the '-ovf' flag is specified.
   100  
   101  Examples:
   102    govc library.clone -vm template-vm my-content template-vm-item
   103    govc library.clone -ovf -vm template-vm my-content ovf-item`
   104  }
   105  
   106  func (cmd *clone) Run(ctx context.Context, f *flag.FlagSet) error {
   107  	path := f.Arg(0)
   108  	name := f.Arg(1)
   109  
   110  	vm, err := cmd.VirtualMachine()
   111  	if err != nil {
   112  		return err
   113  	}
   114  	if vm == nil || name == "" {
   115  		return flag.ErrHelp
   116  	}
   117  	ds, err := cmd.DatastoreIfSpecified()
   118  	if err != nil {
   119  		return err
   120  	}
   121  	folder, err := cmd.FolderOrDefault("vm")
   122  	if err != nil {
   123  		return err
   124  	}
   125  	host, err := cmd.HostSystemIfSpecified()
   126  	if err != nil {
   127  		return err
   128  	}
   129  	cluster, err := cmd.ClusterIfSpecified()
   130  	if err != nil {
   131  		return err
   132  	}
   133  	pool, err := cmd.ResourcePoolIfSpecified()
   134  	if err != nil {
   135  		return err
   136  	}
   137  
   138  	dsID := ""
   139  	if ds != nil {
   140  		dsID = ds.Reference().Value
   141  	}
   142  
   143  	c, err := cmd.FolderFlag.RestClient()
   144  	if err != nil {
   145  		return err
   146  	}
   147  
   148  	l, err := flags.ContentLibrary(ctx, c, path)
   149  	if err != nil {
   150  		return err
   151  	}
   152  
   153  	if cmd.ovf {
   154  		ovf := vcenter.OVF{
   155  			Spec: vcenter.CreateSpec{
   156  				Name: name,
   157  			},
   158  			Source: vcenter.ResourceID{
   159  				Value: vm.Reference().Value,
   160  			},
   161  			Target: vcenter.LibraryTarget{
   162  				LibraryID: l.ID,
   163  			},
   164  		}
   165  		if cmd.extra {
   166  			ovf.Spec.Flags = append(ovf.Spec.Flags, "EXTRA_CONFIG")
   167  		}
   168  		if cmd.mac {
   169  			ovf.Spec.Flags = append(ovf.Spec.Flags, "PRESERVE_MAC")
   170  		}
   171  		id, err := vcenter.NewManager(c).CreateOVF(ctx, ovf)
   172  		if err != nil {
   173  			return err
   174  		}
   175  		fmt.Println(id)
   176  		return nil
   177  	}
   178  
   179  	storage := &vcenter.DiskStorage{
   180  		Datastore: dsID,
   181  		StoragePolicy: &vcenter.StoragePolicy{
   182  			Policy: cmd.profile,
   183  			Type:   "USE_SOURCE_POLICY",
   184  		},
   185  	}
   186  	if cmd.profile != "" {
   187  		storage.StoragePolicy.Type = "USE_SPECIFIED_POLICY"
   188  	}
   189  
   190  	spec := vcenter.Template{
   191  		Name:          name,
   192  		Library:       l.ID,
   193  		DiskStorage:   storage,
   194  		VMHomeStorage: storage,
   195  		SourceVM:      vm.Reference().Value,
   196  		Placement: &vcenter.Placement{
   197  			Folder: folder.Reference().Value,
   198  		},
   199  	}
   200  	if pool != nil {
   201  		spec.Placement.ResourcePool = pool.Reference().Value
   202  	}
   203  	if host != nil {
   204  		spec.Placement.Host = host.Reference().Value
   205  	}
   206  	if cluster != nil {
   207  		spec.Placement.Cluster = cluster.Reference().Value
   208  	}
   209  
   210  	id, err := vcenter.NewManager(c).CreateTemplate(ctx, spec)
   211  	if err != nil {
   212  		return err
   213  	}
   214  
   215  	fmt.Println(id)
   216  
   217  	return nil
   218  }