github.com/vmware/govmomi@v0.37.1/govc/library/deploy.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/govc/importx" 27 "github.com/vmware/govmomi/object" 28 "github.com/vmware/govmomi/vapi/library" 29 "github.com/vmware/govmomi/vapi/vcenter" 30 "github.com/vmware/govmomi/vim25/types" 31 ) 32 33 type deploy struct { 34 *flags.DatastoreFlag 35 *flags.ResourcePoolFlag 36 *flags.HostSystemFlag 37 *flags.FolderFlag 38 *importx.OptionsFlag 39 40 profile string 41 config string 42 } 43 44 func init() { 45 cli.Register("library.deploy", &deploy{}) 46 } 47 48 func (cmd *deploy) Register(ctx context.Context, f *flag.FlagSet) { 49 cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx) 50 cmd.DatastoreFlag.Register(ctx, f) 51 52 cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx) 53 cmd.ResourcePoolFlag.Register(ctx, f) 54 55 cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) 56 cmd.HostSystemFlag.Register(ctx, f) 57 58 cmd.FolderFlag, ctx = flags.NewFolderFlag(ctx) 59 cmd.FolderFlag.Register(ctx, f) 60 61 cmd.OptionsFlag = new(importx.OptionsFlag) 62 cmd.OptionsFlag.Register(ctx, f) 63 64 f.StringVar(&cmd.profile, "profile", "", "Storage profile") 65 66 if cli.ShowUnreleased() { 67 f.StringVar(&cmd.config, "config", "", "VM config spec") 68 } 69 } 70 71 func (cmd *deploy) Process(ctx context.Context) error { 72 if err := cmd.DatastoreFlag.Process(ctx); err != nil { 73 return err 74 } 75 if err := cmd.ResourcePoolFlag.Process(ctx); err != nil { 76 return err 77 } 78 if err := cmd.HostSystemFlag.Process(ctx); err != nil { 79 return err 80 } 81 if err := cmd.FolderFlag.Process(ctx); err != nil { 82 return err 83 } 84 return cmd.OptionsFlag.Process(ctx) 85 } 86 87 func (cmd *deploy) Usage() string { 88 return "TEMPLATE [NAME]" 89 } 90 91 func (cmd *deploy) Description() string { 92 return `Deploy library OVF template. 93 94 Examples: 95 govc library.deploy /library_name/ovf_template vm_name 96 govc library.export /library_name/ovf_template/*.ovf # save local copy of .ovf 97 govc import.spec *.ovf > deploy.json # generate options from .ovf 98 # edit deploy.json as needed 99 govc library.deploy -options deploy.json /library_name/ovf_template` 100 } 101 102 func (cmd *deploy) Run(ctx context.Context, f *flag.FlagSet) error { 103 if f.NArg() > 2 { 104 return flag.ErrHelp 105 } 106 path := f.Arg(0) 107 name := f.Arg(1) 108 109 if name == "" && cmd.Options.Name != nil { 110 name = *cmd.Options.Name 111 } 112 113 vc, err := cmd.DatastoreFlag.Client() 114 if err != nil { 115 return err 116 } 117 cmd.KeepAlive(vc) 118 119 c, err := cmd.DatastoreFlag.RestClient() 120 if err != nil { 121 return err 122 } 123 cmd.KeepAlive(c) 124 125 m := vcenter.NewManager(c) 126 127 item, err := flags.ContentLibraryItem(ctx, c, path) 128 if err != nil { 129 return err 130 } 131 132 ds, err := cmd.DatastoreIfSpecified() 133 if err != nil { 134 return err 135 } 136 rp, err := cmd.ResourcePoolIfSpecified() 137 if err != nil { 138 return err 139 } 140 host, err := cmd.HostSystemIfSpecified() 141 if err != nil { 142 return err 143 } 144 hostID := "" 145 if rp == nil { 146 if host == nil { 147 rp, err = cmd.ResourcePoolFlag.ResourcePool() 148 } else { 149 rp, err = host.ResourcePool(ctx) 150 hostID = host.Reference().Value 151 } 152 if err != nil { 153 return err 154 } 155 } 156 folder, err := cmd.Folder() 157 if err != nil { 158 return err 159 } 160 finder, err := cmd.FolderFlag.Finder(false) 161 if err != nil { 162 return err 163 } 164 165 var networks []vcenter.NetworkMapping 166 for _, net := range cmd.Options.NetworkMapping { 167 if net.Network == "" { 168 continue 169 } 170 obj, err := finder.Network(ctx, net.Network) 171 if err != nil { 172 return err 173 } 174 networks = append(networks, vcenter.NetworkMapping{ 175 Key: net.Name, 176 Value: obj.Reference().Value, 177 }) 178 } 179 180 var properties []vcenter.Property 181 for _, prop := range cmd.Options.PropertyMapping { 182 properties = append(properties, vcenter.Property{ 183 ID: prop.Key, 184 Value: prop.Value, 185 }) 186 } 187 188 dsID := "" 189 if ds != nil { 190 dsID = ds.Reference().Value 191 } 192 193 cmd.FolderFlag.Log("Deploying library item...\n") 194 195 var ref *types.ManagedObjectReference 196 197 switch item.Type { 198 case library.ItemTypeOVF: 199 deploy := vcenter.Deploy{ 200 DeploymentSpec: vcenter.DeploymentSpec{ 201 Name: name, 202 DefaultDatastoreID: dsID, 203 AcceptAllEULA: true, 204 Annotation: cmd.Options.Annotation, 205 AdditionalParams: []vcenter.AdditionalParams{ 206 { 207 Class: vcenter.ClassDeploymentOptionParams, 208 Type: vcenter.TypeDeploymentOptionParams, 209 SelectedKey: cmd.Options.Deployment, 210 }, 211 { 212 Class: vcenter.ClassPropertyParams, 213 Type: vcenter.TypePropertyParams, 214 SelectedKey: cmd.Options.Deployment, 215 Properties: properties, 216 }, 217 }, 218 NetworkMappings: networks, 219 StorageProvisioning: cmd.Options.DiskProvisioning, 220 StorageProfileID: cmd.profile, 221 }, 222 Target: vcenter.Target{ 223 ResourcePoolID: rp.Reference().Value, 224 HostID: hostID, 225 FolderID: folder.Reference().Value, 226 }, 227 } 228 229 if cmd.config != "" { 230 deploy.VmConfigSpec = &vcenter.VmConfigSpec{ 231 Provider: "XML", 232 XML: cmd.config, 233 } 234 } 235 236 ref, err = m.DeployLibraryItem(ctx, item.ID, deploy) 237 if err != nil { 238 return err 239 } 240 case library.ItemTypeVMTX: 241 storage := &vcenter.DiskStorage{ 242 Datastore: dsID, 243 StoragePolicy: &vcenter.StoragePolicy{ 244 Policy: cmd.profile, 245 Type: "USE_SOURCE_POLICY", 246 }, 247 } 248 if cmd.profile != "" { 249 storage.StoragePolicy.Type = "USE_SPECIFIED_POLICY" 250 } 251 252 deploy := vcenter.DeployTemplate{ 253 Name: name, 254 Description: cmd.Options.Annotation, 255 DiskStorage: storage, 256 VMHomeStorage: storage, 257 Placement: &vcenter.Placement{ 258 ResourcePool: rp.Reference().Value, 259 Host: hostID, 260 Folder: folder.Reference().Value, 261 }, 262 } 263 ref, err = m.DeployTemplateLibraryItem(ctx, item.ID, deploy) 264 if err != nil { 265 return err 266 } 267 default: 268 return fmt.Errorf("unsupported library item type: %s", item.Type) 269 } 270 271 obj, err := finder.ObjectReference(ctx, *ref) 272 if err != nil { 273 return err 274 } 275 276 vm := obj.(*object.VirtualMachine) 277 278 return cmd.Deploy(vm, cmd.FolderFlag.OutputFlag) 279 }