github.com/vmware/govmomi@v0.37.1/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 }