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