Skip to content

Commit

Permalink
fix: support content library item uuid for hcp (#438)
Browse files Browse the repository at this point in the history
If a content library item is created, that this item is used for the `vsphere_uuid` in HCP. Stores the `content_library_item_uuid` into state and uses this value if present. otherwise, it uses the default.

Signed-off-by: Ryan Johnson <[email protected]>
  • Loading branch information
Ryan Johnson authored Jun 12, 2024
1 parent 8951b15 commit 597a7c8
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 7 deletions.
Binary file added .DS_Store
Binary file not shown.
23 changes: 18 additions & 5 deletions builder/vsphere/common/hcp_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,35 @@ import (

func GetVMMetadata(vm *driver.VirtualMachineDriver, state multistep.StateBag) map[string]string {
labels := make(map[string]string)

info, err := vm.Info("config.uuid", "config.annotation", "config.hardware", "resourcePool", "datastore", "network", "summary")
if err != nil || info == nil {
log.Printf("[TRACE] error extracting VM metadata: %s", err)
log.Printf("[TRACE] error extracting virtual machine metadata: %s", err)
return labels
}
if info.Config != nil {
labels["vsphere_uuid"] = info.Config.Uuid
// Saved the virtual machine UUID.
// If destroyed after import to content library, the UUID is not saved.
destroyAfterImport, ok := state.Get("destroy_vm").(bool)
if !ok || !destroyAfterImport {
labels["vsphere_uuid"] = info.Config.Uuid
}

// If the content library is used, save the content library item UUID.
if itemUuid, ok := state.Get("content_library_item_uuid").(string); ok {
labels["content_library_item_uuid"] = itemUuid
}

// VM description
// Save the virtual machine annotation, if exists.
if info.Config.Annotation != "" {
labels["annotation"] = info.Config.Annotation
}

// Hardware
// Save the basic virtual machine hardware summary.
labels["num_cpu"] = fmt.Sprintf("%d", info.Config.Hardware.NumCPU)
labels["memory_mb"] = fmt.Sprintf("%d", info.Config.Hardware.MemoryMB)
}

// Save the virtual machine resource pool, if exists.
if info.ResourcePool != nil {
p := vm.NewResourcePool(info.ResourcePool)
poolPath, err := p.Path()
Expand All @@ -40,6 +50,7 @@ func GetVMMetadata(vm *driver.VirtualMachineDriver, state multistep.StateBag) ma
}
}

// Save the virtual machine datastore.
for i, datastore := range info.Datastore {
dsr := datastore.Reference()
ds := vm.NewDatastore(&dsr)
Expand All @@ -54,6 +65,7 @@ func GetVMMetadata(vm *driver.VirtualMachineDriver, state multistep.StateBag) ma
}
}

// Save the virtual machine network.
for i, network := range info.Network {
net := network.Reference()
n := vm.NewNetwork(&net)
Expand All @@ -68,6 +80,7 @@ func GetVMMetadata(vm *driver.VirtualMachineDriver, state multistep.StateBag) ma
}
}

// Save the virtual machine content library datastore.
if datastores, ok := state.Get("content_library_datastore").([]string); ok {
for i, ds := range datastores {
if i == 0 {
Expand Down
18 changes: 16 additions & 2 deletions builder/vsphere/common/step_import_to_content_library.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ func (s *StepImportToContentLibrary) Run(_ context.Context, state multistep.Stat
}
ui.Say(fmt.Sprintf("Importing %s template %s to Content Library '%s' as the item '%s' with the description '%s'...",
vmTypeLabel, s.ContentLibConfig.Name, s.ContentLibConfig.Library, s.ContentLibConfig.Name, s.ContentLibConfig.Description))

if s.ContentLibConfig.Ovf {
err = s.importOvfTemplate(vm)
} else {
Expand All @@ -167,14 +168,27 @@ func (s *StepImportToContentLibrary) Run(_ context.Context, state multistep.Stat
return multistep.ActionHalt
}

// Add a tracer to the state to track if the Destroy parameter was used.
if s.ContentLibConfig.Destroy {
state.Put("destroy_vm", s.ContentLibConfig.Destroy)
}

// For HCP Packer metadata, we save the template's datastore in state.
// For HCP Packer metadata, save the content library item UUID in state.
itemUuid, err := vm.FindContentLibraryItemUUID(s.ContentLibConfig.Library, s.ContentLibConfig.Name)
if err != nil {
ui.Error(fmt.Sprintf("Failed to get content library item uuid: %s", err.Error()))
state.Put("error", err)
return multistep.ActionHalt
} else {
state.Put("content_library_item_uuid", itemUuid)
}

// For HCP Packer metadata, save the content library datastore name in state.
datastores, err := vm.FindContentLibraryTemplateDatastoreName(s.ContentLibConfig.Library)
if err != nil {
ui.Say(fmt.Sprintf("[TRACE] Failed to get Content Library datastore name: %s", err.Error()))
ui.Error(fmt.Sprintf("Failed to get content library datastore name: %s", err.Error()))
state.Put("error", err)
return multistep.ActionHalt
} else {
state.Put("content_library_datastore", datastores)
}
Expand Down
8 changes: 8 additions & 0 deletions builder/vsphere/driver/library.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ func (d *VCenterDriver) FindContentLibraryItem(libraryId string, name string) (*
return nil, fmt.Errorf("content library item %s not found", name)
}

func (d *VCenterDriver) FindContentLibraryItemUUID(libraryId string, name string) (string, error) {
item, err := d.FindContentLibraryItem(libraryId, name)
if err != nil {
return "", err
}
return item.ID, nil
}

func (d *VCenterDriver) FindContentLibraryFileDatastorePath(isoPath string) (string, error) {
log.Printf("Check if ISO path is a Content Library path")
err := d.restClient.Login(d.ctx)
Expand Down
23 changes: 23 additions & 0 deletions builder/vsphere/driver/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,29 @@ func (vm *VirtualMachineDriver) Datacenter() *object.Datacenter {
return vm.driver.datacenter
}

func (vm *VirtualMachineDriver) FindContentLibraryItemUUID(library string, name string) (string, error) {
err := vm.driver.restClient.Login(vm.driver.ctx)
if err != nil {
return "", err
}

l, err := vm.driver.FindContentLibraryByName(library)
if err != nil {
log.Printf("cannot find content library: %v", err)
vm.logout()
return "", err
}

item, err := vm.driver.FindContentLibraryItemUUID(l.library.ID, name)
if err != nil {
log.Printf("cannot find content library item: %v", err)
vm.logout()
return "", err
}

return item, nil
}

func (vm *VirtualMachineDriver) FindContentLibraryTemplateDatastoreName(library string) ([]string, error) {
err := vm.driver.restClient.Login(vm.driver.ctx)
if err != nil {
Expand Down

0 comments on commit 597a7c8

Please sign in to comment.